WIP: bootstrap and partial real Solana watcher implementation
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
import * as util from "../core/util.js";
|
||||
const error = () => {
|
||||
const Sizable = {
|
||||
string: { unit: "caràcters", verb: "contenir" },
|
||||
file: { unit: "bytes", verb: "contenir" },
|
||||
array: { unit: "elements", verb: "contenir" },
|
||||
set: { unit: "elements", verb: "contenir" },
|
||||
};
|
||||
function getSizing(origin) {
|
||||
return Sizable[origin] ?? null;
|
||||
}
|
||||
const FormatDictionary = {
|
||||
regex: "entrada",
|
||||
email: "adreça electrònica",
|
||||
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: "data i hora ISO",
|
||||
date: "data ISO",
|
||||
time: "hora ISO",
|
||||
duration: "durada ISO",
|
||||
ipv4: "adreça IPv4",
|
||||
ipv6: "adreça IPv6",
|
||||
cidrv4: "rang IPv4",
|
||||
cidrv6: "rang IPv6",
|
||||
base64: "cadena codificada en base64",
|
||||
base64url: "cadena codificada en base64url",
|
||||
json_string: "cadena JSON",
|
||||
e164: "número E.164",
|
||||
jwt: "JWT",
|
||||
template_literal: "entrada",
|
||||
};
|
||||
const TypeDictionary = {
|
||||
nan: "NaN",
|
||||
};
|
||||
return (issue) => {
|
||||
switch (issue.code) {
|
||||
case "invalid_type": {
|
||||
const expected = TypeDictionary[issue.expected] ?? issue.expected;
|
||||
const receivedType = util.parsedType(issue.input);
|
||||
const received = TypeDictionary[receivedType] ?? receivedType;
|
||||
if (/^[A-Z]/.test(issue.expected)) {
|
||||
return `Tipus invàlid: s'esperava instanceof ${issue.expected}, s'ha rebut ${received}`;
|
||||
}
|
||||
return `Tipus invàlid: s'esperava ${expected}, s'ha rebut ${received}`;
|
||||
}
|
||||
case "invalid_value":
|
||||
if (issue.values.length === 1)
|
||||
return `Valor invàlid: s'esperava ${util.stringifyPrimitive(issue.values[0])}`;
|
||||
return `Opció invàlida: s'esperava una de ${util.joinValues(issue.values, " o ")}`;
|
||||
case "too_big": {
|
||||
const adj = issue.inclusive ? "com a màxim" : "menys de";
|
||||
const sizing = getSizing(issue.origin);
|
||||
if (sizing)
|
||||
return `Massa gran: s'esperava que ${issue.origin ?? "el valor"} contingués ${adj} ${issue.maximum.toString()} ${sizing.unit ?? "elements"}`;
|
||||
return `Massa gran: s'esperava que ${issue.origin ?? "el valor"} fos ${adj} ${issue.maximum.toString()}`;
|
||||
}
|
||||
case "too_small": {
|
||||
const adj = issue.inclusive ? "com a mínim" : "més de";
|
||||
const sizing = getSizing(issue.origin);
|
||||
if (sizing) {
|
||||
return `Massa petit: s'esperava que ${issue.origin} contingués ${adj} ${issue.minimum.toString()} ${sizing.unit}`;
|
||||
}
|
||||
return `Massa petit: s'esperava que ${issue.origin} fos ${adj} ${issue.minimum.toString()}`;
|
||||
}
|
||||
case "invalid_format": {
|
||||
const _issue = issue;
|
||||
if (_issue.format === "starts_with") {
|
||||
return `Format invàlid: ha de començar amb "${_issue.prefix}"`;
|
||||
}
|
||||
if (_issue.format === "ends_with")
|
||||
return `Format invàlid: ha d'acabar amb "${_issue.suffix}"`;
|
||||
if (_issue.format === "includes")
|
||||
return `Format invàlid: ha d'incloure "${_issue.includes}"`;
|
||||
if (_issue.format === "regex")
|
||||
return `Format invàlid: ha de coincidir amb el patró ${_issue.pattern}`;
|
||||
return `Format invàlid per a ${FormatDictionary[_issue.format] ?? issue.format}`;
|
||||
}
|
||||
case "not_multiple_of":
|
||||
return `Número invàlid: ha de ser múltiple de ${issue.divisor}`;
|
||||
case "unrecognized_keys":
|
||||
return `Clau${issue.keys.length > 1 ? "s" : ""} no reconeguda${issue.keys.length > 1 ? "s" : ""}: ${util.joinValues(issue.keys, ", ")}`;
|
||||
case "invalid_key":
|
||||
return `Clau invàlida a ${issue.origin}`;
|
||||
case "invalid_union":
|
||||
return "Entrada invàlida"; // Could also be "Tipus d'unió invàlid" but "Entrada invàlida" is more general
|
||||
case "invalid_element":
|
||||
return `Element invàlid a ${issue.origin}`;
|
||||
default:
|
||||
return `Entrada invàlida`;
|
||||
}
|
||||
};
|
||||
};
|
||||
export default function () {
|
||||
return {
|
||||
localeError: error(),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,374 @@
|
||||
/**
|
||||
* @fileoverview Disallows or enforces spaces inside of parentheses.
|
||||
* @author Jonathan Rajavuori
|
||||
* @deprecated in ESLint v8.53.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: "8.53.0",
|
||||
availableUntil: "11.0.0",
|
||||
replacedBy: [
|
||||
{
|
||||
message:
|
||||
"ESLint Stylistic now maintains deprecated stylistic core rules.",
|
||||
url: "https://eslint.style/guide/migration",
|
||||
plugin: {
|
||||
name: "@stylistic/eslint-plugin",
|
||||
url: "https://eslint.style",
|
||||
},
|
||||
rule: {
|
||||
name: "space-in-parens",
|
||||
url: "https://eslint.style/rules/space-in-parens",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
type: "layout",
|
||||
|
||||
docs: {
|
||||
description: "Enforce consistent spacing inside parentheses",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/space-in-parens",
|
||||
},
|
||||
|
||||
fixable: "whitespace",
|
||||
|
||||
schema: [
|
||||
{
|
||||
enum: ["always", "never"],
|
||||
},
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
exceptions: {
|
||||
type: "array",
|
||||
items: {
|
||||
enum: ["{}", "[]", "()", "empty"],
|
||||
},
|
||||
uniqueItems: true,
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
|
||||
messages: {
|
||||
missingOpeningSpace: "There must be a space after this paren.",
|
||||
missingClosingSpace: "There must be a space before this paren.",
|
||||
rejectedOpeningSpace: "There should be no space after this paren.",
|
||||
rejectedClosingSpace: "There should be no space before this paren.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const ALWAYS = context.options[0] === "always",
|
||||
exceptionsArrayOptions =
|
||||
(context.options[1] && context.options[1].exceptions) || [],
|
||||
options = {};
|
||||
|
||||
let exceptions;
|
||||
|
||||
if (exceptionsArrayOptions.length) {
|
||||
options.braceException = exceptionsArrayOptions.includes("{}");
|
||||
options.bracketException = exceptionsArrayOptions.includes("[]");
|
||||
options.parenException = exceptionsArrayOptions.includes("()");
|
||||
options.empty = exceptionsArrayOptions.includes("empty");
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces an object with the opener and closer exception values
|
||||
* @returns {Object} `openers` and `closers` exception values
|
||||
* @private
|
||||
*/
|
||||
function getExceptions() {
|
||||
const openers = [],
|
||||
closers = [];
|
||||
|
||||
if (options.braceException) {
|
||||
openers.push("{");
|
||||
closers.push("}");
|
||||
}
|
||||
|
||||
if (options.bracketException) {
|
||||
openers.push("[");
|
||||
closers.push("]");
|
||||
}
|
||||
|
||||
if (options.parenException) {
|
||||
openers.push("(");
|
||||
closers.push(")");
|
||||
}
|
||||
|
||||
if (options.empty) {
|
||||
openers.push(")");
|
||||
closers.push("(");
|
||||
}
|
||||
|
||||
return {
|
||||
openers,
|
||||
closers,
|
||||
};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//--------------------------------------------------------------------------
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
/**
|
||||
* Determines if a token is one of the exceptions for the opener paren
|
||||
* @param {Object} token The token to check
|
||||
* @returns {boolean} True if the token is one of the exceptions for the opener paren
|
||||
*/
|
||||
function isOpenerException(token) {
|
||||
return exceptions.openers.includes(token.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a token is one of the exceptions for the closer paren
|
||||
* @param {Object} token The token to check
|
||||
* @returns {boolean} True if the token is one of the exceptions for the closer paren
|
||||
*/
|
||||
function isCloserException(token) {
|
||||
return exceptions.closers.includes(token.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an opening paren is immediately followed by a required space
|
||||
* @param {Object} openingParenToken The paren token
|
||||
* @param {Object} tokenAfterOpeningParen The token after it
|
||||
* @returns {boolean} True if the opening paren is missing a required space
|
||||
*/
|
||||
function openerMissingSpace(openingParenToken, tokenAfterOpeningParen) {
|
||||
if (
|
||||
sourceCode.isSpaceBetween(
|
||||
openingParenToken,
|
||||
tokenAfterOpeningParen,
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!options.empty &&
|
||||
astUtils.isClosingParenToken(tokenAfterOpeningParen)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ALWAYS) {
|
||||
return !isOpenerException(tokenAfterOpeningParen);
|
||||
}
|
||||
return isOpenerException(tokenAfterOpeningParen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an opening paren is immediately followed by a disallowed space
|
||||
* @param {Object} openingParenToken The paren token
|
||||
* @param {Object} tokenAfterOpeningParen The token after it
|
||||
* @returns {boolean} True if the opening paren has a disallowed space
|
||||
*/
|
||||
function openerRejectsSpace(openingParenToken, tokenAfterOpeningParen) {
|
||||
if (
|
||||
!astUtils.isTokenOnSameLine(
|
||||
openingParenToken,
|
||||
tokenAfterOpeningParen,
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tokenAfterOpeningParen.type === "Line") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!sourceCode.isSpaceBetween(
|
||||
openingParenToken,
|
||||
tokenAfterOpeningParen,
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ALWAYS) {
|
||||
return isOpenerException(tokenAfterOpeningParen);
|
||||
}
|
||||
return !isOpenerException(tokenAfterOpeningParen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a closing paren is immediately preceded by a required space
|
||||
* @param {Object} tokenBeforeClosingParen The token before the paren
|
||||
* @param {Object} closingParenToken The paren token
|
||||
* @returns {boolean} True if the closing paren is missing a required space
|
||||
*/
|
||||
function closerMissingSpace(
|
||||
tokenBeforeClosingParen,
|
||||
closingParenToken,
|
||||
) {
|
||||
if (
|
||||
sourceCode.isSpaceBetween(
|
||||
tokenBeforeClosingParen,
|
||||
closingParenToken,
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!options.empty &&
|
||||
astUtils.isOpeningParenToken(tokenBeforeClosingParen)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ALWAYS) {
|
||||
return !isCloserException(tokenBeforeClosingParen);
|
||||
}
|
||||
return isCloserException(tokenBeforeClosingParen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a closer paren is immediately preceded by a disallowed space
|
||||
* @param {Object} tokenBeforeClosingParen The token before the paren
|
||||
* @param {Object} closingParenToken The paren token
|
||||
* @returns {boolean} True if the closing paren has a disallowed space
|
||||
*/
|
||||
function closerRejectsSpace(
|
||||
tokenBeforeClosingParen,
|
||||
closingParenToken,
|
||||
) {
|
||||
if (
|
||||
!astUtils.isTokenOnSameLine(
|
||||
tokenBeforeClosingParen,
|
||||
closingParenToken,
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!sourceCode.isSpaceBetween(
|
||||
tokenBeforeClosingParen,
|
||||
closingParenToken,
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ALWAYS) {
|
||||
return isCloserException(tokenBeforeClosingParen);
|
||||
}
|
||||
return !isCloserException(tokenBeforeClosingParen);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
Program: function checkParenSpaces(node) {
|
||||
exceptions = getExceptions();
|
||||
const tokens = sourceCode.tokensAndComments;
|
||||
|
||||
tokens.forEach((token, i) => {
|
||||
const prevToken = tokens[i - 1];
|
||||
const nextToken = tokens[i + 1];
|
||||
|
||||
// if token is not an opening or closing paren token, do nothing
|
||||
if (
|
||||
!astUtils.isOpeningParenToken(token) &&
|
||||
!astUtils.isClosingParenToken(token)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if token is an opening paren and is not followed by a required space
|
||||
if (
|
||||
token.value === "(" &&
|
||||
openerMissingSpace(token, nextToken)
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
loc: token.loc,
|
||||
messageId: "missingOpeningSpace",
|
||||
fix(fixer) {
|
||||
return fixer.insertTextAfter(token, " ");
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// if token is an opening paren and is followed by a disallowed space
|
||||
if (
|
||||
token.value === "(" &&
|
||||
openerRejectsSpace(token, nextToken)
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
loc: {
|
||||
start: token.loc.end,
|
||||
end: nextToken.loc.start,
|
||||
},
|
||||
messageId: "rejectedOpeningSpace",
|
||||
fix(fixer) {
|
||||
return fixer.removeRange([
|
||||
token.range[1],
|
||||
nextToken.range[0],
|
||||
]);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// if token is a closing paren and is not preceded by a required space
|
||||
if (
|
||||
token.value === ")" &&
|
||||
closerMissingSpace(prevToken, token)
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
loc: token.loc,
|
||||
messageId: "missingClosingSpace",
|
||||
fix(fixer) {
|
||||
return fixer.insertTextBefore(token, " ");
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// if token is a closing paren and is preceded by a disallowed space
|
||||
if (
|
||||
token.value === ")" &&
|
||||
closerRejectsSpace(prevToken, token)
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
loc: {
|
||||
start: prevToken.loc.end,
|
||||
end: token.loc.start,
|
||||
},
|
||||
messageId: "rejectedClosingSpace",
|
||||
fix(fixer) {
|
||||
return fixer.removeRange([
|
||||
prevToken.range[1],
|
||||
token.range[0],
|
||||
]);
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
import type { TSESTree } from '@typescript-eslint/utils';
|
||||
export declare function isNullLiteral(i: TSESTree.Node): i is TSESTree.NullLiteral;
|
||||
@@ -0,0 +1,93 @@
|
||||
'use strict'
|
||||
|
||||
const test = require('node:test')
|
||||
const assert = require('node:assert')
|
||||
const os = require('node:os')
|
||||
|
||||
const { sink, once } = require('./helper')
|
||||
const pino = require('../')
|
||||
|
||||
const { pid } = process
|
||||
const hostname = os.hostname()
|
||||
|
||||
function testEscape (ch, key) {
|
||||
test('correctly escape ' + ch, async () => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
name: 'hello'
|
||||
}, stream)
|
||||
instance.fatal('this contains ' + key)
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
assert.deepEqual(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 60,
|
||||
name: 'hello',
|
||||
msg: 'this contains ' + key
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
testEscape('\\n', '\n')
|
||||
testEscape('\\/', '/')
|
||||
testEscape('\\\\', '\\')
|
||||
testEscape('\\r', '\r')
|
||||
testEscape('\\t', '\t')
|
||||
testEscape('\\b', '\b')
|
||||
|
||||
const toEscape = [
|
||||
'\u0000', // NUL Null character
|
||||
'\u0001', // SOH Start of Heading
|
||||
'\u0002', // STX Start of Text
|
||||
'\u0003', // ETX End-of-text character
|
||||
'\u0004', // EOT End-of-transmission character
|
||||
'\u0005', // ENQ Enquiry character
|
||||
'\u0006', // ACK Acknowledge character
|
||||
'\u0007', // BEL Bell character
|
||||
'\u0008', // BS Backspace
|
||||
'\u0009', // HT Horizontal tab
|
||||
'\u000A', // LF Line feed
|
||||
'\u000B', // VT Vertical tab
|
||||
'\u000C', // FF Form feed
|
||||
'\u000D', // CR Carriage return
|
||||
'\u000E', // SO Shift Out
|
||||
'\u000F', // SI Shift In
|
||||
'\u0010', // DLE Data Link Escape
|
||||
'\u0011', // DC1 Device Control 1
|
||||
'\u0012', // DC2 Device Control 2
|
||||
'\u0013', // DC3 Device Control 3
|
||||
'\u0014', // DC4 Device Control 4
|
||||
'\u0015', // NAK Negative-acknowledge character
|
||||
'\u0016', // SYN Synchronous Idle
|
||||
'\u0017', // ETB End of Transmission Block
|
||||
'\u0018', // CAN Cancel character
|
||||
'\u0019', // EM End of Medium
|
||||
'\u001A', // SUB Substitute character
|
||||
'\u001B', // ESC Escape character
|
||||
'\u001C', // FS File Separator
|
||||
'\u001D', // GS Group Separator
|
||||
'\u001E', // RS Record Separator
|
||||
'\u001F' // US Unit Separator
|
||||
]
|
||||
|
||||
toEscape.forEach((key) => {
|
||||
testEscape(JSON.stringify(key), key)
|
||||
})
|
||||
|
||||
test('correctly escape `hello \\u001F world \\n \\u0022`', async () => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
name: 'hello'
|
||||
}, stream)
|
||||
instance.fatal('hello \u001F world \n \u0022')
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
assert.deepEqual(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 60,
|
||||
name: 'hello',
|
||||
msg: 'hello \u001F world \n \u0022'
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,3 @@
|
||||
import { type ZodErrorMap } from "../ZodError.js";
|
||||
declare const errorMap: ZodErrorMap;
|
||||
export default errorMap;
|
||||
@@ -0,0 +1,11 @@
|
||||
export * from './AST';
|
||||
export * from './Config';
|
||||
export * from './ESLint';
|
||||
export * from './Linter';
|
||||
export * from './Parser';
|
||||
export * from './ParserOptions';
|
||||
export * from './Processor';
|
||||
export * from './Rule';
|
||||
export * from './RuleTester';
|
||||
export * from './Scope';
|
||||
export * from './SourceCode';
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"montgomery.d.ts","sourceRoot":"","sources":["../src/abstract/montgomery.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAM/C,KAAK,GAAG,GAAG,MAAM,GAAG,UAAU,CAAC;AAE/B,MAAM,MAAM,SAAS,GAAG;IACtB,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACxB,iBAAiB,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,UAAU,CAAC;IACrD,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAClC,WAAW,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,MAAM,KAAK,UAAU,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,KAAK,UAAU,CAAC;IAChD,cAAc,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,UAAU,CAAC;IAC5C,eAAe,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,KAAK,UAAU,CAAC;IAClE,YAAY,EAAE,CAAC,SAAS,EAAE,GAAG,KAAK,UAAU,CAAC;IAC7C,KAAK,EAAE;QACL,eAAe,EAAE,MAAM,UAAU,CAAC;QAClC,wCAAwC;QACxC,gBAAgB,EAAE,MAAM,UAAU,CAAC;KACpC,CAAC;IACF,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,UAAU,KAAK;QAAE,SAAS,EAAE,UAAU,CAAC;QAAC,SAAS,EAAE,UAAU,CAAA;KAAE,CAAC;CACjF,CAAC;AACF,MAAM,MAAM,OAAO,GAAG,cAAc,CAAC;AAUrC,wBAAgB,UAAU,CAAC,QAAQ,EAAE,SAAS,GAAG,cAAc,CAyI9D"}
|
||||
@@ -0,0 +1,583 @@
|
||||
/**
|
||||
* @fileoverview A module that filters reported problems based on `eslint-disable` and `eslint-enable` comments
|
||||
* @author Teddy Katz
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Typedefs
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @typedef {import("../types").Linter.LintMessage} LintMessage */
|
||||
/** @typedef {import("@eslint/core").Language} Language */
|
||||
/** @typedef {import("@eslint/core").Position} Position */
|
||||
/** @typedef {import("@eslint/core").RulesConfig} RulesConfig */
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Module Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const escapeRegExp = require("escape-string-regexp");
|
||||
const { Config } = require("../config/config.js");
|
||||
|
||||
/**
|
||||
* Compares the locations of two objects in a source file
|
||||
* @param {Position} itemA The first object
|
||||
* @param {Position} itemB The second object
|
||||
* @returns {number} A value less than 1 if itemA appears before itemB in the source file, greater than 1 if
|
||||
* itemA appears after itemB in the source file, or 0 if itemA and itemB have the same location.
|
||||
*/
|
||||
function compareLocations(itemA, itemB) {
|
||||
return itemA.line - itemB.line || itemA.column - itemB.column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups a set of directives into sub-arrays by their parent comment.
|
||||
* @param {Iterable<Directive>} directives Unused directives to be removed.
|
||||
* @returns {Directive[][]} Directives grouped by their parent comment.
|
||||
*/
|
||||
function groupByParentDirective(directives) {
|
||||
const groups = new Map();
|
||||
|
||||
for (const directive of directives) {
|
||||
const {
|
||||
unprocessedDirective: { parentDirective },
|
||||
} = directive;
|
||||
|
||||
if (groups.has(parentDirective)) {
|
||||
groups.get(parentDirective).push(directive);
|
||||
} else {
|
||||
groups.set(parentDirective, [directive]);
|
||||
}
|
||||
}
|
||||
|
||||
return [...groups.values()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates removal details for a set of directives within the same comment.
|
||||
* @param {Directive[]} directives Unused directives to be removed.
|
||||
* @param {{node: Token, value: string}} parentDirective Data about the backing directive.
|
||||
* @param {SourceCode} sourceCode The source code object for the file being linted.
|
||||
* @returns {{ description, fix, unprocessedDirective }[]} Details for later creation of output Problems.
|
||||
*/
|
||||
function createIndividualDirectivesRemoval(
|
||||
directives,
|
||||
parentDirective,
|
||||
sourceCode,
|
||||
) {
|
||||
/*
|
||||
* Get the list of the rules text without any surrounding whitespace. In order to preserve the original
|
||||
* formatting, we don't want to change that whitespace.
|
||||
*
|
||||
* // eslint-disable-line rule-one , rule-two , rule-three -- comment
|
||||
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
*/
|
||||
const listText = parentDirective.value.trim();
|
||||
|
||||
// Calculate where it starts in the source code text
|
||||
const listStart = sourceCode.text.indexOf(
|
||||
listText,
|
||||
sourceCode.getRange(parentDirective.node)[0],
|
||||
);
|
||||
|
||||
/*
|
||||
* We can assume that `listText` contains multiple elements.
|
||||
* Otherwise, this function wouldn't be called - if there is
|
||||
* only one rule in the list, then the whole comment must be removed.
|
||||
*/
|
||||
|
||||
return directives.map(directive => {
|
||||
const { ruleId } = directive;
|
||||
|
||||
const regex = new RegExp(
|
||||
String.raw`(?:^|\s*,\s*)(?<quote>['"]?)${escapeRegExp(ruleId)}\k<quote>(?:\s*,\s*|$)`,
|
||||
"u",
|
||||
);
|
||||
const match = regex.exec(listText);
|
||||
const matchedText = match[0];
|
||||
const matchStart = listStart + match.index;
|
||||
const matchEnd = matchStart + matchedText.length;
|
||||
|
||||
const firstIndexOfComma = matchedText.indexOf(",");
|
||||
const lastIndexOfComma = matchedText.lastIndexOf(",");
|
||||
|
||||
let removalStart, removalEnd;
|
||||
|
||||
if (firstIndexOfComma !== lastIndexOfComma) {
|
||||
/*
|
||||
* Since there are two commas, this must one of the elements in the middle of the list.
|
||||
* Matched range starts where the previous rule name ends, and ends where the next rule name starts.
|
||||
*
|
||||
* // eslint-disable-line rule-one , rule-two , rule-three -- comment
|
||||
* ^^^^^^^^^^^^^^
|
||||
*
|
||||
* We want to remove only the content between the two commas, and also one of the commas.
|
||||
*
|
||||
* // eslint-disable-line rule-one , rule-two , rule-three -- comment
|
||||
* ^^^^^^^^^^^
|
||||
*/
|
||||
removalStart = matchStart + firstIndexOfComma;
|
||||
removalEnd = matchStart + lastIndexOfComma;
|
||||
} else {
|
||||
/*
|
||||
* This is either the first element or the last element.
|
||||
*
|
||||
* If this is the first element, matched range starts where the first rule name starts
|
||||
* and ends where the second rule name starts. This is exactly the range we want
|
||||
* to remove so that the second rule name will start where the first one was starting
|
||||
* and thus preserve the original formatting.
|
||||
*
|
||||
* // eslint-disable-line rule-one , rule-two , rule-three -- comment
|
||||
* ^^^^^^^^^^^
|
||||
*
|
||||
* Similarly, if this is the last element, we've already matched the range we want to
|
||||
* remove. The previous rule name will end where the last one was ending, relative
|
||||
* to the content on the right side.
|
||||
*
|
||||
* // eslint-disable-line rule-one , rule-two , rule-three -- comment
|
||||
* ^^^^^^^^^^^^^
|
||||
*/
|
||||
removalStart = matchStart;
|
||||
removalEnd = matchEnd;
|
||||
}
|
||||
|
||||
return {
|
||||
description: `'${ruleId}'`,
|
||||
fix: {
|
||||
range: [removalStart, removalEnd],
|
||||
text: "",
|
||||
},
|
||||
unprocessedDirective: directive.unprocessedDirective,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a description of deleting an entire unused disable directive.
|
||||
* @param {Directive[]} directives Unused directives to be removed.
|
||||
* @param {Token} node The backing Comment token.
|
||||
* @param {SourceCode} sourceCode The source code object for the file being linted.
|
||||
* @returns {{ description, fix, unprocessedDirective }} Details for later creation of an output problem.
|
||||
*/
|
||||
function createDirectiveRemoval(directives, node, sourceCode) {
|
||||
const range = sourceCode.getRange(node);
|
||||
const ruleIds = directives
|
||||
.filter(directive => directive.ruleId)
|
||||
.map(directive => `'${directive.ruleId}'`);
|
||||
|
||||
return {
|
||||
description:
|
||||
ruleIds.length <= 2
|
||||
? ruleIds.join(" or ")
|
||||
: `${ruleIds.slice(0, ruleIds.length - 1).join(", ")}, or ${ruleIds.at(-1)}`,
|
||||
fix: {
|
||||
range,
|
||||
text: " ",
|
||||
},
|
||||
unprocessedDirective: directives[0].unprocessedDirective,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses details from directives to create output Problems.
|
||||
* @param {Iterable<Directive>} allDirectives Unused directives to be removed.
|
||||
* @param {SourceCode} sourceCode The source code object for the file being linted.
|
||||
* @returns {{ description, fix, unprocessedDirective }[]} Details for later creation of output Problems.
|
||||
*/
|
||||
function processUnusedDirectives(allDirectives, sourceCode) {
|
||||
const directiveGroups = groupByParentDirective(allDirectives);
|
||||
|
||||
return directiveGroups.flatMap(directives => {
|
||||
const { parentDirective } = directives[0].unprocessedDirective;
|
||||
const remainingRuleIds = new Set(parentDirective.ruleIds);
|
||||
|
||||
for (const directive of directives) {
|
||||
remainingRuleIds.delete(directive.ruleId);
|
||||
}
|
||||
|
||||
return remainingRuleIds.size
|
||||
? createIndividualDirectivesRemoval(
|
||||
directives,
|
||||
parentDirective,
|
||||
sourceCode,
|
||||
)
|
||||
: [
|
||||
createDirectiveRemoval(
|
||||
directives,
|
||||
parentDirective.node,
|
||||
sourceCode,
|
||||
),
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect eslint-enable comments that are removing suppressions by eslint-disable comments.
|
||||
* @param {Directive[]} directives The directives to check.
|
||||
* @returns {Set<Directive>} The used eslint-enable comments
|
||||
*/
|
||||
function collectUsedEnableDirectives(directives) {
|
||||
/**
|
||||
* A Map of `eslint-enable` keyed by ruleIds that may be marked as used.
|
||||
* If `eslint-enable` does not have a ruleId, the key will be `null`.
|
||||
* @type {Map<string|null, Directive>}
|
||||
*/
|
||||
const enabledRules = new Map();
|
||||
|
||||
/**
|
||||
* A Set of `eslint-enable` marked as used.
|
||||
* It is also the return value of `collectUsedEnableDirectives` function.
|
||||
* @type {Set<Directive>}
|
||||
*/
|
||||
const usedEnableDirectives = new Set();
|
||||
|
||||
/*
|
||||
* Checks the directives backwards to see if the encountered `eslint-enable` is used by the previous `eslint-disable`,
|
||||
* and if so, stores the `eslint-enable` in `usedEnableDirectives`.
|
||||
*/
|
||||
for (let index = directives.length - 1; index >= 0; index--) {
|
||||
const directive = directives[index];
|
||||
|
||||
if (directive.type === "disable") {
|
||||
if (enabledRules.size === 0) {
|
||||
continue;
|
||||
}
|
||||
if (directive.ruleId === null) {
|
||||
// If encounter `eslint-disable` without ruleId,
|
||||
// mark all `eslint-enable` currently held in enabledRules as used.
|
||||
// e.g.
|
||||
// /* eslint-disable */ <- current directive
|
||||
// /* eslint-enable rule-id1 */ <- used
|
||||
// /* eslint-enable rule-id2 */ <- used
|
||||
// /* eslint-enable */ <- used
|
||||
for (const enableDirective of enabledRules.values()) {
|
||||
usedEnableDirectives.add(enableDirective);
|
||||
}
|
||||
enabledRules.clear();
|
||||
} else {
|
||||
const enableDirective = enabledRules.get(directive.ruleId);
|
||||
|
||||
if (enableDirective) {
|
||||
// If encounter `eslint-disable` with ruleId, and there is an `eslint-enable` with the same ruleId in enabledRules,
|
||||
// mark `eslint-enable` with ruleId as used.
|
||||
// e.g.
|
||||
// /* eslint-disable rule-id */ <- current directive
|
||||
// /* eslint-enable rule-id */ <- used
|
||||
usedEnableDirectives.add(enableDirective);
|
||||
} else {
|
||||
const enabledDirectiveWithoutRuleId =
|
||||
enabledRules.get(null);
|
||||
|
||||
if (enabledDirectiveWithoutRuleId) {
|
||||
// If encounter `eslint-disable` with ruleId, and there is no `eslint-enable` with the same ruleId in enabledRules,
|
||||
// mark `eslint-enable` without ruleId as used.
|
||||
// e.g.
|
||||
// /* eslint-disable rule-id */ <- current directive
|
||||
// /* eslint-enable */ <- used
|
||||
usedEnableDirectives.add(enabledDirectiveWithoutRuleId);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (directive.type === "enable") {
|
||||
if (directive.ruleId === null) {
|
||||
// If encounter `eslint-enable` without ruleId, the `eslint-enable` that follows it are unused.
|
||||
// So clear enabledRules.
|
||||
// e.g.
|
||||
// /* eslint-enable */ <- current directive
|
||||
// /* eslint-enable rule-id *// <- unused
|
||||
// /* eslint-enable */ <- unused
|
||||
enabledRules.clear();
|
||||
enabledRules.set(null, directive);
|
||||
} else {
|
||||
enabledRules.set(directive.ruleId, directive);
|
||||
}
|
||||
}
|
||||
}
|
||||
return usedEnableDirectives;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the same as the exported function, except that it
|
||||
* doesn't handle disable-line and disable-next-line directives, and it always reports unused
|
||||
* disable directives.
|
||||
* @param {Object} options options for applying directives. This is the same as the options
|
||||
* for the exported function, except that `reportUnusedDisableDirectives` is not supported
|
||||
* (this function always reports unused disable directives).
|
||||
* @returns {{problems: LintMessage[], unusedDirectives: LintMessage[]}} An object with a list
|
||||
* of problems (including suppressed ones) and unused eslint-disable directives
|
||||
*/
|
||||
function applyDirectives(options) {
|
||||
const problems = [];
|
||||
const usedDisableDirectives = new Set();
|
||||
const { sourceCode } = options;
|
||||
|
||||
for (const problem of options.problems) {
|
||||
let disableDirectivesForProblem = [];
|
||||
let nextDirectiveIndex = 0;
|
||||
|
||||
while (
|
||||
nextDirectiveIndex < options.directives.length &&
|
||||
compareLocations(options.directives[nextDirectiveIndex], problem) <=
|
||||
0
|
||||
) {
|
||||
const directive = options.directives[nextDirectiveIndex++];
|
||||
|
||||
if (
|
||||
directive.ruleId === null ||
|
||||
directive.ruleId === problem.ruleId
|
||||
) {
|
||||
switch (directive.type) {
|
||||
case "disable":
|
||||
disableDirectivesForProblem.push(directive);
|
||||
break;
|
||||
|
||||
case "enable":
|
||||
disableDirectivesForProblem = [];
|
||||
break;
|
||||
|
||||
// no default
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (disableDirectivesForProblem.length > 0) {
|
||||
const suppressions = disableDirectivesForProblem.map(directive => ({
|
||||
kind: "directive",
|
||||
justification: directive.unprocessedDirective.justification,
|
||||
}));
|
||||
|
||||
if (problem.suppressions) {
|
||||
problem.suppressions =
|
||||
problem.suppressions.concat(suppressions);
|
||||
} else {
|
||||
problem.suppressions = suppressions;
|
||||
usedDisableDirectives.add(disableDirectivesForProblem.at(-1));
|
||||
}
|
||||
}
|
||||
|
||||
problems.push(problem);
|
||||
}
|
||||
|
||||
const unusedDisableDirectivesToReport = options.directives.filter(
|
||||
directive =>
|
||||
directive.type === "disable" &&
|
||||
!usedDisableDirectives.has(directive) &&
|
||||
!options.rulesToIgnore.has(directive.ruleId),
|
||||
);
|
||||
|
||||
const unusedEnableDirectivesToReport = new Set(
|
||||
options.directives.filter(
|
||||
directive =>
|
||||
directive.unprocessedDirective.type === "enable" &&
|
||||
!options.rulesToIgnore.has(directive.ruleId),
|
||||
),
|
||||
);
|
||||
|
||||
/*
|
||||
* If directives has the eslint-enable directive,
|
||||
* check whether the eslint-enable comment is used.
|
||||
*/
|
||||
if (unusedEnableDirectivesToReport.size > 0) {
|
||||
for (const directive of collectUsedEnableDirectives(
|
||||
options.directives,
|
||||
)) {
|
||||
unusedEnableDirectivesToReport.delete(directive);
|
||||
}
|
||||
}
|
||||
|
||||
const processed = processUnusedDirectives(
|
||||
unusedDisableDirectivesToReport,
|
||||
sourceCode,
|
||||
).concat(
|
||||
processUnusedDirectives(unusedEnableDirectivesToReport, sourceCode),
|
||||
);
|
||||
const columnOffset = options.language.columnStart === 1 ? 0 : 1;
|
||||
const lineOffset = options.language.lineStart === 1 ? 0 : 1;
|
||||
|
||||
const unusedDirectives = processed.map(
|
||||
({ description, fix, unprocessedDirective }) => {
|
||||
const { parentDirective, type, line, column } =
|
||||
unprocessedDirective;
|
||||
|
||||
let message;
|
||||
|
||||
if (type === "enable") {
|
||||
message = description
|
||||
? `Unused eslint-enable directive (no matching eslint-disable directives were found for ${description}).`
|
||||
: "Unused eslint-enable directive (no matching eslint-disable directives were found).";
|
||||
} else {
|
||||
message = description
|
||||
? `Unused eslint-disable directive (no problems were reported from ${description}).`
|
||||
: "Unused eslint-disable directive (no problems were reported).";
|
||||
}
|
||||
|
||||
const loc = sourceCode.getLoc(parentDirective.node);
|
||||
|
||||
return {
|
||||
ruleId: null,
|
||||
message,
|
||||
line:
|
||||
type === "disable-next-line"
|
||||
? loc.start.line + lineOffset
|
||||
: line,
|
||||
column:
|
||||
type === "disable-next-line"
|
||||
? loc.start.column + columnOffset
|
||||
: column,
|
||||
severity:
|
||||
options.reportUnusedDisableDirectives === "warn" ? 1 : 2,
|
||||
...(options.disableFixes ? {} : { fix }),
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
return { problems, unusedDirectives };
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a list of directive comments (i.e. metadata about eslint-disable and eslint-enable comments) and a list
|
||||
* of reported problems, adds the suppression information to the problems.
|
||||
* @param {Object} options Information about directives and problems
|
||||
* @param {Language} options.language The language being linted.
|
||||
* @param {SourceCode} options.sourceCode The source code object for the file being linted.
|
||||
* @param {{
|
||||
* type: ("disable"|"enable"|"disable-line"|"disable-next-line"),
|
||||
* ruleId: (string|null),
|
||||
* line: number,
|
||||
* column: number,
|
||||
* justification: string
|
||||
* }} options.directives Directive comments found in the file, with one-based columns.
|
||||
* Two directive comments can only have the same location if they also have the same type (e.g. a single eslint-disable
|
||||
* comment for two different rules is represented as two directives).
|
||||
* @param {{ruleId: (string|null), line: number, column: number}[]} options.problems
|
||||
* A list of problems reported by rules, sorted by increasing location in the file, with one-based columns.
|
||||
* @param {"off" | "warn" | "error"} options.reportUnusedDisableDirectives If `"warn"` or `"error"`, adds additional problems for unused directives
|
||||
* @param {RulesConfig} options.configuredRules The rules configuration.
|
||||
* @param {Function} options.ruleFilter A predicate function to filter which rules should be executed.
|
||||
* @param {boolean} options.disableFixes If true, it doesn't make `fix` properties.
|
||||
* @returns {{ruleId: (string|null), line: number, column: number, suppressions?: {kind: string, justification: string}}[]}
|
||||
* An object with a list of reported problems, the suppressed of which contain the suppression information.
|
||||
*/
|
||||
module.exports = ({
|
||||
language,
|
||||
sourceCode,
|
||||
directives,
|
||||
disableFixes,
|
||||
problems,
|
||||
configuredRules,
|
||||
ruleFilter,
|
||||
reportUnusedDisableDirectives = "off",
|
||||
}) => {
|
||||
const blockDirectives = directives
|
||||
.filter(
|
||||
directive =>
|
||||
directive.type === "disable" || directive.type === "enable",
|
||||
)
|
||||
.map(directive =>
|
||||
Object.assign({}, directive, { unprocessedDirective: directive }),
|
||||
)
|
||||
.sort(compareLocations);
|
||||
|
||||
const lineDirectives = directives
|
||||
.flatMap(directive => {
|
||||
switch (directive.type) {
|
||||
case "disable":
|
||||
case "enable":
|
||||
return [];
|
||||
|
||||
case "disable-line":
|
||||
return [
|
||||
{
|
||||
type: "disable",
|
||||
line: directive.line,
|
||||
column: 1,
|
||||
ruleId: directive.ruleId,
|
||||
unprocessedDirective: directive,
|
||||
},
|
||||
{
|
||||
type: "enable",
|
||||
line: directive.line + 1,
|
||||
column: 0,
|
||||
ruleId: directive.ruleId,
|
||||
unprocessedDirective: directive,
|
||||
},
|
||||
];
|
||||
|
||||
case "disable-next-line":
|
||||
return [
|
||||
{
|
||||
type: "disable",
|
||||
line: directive.line + 1,
|
||||
column: 1,
|
||||
ruleId: directive.ruleId,
|
||||
unprocessedDirective: directive,
|
||||
},
|
||||
{
|
||||
type: "enable",
|
||||
line: directive.line + 2,
|
||||
column: 0,
|
||||
ruleId: directive.ruleId,
|
||||
unprocessedDirective: directive,
|
||||
},
|
||||
];
|
||||
|
||||
default:
|
||||
throw new TypeError(
|
||||
`Unrecognized directive type '${directive.type}'`,
|
||||
);
|
||||
}
|
||||
})
|
||||
.sort(compareLocations);
|
||||
|
||||
// This determines a list of rules that are not being run by the given ruleFilter, if present.
|
||||
const rulesToIgnore =
|
||||
configuredRules && ruleFilter
|
||||
? new Set(
|
||||
Object.keys(configuredRules).filter(ruleId => {
|
||||
const severity = Config.getRuleNumericSeverity(
|
||||
configuredRules[ruleId],
|
||||
);
|
||||
|
||||
// Ignore for disabled rules.
|
||||
if (severity === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !ruleFilter({ severity, ruleId });
|
||||
}),
|
||||
)
|
||||
: new Set();
|
||||
|
||||
// If no ruleId is supplied that means this directive is applied to all rules, so we can't determine if it's unused if any rules are filtered out.
|
||||
if (rulesToIgnore.size > 0) {
|
||||
rulesToIgnore.add(null);
|
||||
}
|
||||
|
||||
const blockDirectivesResult = applyDirectives({
|
||||
language,
|
||||
sourceCode,
|
||||
problems,
|
||||
directives: blockDirectives,
|
||||
disableFixes,
|
||||
reportUnusedDisableDirectives,
|
||||
rulesToIgnore,
|
||||
});
|
||||
const lineDirectivesResult = applyDirectives({
|
||||
language,
|
||||
sourceCode,
|
||||
problems: blockDirectivesResult.problems,
|
||||
directives: lineDirectives,
|
||||
disableFixes,
|
||||
reportUnusedDisableDirectives,
|
||||
rulesToIgnore,
|
||||
});
|
||||
|
||||
return reportUnusedDisableDirectives !== "off"
|
||||
? lineDirectivesResult.problems
|
||||
.concat(blockDirectivesResult.unusedDirectives)
|
||||
.concat(lineDirectivesResult.unusedDirectives)
|
||||
.sort(compareLocations)
|
||||
: lineDirectivesResult.problems;
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
export declare var TypeFlags: any;
|
||||
//# sourceMappingURL=typeFlags.d.ts.map
|
||||
@@ -0,0 +1,114 @@
|
||||
declare module "node:stream/consumers" {
|
||||
import { Blob, NonSharedBuffer } from "node:buffer";
|
||||
import { ReadableStream } from "node:stream/web";
|
||||
/**
|
||||
* ```js
|
||||
* import { arrayBuffer } from 'node:stream/consumers';
|
||||
* import { Readable } from 'node:stream';
|
||||
* import { TextEncoder } from 'node:util';
|
||||
*
|
||||
* const encoder = new TextEncoder();
|
||||
* const dataArray = encoder.encode('hello world from consumers!');
|
||||
*
|
||||
* const readable = Readable.from(dataArray);
|
||||
* const data = await arrayBuffer(readable);
|
||||
* console.log(`from readable: ${data.byteLength}`);
|
||||
* // Prints: from readable: 76
|
||||
* ```
|
||||
* @since v16.7.0
|
||||
* @returns Fulfills with an `ArrayBuffer` containing the full contents of the stream.
|
||||
*/
|
||||
function arrayBuffer(stream: ReadableStream | NodeJS.ReadableStream | AsyncIterable<any>): Promise<ArrayBuffer>;
|
||||
/**
|
||||
* ```js
|
||||
* import { blob } from 'node:stream/consumers';
|
||||
*
|
||||
* const dataBlob = new Blob(['hello world from consumers!']);
|
||||
*
|
||||
* const readable = dataBlob.stream();
|
||||
* const data = await blob(readable);
|
||||
* console.log(`from readable: ${data.size}`);
|
||||
* // Prints: from readable: 27
|
||||
* ```
|
||||
* @since v16.7.0
|
||||
* @returns Fulfills with a `Blob` containing the full contents of the stream.
|
||||
*/
|
||||
function blob(stream: ReadableStream | NodeJS.ReadableStream | AsyncIterable<any>): Promise<Blob>;
|
||||
/**
|
||||
* ```js
|
||||
* import { buffer } from 'node:stream/consumers';
|
||||
* import { Readable } from 'node:stream';
|
||||
* import { Buffer } from 'node:buffer';
|
||||
*
|
||||
* const dataBuffer = Buffer.from('hello world from consumers!');
|
||||
*
|
||||
* const readable = Readable.from(dataBuffer);
|
||||
* const data = await buffer(readable);
|
||||
* console.log(`from readable: ${data.length}`);
|
||||
* // Prints: from readable: 27
|
||||
* ```
|
||||
* @since v16.7.0
|
||||
* @returns Fulfills with a `Buffer` containing the full contents of the stream.
|
||||
*/
|
||||
function buffer(stream: ReadableStream | NodeJS.ReadableStream | AsyncIterable<any>): Promise<NonSharedBuffer>;
|
||||
/**
|
||||
* ```js
|
||||
* import { bytes } from 'node:stream/consumers';
|
||||
* import { Readable } from 'node:stream';
|
||||
* import { Buffer } from 'node:buffer';
|
||||
*
|
||||
* const dataBuffer = Buffer.from('hello world from consumers!');
|
||||
*
|
||||
* const readable = Readable.from(dataBuffer);
|
||||
* const data = await bytes(readable);
|
||||
* console.log(`from readable: ${data.length}`);
|
||||
* // Prints: from readable: 27
|
||||
* ```
|
||||
* @since v25.6.0
|
||||
* @returns Fulfills with a `Uint8Array` containing the full contents of the stream.
|
||||
*/
|
||||
function bytes(
|
||||
stream: ReadableStream | NodeJS.ReadableStream | AsyncIterable<any>,
|
||||
): Promise<NodeJS.NonSharedUint8Array>;
|
||||
/**
|
||||
* ```js
|
||||
* import { json } from 'node:stream/consumers';
|
||||
* import { Readable } from 'node:stream';
|
||||
*
|
||||
* const items = Array.from(
|
||||
* {
|
||||
* length: 100,
|
||||
* },
|
||||
* () => ({
|
||||
* message: 'hello world from consumers!',
|
||||
* }),
|
||||
* );
|
||||
*
|
||||
* const readable = Readable.from(JSON.stringify(items));
|
||||
* const data = await json(readable);
|
||||
* console.log(`from readable: ${data.length}`);
|
||||
* // Prints: from readable: 100
|
||||
* ```
|
||||
* @since v16.7.0
|
||||
* @returns Fulfills with the contents of the stream parsed as a
|
||||
* UTF-8 encoded string that is then passed through `JSON.parse()`.
|
||||
*/
|
||||
function json(stream: ReadableStream | NodeJS.ReadableStream | AsyncIterable<any>): Promise<unknown>;
|
||||
/**
|
||||
* ```js
|
||||
* import { text } from 'node:stream/consumers';
|
||||
* import { Readable } from 'node:stream';
|
||||
*
|
||||
* const readable = Readable.from('Hello world from consumers!');
|
||||
* const data = await text(readable);
|
||||
* console.log(`from readable: ${data.length}`);
|
||||
* // Prints: from readable: 27
|
||||
* ```
|
||||
* @since v16.7.0
|
||||
* @returns Fulfills with the contents of the stream parsed as a UTF-8 encoded string.
|
||||
*/
|
||||
function text(stream: ReadableStream | NodeJS.ReadableStream | AsyncIterable<any>): Promise<string>;
|
||||
}
|
||||
declare module "stream/consumers" {
|
||||
export * from "node:stream/consumers";
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,47 @@
|
||||
import * as path from 'node:path';
|
||||
import path__default from 'node:path';
|
||||
|
||||
/**
|
||||
* Constant for path separator.
|
||||
*
|
||||
* Always equals to `"/"`.
|
||||
*/
|
||||
declare const sep = "/";
|
||||
declare const normalize: typeof path__default.normalize;
|
||||
declare const join: typeof path__default.join;
|
||||
declare const resolve: typeof path__default.resolve;
|
||||
/**
|
||||
* Resolves a string path, resolving '.' and '.' segments and allowing paths above the root.
|
||||
*
|
||||
* @param path - The path to normalise.
|
||||
* @param allowAboveRoot - Whether to allow the resulting path to be above the root directory.
|
||||
* @returns the normalised path string.
|
||||
*/
|
||||
declare function normalizeString(path: string, allowAboveRoot: boolean): string;
|
||||
declare const isAbsolute: typeof path__default.isAbsolute;
|
||||
declare const toNamespacedPath: typeof path__default.toNamespacedPath;
|
||||
declare const extname: typeof path__default.extname;
|
||||
declare const relative: typeof path__default.relative;
|
||||
declare const dirname: typeof path__default.dirname;
|
||||
declare const format: typeof path__default.format;
|
||||
declare const basename: typeof path__default.basename;
|
||||
declare const parse: typeof path__default.parse;
|
||||
/**
|
||||
* The `path.matchesGlob()` method determines if `path` matches the `pattern`.
|
||||
* @param path The path to glob-match against.
|
||||
* @param pattern The glob to check the path against.
|
||||
*/
|
||||
declare const matchesGlob: (path: string, pattern: string | string[]) => boolean;
|
||||
|
||||
type NodePath = typeof path;
|
||||
/**
|
||||
* The platform-specific file delimiter.
|
||||
*
|
||||
* Equals to `";"` in windows and `":"` in all other platforms.
|
||||
*/
|
||||
declare const delimiter: ";" | ":";
|
||||
declare const posix: NodePath["posix"];
|
||||
declare const win32: NodePath["win32"];
|
||||
declare const _default: NodePath;
|
||||
|
||||
export { basename, _default as default, delimiter, dirname, extname, format, isAbsolute, join, matchesGlob, normalize, normalizeString, parse, posix, relative, resolve, sep, toNamespacedPath, win32 };
|
||||
@@ -0,0 +1,54 @@
|
||||
# VSCode JSON RPC
|
||||
|
||||
[](https://npmjs.org/package/vscode-jsonrpc)
|
||||
[](https://npmjs.org/package/vscode-jsonrpc)
|
||||
[](https://dev.azure.com/vscode/vscode-languageserver-node/_build/latest?definitionId=52&branchName=main)
|
||||
|
||||
This npm module implements the base messaging protocol spoken between a VSCode language server and a VSCode language client.
|
||||
|
||||
The npm module can also be used standalone to establish a [JSON-RPC](http://www.jsonrpc.org/) channel between
|
||||
a client and a server. Below an example how to setup a JSON-RPC connection. First the client side.
|
||||
|
||||
```ts
|
||||
import * as cp from 'child_process';
|
||||
import * as rpc from 'vscode-jsonrpc/node';
|
||||
|
||||
let childProcess = cp.spawn(...);
|
||||
|
||||
// Use stdin and stdout for communication:
|
||||
let connection = rpc.createMessageConnection(
|
||||
new rpc.StreamMessageReader(childProcess.stdout),
|
||||
new rpc.StreamMessageWriter(childProcess.stdin));
|
||||
|
||||
let notification = new rpc.NotificationType<string, void>('testNotification');
|
||||
|
||||
connection.listen();
|
||||
|
||||
connection.sendNotification(notification, 'Hello World');
|
||||
```
|
||||
|
||||
The server side looks very symmetrical:
|
||||
|
||||
```ts
|
||||
import * as rpc from 'vscode-jsonrpc/node';
|
||||
|
||||
|
||||
let connection = rpc.createMessageConnection(
|
||||
new rpc.StreamMessageReader(process.stdin),
|
||||
new rpc.StreamMessageWriter(process.stdout));
|
||||
|
||||
let notification = new rpc.NotificationType<string, void>('testNotification');
|
||||
connection.onNotification(notification, (param: string) => {
|
||||
console.log(param); // This prints Hello World
|
||||
});
|
||||
|
||||
connection.listen();
|
||||
```
|
||||
|
||||
# History
|
||||
|
||||
For the history please see the [main repository](https://github.com/Microsoft/vscode-languageserver-node/blob/master/README.md)
|
||||
|
||||
|
||||
## License
|
||||
[MIT](https://github.com/Microsoft/vscode-languageserver-node/blob/master/License.txt)
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"resize-codec.d.ts","sourceRoot":"","sources":["../../src/resize-codec.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,EAGL,OAAO,EACP,OAAO,EACP,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAEnB,MAAM,SAAS,CAAC;AAIjB,KAAK,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;AAE/B,KAAK,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;AAE/B,KAAK,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;AAE3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,SAAS,MAAM,EAAE,QAAQ,SAAS,MAAM,EAC9E,OAAO,EAAE,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,EACvC,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,QAAQ,GAClC,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AACrC,wBAAgB,aAAa,CAAC,QAAQ,SAAS,UAAU,EACrD,OAAO,EAAE,QAAQ,EACjB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GACjC,QAAQ,CAAC;AA8BZ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,SAAS,MAAM,EAAE,QAAQ,SAAS,MAAM,EAC9E,OAAO,EAAE,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,EACvC,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,QAAQ,GAClC,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AACrC,wBAAgB,aAAa,CAAC,QAAQ,SAAS,UAAU,EACrD,OAAO,EAAE,QAAQ,EACjB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GACjC,QAAQ,CAAC;AAkBZ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,GAAG,SAAS,KAAK,EAAE,KAAK,SAAS,MAAM,EAAE,QAAQ,SAAS,MAAM,EAC/F,KAAK,EAAE,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,EACxC,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,QAAQ,GAClC,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;AACxC,wBAAgB,WAAW,CAAC,MAAM,SAAS,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAAC"}
|
||||
@@ -0,0 +1,2 @@
|
||||
export declare var ModuleKind: any;
|
||||
//# sourceMappingURL=moduleKind.d.ts.map
|
||||
@@ -0,0 +1,14 @@
|
||||
import type { TypeOrValueSpecifier } from '../util';
|
||||
export type MessageIds = 'object' | 'undef';
|
||||
export type Options = [
|
||||
{
|
||||
allow?: TypeOrValueSpecifier[];
|
||||
allowRethrowing?: boolean;
|
||||
allowThrowingAny?: boolean;
|
||||
allowThrowingUnknown?: boolean;
|
||||
}
|
||||
];
|
||||
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<MessageIds, Options, import("../../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
||||
name: string;
|
||||
};
|
||||
export default _default;
|
||||
@@ -0,0 +1,18 @@
|
||||
This software is released under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,494 @@
|
||||
'use strict'
|
||||
|
||||
let Comment = require('./comment')
|
||||
let Declaration = require('./declaration')
|
||||
let Node = require('./node')
|
||||
let { isClean, my } = require('./symbols')
|
||||
|
||||
let AtRule, parse, Root, Rule
|
||||
|
||||
function cleanSource(nodes) {
|
||||
let stack = nodes.slice()
|
||||
while (stack.length > 0) {
|
||||
let node = stack.pop()
|
||||
delete node.source
|
||||
if (node.nodes) {
|
||||
node.nodes = node.nodes.slice()
|
||||
for (let i of node.nodes) stack.push(i)
|
||||
}
|
||||
}
|
||||
return nodes.slice()
|
||||
}
|
||||
|
||||
function markTreeDirty(node) {
|
||||
let stack = [node]
|
||||
while (stack.length > 0) {
|
||||
let next = stack.pop()
|
||||
next[isClean] = false
|
||||
if (next.proxyOf.nodes) {
|
||||
for (let i of next.proxyOf.nodes) stack.push(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Container extends Node {
|
||||
get first() {
|
||||
if (!this.proxyOf.nodes) return undefined
|
||||
return this.proxyOf.nodes[0]
|
||||
}
|
||||
|
||||
get last() {
|
||||
if (!this.proxyOf.nodes) return undefined
|
||||
return this.proxyOf.nodes[this.proxyOf.nodes.length - 1]
|
||||
}
|
||||
|
||||
append(...children) {
|
||||
for (let child of children) {
|
||||
let nodes = this.normalize(child, this.last)
|
||||
for (let node of nodes) this.proxyOf.nodes.push(node)
|
||||
}
|
||||
|
||||
this.markDirty()
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
cleanRaws(keepBetween) {
|
||||
let stack = [this]
|
||||
while (stack.length > 0) {
|
||||
let node = stack.pop()
|
||||
if (node !== this && node.cleanRaws !== Container.prototype.cleanRaws) {
|
||||
// Subclass with own logic; let it handle its subtree
|
||||
node.cleanRaws(keepBetween)
|
||||
continue
|
||||
}
|
||||
Node.prototype.cleanRaws.call(node, keepBetween)
|
||||
if (node.nodes) {
|
||||
for (let child of node.nodes) stack.push(child)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
each(callback) {
|
||||
if (!this.proxyOf.nodes) return undefined
|
||||
let iterator = this.getIterator()
|
||||
|
||||
let index, result
|
||||
while (this.indexes[iterator] < this.proxyOf.nodes.length) {
|
||||
index = this.indexes[iterator]
|
||||
result = callback(this.proxyOf.nodes[index], index)
|
||||
if (result === false) break
|
||||
|
||||
this.indexes[iterator] += 1
|
||||
}
|
||||
|
||||
delete this.indexes[iterator]
|
||||
return result
|
||||
}
|
||||
|
||||
every(condition) {
|
||||
return this.nodes.every(condition)
|
||||
}
|
||||
|
||||
getIterator() {
|
||||
if (!this.lastEach) this.lastEach = 0
|
||||
if (!this.indexes) this.indexes = {}
|
||||
|
||||
this.lastEach += 1
|
||||
let iterator = this.lastEach
|
||||
this.indexes[iterator] = 0
|
||||
|
||||
return iterator
|
||||
}
|
||||
|
||||
getProxyProcessor() {
|
||||
return {
|
||||
get(node, prop) {
|
||||
if (prop === 'proxyOf') {
|
||||
return node
|
||||
} else if (!node[prop]) {
|
||||
return node[prop]
|
||||
} else if (
|
||||
prop === 'each' ||
|
||||
(typeof prop === 'string' && prop.startsWith('walk'))
|
||||
) {
|
||||
return (...args) => {
|
||||
return node[prop](
|
||||
...args.map(i => {
|
||||
if (typeof i === 'function') {
|
||||
return (child, index) => i(child.toProxy(), index)
|
||||
} else {
|
||||
return i
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
} else if (prop === 'every' || prop === 'some') {
|
||||
return cb => {
|
||||
return node[prop]((child, ...other) =>
|
||||
cb(child.toProxy(), ...other)
|
||||
)
|
||||
}
|
||||
} else if (prop === 'root') {
|
||||
return () => node.root().toProxy()
|
||||
} else if (prop === 'nodes') {
|
||||
return node.nodes.map(i => i.toProxy())
|
||||
} else if (prop === 'first' || prop === 'last') {
|
||||
return node[prop].toProxy()
|
||||
} else {
|
||||
return node[prop]
|
||||
}
|
||||
},
|
||||
|
||||
set(node, prop, value) {
|
||||
if (node[prop] === value) return true
|
||||
node[prop] = value
|
||||
if (prop === 'name' || prop === 'params' || prop === 'selector') {
|
||||
node.markDirty()
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
index(child) {
|
||||
if (typeof child === 'number') return child
|
||||
if (child.proxyOf) child = child.proxyOf
|
||||
return this.proxyOf.nodes.indexOf(child)
|
||||
}
|
||||
|
||||
insertAfter(exist, add) {
|
||||
let existIndex = this.index(exist)
|
||||
let nodes = this.normalize(add, this.proxyOf.nodes[existIndex]).reverse()
|
||||
existIndex = this.index(exist)
|
||||
for (let node of nodes) this.proxyOf.nodes.splice(existIndex + 1, 0, node)
|
||||
|
||||
let index
|
||||
for (let id in this.indexes) {
|
||||
index = this.indexes[id]
|
||||
if (existIndex < index) {
|
||||
this.indexes[id] = index + nodes.length
|
||||
}
|
||||
}
|
||||
|
||||
this.markDirty()
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
insertBefore(exist, add) {
|
||||
let existIndex = this.index(exist)
|
||||
let type = existIndex === 0 ? 'prepend' : false
|
||||
let nodes = this.normalize(
|
||||
add,
|
||||
this.proxyOf.nodes[existIndex],
|
||||
type
|
||||
).reverse()
|
||||
existIndex = this.index(exist)
|
||||
for (let node of nodes) this.proxyOf.nodes.splice(existIndex, 0, node)
|
||||
|
||||
let index
|
||||
for (let id in this.indexes) {
|
||||
index = this.indexes[id]
|
||||
if (existIndex <= index) {
|
||||
this.indexes[id] = index + nodes.length
|
||||
}
|
||||
}
|
||||
|
||||
this.markDirty()
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
normalize(nodes, sample) {
|
||||
if (typeof nodes === 'string') {
|
||||
nodes = cleanSource(parse(nodes).nodes)
|
||||
} else if (typeof nodes === 'undefined') {
|
||||
nodes = []
|
||||
} else if (Array.isArray(nodes)) {
|
||||
nodes = nodes.slice(0)
|
||||
for (let i of nodes) {
|
||||
if (i.parent) i.parent.removeChild(i, 'ignore')
|
||||
}
|
||||
} else if (nodes.type === 'root' && this.type !== 'document') {
|
||||
nodes = nodes.nodes.slice(0)
|
||||
for (let i of nodes) {
|
||||
if (i.parent) i.parent.removeChild(i, 'ignore')
|
||||
}
|
||||
} else if (nodes.type) {
|
||||
nodes = [nodes]
|
||||
} else if (nodes.prop) {
|
||||
if (typeof nodes.value === 'undefined') {
|
||||
throw new Error('Value field is missed in node creation')
|
||||
} else if (typeof nodes.value !== 'string') {
|
||||
nodes.value = String(nodes.value)
|
||||
}
|
||||
nodes = [new Declaration(nodes)]
|
||||
} else if (nodes.selector || nodes.selectors) {
|
||||
nodes = [new Rule(nodes)]
|
||||
} else if (nodes.name) {
|
||||
nodes = [new AtRule(nodes)]
|
||||
} else if (nodes.text) {
|
||||
nodes = [new Comment(nodes)]
|
||||
} else {
|
||||
throw new Error('Unknown node type in node creation')
|
||||
}
|
||||
|
||||
let processed = nodes.map(i => {
|
||||
/* c8 ignore next */
|
||||
if (!i[my]) Container.rebuild(i)
|
||||
i = i.proxyOf
|
||||
if (i.parent) i.parent.removeChild(i)
|
||||
if (i[isClean]) markTreeDirty(i)
|
||||
|
||||
if (!i.raws) i.raws = {}
|
||||
if (typeof i.raws.before === 'undefined') {
|
||||
if (sample && typeof sample.raws.before !== 'undefined') {
|
||||
i.raws.before = sample.raws.before.replace(/\S/g, '')
|
||||
}
|
||||
}
|
||||
i.parent = this.proxyOf
|
||||
return i
|
||||
})
|
||||
|
||||
return processed
|
||||
}
|
||||
|
||||
prepend(...children) {
|
||||
children = children.reverse()
|
||||
for (let child of children) {
|
||||
let nodes = this.normalize(child, this.first, 'prepend').reverse()
|
||||
for (let node of nodes) this.proxyOf.nodes.unshift(node)
|
||||
for (let id in this.indexes) {
|
||||
this.indexes[id] = this.indexes[id] + nodes.length
|
||||
}
|
||||
}
|
||||
|
||||
this.markDirty()
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
push(child) {
|
||||
child.parent = this
|
||||
this.proxyOf.nodes.push(child)
|
||||
return this
|
||||
}
|
||||
|
||||
removeAll() {
|
||||
for (let node of this.proxyOf.nodes) node.parent = undefined
|
||||
this.proxyOf.nodes = []
|
||||
|
||||
this.markDirty()
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
removeChild(child) {
|
||||
child = this.index(child)
|
||||
this.proxyOf.nodes[child].parent = undefined
|
||||
this.proxyOf.nodes.splice(child, 1)
|
||||
|
||||
let index
|
||||
for (let id in this.indexes) {
|
||||
index = this.indexes[id]
|
||||
if (index >= child) {
|
||||
this.indexes[id] = index - 1
|
||||
}
|
||||
}
|
||||
|
||||
this.markDirty()
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
replaceValues(pattern, opts, callback) {
|
||||
if (!callback) {
|
||||
callback = opts
|
||||
opts = {}
|
||||
}
|
||||
|
||||
this.walkDecls(decl => {
|
||||
if (opts.props && !opts.props.includes(decl.prop)) return
|
||||
if (opts.fast && !decl.value.includes(opts.fast)) return
|
||||
|
||||
decl.value = decl.value.replace(pattern, callback)
|
||||
})
|
||||
|
||||
this.markDirty()
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
some(condition) {
|
||||
return this.nodes.some(condition)
|
||||
}
|
||||
|
||||
walk(callback) {
|
||||
if (!this.proxyOf.nodes) return undefined
|
||||
|
||||
// An explicit stack instead of recursive `each()` calls to survive
|
||||
// deeply nested trees. Each frame keeps a live `indexes` slot, so
|
||||
// insertion and removal during the walk behave like `each()`: the
|
||||
// slot stays at the current child until its subtree is finished.
|
||||
let stack = [{ iterator: this.getIterator(), node: this.proxyOf }]
|
||||
|
||||
while (stack.length > 0) {
|
||||
let { iterator, node } = stack[stack.length - 1]
|
||||
let index = node.indexes[iterator]
|
||||
|
||||
if (index >= node.proxyOf.nodes.length) {
|
||||
delete node.indexes[iterator]
|
||||
stack.pop()
|
||||
let parent = stack[stack.length - 1]
|
||||
// Finish the parent’s step for the child subtree we just left
|
||||
if (parent) parent.node.indexes[parent.iterator] += 1
|
||||
continue
|
||||
}
|
||||
|
||||
let child = node.proxyOf.nodes[index]
|
||||
let result
|
||||
try {
|
||||
result = callback(child, index)
|
||||
} catch (e) {
|
||||
throw child.addToError(e)
|
||||
}
|
||||
if (result === false) {
|
||||
for (let opened of stack) {
|
||||
delete opened.node.indexes[opened.iterator]
|
||||
}
|
||||
return false
|
||||
}
|
||||
if (child.walk && child.proxyOf.nodes) {
|
||||
stack.push({ iterator: child.getIterator(), node: child })
|
||||
} else {
|
||||
node.indexes[iterator] += 1
|
||||
}
|
||||
}
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
walkAtRules(name, callback) {
|
||||
if (!callback) {
|
||||
callback = name
|
||||
return this.walk((child, i) => {
|
||||
if (child.type === 'atrule') {
|
||||
return callback(child, i)
|
||||
}
|
||||
})
|
||||
}
|
||||
if (name instanceof RegExp) {
|
||||
return this.walk((child, i) => {
|
||||
if (child.type === 'atrule' && name.test(child.name)) {
|
||||
return callback(child, i)
|
||||
}
|
||||
})
|
||||
}
|
||||
return this.walk((child, i) => {
|
||||
if (child.type === 'atrule' && child.name === name) {
|
||||
return callback(child, i)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
walkComments(callback) {
|
||||
return this.walk((child, i) => {
|
||||
if (child.type === 'comment') {
|
||||
return callback(child, i)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
walkDecls(prop, callback) {
|
||||
if (!callback) {
|
||||
callback = prop
|
||||
return this.walk((child, i) => {
|
||||
if (child.type === 'decl') {
|
||||
return callback(child, i)
|
||||
}
|
||||
})
|
||||
}
|
||||
if (prop instanceof RegExp) {
|
||||
return this.walk((child, i) => {
|
||||
if (child.type === 'decl' && prop.test(child.prop)) {
|
||||
return callback(child, i)
|
||||
}
|
||||
})
|
||||
}
|
||||
return this.walk((child, i) => {
|
||||
if (child.type === 'decl' && child.prop === prop) {
|
||||
return callback(child, i)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
walkRules(selector, callback) {
|
||||
if (!callback) {
|
||||
callback = selector
|
||||
|
||||
return this.walk((child, i) => {
|
||||
if (child.type === 'rule') {
|
||||
return callback(child, i)
|
||||
}
|
||||
})
|
||||
}
|
||||
if (selector instanceof RegExp) {
|
||||
return this.walk((child, i) => {
|
||||
if (child.type === 'rule' && selector.test(child.selector)) {
|
||||
return callback(child, i)
|
||||
}
|
||||
})
|
||||
}
|
||||
return this.walk((child, i) => {
|
||||
if (child.type === 'rule' && child.selector === selector) {
|
||||
return callback(child, i)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Container.registerParse = dependant => {
|
||||
parse = dependant
|
||||
}
|
||||
|
||||
Container.registerRule = dependant => {
|
||||
Rule = dependant
|
||||
}
|
||||
|
||||
Container.registerAtRule = dependant => {
|
||||
AtRule = dependant
|
||||
}
|
||||
|
||||
Container.registerRoot = dependant => {
|
||||
Root = dependant
|
||||
}
|
||||
|
||||
module.exports = Container
|
||||
Container.default = Container
|
||||
|
||||
/* c8 ignore start */
|
||||
Container.rebuild = node => {
|
||||
let stack = [node]
|
||||
while (stack.length > 0) {
|
||||
let next = stack.pop()
|
||||
if (next.type === 'atrule') {
|
||||
Object.setPrototypeOf(next, AtRule.prototype)
|
||||
} else if (next.type === 'rule') {
|
||||
Object.setPrototypeOf(next, Rule.prototype)
|
||||
} else if (next.type === 'decl') {
|
||||
Object.setPrototypeOf(next, Declaration.prototype)
|
||||
} else if (next.type === 'comment') {
|
||||
Object.setPrototypeOf(next, Comment.prototype)
|
||||
} else if (next.type === 'root') {
|
||||
Object.setPrototypeOf(next, Root.prototype)
|
||||
}
|
||||
|
||||
next[my] = true
|
||||
|
||||
if (next.nodes) {
|
||||
for (let child of next.nodes) stack.push(child)
|
||||
}
|
||||
}
|
||||
}
|
||||
/* c8 ignore stop */
|
||||
@@ -0,0 +1,91 @@
|
||||
import { join } from 'node:path'
|
||||
import { tmpdir } from 'node:os'
|
||||
import pinoPretty from 'pino-pretty'
|
||||
// Test both default ("Pino") and named ("pino") imports.
|
||||
import Pino, { type LoggerOptions, type StreamEntry, pino, multistream, transport } from '../../pino'
|
||||
|
||||
const destination = join(
|
||||
tmpdir(),
|
||||
'_' + Math.random().toString(36).substr(2, 9)
|
||||
)
|
||||
|
||||
// Single
|
||||
const transport1 = transport({
|
||||
target: 'pino-pretty',
|
||||
options: { some: 'options for', the: 'transport' }
|
||||
})
|
||||
const logger = pino(transport1)
|
||||
logger.setBindings({ some: 'bindings' })
|
||||
logger.info('test2')
|
||||
logger.flush()
|
||||
const loggerDefault = Pino(transport1)
|
||||
loggerDefault.setBindings({ some: 'bindings' })
|
||||
loggerDefault.info('test2')
|
||||
loggerDefault.flush()
|
||||
|
||||
const transport2 = transport({
|
||||
target: 'pino-pretty',
|
||||
})
|
||||
const logger2 = pino(transport2)
|
||||
logger2.info('test2')
|
||||
const logger2Default = Pino(transport2)
|
||||
logger2Default.info('test2')
|
||||
|
||||
// Multiple
|
||||
|
||||
const transports = transport({
|
||||
targets: [
|
||||
{
|
||||
level: 'info',
|
||||
target: 'pino-pretty',
|
||||
options: { some: 'options for', the: 'transport' }
|
||||
},
|
||||
{
|
||||
level: 'trace',
|
||||
target: 'pino/file',
|
||||
options: { destination }
|
||||
}
|
||||
]
|
||||
})
|
||||
const loggerMulti = pino(transports)
|
||||
loggerMulti.info('test2')
|
||||
|
||||
// custom levels
|
||||
|
||||
const customLevels = {
|
||||
customDebug: 1,
|
||||
info: 2,
|
||||
customNetwork: 3,
|
||||
customError: 4,
|
||||
}
|
||||
|
||||
type CustomLevels = keyof typeof customLevels
|
||||
|
||||
const pinoOpts = {
|
||||
useOnlyCustomLevels: true,
|
||||
customLevels,
|
||||
level: 'customDebug',
|
||||
} satisfies LoggerOptions
|
||||
|
||||
const multistreamOpts = {
|
||||
dedupe: true,
|
||||
levels: customLevels
|
||||
}
|
||||
|
||||
const streams: StreamEntry<CustomLevels>[] = [
|
||||
{ level: 'customDebug', stream: pinoPretty() },
|
||||
{ level: 'info', stream: pinoPretty() },
|
||||
{ level: 'customNetwork', stream: pinoPretty() },
|
||||
{ level: 'customError', stream: pinoPretty() },
|
||||
]
|
||||
|
||||
const loggerCustomLevel = pino(pinoOpts, multistream(streams, multistreamOpts))
|
||||
loggerCustomLevel.customDebug('test3')
|
||||
loggerCustomLevel.info('test4')
|
||||
loggerCustomLevel.customError('test5')
|
||||
loggerCustomLevel.customNetwork('test6')
|
||||
const loggerCustomLevelDefault = Pino(pinoOpts, multistream(streams, multistreamOpts))
|
||||
loggerCustomLevelDefault.customDebug('test3')
|
||||
loggerCustomLevelDefault.info('test4')
|
||||
loggerCustomLevelDefault.customError('test5')
|
||||
loggerCustomLevelDefault.customNetwork('test6')
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* @fileoverview Rule to flag octal escape sequences in string literals.
|
||||
* @author Ian Christian Myers
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "suggestion",
|
||||
|
||||
docs: {
|
||||
description: "Disallow octal escape sequences in string literals",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/no-octal-escape",
|
||||
},
|
||||
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
octalEscapeSequence:
|
||||
"Don't use octal: '\\{{sequence}}'. Use '\\u....' instead.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
return {
|
||||
Literal(node) {
|
||||
if (typeof node.value !== "string") {
|
||||
return;
|
||||
}
|
||||
|
||||
// \0 represents a valid NULL character if it isn't followed by a digit.
|
||||
const match = node.raw.match(
|
||||
/^(?:[^\\]|\\.)*?\\([0-3][0-7]{1,2}|[4-7][0-7]|0(?=[89])|[1-7])/su,
|
||||
);
|
||||
|
||||
if (match) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "octalEscapeSequence",
|
||||
data: { sequence: match[1] },
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,52 @@
|
||||
import _typeof from "./typeof.js";
|
||||
import setPrototypeOf from "./setPrototypeOf.js";
|
||||
import inherits from "./inherits.js";
|
||||
function _wrapRegExp() {
|
||||
_wrapRegExp = function _wrapRegExp(e, r) {
|
||||
return new BabelRegExp(e, void 0, r);
|
||||
};
|
||||
var e = RegExp.prototype,
|
||||
r = new WeakMap();
|
||||
function BabelRegExp(e, t, p) {
|
||||
var o = RegExp(e, t);
|
||||
return r.set(o, p || r.get(e)), setPrototypeOf(o, BabelRegExp.prototype);
|
||||
}
|
||||
function buildGroups(e, t) {
|
||||
var p = r.get(t);
|
||||
return Object.keys(p).reduce(function (r, t) {
|
||||
var o = p[t];
|
||||
if ("number" == typeof o) r[t] = e[o];else {
|
||||
for (var i = 0; void 0 === e[o[i]] && i + 1 < o.length;) i++;
|
||||
r[t] = e[o[i]];
|
||||
}
|
||||
return r;
|
||||
}, Object.create(null));
|
||||
}
|
||||
return inherits(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (r) {
|
||||
var t = e.exec.call(this, r);
|
||||
if (t) {
|
||||
t.groups = buildGroups(t, this);
|
||||
var p = t.indices;
|
||||
p && (p.groups = buildGroups(p, this));
|
||||
}
|
||||
return t;
|
||||
}, BabelRegExp.prototype[Symbol.replace] = function (t, p) {
|
||||
if ("string" == typeof p) {
|
||||
var o = r.get(this);
|
||||
return e[Symbol.replace].call(this, t, p.replace(/\$<([^>]+)(>|$)/g, function (e, r, t) {
|
||||
if ("" === t) return e;
|
||||
var p = o[r];
|
||||
return Array.isArray(p) ? "$" + p.join("$") : "number" == typeof p ? "$" + p : "";
|
||||
}));
|
||||
}
|
||||
if ("function" == typeof p) {
|
||||
var i = this;
|
||||
return e[Symbol.replace].call(this, t, function () {
|
||||
var e = arguments;
|
||||
return "object" != _typeof(e[e.length - 1]) && (e = [].slice.call(e)).push(buildGroups(e, i)), p.apply(this, e);
|
||||
});
|
||||
}
|
||||
return e[Symbol.replace].call(this, t, p);
|
||||
}, _wrapRegExp.apply(this, arguments);
|
||||
}
|
||||
export { _wrapRegExp as default };
|
||||
@@ -0,0 +1,76 @@
|
||||
"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.getContextualType = getContextualType;
|
||||
const ts = __importStar(require("typescript"));
|
||||
/**
|
||||
* Returns the contextual type of a given node.
|
||||
* Contextual type is the type of the target the node is going into.
|
||||
* i.e. the type of a called function's parameter, or the defined type of a variable declaration
|
||||
*/
|
||||
function getContextualType(checker, node) {
|
||||
const parent = node.parent;
|
||||
if (ts.isCallExpression(parent) || ts.isNewExpression(parent)) {
|
||||
if (node === parent.expression) {
|
||||
// is the callee, so has no contextual type
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (ts.isVariableDeclaration(parent) ||
|
||||
ts.isPropertyDeclaration(parent) ||
|
||||
ts.isParameter(parent)) {
|
||||
return parent.type ? checker.getTypeFromTypeNode(parent.type) : undefined;
|
||||
}
|
||||
else if (ts.isJsxExpression(parent)) {
|
||||
return checker.getContextualType(parent);
|
||||
}
|
||||
else if (ts.isIdentifier(node) &&
|
||||
(ts.isPropertyAssignment(parent) ||
|
||||
ts.isShorthandPropertyAssignment(parent))) {
|
||||
return checker.getContextualType(node);
|
||||
}
|
||||
else if (ts.isBinaryExpression(parent) &&
|
||||
parent.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
||||
parent.right === node) {
|
||||
// is RHS of assignment
|
||||
return checker.getTypeAtLocation(parent.left);
|
||||
}
|
||||
else if (![ts.SyntaxKind.JsxExpression, ts.SyntaxKind.TemplateSpan].includes(parent.kind)) {
|
||||
// parent is not something we know we can get the contextual type of
|
||||
return;
|
||||
}
|
||||
// TODO - support return statement checking
|
||||
return checker.getContextualType(node);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAKH,gBAAgB,EAChB,gBAAgB,EAGnB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAU,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAErD,KAAK,wBAAwB,CAAC,KAAK,SAAS,MAAM,IAAI;IAClD,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,KAAK,CAAC;CACf,CAAC;AAEF,KAAK,yBAAyB,CAAC,KAAK,EAAE,KAAK,SAAS,MAAM,IAAI,wBAAwB,CAAC,KAAK,CAAC,GAAG;IAC5F,KAAK,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;IAC3C,GAAG,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CACvE,CAAC;AAEF,KAAK,yBAAyB,CAAC,GAAG,EAAE,KAAK,SAAS,MAAM,IAAI,wBAAwB,CAAC,KAAK,CAAC,GAAG;IAC1F,GAAG,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,CAAC,EAAE,OAAO,KAAK,GAAG,CAAC;CACxD,CAAC;AAMF,wBAAgB,oBAAoB,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,EAAE,KAAK,SAAS,MAAM,EACpF,KAAK,EAAE,yBAAyB,CAAC,KAAK,EAAE,KAAK,CAAC,GAC/C,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,CAahC;AAED,wBAAgB,oBAAoB,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM,EAAE,KAAK,SAAS,MAAM,EAClF,KAAK,EAAE,yBAAyB,CAAC,GAAG,EAAE,KAAK,CAAC,GAC7C,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,CAU9B"}
|
||||
@@ -0,0 +1,6 @@
|
||||
# undici-types
|
||||
|
||||
This package is a dual-publish of the [undici](https://www.npmjs.com/package/undici) library types. The `undici` package **still contains types**. This package is for users who _only_ need undici types (such as for `@types/node`). It is published alongside every release of `undici`, so you can always use the same version.
|
||||
|
||||
- [GitHub nodejs/undici](https://github.com/nodejs/undici)
|
||||
- [Undici Documentation](https://undici.nodejs.org/#/)
|
||||
@@ -0,0 +1,22 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = function (it) {
|
||||
const { pluginId, plugins } = it;
|
||||
|
||||
let result = `ESLint couldn't determine the plugin "${pluginId}" uniquely.
|
||||
`;
|
||||
|
||||
for (const { filePath, importerName } of plugins) {
|
||||
result += `
|
||||
- ${filePath} (loaded in "${importerName}")`;
|
||||
}
|
||||
|
||||
result += `
|
||||
|
||||
Please remove the "plugins" setting from either config or remove either plugin installation.
|
||||
|
||||
If you still can't figure out the problem, please see https://eslint.org/docs/latest/use/troubleshooting.
|
||||
`;
|
||||
|
||||
return result;
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
import { c as createCLI } from './chunks/cac.DdICfEr1.js';
|
||||
import '@vitest/utils/helpers';
|
||||
import 'events';
|
||||
import 'pathe';
|
||||
import 'tinyrainbow';
|
||||
import './chunks/env.D4Lgay0q.js';
|
||||
import 'std-env';
|
||||
import './chunks/constants.CPYnjOGj.js';
|
||||
import 'node:assert';
|
||||
|
||||
createCLI().parse();
|
||||
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* Helpers.
|
||||
*/
|
||||
|
||||
var s = 1000;
|
||||
var m = s * 60;
|
||||
var h = m * 60;
|
||||
var d = h * 24;
|
||||
var w = d * 7;
|
||||
var y = d * 365.25;
|
||||
|
||||
/**
|
||||
* Parse or format the given `val`.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `long` verbose formatting [false]
|
||||
*
|
||||
* @param {String|Number} val
|
||||
* @param {Object} [options]
|
||||
* @throws {Error} throw an error if val is not a non-empty string or a number
|
||||
* @return {String|Number}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function (val, options) {
|
||||
options = options || {};
|
||||
var type = typeof val;
|
||||
if (type === 'string' && val.length > 0) {
|
||||
return parse(val);
|
||||
} else if (type === 'number' && isFinite(val)) {
|
||||
return options.long ? fmtLong(val) : fmtShort(val);
|
||||
}
|
||||
throw new Error(
|
||||
'val is not a non-empty string or a valid number. val=' +
|
||||
JSON.stringify(val)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the given `str` and return milliseconds.
|
||||
*
|
||||
* @param {String} str
|
||||
* @return {Number}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function parse(str) {
|
||||
str = String(str);
|
||||
if (str.length > 100) {
|
||||
return;
|
||||
}
|
||||
var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
|
||||
str
|
||||
);
|
||||
if (!match) {
|
||||
return;
|
||||
}
|
||||
var n = parseFloat(match[1]);
|
||||
var type = (match[2] || 'ms').toLowerCase();
|
||||
switch (type) {
|
||||
case 'years':
|
||||
case 'year':
|
||||
case 'yrs':
|
||||
case 'yr':
|
||||
case 'y':
|
||||
return n * y;
|
||||
case 'weeks':
|
||||
case 'week':
|
||||
case 'w':
|
||||
return n * w;
|
||||
case 'days':
|
||||
case 'day':
|
||||
case 'd':
|
||||
return n * d;
|
||||
case 'hours':
|
||||
case 'hour':
|
||||
case 'hrs':
|
||||
case 'hr':
|
||||
case 'h':
|
||||
return n * h;
|
||||
case 'minutes':
|
||||
case 'minute':
|
||||
case 'mins':
|
||||
case 'min':
|
||||
case 'm':
|
||||
return n * m;
|
||||
case 'seconds':
|
||||
case 'second':
|
||||
case 'secs':
|
||||
case 'sec':
|
||||
case 's':
|
||||
return n * s;
|
||||
case 'milliseconds':
|
||||
case 'millisecond':
|
||||
case 'msecs':
|
||||
case 'msec':
|
||||
case 'ms':
|
||||
return n;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Short format for `ms`.
|
||||
*
|
||||
* @param {Number} ms
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function fmtShort(ms) {
|
||||
var msAbs = Math.abs(ms);
|
||||
if (msAbs >= d) {
|
||||
return Math.round(ms / d) + 'd';
|
||||
}
|
||||
if (msAbs >= h) {
|
||||
return Math.round(ms / h) + 'h';
|
||||
}
|
||||
if (msAbs >= m) {
|
||||
return Math.round(ms / m) + 'm';
|
||||
}
|
||||
if (msAbs >= s) {
|
||||
return Math.round(ms / s) + 's';
|
||||
}
|
||||
return ms + 'ms';
|
||||
}
|
||||
|
||||
/**
|
||||
* Long format for `ms`.
|
||||
*
|
||||
* @param {Number} ms
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function fmtLong(ms) {
|
||||
var msAbs = Math.abs(ms);
|
||||
if (msAbs >= d) {
|
||||
return plural(ms, msAbs, d, 'day');
|
||||
}
|
||||
if (msAbs >= h) {
|
||||
return plural(ms, msAbs, h, 'hour');
|
||||
}
|
||||
if (msAbs >= m) {
|
||||
return plural(ms, msAbs, m, 'minute');
|
||||
}
|
||||
if (msAbs >= s) {
|
||||
return plural(ms, msAbs, s, 'second');
|
||||
}
|
||||
return ms + ' ms';
|
||||
}
|
||||
|
||||
/**
|
||||
* Pluralization helper.
|
||||
*/
|
||||
|
||||
function plural(ms, msAbs, n, name) {
|
||||
var isPlural = msAbs >= n * 1.5;
|
||||
return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
/**
|
||||
* Experimental KDF for AES.
|
||||
*/
|
||||
import { hkdf } from './hkdf.ts';
|
||||
import { pbkdf2 as _pbkdf2 } from './pbkdf2.ts';
|
||||
import { scrypt as _scrypt } from './scrypt.ts';
|
||||
import { sha256 } from './sha256.ts';
|
||||
import { abytes, bytesToHex, clean, createView, hexToBytes, kdfInputToBytes } from './utils.ts';
|
||||
|
||||
// A tiny KDF for various applications like AES key-gen.
|
||||
// Uses HKDF in a non-standard way, so it's not "KDF-secure", only "PRF-secure".
|
||||
// Which is good enough: assume sha2-256 retained preimage resistance.
|
||||
|
||||
const SCRYPT_FACTOR = 2 ** 19;
|
||||
const PBKDF2_FACTOR = 2 ** 17;
|
||||
|
||||
// Scrypt KDF
|
||||
export function scrypt(password: string, salt: string): Uint8Array {
|
||||
return _scrypt(password, salt, { N: SCRYPT_FACTOR, r: 8, p: 1, dkLen: 32 });
|
||||
}
|
||||
|
||||
// PBKDF2-HMAC-SHA256
|
||||
export function pbkdf2(password: string, salt: string): Uint8Array {
|
||||
return _pbkdf2(sha256, password, salt, { c: PBKDF2_FACTOR, dkLen: 32 });
|
||||
}
|
||||
|
||||
// Combines two 32-byte byte arrays
|
||||
function xor32(a: Uint8Array, b: Uint8Array): Uint8Array {
|
||||
abytes(a, 32);
|
||||
abytes(b, 32);
|
||||
const arr = new Uint8Array(32);
|
||||
for (let i = 0; i < 32; i++) {
|
||||
arr[i] = a[i] ^ b[i];
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
function strHasLength(str: string, min: number, max: number): boolean {
|
||||
return typeof str === 'string' && str.length >= min && str.length <= max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives main seed. Takes a lot of time. Prefer `eskdf` method instead.
|
||||
*/
|
||||
export function deriveMainSeed(username: string, password: string): Uint8Array {
|
||||
if (!strHasLength(username, 8, 255)) throw new Error('invalid username');
|
||||
if (!strHasLength(password, 8, 255)) throw new Error('invalid password');
|
||||
// Declared like this to throw off minifiers which auto-convert .fromCharCode(1) to actual string.
|
||||
// String with non-ascii may be problematic in some envs
|
||||
const codes = { _1: 1, _2: 2 };
|
||||
const sep = { s: String.fromCharCode(codes._1), p: String.fromCharCode(codes._2) };
|
||||
const scr = scrypt(password + sep.s, username + sep.s);
|
||||
const pbk = pbkdf2(password + sep.p, username + sep.p);
|
||||
const res = xor32(scr, pbk);
|
||||
clean(scr, pbk);
|
||||
return res;
|
||||
}
|
||||
|
||||
type AccountID = number | string;
|
||||
|
||||
/**
|
||||
* Converts protocol & accountId pair to HKDF salt & info params.
|
||||
*/
|
||||
function getSaltInfo(protocol: string, accountId: AccountID = 0) {
|
||||
// Note that length here also repeats two lines below
|
||||
// We do an additional length check here to reduce the scope of DoS attacks
|
||||
if (!(strHasLength(protocol, 3, 15) && /^[a-z0-9]{3,15}$/.test(protocol))) {
|
||||
throw new Error('invalid protocol');
|
||||
}
|
||||
|
||||
// Allow string account ids for some protocols
|
||||
const allowsStr = /^password\d{0,3}|ssh|tor|file$/.test(protocol);
|
||||
let salt: Uint8Array; // Extract salt. Default is undefined.
|
||||
if (typeof accountId === 'string') {
|
||||
if (!allowsStr) throw new Error('accountId must be a number');
|
||||
if (!strHasLength(accountId, 1, 255))
|
||||
throw new Error('accountId must be string of length 1..255');
|
||||
salt = kdfInputToBytes(accountId);
|
||||
} else if (Number.isSafeInteger(accountId)) {
|
||||
if (accountId < 0 || accountId > Math.pow(2, 32) - 1) throw new Error('invalid accountId');
|
||||
// Convert to Big Endian Uint32
|
||||
salt = new Uint8Array(4);
|
||||
createView(salt).setUint32(0, accountId, false);
|
||||
} else {
|
||||
throw new Error('accountId must be a number' + (allowsStr ? ' or string' : ''));
|
||||
}
|
||||
const info = kdfInputToBytes(protocol);
|
||||
return { salt, info };
|
||||
}
|
||||
|
||||
type OptsLength = { keyLength: number };
|
||||
type OptsMod = { modulus: bigint };
|
||||
type KeyOpts = undefined | OptsLength | OptsMod;
|
||||
|
||||
function countBytes(num: bigint): number {
|
||||
if (typeof num !== 'bigint' || num <= BigInt(128)) throw new Error('invalid number');
|
||||
return Math.ceil(num.toString(2).length / 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses keyLength and modulus options to extract length of result key.
|
||||
* If modulus is used, adds 64 bits to it as per FIPS 186 B.4.1 to combat modulo bias.
|
||||
*/
|
||||
function getKeyLength(options: KeyOpts): number {
|
||||
if (!options || typeof options !== 'object') return 32;
|
||||
const hasLen = 'keyLength' in options;
|
||||
const hasMod = 'modulus' in options;
|
||||
if (hasLen && hasMod) throw new Error('cannot combine keyLength and modulus options');
|
||||
if (!hasLen && !hasMod) throw new Error('must have either keyLength or modulus option');
|
||||
// FIPS 186 B.4.1 requires at least 64 more bits
|
||||
const l = hasMod ? countBytes(options.modulus) + 8 : options.keyLength;
|
||||
if (!(typeof l === 'number' && l >= 16 && l <= 8192)) throw new Error('invalid keyLength');
|
||||
return l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts key to bigint and divides it by modulus. Big Endian.
|
||||
* Implements FIPS 186 B.4.1, which removes 0 and modulo bias from output.
|
||||
*/
|
||||
function modReduceKey(key: Uint8Array, modulus: bigint): Uint8Array {
|
||||
const _1 = BigInt(1);
|
||||
const num = BigInt('0x' + bytesToHex(key)); // check for ui8a, then bytesToNumber()
|
||||
const res = (num % (modulus - _1)) + _1; // Remove 0 from output
|
||||
if (res < _1) throw new Error('expected positive number'); // Guard against bad values
|
||||
const len = key.length - 8; // FIPS requires 64 more bits = 8 bytes
|
||||
const hex = res.toString(16).padStart(len * 2, '0'); // numberToHex()
|
||||
const bytes = hexToBytes(hex);
|
||||
if (bytes.length !== len) throw new Error('invalid length of result key');
|
||||
return bytes;
|
||||
}
|
||||
|
||||
// We are not using classes because constructor cannot be async
|
||||
export interface ESKDF {
|
||||
/**
|
||||
* Derives a child key. Child key will not be associated with any
|
||||
* other child key because of properties of underlying KDF.
|
||||
*
|
||||
* @param protocol - 3-15 character protocol name
|
||||
* @param accountId - numeric identifier of account
|
||||
* @param options - `keyLength: 64` or `modulus: 41920438n`
|
||||
* @example deriveChildKey('aes', 0)
|
||||
*/
|
||||
deriveChildKey: (protocol: string, accountId: AccountID, options?: KeyOpts) => Uint8Array;
|
||||
/**
|
||||
* Deletes the main seed from eskdf instance
|
||||
*/
|
||||
expire: () => void;
|
||||
/**
|
||||
* Account fingerprint
|
||||
*/
|
||||
fingerprint: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* ESKDF
|
||||
* @param username - username, email, or identifier, min: 8 characters, should have enough entropy
|
||||
* @param password - password, min: 8 characters, should have enough entropy
|
||||
* @example
|
||||
* const kdf = await eskdf('example-university', 'beginning-new-example');
|
||||
* const key = kdf.deriveChildKey('aes', 0);
|
||||
* console.log(kdf.fingerprint);
|
||||
* kdf.expire();
|
||||
*/
|
||||
export async function eskdf(username: string, password: string): Promise<ESKDF> {
|
||||
// We are using closure + object instead of class because
|
||||
// we want to make `seed` non-accessible for any external function.
|
||||
let seed: Uint8Array | undefined = deriveMainSeed(username, password);
|
||||
|
||||
function deriveCK(protocol: string, accountId: AccountID = 0, options?: KeyOpts): Uint8Array {
|
||||
abytes(seed, 32);
|
||||
const { salt, info } = getSaltInfo(protocol, accountId); // validate protocol & accountId
|
||||
const keyLength = getKeyLength(options); // validate options
|
||||
const key = hkdf(sha256, seed!, salt, info, keyLength);
|
||||
// Modulus has already been validated
|
||||
return options && 'modulus' in options ? modReduceKey(key, options.modulus) : key;
|
||||
}
|
||||
function expire() {
|
||||
if (seed) seed.fill(1);
|
||||
seed = undefined;
|
||||
}
|
||||
// prettier-ignore
|
||||
const fingerprint = Array.from(deriveCK('fingerprint', 0))
|
||||
.slice(0, 6)
|
||||
.map((char) => char.toString(16).padStart(2, '0').toUpperCase())
|
||||
.join(':');
|
||||
return Object.freeze({ deriveChildKey: deriveCK, expire, fingerprint });
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
import * as core from "./core.js";
|
||||
import * as errors from "./errors.js";
|
||||
import * as util from "./util.js";
|
||||
export const _parse = (_Err) => (schema, value, _ctx, _params) => {
|
||||
const ctx = _ctx ? { ..._ctx, async: false } : { async: false };
|
||||
const result = schema._zod.run({ value, issues: [] }, ctx);
|
||||
if (result instanceof Promise) {
|
||||
throw new core.$ZodAsyncError();
|
||||
}
|
||||
if (result.issues.length) {
|
||||
const e = new (_params?.Err ?? _Err)(result.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())));
|
||||
util.captureStackTrace(e, _params?.callee);
|
||||
throw e;
|
||||
}
|
||||
return result.value;
|
||||
};
|
||||
export const parse = /* @__PURE__*/ _parse(errors.$ZodRealError);
|
||||
export const _parseAsync = (_Err) => async (schema, value, _ctx, params) => {
|
||||
const ctx = _ctx ? { ..._ctx, async: true } : { async: true };
|
||||
let result = schema._zod.run({ value, issues: [] }, ctx);
|
||||
if (result instanceof Promise)
|
||||
result = await result;
|
||||
if (result.issues.length) {
|
||||
const e = new (params?.Err ?? _Err)(result.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())));
|
||||
util.captureStackTrace(e, params?.callee);
|
||||
throw e;
|
||||
}
|
||||
return result.value;
|
||||
};
|
||||
export const parseAsync = /* @__PURE__*/ _parseAsync(errors.$ZodRealError);
|
||||
export const _safeParse = (_Err) => (schema, value, _ctx) => {
|
||||
const ctx = _ctx ? { ..._ctx, async: false } : { async: false };
|
||||
const result = schema._zod.run({ value, issues: [] }, ctx);
|
||||
if (result instanceof Promise) {
|
||||
throw new core.$ZodAsyncError();
|
||||
}
|
||||
return result.issues.length
|
||||
? {
|
||||
success: false,
|
||||
error: new (_Err ?? errors.$ZodError)(result.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config()))),
|
||||
}
|
||||
: { success: true, data: result.value };
|
||||
};
|
||||
export const safeParse = /* @__PURE__*/ _safeParse(errors.$ZodRealError);
|
||||
export const _safeParseAsync = (_Err) => async (schema, value, _ctx) => {
|
||||
const ctx = _ctx ? { ..._ctx, async: true } : { async: true };
|
||||
let result = schema._zod.run({ value, issues: [] }, ctx);
|
||||
if (result instanceof Promise)
|
||||
result = await result;
|
||||
return result.issues.length
|
||||
? {
|
||||
success: false,
|
||||
error: new _Err(result.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config()))),
|
||||
}
|
||||
: { success: true, data: result.value };
|
||||
};
|
||||
export const safeParseAsync = /* @__PURE__*/ _safeParseAsync(errors.$ZodRealError);
|
||||
export const _encode = (_Err) => (schema, value, _ctx) => {
|
||||
const ctx = _ctx ? { ..._ctx, direction: "backward" } : { direction: "backward" };
|
||||
return _parse(_Err)(schema, value, ctx);
|
||||
};
|
||||
export const encode = /* @__PURE__*/ _encode(errors.$ZodRealError);
|
||||
export const _decode = (_Err) => (schema, value, _ctx) => {
|
||||
return _parse(_Err)(schema, value, _ctx);
|
||||
};
|
||||
export const decode = /* @__PURE__*/ _decode(errors.$ZodRealError);
|
||||
export const _encodeAsync = (_Err) => async (schema, value, _ctx) => {
|
||||
const ctx = _ctx ? { ..._ctx, direction: "backward" } : { direction: "backward" };
|
||||
return _parseAsync(_Err)(schema, value, ctx);
|
||||
};
|
||||
export const encodeAsync = /* @__PURE__*/ _encodeAsync(errors.$ZodRealError);
|
||||
export const _decodeAsync = (_Err) => async (schema, value, _ctx) => {
|
||||
return _parseAsync(_Err)(schema, value, _ctx);
|
||||
};
|
||||
export const decodeAsync = /* @__PURE__*/ _decodeAsync(errors.$ZodRealError);
|
||||
export const _safeEncode = (_Err) => (schema, value, _ctx) => {
|
||||
const ctx = _ctx ? { ..._ctx, direction: "backward" } : { direction: "backward" };
|
||||
return _safeParse(_Err)(schema, value, ctx);
|
||||
};
|
||||
export const safeEncode = /* @__PURE__*/ _safeEncode(errors.$ZodRealError);
|
||||
export const _safeDecode = (_Err) => (schema, value, _ctx) => {
|
||||
return _safeParse(_Err)(schema, value, _ctx);
|
||||
};
|
||||
export const safeDecode = /* @__PURE__*/ _safeDecode(errors.$ZodRealError);
|
||||
export const _safeEncodeAsync = (_Err) => async (schema, value, _ctx) => {
|
||||
const ctx = _ctx ? { ..._ctx, direction: "backward" } : { direction: "backward" };
|
||||
return _safeParseAsync(_Err)(schema, value, ctx);
|
||||
};
|
||||
export const safeEncodeAsync = /* @__PURE__*/ _safeEncodeAsync(errors.$ZodRealError);
|
||||
export const _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {
|
||||
return _safeParseAsync(_Err)(schema, value, _ctx);
|
||||
};
|
||||
export const safeDecodeAsync = /* @__PURE__*/ _safeDecodeAsync(errors.$ZodRealError);
|
||||
@@ -0,0 +1,16 @@
|
||||
declare module 'timers' {
|
||||
function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timeout;
|
||||
namespace setTimeout {
|
||||
function __promisify__(ms: number): Promise<void>;
|
||||
function __promisify__<T>(ms: number, value: T): Promise<T>;
|
||||
}
|
||||
function clearTimeout(timeoutId: NodeJS.Timeout | string | number | undefined): void;
|
||||
function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timeout;
|
||||
function clearInterval(intervalId: NodeJS.Timeout | string | number | undefined): void;
|
||||
function setImmediate(callback: (...args: any[]) => void, ...args: any[]): NodeJS.Immediate;
|
||||
namespace setImmediate {
|
||||
function __promisify__(): Promise<void>;
|
||||
function __promisify__<T>(value: T): Promise<T>;
|
||||
}
|
||||
function clearImmediate(immediateId: NodeJS.Immediate | undefined): void;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.RuleTester = void 0;
|
||||
/* eslint-disable @typescript-eslint/no-deprecated */
|
||||
const eslint_1 = require("eslint");
|
||||
/**
|
||||
* @deprecated Use `@typescript-eslint/rule-tester` instead.
|
||||
*/
|
||||
class RuleTester extends eslint_1.RuleTester {
|
||||
}
|
||||
exports.RuleTester = RuleTester;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,854 @@
|
||||
// @flow
|
||||
|
||||
type Exclude<A, B> = A;
|
||||
// see https://gist.github.com/thecotne/6e5969f4aaf8f253985ed36b30ac9fe0
|
||||
type $FlowGen$If<X: boolean, Then, Else = empty> = $Call<
|
||||
((true, Then, Else) => Then) & ((false, Then, Else) => Else),
|
||||
X,
|
||||
Then,
|
||||
Else
|
||||
>;
|
||||
|
||||
type $FlowGen$Assignable<A, B> = $Call<
|
||||
((...r: [B]) => true) & ((...r: [A]) => false),
|
||||
A
|
||||
>;
|
||||
|
||||
import type {
|
||||
Angle,
|
||||
CssColor,
|
||||
Rule,
|
||||
CustomProperty,
|
||||
EnvironmentVariable,
|
||||
Function,
|
||||
Image,
|
||||
LengthValue,
|
||||
MediaQuery,
|
||||
Declaration,
|
||||
Ratio,
|
||||
Resolution,
|
||||
Selector,
|
||||
SupportsCondition,
|
||||
Time,
|
||||
Token,
|
||||
TokenOrValue,
|
||||
UnknownAtRule,
|
||||
Url,
|
||||
Variable,
|
||||
StyleRule,
|
||||
DeclarationBlock,
|
||||
ParsedComponent,
|
||||
Multiplier,
|
||||
StyleSheet,
|
||||
Location2,
|
||||
} from "./ast.js.flow";
|
||||
import { Targets, Features } from "./targets.js.flow";
|
||||
declare export * from "./ast.js.flow";
|
||||
declare export { Targets, Features };
|
||||
export type TransformOptions<C: CustomAtRules> = {|
|
||||
/**
|
||||
* The filename being transformed. Used for error messages and source maps.
|
||||
*/
|
||||
filename: string,
|
||||
|
||||
/**
|
||||
* The source code to transform.
|
||||
*/
|
||||
code: Uint8Array,
|
||||
|
||||
/**
|
||||
* Whether to enable minification.
|
||||
*/
|
||||
minify?: boolean,
|
||||
|
||||
/**
|
||||
* Whether to output a source map.
|
||||
*/
|
||||
sourceMap?: boolean,
|
||||
|
||||
/**
|
||||
* An input source map to extend.
|
||||
*/
|
||||
inputSourceMap?: string,
|
||||
|
||||
/**
|
||||
* An optional project root path, used as the source root in the output source map.
|
||||
* Also used to generate relative paths for sources used in CSS module hashes.
|
||||
*/
|
||||
projectRoot?: string,
|
||||
|
||||
/**
|
||||
* The browser targets for the generated code.
|
||||
*/
|
||||
targets?: Targets,
|
||||
|
||||
/**
|
||||
* Features that should always be compiled, even when supported by targets.
|
||||
*/
|
||||
include?: number,
|
||||
|
||||
/**
|
||||
* Features that should never be compiled, even when unsupported by targets.
|
||||
*/
|
||||
exclude?: number,
|
||||
|
||||
/**
|
||||
* Whether to enable parsing various draft syntax.
|
||||
*/
|
||||
drafts?: Drafts,
|
||||
|
||||
/**
|
||||
* Whether to enable various non-standard syntax.
|
||||
*/
|
||||
nonStandard?: NonStandard,
|
||||
|
||||
/**
|
||||
* Whether to compile this file as a CSS module.
|
||||
*/
|
||||
cssModules?: boolean | CSSModulesConfig,
|
||||
|
||||
/**
|
||||
* Whether to analyze dependencies (e.g. string).
|
||||
* When enabled, string dependencies
|
||||
* are replaced with hashed placeholders that can be replaced with the final
|
||||
* urls later (after bundling). Dependencies are returned as part of the result.
|
||||
*/
|
||||
analyzeDependencies?: boolean | DependencyOptions,
|
||||
|
||||
/**
|
||||
* Replaces user action pseudo classes with class names that can be applied from JavaScript.
|
||||
* This is useful for polyfills, for example.
|
||||
*/
|
||||
pseudoClasses?: PseudoClasses,
|
||||
|
||||
/**
|
||||
* A list of class names, ids, and custom identifiers (e.g. @keyframes) that are known
|
||||
* to be unused. These will be removed during minification. Note that these are not
|
||||
* selectors but individual names (without any . or # prefixes).
|
||||
*/
|
||||
unusedSymbols?: string[],
|
||||
|
||||
/**
|
||||
* Whether to ignore invalid rules and declarations rather than erroring.
|
||||
* When enabled, warnings are returned, and the invalid rule or declaration is
|
||||
* omitted from the output code.
|
||||
*/
|
||||
errorRecovery?: boolean,
|
||||
|
||||
/**
|
||||
* An AST visitor object. This allows custom transforms or analysis to be implemented in JavaScript.
|
||||
* Multiple visitors can be composed into one using the string function.
|
||||
* For optimal performance, visitors should be as specific as possible about what types of values
|
||||
* they care about so that JavaScript has to be called as little as possible.
|
||||
*/
|
||||
visitor?: Visitor<C> | VisitorFunction<C>,
|
||||
|
||||
/**
|
||||
* Defines how to parse custom CSS at-rules. Each at-rule can have a prelude, defined using a CSS
|
||||
* [syntax string](https://drafts.css-houdini.org/css-properties-values-api/#syntax-strings), and
|
||||
* a block body. The body can be a declaration list, rule list, or style block as defined in the
|
||||
* [css spec](https://drafts.csswg.org/css-syntax/#declaration-rule-list).
|
||||
*/
|
||||
customAtRules?: C,
|
||||
|};
|
||||
declare type PropertyStart =
|
||||
| "-"
|
||||
| "_"
|
||||
| "a"
|
||||
| "b"
|
||||
| "c"
|
||||
| "d"
|
||||
| "e"
|
||||
| "f"
|
||||
| "g"
|
||||
| "h"
|
||||
| "i"
|
||||
| "j"
|
||||
| "k"
|
||||
| "l"
|
||||
| "m"
|
||||
| "n"
|
||||
| "o"
|
||||
| "p"
|
||||
| "q"
|
||||
| "r"
|
||||
| "s"
|
||||
| "t"
|
||||
| "u"
|
||||
| "v"
|
||||
| "w"
|
||||
| "x"
|
||||
| "y"
|
||||
| "z";
|
||||
export type ReturnedDeclaration =
|
||||
| Declaration
|
||||
| {|
|
||||
/**
|
||||
* The property name.
|
||||
*/
|
||||
property: string,
|
||||
|
||||
/**
|
||||
* The raw string value for the declaration.
|
||||
*/
|
||||
raw: string,
|
||||
|};
|
||||
export type ReturnedMediaQuery =
|
||||
| MediaQuery
|
||||
| {|
|
||||
/**
|
||||
* The raw string value for the media query.
|
||||
*/
|
||||
raw: string,
|
||||
|};
|
||||
declare type FindByType<Union, Name> = $FlowGen$If<
|
||||
$FlowGen$Assignable<
|
||||
Union,
|
||||
{|
|
||||
type: Name,
|
||||
|}
|
||||
>,
|
||||
Union,
|
||||
empty
|
||||
>;
|
||||
export type ReturnedRule = Rule<ReturnedDeclaration, ReturnedMediaQuery>;
|
||||
declare type RequiredValue<Rule> = $FlowGen$If<
|
||||
$FlowGen$Assignable<
|
||||
Rule,
|
||||
{|
|
||||
value: { [key: string]: any },
|
||||
|}
|
||||
>,
|
||||
$FlowGen$If<
|
||||
$FlowGen$Assignable<$PropertyType<Rule, "value">, StyleRule>,
|
||||
{|
|
||||
...Rule,
|
||||
...{|
|
||||
value: {|
|
||||
...Required<StyleRule>,
|
||||
...{|
|
||||
declarations: Required<DeclarationBlock>,
|
||||
|},
|
||||
|},
|
||||
|},
|
||||
|},
|
||||
{|
|
||||
...Rule,
|
||||
...{|
|
||||
value: Required<$PropertyType<Rule, "value">>,
|
||||
|},
|
||||
|}
|
||||
>,
|
||||
Rule
|
||||
>;
|
||||
declare type RuleVisitor<R = RequiredValue<Rule>> = (
|
||||
rule: R
|
||||
) => ReturnedRule | ReturnedRule[] | void;
|
||||
declare type MappedRuleVisitors = $ObjMapi<
|
||||
{ [k: Exclude<$PropertyType<Rule, "type">, "unknown" | "custom">]: any },
|
||||
<Name>(Name) => RuleVisitor<RequiredValue<FindByType<Rule, Name>>>
|
||||
>;
|
||||
declare type UnknownVisitors<T> = {
|
||||
[name: string]: RuleVisitor<T>,
|
||||
};
|
||||
declare type CustomVisitors<T: CustomAtRules> = $ObjMapi<
|
||||
T,
|
||||
<Name>(Name) => RuleVisitor<CustomAtRule<Name, $ElementType<T, Name>>>
|
||||
>;
|
||||
declare type AnyCustomAtRule<C: CustomAtRules> = $ElementType<
|
||||
$ObjMapi<C, <Key>(Key) => CustomAtRule<Key, $ElementType<C, Key>>>,
|
||||
$Keys<C>
|
||||
>;
|
||||
declare type RuleVisitors<C: CustomAtRules> = {|
|
||||
...MappedRuleVisitors,
|
||||
...{|
|
||||
unknown?:
|
||||
| UnknownVisitors<UnknownAtRule>
|
||||
| $Diff<
|
||||
RuleVisitor<UnknownAtRule>,
|
||||
{ [key: $Keys<CallableFunction>]: any }
|
||||
>,
|
||||
custom?:
|
||||
| CustomVisitors<C>
|
||||
| $Diff<
|
||||
RuleVisitor<AnyCustomAtRule<C>>,
|
||||
{ [key: $Keys<CallableFunction>]: any }
|
||||
>,
|
||||
|},
|
||||
|};
|
||||
declare type PreludeTypes = Exclude<
|
||||
$PropertyType<ParsedComponent, "type">,
|
||||
"literal" | "repeated" | "token"
|
||||
>;
|
||||
declare type SyntaxString = string | string;
|
||||
declare type ComponentTypes = $ObjMapi<
|
||||
{ [k: PreludeTypes]: any },
|
||||
<Key>(Key) => FindByType<ParsedComponent, Key>
|
||||
>;
|
||||
declare type Repetitions = $ObjMapi<
|
||||
{ [k: PreludeTypes]: any },
|
||||
<Key>(Key) => {|
|
||||
type: "repeated",
|
||||
value: {|
|
||||
components: FindByType<ParsedComponent, Key>[],
|
||||
multiplier: Multiplier,
|
||||
|},
|
||||
|}
|
||||
>;
|
||||
declare type MappedPrelude = {| ...ComponentTypes, ...Repetitions |};
|
||||
declare type MappedBody<P: $PropertyType<CustomAtRuleDefinition, "body">> =
|
||||
$FlowGen$If<$FlowGen$Assignable<P, "style-block">, "rule-list", P>;
|
||||
declare type CustomAtRule<N, R: CustomAtRuleDefinition> = {|
|
||||
name: N,
|
||||
prelude: $FlowGen$If<
|
||||
$FlowGen$Assignable<$PropertyType<R, "prelude">, $Keys<MappedPrelude>>,
|
||||
$ElementType<MappedPrelude, $PropertyType<R, "prelude">>,
|
||||
ParsedComponent
|
||||
>,
|
||||
body: FindByType<CustomAtRuleBody, MappedBody<$PropertyType<R, "body">>>,
|
||||
loc: Location2,
|
||||
|};
|
||||
declare type CustomAtRuleBody =
|
||||
| {|
|
||||
type: "declaration-list",
|
||||
value: Required<DeclarationBlock>,
|
||||
|}
|
||||
| {|
|
||||
type: "rule-list",
|
||||
value: RequiredValue<Rule>[],
|
||||
|};
|
||||
declare type FindProperty<Union, Name> = $FlowGen$If<
|
||||
$FlowGen$Assignable<
|
||||
Union,
|
||||
{|
|
||||
property: Name,
|
||||
|}
|
||||
>,
|
||||
Union,
|
||||
empty
|
||||
>;
|
||||
declare type DeclarationVisitor<P = Declaration> = (
|
||||
property: P
|
||||
) => ReturnedDeclaration | ReturnedDeclaration[] | void;
|
||||
declare type MappedDeclarationVisitors = $ObjMapi<
|
||||
{
|
||||
[k: Exclude<
|
||||
$PropertyType<Declaration, "property">,
|
||||
"unparsed" | "custom"
|
||||
>]: any,
|
||||
},
|
||||
<Name>(
|
||||
Name
|
||||
) => DeclarationVisitor<
|
||||
FindProperty<Declaration, Name> | FindProperty<Declaration, "unparsed">
|
||||
>
|
||||
>;
|
||||
declare type CustomPropertyVisitors = {
|
||||
[name: string]: DeclarationVisitor<CustomProperty>,
|
||||
};
|
||||
declare type DeclarationVisitors = {|
|
||||
...MappedDeclarationVisitors,
|
||||
...{|
|
||||
custom?: CustomPropertyVisitors | DeclarationVisitor<CustomProperty>,
|
||||
|},
|
||||
|};
|
||||
declare type RawValue = {|
|
||||
/**
|
||||
* A raw string value which will be parsed like CSS.
|
||||
*/
|
||||
raw: string,
|
||||
|};
|
||||
declare type TokenReturnValue = TokenOrValue | TokenOrValue[] | RawValue | void;
|
||||
declare type TokenVisitor = (token: Token) => TokenReturnValue;
|
||||
declare type VisitableTokenTypes =
|
||||
| "ident"
|
||||
| "at-keyword"
|
||||
| "hash"
|
||||
| "id-hash"
|
||||
| "string"
|
||||
| "number"
|
||||
| "percentage"
|
||||
| "dimension";
|
||||
declare type TokenVisitors = $ObjMapi<
|
||||
{ [k: VisitableTokenTypes]: any },
|
||||
<Name>(Name) => (token: FindByType<Token, Name>) => TokenReturnValue
|
||||
>;
|
||||
declare type FunctionVisitor = (fn: Function) => TokenReturnValue;
|
||||
declare type EnvironmentVariableVisitor = (
|
||||
env: EnvironmentVariable
|
||||
) => TokenReturnValue;
|
||||
declare type EnvironmentVariableVisitors = {
|
||||
[name: string]: EnvironmentVariableVisitor,
|
||||
};
|
||||
export type Visitor<C: CustomAtRules> = {|
|
||||
StyleSheet?: (
|
||||
stylesheet: StyleSheet
|
||||
) => StyleSheet<ReturnedDeclaration, ReturnedMediaQuery> | void,
|
||||
StyleSheetExit?: (
|
||||
stylesheet: StyleSheet
|
||||
) => StyleSheet<ReturnedDeclaration, ReturnedMediaQuery> | void,
|
||||
Rule?: RuleVisitor<> | RuleVisitors<C>,
|
||||
RuleExit?: RuleVisitor<> | RuleVisitors<C>,
|
||||
Declaration?: DeclarationVisitor<> | DeclarationVisitors,
|
||||
DeclarationExit?: DeclarationVisitor<> | DeclarationVisitors,
|
||||
Url?: (url: Url) => Url | void,
|
||||
Color?: (color: CssColor) => CssColor | void,
|
||||
Image?: (image: Image) => Image | void,
|
||||
ImageExit?: (image: Image) => Image | void,
|
||||
Length?: (length: LengthValue) => LengthValue | void,
|
||||
Angle?: (angle: Angle) => Angle | void,
|
||||
Ratio?: (ratio: Ratio) => Ratio | void,
|
||||
Resolution?: (resolution: Resolution) => Resolution | void,
|
||||
Time?: (time: Time) => Time | void,
|
||||
CustomIdent?: (ident: string) => string | void,
|
||||
DashedIdent?: (ident: string) => string | void,
|
||||
MediaQuery?: (
|
||||
query: MediaQuery
|
||||
) => ReturnedMediaQuery | ReturnedMediaQuery[] | void,
|
||||
MediaQueryExit?: (
|
||||
query: MediaQuery
|
||||
) => ReturnedMediaQuery | ReturnedMediaQuery[] | void,
|
||||
SupportsCondition?: (condition: SupportsCondition) => SupportsCondition,
|
||||
SupportsConditionExit?: (condition: SupportsCondition) => SupportsCondition,
|
||||
Selector?: (selector: Selector) => Selector | Selector[] | void,
|
||||
Token?: TokenVisitor | TokenVisitors,
|
||||
Function?:
|
||||
| FunctionVisitor
|
||||
| {
|
||||
[name: string]: FunctionVisitor,
|
||||
},
|
||||
FunctionExit?:
|
||||
| FunctionVisitor
|
||||
| {
|
||||
[name: string]: FunctionVisitor,
|
||||
},
|
||||
Variable?: (variable: Variable) => TokenReturnValue,
|
||||
VariableExit?: (variable: Variable) => TokenReturnValue,
|
||||
EnvironmentVariable?:
|
||||
| EnvironmentVariableVisitor
|
||||
| EnvironmentVariableVisitors,
|
||||
EnvironmentVariableExit?:
|
||||
| EnvironmentVariableVisitor
|
||||
| EnvironmentVariableVisitors,
|
||||
|};
|
||||
export type VisitorDependency = FileDependency | GlobDependency;
|
||||
export type VisitorOptions = {|
|
||||
addDependency: (dep: VisitorDependency) => void,
|
||||
|};
|
||||
export type VisitorFunction<C: CustomAtRules> = (
|
||||
options: VisitorOptions
|
||||
) => Visitor<C>;
|
||||
export type CustomAtRules = {|
|
||||
[name: string]: CustomAtRuleDefinition,
|
||||
|};
|
||||
export type CustomAtRuleDefinition = {|
|
||||
/**
|
||||
* Defines the syntax for a custom at-rule prelude. The value should be a
|
||||
* CSS [syntax string](https://drafts.css-houdini.org/css-properties-values-api/#syntax-strings)
|
||||
* representing the types of values that are accepted. This property may be omitted or
|
||||
* set to null to indicate that no prelude is accepted.
|
||||
*/
|
||||
prelude?: SyntaxString | null,
|
||||
|
||||
/**
|
||||
* Defines the type of body contained within the at-rule block.
|
||||
* - declaration-list: A CSS declaration list, as in a style rule.
|
||||
* - rule-list: A list of CSS rules, as supported within a non-nested
|
||||
* at-rule such as string.
|
||||
* - style-block: Both a declaration list and rule list, as accepted within
|
||||
* a nested at-rule within a style rule (e.g. string inside a style rule
|
||||
* with directly nested declarations).
|
||||
*/
|
||||
body?: "declaration-list" | "rule-list" | "style-block" | null,
|
||||
|};
|
||||
export type DependencyOptions = {|
|
||||
/**
|
||||
* Whether to preserve string rules rather than removing them.
|
||||
*/
|
||||
preserveImports?: boolean,
|
||||
|};
|
||||
export type BundleOptions<C: CustomAtRules> = $Diff<
|
||||
TransformOptions<C>,
|
||||
{| code: any |}
|
||||
>;
|
||||
export type BundleAsyncOptions<C: CustomAtRules> = {|
|
||||
...$Exact<BundleOptions<C>>,
|
||||
|
||||
resolver?: Resolver,
|
||||
|};
|
||||
declare type MaybePromise<T> = T | Promise<T>;
|
||||
/**
|
||||
* Custom resolver to use when loading CSS files.
|
||||
*/
|
||||
export type Resolver = {|
|
||||
/**
|
||||
* Read the given file and return its contents as a string.
|
||||
*/
|
||||
read?: (file: string) => string | Promise<string>,
|
||||
|
||||
/**
|
||||
* Resolve the given CSS import specifier from the provided originating file to a
|
||||
* path which gets passed to string.
|
||||
*/
|
||||
resolve?: (
|
||||
specifier: string,
|
||||
originatingFile: string
|
||||
) => MaybePromise<
|
||||
| string
|
||||
| {|
|
||||
external: string,
|
||||
|}
|
||||
>,
|
||||
|};
|
||||
export type Drafts = {|
|
||||
/**
|
||||
* Whether to enable @custom-media rules.
|
||||
*/
|
||||
customMedia?: boolean,
|
||||
|
||||
/**
|
||||
* Whether to enable the scroll navigation controls.
|
||||
* https://drafts.csswg.org/css-overflow-5/#scroll-navigation
|
||||
*/
|
||||
scrollNavigationControls?: boolean,
|
||||
|};
|
||||
export type NonStandard = {|
|
||||
/**
|
||||
* Whether to enable the non-standard >>> and /deep/ selector combinators used by Angular and Vue.
|
||||
*/
|
||||
deepSelectorCombinator?: boolean,
|
||||
|};
|
||||
export type PseudoClasses = {|
|
||||
hover?: string,
|
||||
active?: string,
|
||||
focus?: string,
|
||||
focusVisible?: string,
|
||||
focusWithin?: string,
|
||||
|};
|
||||
export type TransformResult = {|
|
||||
/**
|
||||
* The transformed code.
|
||||
*/
|
||||
code: Uint8Array,
|
||||
|
||||
/**
|
||||
* The generated source map, if enabled.
|
||||
*/
|
||||
map: Uint8Array | void,
|
||||
|
||||
/**
|
||||
* CSS module exports, if enabled.
|
||||
*/
|
||||
exports: CSSModuleExports | void,
|
||||
|
||||
/**
|
||||
* CSS module references, if string is enabled.
|
||||
*/
|
||||
references: CSSModuleReferences,
|
||||
|
||||
/**
|
||||
* string dependencies, if enabled.
|
||||
*/
|
||||
dependencies: Dependency[] | void,
|
||||
|
||||
/**
|
||||
* Warnings that occurred during compilation.
|
||||
*/
|
||||
warnings: Warning[],
|
||||
|};
|
||||
export type Warning = {|
|
||||
message: string,
|
||||
type: string,
|
||||
value?: any,
|
||||
loc: ErrorLocation,
|
||||
|};
|
||||
export type CSSModulesConfig = {|
|
||||
/**
|
||||
* The pattern to use when renaming class names and other identifiers. Default is string.
|
||||
*/
|
||||
pattern?: string,
|
||||
|
||||
/**
|
||||
* Whether to rename dashed identifiers, e.g. custom properties.
|
||||
*/
|
||||
dashedIdents?: boolean,
|
||||
|
||||
/**
|
||||
* Whether to enable hashing for string.
|
||||
*/
|
||||
animation?: boolean,
|
||||
|
||||
/**
|
||||
* Whether to enable hashing for CSS grid identifiers.
|
||||
*/
|
||||
grid?: boolean,
|
||||
|
||||
/**
|
||||
* Whether to enable hashing for string names.
|
||||
*/
|
||||
container?: boolean,
|
||||
|
||||
/**
|
||||
* Whether to enable hashing for custom identifiers.
|
||||
*/
|
||||
customIdents?: boolean,
|
||||
|
||||
/**
|
||||
* Whether to require at least one class or id selector in each rule.
|
||||
*/
|
||||
pure?: boolean,
|
||||
|};
|
||||
export type CSSModuleExports = {
|
||||
/**
|
||||
* Maps exported (i.e. original) names to local names.
|
||||
*/
|
||||
[name: string]: CSSModuleExport,
|
||||
};
|
||||
export type CSSModuleExport = {|
|
||||
/**
|
||||
* The local (compiled) name for this export.
|
||||
*/
|
||||
name: string,
|
||||
|
||||
/**
|
||||
* Whether the export is referenced in this file.
|
||||
*/
|
||||
isReferenced: boolean,
|
||||
|
||||
/**
|
||||
* Other names that are composed by this export.
|
||||
*/
|
||||
composes: CSSModuleReference[],
|
||||
|};
|
||||
export type CSSModuleReferences = {
|
||||
/**
|
||||
* Maps placeholder names to references.
|
||||
*/
|
||||
[name: string]: DependencyCSSModuleReference,
|
||||
};
|
||||
export type CSSModuleReference =
|
||||
| LocalCSSModuleReference
|
||||
| GlobalCSSModuleReference
|
||||
| DependencyCSSModuleReference;
|
||||
export type LocalCSSModuleReference = {|
|
||||
type: "local",
|
||||
|
||||
/**
|
||||
* The local (compiled) name for the reference.
|
||||
*/
|
||||
name: string,
|
||||
|};
|
||||
export type GlobalCSSModuleReference = {|
|
||||
type: "global",
|
||||
|
||||
/**
|
||||
* The referenced global name.
|
||||
*/
|
||||
name: string,
|
||||
|};
|
||||
export type DependencyCSSModuleReference = {|
|
||||
type: "dependency",
|
||||
|
||||
/**
|
||||
* The name to reference within the dependency.
|
||||
*/
|
||||
name: string,
|
||||
|
||||
/**
|
||||
* The dependency specifier for the referenced file.
|
||||
*/
|
||||
specifier: string,
|
||||
|};
|
||||
export type Dependency =
|
||||
| ImportDependency
|
||||
| UrlDependency
|
||||
| FileDependency
|
||||
| GlobDependency;
|
||||
export type ImportDependency = {|
|
||||
type: "import",
|
||||
|
||||
/**
|
||||
* The url of the string dependency.
|
||||
*/
|
||||
url: string,
|
||||
|
||||
/**
|
||||
* The media query for the string rule.
|
||||
*/
|
||||
media: string | null,
|
||||
|
||||
/**
|
||||
* The string rule.
|
||||
*/
|
||||
supports: string | null,
|
||||
|
||||
/**
|
||||
* The source location where the string rule was found.
|
||||
*/
|
||||
loc: SourceLocation,
|
||||
|
||||
/**
|
||||
* The placeholder that the import was replaced with.
|
||||
*/
|
||||
placeholder: string,
|
||||
|};
|
||||
export type UrlDependency = {|
|
||||
type: "url",
|
||||
|
||||
/**
|
||||
* The url of the dependency.
|
||||
*/
|
||||
url: string,
|
||||
|
||||
/**
|
||||
* The source location where the string was found.
|
||||
*/
|
||||
loc: SourceLocation,
|
||||
|
||||
/**
|
||||
* The placeholder that the url was replaced with.
|
||||
*/
|
||||
placeholder: string,
|
||||
|};
|
||||
export type FileDependency = {|
|
||||
type: "file",
|
||||
filePath: string,
|
||||
|};
|
||||
export type GlobDependency = {|
|
||||
type: "glob",
|
||||
glob: string,
|
||||
|};
|
||||
export type SourceLocation = {|
|
||||
/**
|
||||
* The file path in which the dependency exists.
|
||||
*/
|
||||
filePath: string,
|
||||
|
||||
/**
|
||||
* The start location of the dependency.
|
||||
*/
|
||||
start: Location,
|
||||
|
||||
/**
|
||||
* The end location (inclusive) of the dependency.
|
||||
*/
|
||||
end: Location,
|
||||
|};
|
||||
export type Location = {|
|
||||
/**
|
||||
* The line number (1-based).
|
||||
*/
|
||||
line: number,
|
||||
|
||||
/**
|
||||
* The column number (0-based).
|
||||
*/
|
||||
column: number,
|
||||
|};
|
||||
export type ErrorLocation = {|
|
||||
...$Exact<Location>,
|
||||
|
||||
filename: string,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Compiles a CSS file, including optionally minifying and lowering syntax to the given
|
||||
* targets. A source map may also be generated, but this is not enabled by default.
|
||||
*/
|
||||
declare export function transform<C: CustomAtRules>(
|
||||
options: TransformOptions<C>
|
||||
): TransformResult;
|
||||
export type TransformAttributeOptions = {|
|
||||
/**
|
||||
* The filename in which the style attribute appeared. Used for error messages and dependencies.
|
||||
*/
|
||||
filename?: string,
|
||||
|
||||
/**
|
||||
* The source code to transform.
|
||||
*/
|
||||
code: Uint8Array,
|
||||
|
||||
/**
|
||||
* Whether to enable minification.
|
||||
*/
|
||||
minify?: boolean,
|
||||
|
||||
/**
|
||||
* The browser targets for the generated code.
|
||||
*/
|
||||
targets?: Targets,
|
||||
|
||||
/**
|
||||
* Whether to analyze string dependencies.
|
||||
* When enabled, string dependencies are replaced with hashed placeholders
|
||||
* that can be replaced with the final urls later (after bundling).
|
||||
* Dependencies are returned as part of the result.
|
||||
*/
|
||||
analyzeDependencies?: boolean,
|
||||
|
||||
/**
|
||||
* Whether to ignore invalid rules and declarations rather than erroring.
|
||||
* When enabled, warnings are returned, and the invalid rule or declaration is
|
||||
* omitted from the output code.
|
||||
*/
|
||||
errorRecovery?: boolean,
|
||||
|
||||
/**
|
||||
* An AST visitor object. This allows custom transforms or analysis to be implemented in JavaScript.
|
||||
* Multiple visitors can be composed into one using the string function.
|
||||
* For optimal performance, visitors should be as specific as possible about what types of values
|
||||
* they care about so that JavaScript has to be called as little as possible.
|
||||
*/
|
||||
visitor?: Visitor<empty> | VisitorFunction<empty>,
|
||||
|};
|
||||
export type TransformAttributeResult = {|
|
||||
/**
|
||||
* The transformed code.
|
||||
*/
|
||||
code: Uint8Array,
|
||||
|
||||
/**
|
||||
* string dependencies, if enabled.
|
||||
*/
|
||||
dependencies: Dependency[] | void,
|
||||
|
||||
/**
|
||||
* Warnings that occurred during compilation.
|
||||
*/
|
||||
warnings: Warning[],
|
||||
|};
|
||||
|
||||
/**
|
||||
* Compiles a single CSS declaration list, such as an inline style attribute in HTML.
|
||||
*/
|
||||
declare export function transformStyleAttribute(
|
||||
options: TransformAttributeOptions
|
||||
): TransformAttributeResult;
|
||||
|
||||
/**
|
||||
* Converts a browserslist result into targets that can be passed to lightningcss.
|
||||
* @param browserslist the result of calling string
|
||||
*/
|
||||
declare export function browserslistToTargets(browserslist: string[]): Targets;
|
||||
|
||||
/**
|
||||
* Bundles a CSS file and its dependencies, inlining @import rules.
|
||||
*/
|
||||
declare export function bundle<C: CustomAtRules>(
|
||||
options: BundleOptions<C>
|
||||
): TransformResult;
|
||||
|
||||
/**
|
||||
* Bundles a CSS file and its dependencies asynchronously, inlining @import rules.
|
||||
*/
|
||||
declare export function bundleAsync<C: CustomAtRules>(
|
||||
options: BundleAsyncOptions<C>
|
||||
): Promise<TransformResult>;
|
||||
|
||||
/**
|
||||
* Composes multiple visitor objects into a single one.
|
||||
*/
|
||||
declare export function composeVisitors<C: CustomAtRules>(
|
||||
visitors: (Visitor<C> | VisitorFunction<C>)[]
|
||||
): Visitor<C> | VisitorFunction<C>;
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "escape-string-regexp",
|
||||
"version": "4.0.0",
|
||||
"description": "Escape RegExp special characters",
|
||||
"license": "MIT",
|
||||
"repository": "sindresorhus/escape-string-regexp",
|
||||
"funding": "https://github.com/sponsors/sindresorhus",
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "https://sindresorhus.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "xo && ava && tsd"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"index.d.ts"
|
||||
],
|
||||
"keywords": [
|
||||
"escape",
|
||||
"regex",
|
||||
"regexp",
|
||||
"regular",
|
||||
"expression",
|
||||
"string",
|
||||
"special",
|
||||
"characters"
|
||||
],
|
||||
"devDependencies": {
|
||||
"ava": "^1.4.1",
|
||||
"tsd": "^0.11.0",
|
||||
"xo": "^0.28.3"
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user