storybook
Version:
Storybook: Develop, document, and test UI components in isolation
1,201 lines (1,200 loc) • 117 kB
JavaScript
import {
mapValues
} from "./chunk-AIOS4NGK.js";
import {
isPlainObject
} from "./chunk-GFLS4VP3.js";
import {
__commonJS,
__toESM
} from "./chunk-A242L54C.js";
// ../node_modules/jsdoc-type-pratt-parser/dist/index.js
var require_dist = __commonJS({
"../node_modules/jsdoc-type-pratt-parser/dist/index.js"(exports, module) {
(function(global, factory) {
typeof exports == "object" && typeof module < "u" ? factory(exports) : typeof define == "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis < "u" ? globalThis : global || self, factory(global.jtpp = {}));
})(exports, (function(exports2) {
"use strict";
function tokenToString(token) {
return token.text !== void 0 && token.text !== "" ? `'${token.type}' with value '${token.text}'` : `'${token.type}'`;
}
class NoParsletFoundError extends Error {
constructor(token) {
super(`No parslet found for token: ${tokenToString(token)}`), this.token = token, Object.setPrototypeOf(this, NoParsletFoundError.prototype);
}
getToken() {
return this.token;
}
}
class EarlyEndOfParseError extends Error {
constructor(token) {
super(`The parsing ended early. The next token was: ${tokenToString(token)}`), this.token = token, Object.setPrototypeOf(this, EarlyEndOfParseError.prototype);
}
getToken() {
return this.token;
}
}
class UnexpectedTypeError extends Error {
constructor(result, message) {
let error = `Unexpected type: '${result.type}'.`;
message !== void 0 && (error += ` Message: ${message}`), super(error), Object.setPrototypeOf(this, UnexpectedTypeError.prototype);
}
}
function makePunctuationRule(type) {
return (text) => text.startsWith(type) ? { type, text: type } : null;
}
function getQuoted(text) {
let position = 0, char, mark = text[0], escaped = !1;
if (mark !== "'" && mark !== '"')
return null;
for (; position < text.length; ) {
if (position++, char = text[position], !escaped && char === mark) {
position++;
break;
}
escaped = !escaped && char === "\\";
}
if (char !== mark)
throw new Error("Unterminated String");
return text.slice(0, position);
}
let identifierStartRegex = new RegExp("[$_\\p{ID_Start}]|\\\\u\\p{Hex_Digit}{4}|\\\\u\\{0*(?:\\p{Hex_Digit}{1,5}|10\\p{Hex_Digit}{4})\\}", "u"), identifierContinueRegex = new RegExp("[$\\-\\p{ID_Continue}\\u200C\\u200D]|\\\\u\\p{Hex_Digit}{4}|\\\\u\\{0*(?:\\p{Hex_Digit}{1,5}|10\\p{Hex_Digit}{4})\\}", "u");
function getIdentifier(text) {
let char = text[0];
if (!identifierStartRegex.test(char))
return null;
let position = 1;
do {
if (char = text[position], !identifierContinueRegex.test(char))
break;
position++;
} while (position < text.length);
return text.slice(0, position);
}
let numberRegex = /^(NaN|-?((\d*\.\d+|\d+)([Ee][+-]?\d+)?|Infinity))/;
function getNumber(text) {
var _a, _b;
return (_b = (_a = numberRegex.exec(text)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : null;
}
let identifierRule = (text) => {
let value = getIdentifier(text);
return value == null ? null : {
type: "Identifier",
text: value
};
};
function makeKeyWordRule(type) {
return (text) => {
if (!text.startsWith(type))
return null;
let prepends = text[type.length];
return prepends !== void 0 && identifierContinueRegex.test(prepends) ? null : {
type,
text: type
};
};
}
let stringValueRule = (text) => {
let value = getQuoted(text);
return value == null ? null : {
type: "StringValue",
text: value
};
}, eofRule = (text) => text.length > 0 ? null : {
type: "EOF",
text: ""
}, numberRule = (text) => {
let value = getNumber(text);
return value === null ? null : {
type: "Number",
text: value
};
}, rules = [
eofRule,
makePunctuationRule("=>"),
makePunctuationRule("("),
makePunctuationRule(")"),
makePunctuationRule("{"),
makePunctuationRule("}"),
makePunctuationRule("["),
makePunctuationRule("]"),
makePunctuationRule("|"),
makePunctuationRule("&"),
makePunctuationRule("<"),
makePunctuationRule(">"),
makePunctuationRule(","),
makePunctuationRule(";"),
makePunctuationRule("*"),
makePunctuationRule("?"),
makePunctuationRule("!"),
makePunctuationRule("="),
makePunctuationRule(":"),
makePunctuationRule("..."),
makePunctuationRule("."),
makePunctuationRule("#"),
makePunctuationRule("~"),
makePunctuationRule("/"),
makePunctuationRule("@"),
makeKeyWordRule("undefined"),
makeKeyWordRule("null"),
makeKeyWordRule("function"),
makeKeyWordRule("this"),
makeKeyWordRule("new"),
makeKeyWordRule("module"),
makeKeyWordRule("event"),
makeKeyWordRule("extends"),
makeKeyWordRule("external"),
makeKeyWordRule("infer"),
makeKeyWordRule("typeof"),
makeKeyWordRule("keyof"),
makeKeyWordRule("readonly"),
makeKeyWordRule("import"),
makeKeyWordRule("is"),
makeKeyWordRule("in"),
makeKeyWordRule("asserts"),
numberRule,
identifierRule,
stringValueRule
], breakingWhitespaceRegex = /^\s*\n\s*/;
class Lexer {
static create(text) {
let current = this.read(text);
text = current.text;
let next = this.read(text);
return text = next.text, new Lexer(text, void 0, current.token, next.token);
}
constructor(text, previous, current, next) {
this.text = "", this.text = text, this.previous = previous, this.current = current, this.next = next;
}
static read(text, startOfLine = !1) {
startOfLine = startOfLine || breakingWhitespaceRegex.test(text), text = text.trim();
for (let rule of rules) {
let partial = rule(text);
if (partial !== null) {
let token = Object.assign(Object.assign({}, partial), { startOfLine });
return text = text.slice(token.text.length), { text, token };
}
}
throw new Error("Unexpected Token " + text);
}
advance() {
let next = Lexer.read(this.text);
return new Lexer(next.text, this.current, this.next, next.token);
}
}
function assertRootResult(result) {
if (result === void 0)
throw new Error("Unexpected undefined");
if (result.type === "JsdocTypeKeyValue" || result.type === "JsdocTypeParameterList" || result.type === "JsdocTypeProperty" || result.type === "JsdocTypeReadonlyProperty" || result.type === "JsdocTypeObjectField" || result.type === "JsdocTypeJsdocObjectField" || result.type === "JsdocTypeIndexSignature" || result.type === "JsdocTypeMappedType" || result.type === "JsdocTypeTypeParameter")
throw new UnexpectedTypeError(result);
return result;
}
function assertPlainKeyValueOrRootResult(result) {
return result.type === "JsdocTypeKeyValue" ? assertPlainKeyValueResult(result) : assertRootResult(result);
}
function assertPlainKeyValueOrNameResult(result) {
return result.type === "JsdocTypeName" ? result : assertPlainKeyValueResult(result);
}
function assertPlainKeyValueResult(result) {
if (result.type !== "JsdocTypeKeyValue")
throw new UnexpectedTypeError(result);
return result;
}
function assertNumberOrVariadicNameResult(result) {
var _a;
if (result.type === "JsdocTypeVariadic") {
if (((_a = result.element) === null || _a === void 0 ? void 0 : _a.type) === "JsdocTypeName")
return result;
throw new UnexpectedTypeError(result);
}
if (result.type !== "JsdocTypeNumber" && result.type !== "JsdocTypeName")
throw new UnexpectedTypeError(result);
return result;
}
function assertArrayOrTupleResult(result) {
if (result.type === "JsdocTypeTuple" || result.type === "JsdocTypeGeneric" && result.meta.brackets === "square")
return result;
throw new UnexpectedTypeError(result);
}
function isSquaredProperty(result) {
return result.type === "JsdocTypeIndexSignature" || result.type === "JsdocTypeMappedType";
}
var Precedence;
(function(Precedence2) {
Precedence2[Precedence2.ALL = 0] = "ALL", Precedence2[Precedence2.PARAMETER_LIST = 1] = "PARAMETER_LIST", Precedence2[Precedence2.OBJECT = 2] = "OBJECT", Precedence2[Precedence2.KEY_VALUE = 3] = "KEY_VALUE", Precedence2[Precedence2.INDEX_BRACKETS = 4] = "INDEX_BRACKETS", Precedence2[Precedence2.UNION = 5] = "UNION", Precedence2[Precedence2.INTERSECTION = 6] = "INTERSECTION", Precedence2[Precedence2.PREFIX = 7] = "PREFIX", Precedence2[Precedence2.INFIX = 8] = "INFIX", Precedence2[Precedence2.TUPLE = 9] = "TUPLE", Precedence2[Precedence2.SYMBOL = 10] = "SYMBOL", Precedence2[Precedence2.OPTIONAL = 11] = "OPTIONAL", Precedence2[Precedence2.NULLABLE = 12] = "NULLABLE", Precedence2[Precedence2.KEY_OF_TYPE_OF = 13] = "KEY_OF_TYPE_OF", Precedence2[Precedence2.FUNCTION = 14] = "FUNCTION", Precedence2[Precedence2.ARROW = 15] = "ARROW", Precedence2[Precedence2.ARRAY_BRACKETS = 16] = "ARRAY_BRACKETS", Precedence2[Precedence2.GENERIC = 17] = "GENERIC", Precedence2[Precedence2.NAME_PATH = 18] = "NAME_PATH", Precedence2[Precedence2.PARENTHESIS = 19] = "PARENTHESIS", Precedence2[Precedence2.SPECIAL_TYPES = 20] = "SPECIAL_TYPES";
})(Precedence || (Precedence = {}));
class Parser {
constructor(grammar, textOrLexer, baseParser) {
this.grammar = grammar, typeof textOrLexer == "string" ? this._lexer = Lexer.create(textOrLexer) : this._lexer = textOrLexer, this.baseParser = baseParser;
}
get lexer() {
return this._lexer;
}
/**
* Parses a given string and throws an error if the parse ended before the end of the string.
*/
parse() {
let result = this.parseType(Precedence.ALL);
if (this.lexer.current.type !== "EOF")
throw new EarlyEndOfParseError(this.lexer.current);
return result;
}
/**
* Parses with the current lexer and asserts that the result is a {@link RootResult}.
*/
parseType(precedence) {
return assertRootResult(this.parseIntermediateType(precedence));
}
/**
* The main parsing function. First it tries to parse the current state in the prefix step, and then it continues
* to parse the state in the infix step.
*/
parseIntermediateType(precedence) {
let result = this.tryParslets(null, precedence);
if (result === null)
throw new NoParsletFoundError(this.lexer.current);
return this.parseInfixIntermediateType(result, precedence);
}
/**
* In the infix parsing step the parser continues to parse the current state with all parslets until none returns
* a result.
*/
parseInfixIntermediateType(left, precedence) {
let result = this.tryParslets(left, precedence);
for (; result !== null; )
left = result, result = this.tryParslets(left, precedence);
return left;
}
/**
* Tries to parse the current state with all parslets in the grammar and returns the first non null result.
*/
tryParslets(left, precedence) {
for (let parslet of this.grammar) {
let result = parslet(this, precedence, left);
if (result !== null)
return result;
}
return null;
}
/**
* If the given type equals the current type of the {@link Lexer} advance the lexer. Return true if the lexer was
* advanced.
*/
consume(types) {
return Array.isArray(types) || (types = [types]), types.includes(this.lexer.current.type) ? (this._lexer = this.lexer.advance(), !0) : !1;
}
acceptLexerState(parser) {
this._lexer = parser.lexer;
}
}
function isQuestionMarkUnknownType(next) {
return next === "}" || next === "EOF" || next === "|" || next === "," || next === ")" || next === ">";
}
let nullableParslet = (parser, precedence, left) => {
let type = parser.lexer.current.type, next = parser.lexer.next.type;
return left == null && type === "?" && !isQuestionMarkUnknownType(next) || left != null && type === "?" ? (parser.consume("?"), left == null ? {
type: "JsdocTypeNullable",
element: parser.parseType(Precedence.NULLABLE),
meta: {
position: "prefix"
}
} : {
type: "JsdocTypeNullable",
element: assertRootResult(left),
meta: {
position: "suffix"
}
}) : null;
};
function composeParslet(options) {
let parslet = (parser, curPrecedence, left) => {
let type = parser.lexer.current.type, next = parser.lexer.next.type;
if (left === null) {
if ("parsePrefix" in options && options.accept(type, next))
return options.parsePrefix(parser);
} else if ("parseInfix" in options && options.precedence > curPrecedence && options.accept(type, next))
return options.parseInfix(parser, left);
return null;
};
return Object.defineProperty(parslet, "name", {
value: options.name
}), parslet;
}
let optionalParslet = composeParslet({
name: "optionalParslet",
accept: (type) => type === "=",
precedence: Precedence.OPTIONAL,
parsePrefix: (parser) => (parser.consume("="), {
type: "JsdocTypeOptional",
element: parser.parseType(Precedence.OPTIONAL),
meta: {
position: "prefix"
}
}),
parseInfix: (parser, left) => (parser.consume("="), {
type: "JsdocTypeOptional",
element: assertRootResult(left),
meta: {
position: "suffix"
}
})
}), numberParslet = composeParslet({
name: "numberParslet",
accept: (type) => type === "Number",
parsePrefix: (parser) => {
let value = parseFloat(parser.lexer.current.text);
return parser.consume("Number"), {
type: "JsdocTypeNumber",
value
};
}
}), parenthesisParslet = composeParslet({
name: "parenthesisParslet",
accept: (type) => type === "(",
parsePrefix: (parser) => {
if (parser.consume("("), parser.consume(")"))
return {
type: "JsdocTypeParameterList",
elements: []
};
let result = parser.parseIntermediateType(Precedence.ALL);
if (!parser.consume(")"))
throw new Error("Unterminated parenthesis");
return result.type === "JsdocTypeParameterList" ? result : result.type === "JsdocTypeKeyValue" ? {
type: "JsdocTypeParameterList",
elements: [result]
} : {
type: "JsdocTypeParenthesis",
element: assertRootResult(result)
};
}
}), specialTypesParslet = composeParslet({
name: "specialTypesParslet",
accept: (type, next) => type === "?" && isQuestionMarkUnknownType(next) || type === "null" || type === "undefined" || type === "*",
parsePrefix: (parser) => {
if (parser.consume("null"))
return {
type: "JsdocTypeNull"
};
if (parser.consume("undefined"))
return {
type: "JsdocTypeUndefined"
};
if (parser.consume("*"))
return {
type: "JsdocTypeAny"
};
if (parser.consume("?"))
return {
type: "JsdocTypeUnknown"
};
throw new Error("Unacceptable token: " + parser.lexer.current.text);
}
}), notNullableParslet = composeParslet({
name: "notNullableParslet",
accept: (type) => type === "!",
precedence: Precedence.NULLABLE,
parsePrefix: (parser) => (parser.consume("!"), {
type: "JsdocTypeNotNullable",
element: parser.parseType(Precedence.NULLABLE),
meta: {
position: "prefix"
}
}),
parseInfix: (parser, left) => (parser.consume("!"), {
type: "JsdocTypeNotNullable",
element: assertRootResult(left),
meta: {
position: "suffix"
}
})
});
function createParameterListParslet({ allowTrailingComma }) {
return composeParslet({
name: "parameterListParslet",
accept: (type) => type === ",",
precedence: Precedence.PARAMETER_LIST,
parseInfix: (parser, left) => {
let elements = [
assertPlainKeyValueOrRootResult(left)
];
parser.consume(",");
do
try {
let next = parser.parseIntermediateType(Precedence.PARAMETER_LIST);
elements.push(assertPlainKeyValueOrRootResult(next));
} catch (e) {
if (e instanceof NoParsletFoundError)
break;
throw e;
}
while (parser.consume(","));
if (elements.length > 0 && elements.slice(0, -1).some((e) => e.type === "JsdocTypeVariadic"))
throw new Error("Only the last parameter may be a rest parameter");
return {
type: "JsdocTypeParameterList",
elements
};
}
});
}
let genericParslet = composeParslet({
name: "genericParslet",
accept: (type, next) => type === "<" || type === "." && next === "<",
precedence: Precedence.GENERIC,
parseInfix: (parser, left) => {
let dot = parser.consume(".");
parser.consume("<");
let objects = [], infer = !1;
if (parser.consume("infer")) {
infer = !0;
let left2 = parser.parseIntermediateType(Precedence.SYMBOL);
if (left2.type !== "JsdocTypeName")
throw new UnexpectedTypeError(left2, "A typescript asserts always has to have a name on the left side.");
objects.push(left2);
} else
do
objects.push(parser.parseType(Precedence.PARAMETER_LIST));
while (parser.consume(","));
if (!parser.consume(">"))
throw new Error("Unterminated generic parameter list");
return Object.assign(Object.assign({ type: "JsdocTypeGeneric", left: assertRootResult(left), elements: objects }, infer ? { infer: !0 } : {}), { meta: {
brackets: "angle",
dot
} });
}
}), unionParslet = composeParslet({
name: "unionParslet",
accept: (type) => type === "|",
precedence: Precedence.UNION,
parseInfix: (parser, left) => {
parser.consume("|");
let elements = [];
do
elements.push(parser.parseType(Precedence.UNION));
while (parser.consume("|"));
return {
type: "JsdocTypeUnion",
elements: [assertRootResult(left), ...elements]
};
}
}), baseGrammar = [
nullableParslet,
optionalParslet,
numberParslet,
parenthesisParslet,
specialTypesParslet,
notNullableParslet,
createParameterListParslet({
allowTrailingComma: !0
}),
genericParslet,
unionParslet,
optionalParslet
];
function createNamePathParslet({ allowSquareBracketsOnAnyType, allowJsdocNamePaths, pathGrammar: pathGrammar2 }) {
return function(parser, precedence, left) {
if (left == null || precedence >= Precedence.NAME_PATH)
return null;
let type = parser.lexer.current.type, next = parser.lexer.next.type;
if (!(type === "." && next !== "<" || type === "[" && (allowSquareBracketsOnAnyType || left.type === "JsdocTypeName") || allowJsdocNamePaths && (type === "~" || type === "#")))
return null;
let pathType, brackets = !1;
parser.consume(".") ? pathType = "property" : parser.consume("[") ? (pathType = "property-brackets", brackets = !0) : parser.consume("~") ? pathType = "inner" : (parser.consume("#"), pathType = "instance");
let pathParser = pathGrammar2 !== null ? new Parser(pathGrammar2, parser.lexer, parser) : parser, parsed = pathParser.parseIntermediateType(Precedence.NAME_PATH);
parser.acceptLexerState(pathParser);
let right;
switch (parsed.type) {
case "JsdocTypeName":
right = {
type: "JsdocTypeProperty",
value: parsed.value,
meta: {
quote: void 0
}
};
break;
case "JsdocTypeNumber":
right = {
type: "JsdocTypeProperty",
value: parsed.value.toString(10),
meta: {
quote: void 0
}
};
break;
case "JsdocTypeStringValue":
right = {
type: "JsdocTypeProperty",
value: parsed.value,
meta: {
quote: parsed.meta.quote
}
};
break;
case "JsdocTypeSpecialNamePath":
if (parsed.specialType === "event")
right = parsed;
else
throw new UnexpectedTypeError(parsed, "Type 'JsdocTypeSpecialNamePath' is only allowed with specialType 'event'");
break;
default:
throw new UnexpectedTypeError(parsed, "Expecting 'JsdocTypeName', 'JsdocTypeNumber', 'JsdocStringValue' or 'JsdocTypeSpecialNamePath'");
}
if (brackets && !parser.consume("]")) {
let token = parser.lexer.current;
throw new Error(`Unterminated square brackets. Next token is '${token.type}' with text '${token.text}'`);
}
return {
type: "JsdocTypeNamePath",
left: assertRootResult(left),
right,
pathType
};
};
}
function createNameParslet({ allowedAdditionalTokens }) {
return composeParslet({
name: "nameParslet",
accept: (type) => type === "Identifier" || type === "this" || type === "new" || allowedAdditionalTokens.includes(type),
parsePrefix: (parser) => {
let { type, text } = parser.lexer.current;
return parser.consume(type), {
type: "JsdocTypeName",
value: text
};
}
});
}
let stringValueParslet = composeParslet({
name: "stringValueParslet",
accept: (type) => type === "StringValue",
parsePrefix: (parser) => {
let text = parser.lexer.current.text;
return parser.consume("StringValue"), {
type: "JsdocTypeStringValue",
value: text.slice(1, -1),
meta: {
quote: text[0] === "'" ? "single" : "double"
}
};
}
});
function createSpecialNamePathParslet({ pathGrammar: pathGrammar2, allowedTypes }) {
return composeParslet({
name: "specialNamePathParslet",
accept: (type) => allowedTypes.includes(type),
parsePrefix: (parser) => {
let type = parser.lexer.current.type;
if (parser.consume(type), !parser.consume(":"))
return {
type: "JsdocTypeName",
value: type
};
let result, token = parser.lexer.current;
if (parser.consume("StringValue"))
result = {
type: "JsdocTypeSpecialNamePath",
value: token.text.slice(1, -1),
specialType: type,
meta: {
quote: token.text[0] === "'" ? "single" : "double"
}
};
else {
let value = "", allowed = ["Identifier", "@", "/"];
for (; allowed.some((type2) => parser.consume(type2)); )
value += token.text, token = parser.lexer.current;
result = {
type: "JsdocTypeSpecialNamePath",
value,
specialType: type,
meta: {
quote: void 0
}
};
}
let moduleParser = new Parser(pathGrammar2, parser.lexer, parser), moduleResult = moduleParser.parseInfixIntermediateType(result, Precedence.ALL);
return parser.acceptLexerState(moduleParser), assertRootResult(moduleResult);
}
});
}
let basePathGrammar = [
createNameParslet({
allowedAdditionalTokens: ["external", "module"]
}),
stringValueParslet,
numberParslet,
createNamePathParslet({
allowSquareBracketsOnAnyType: !1,
allowJsdocNamePaths: !0,
pathGrammar: null
})
], pathGrammar = [
...basePathGrammar,
createSpecialNamePathParslet({
allowedTypes: ["event"],
pathGrammar: basePathGrammar
})
];
function getParameters(value) {
let parameters;
if (value.type === "JsdocTypeParameterList")
parameters = value.elements;
else if (value.type === "JsdocTypeParenthesis")
parameters = [value.element];
else
throw new UnexpectedTypeError(value);
return parameters.map((p) => assertPlainKeyValueOrRootResult(p));
}
function getUnnamedParameters(value) {
let parameters = getParameters(value);
if (parameters.some((p) => p.type === "JsdocTypeKeyValue"))
throw new Error("No parameter should be named");
return parameters;
}
function createFunctionParslet({ allowNamedParameters, allowNoReturnType, allowWithoutParenthesis, allowNewAsFunctionKeyword }) {
return composeParslet({
name: "functionParslet",
accept: (type, next) => type === "function" || allowNewAsFunctionKeyword && type === "new" && next === "(",
parsePrefix: (parser) => {
let newKeyword = parser.consume("new");
parser.consume("function");
let hasParenthesis = parser.lexer.current.type === "(";
if (!hasParenthesis) {
if (!allowWithoutParenthesis)
throw new Error("function is missing parameter list");
return {
type: "JsdocTypeName",
value: "function"
};
}
let result = {
type: "JsdocTypeFunction",
parameters: [],
arrow: !1,
constructor: newKeyword,
parenthesis: hasParenthesis
}, value = parser.parseIntermediateType(Precedence.FUNCTION);
if (allowNamedParameters === void 0)
result.parameters = getUnnamedParameters(value);
else {
if (newKeyword && value.type === "JsdocTypeFunction" && value.arrow)
return result = value, result.constructor = !0, result;
result.parameters = getParameters(value);
for (let p of result.parameters)
if (p.type === "JsdocTypeKeyValue" && !allowNamedParameters.includes(p.key))
throw new Error(`only allowed named parameters are ${allowNamedParameters.join(", ")} but got ${p.type}`);
}
if (parser.consume(":"))
result.returnType = parser.parseType(Precedence.PREFIX);
else if (!allowNoReturnType)
throw new Error("function is missing return type");
return result;
}
});
}
function createVariadicParslet({ allowPostfix, allowEnclosingBrackets }) {
return composeParslet({
name: "variadicParslet",
accept: (type) => type === "...",
precedence: Precedence.PREFIX,
parsePrefix: (parser) => {
parser.consume("...");
let brackets = allowEnclosingBrackets && parser.consume("[");
try {
let element = parser.parseType(Precedence.PREFIX);
if (brackets && !parser.consume("]"))
throw new Error("Unterminated variadic type. Missing ']'");
return {
type: "JsdocTypeVariadic",
element: assertRootResult(element),
meta: {
position: "prefix",
squareBrackets: brackets
}
};
} catch (e) {
if (e instanceof NoParsletFoundError) {
if (brackets)
throw new Error("Empty square brackets for variadic are not allowed.");
return {
type: "JsdocTypeVariadic",
meta: {
position: void 0,
squareBrackets: !1
}
};
} else
throw e;
}
},
parseInfix: allowPostfix ? (parser, left) => (parser.consume("..."), {
type: "JsdocTypeVariadic",
element: assertRootResult(left),
meta: {
position: "suffix",
squareBrackets: !1
}
}) : void 0
});
}
let symbolParslet = composeParslet({
name: "symbolParslet",
accept: (type) => type === "(",
precedence: Precedence.SYMBOL,
parseInfix: (parser, left) => {
if (left.type !== "JsdocTypeName")
throw new Error("Symbol expects a name on the left side. (Reacting on '(')");
parser.consume("(");
let result = {
type: "JsdocTypeSymbol",
value: left.value
};
if (!parser.consume(")")) {
let next = parser.parseIntermediateType(Precedence.SYMBOL);
if (result.element = assertNumberOrVariadicNameResult(next), !parser.consume(")"))
throw new Error("Symbol does not end after value");
}
return result;
}
}), arrayBracketsParslet = composeParslet({
name: "arrayBracketsParslet",
precedence: Precedence.ARRAY_BRACKETS,
accept: (type, next) => type === "[" && next === "]",
parseInfix: (parser, left) => (parser.consume("["), parser.consume("]"), {
type: "JsdocTypeGeneric",
left: {
type: "JsdocTypeName",
value: "Array"
},
elements: [
assertRootResult(left)
],
meta: {
brackets: "square",
dot: !1
}
})
});
function createObjectParslet({ objectFieldGrammar: objectFieldGrammar2, allowKeyTypes }) {
return composeParslet({
name: "objectParslet",
accept: (type) => type === "{",
parsePrefix: (parser) => {
parser.consume("{");
let result = {
type: "JsdocTypeObject",
meta: {
separator: "comma"
},
elements: []
};
if (!parser.consume("}")) {
let separator, fieldParser = new Parser(objectFieldGrammar2, parser.lexer, parser);
for (; ; ) {
fieldParser.acceptLexerState(parser);
let field = fieldParser.parseIntermediateType(Precedence.OBJECT);
parser.acceptLexerState(fieldParser), field === void 0 && allowKeyTypes && (field = parser.parseIntermediateType(Precedence.OBJECT));
let optional = !1;
if (field.type === "JsdocTypeNullable" && (optional = !0, field = field.element), field.type === "JsdocTypeNumber" || field.type === "JsdocTypeName" || field.type === "JsdocTypeStringValue") {
let quote2;
field.type === "JsdocTypeStringValue" && (quote2 = field.meta.quote), result.elements.push({
type: "JsdocTypeObjectField",
key: field.value.toString(),
right: void 0,
optional,
readonly: !1,
meta: {
quote: quote2
}
});
} else if (field.type === "JsdocTypeObjectField" || field.type === "JsdocTypeJsdocObjectField")
result.elements.push(field);
else
throw new UnexpectedTypeError(field);
if (parser.lexer.current.startOfLine)
separator = "linebreak", parser.consume(",") || parser.consume(";");
else if (parser.consume(","))
separator = "comma";
else if (parser.consume(";"))
separator = "semicolon";
else
break;
if (parser.lexer.current.type === "}")
break;
}
if (result.meta.separator = separator ?? "comma", separator === "linebreak" && (result.meta.propertyIndent = " "), !parser.consume("}"))
throw new Error("Unterminated record type. Missing '}'");
}
return result;
}
});
}
function createObjectFieldParslet({ allowSquaredProperties, allowKeyTypes, allowReadonly, allowOptional }) {
return composeParslet({
name: "objectFieldParslet",
precedence: Precedence.KEY_VALUE,
accept: (type) => type === ":",
parseInfix: (parser, left) => {
var _a;
let optional = !1, readonlyProperty = !1;
allowOptional && left.type === "JsdocTypeNullable" && (optional = !0, left = left.element), allowReadonly && left.type === "JsdocTypeReadonlyProperty" && (readonlyProperty = !0, left = left.element);
let parentParser = (_a = parser.baseParser) !== null && _a !== void 0 ? _a : parser;
if (parentParser.acceptLexerState(parser), left.type === "JsdocTypeNumber" || left.type === "JsdocTypeName" || left.type === "JsdocTypeStringValue" || isSquaredProperty(left)) {
if (isSquaredProperty(left) && !allowSquaredProperties)
throw new UnexpectedTypeError(left);
parentParser.consume(":");
let quote2;
left.type === "JsdocTypeStringValue" && (quote2 = left.meta.quote);
let right = parentParser.parseType(Precedence.KEY_VALUE);
return parser.acceptLexerState(parentParser), {
type: "JsdocTypeObjectField",
key: isSquaredProperty(left) ? left : left.value.toString(),
right,
optional,
readonly: readonlyProperty,
meta: {
quote: quote2
}
};
} else {
if (!allowKeyTypes)
throw new UnexpectedTypeError(left);
parentParser.consume(":");
let right = parentParser.parseType(Precedence.KEY_VALUE);
return parser.acceptLexerState(parentParser), {
type: "JsdocTypeJsdocObjectField",
left: assertRootResult(left),
right
};
}
}
});
}
function createKeyValueParslet({ allowOptional, allowVariadic }) {
return composeParslet({
name: "keyValueParslet",
precedence: Precedence.KEY_VALUE,
accept: (type) => type === ":",
parseInfix: (parser, left) => {
let optional = !1, variadic = !1;
if (allowOptional && left.type === "JsdocTypeNullable" && (optional = !0, left = left.element), allowVariadic && left.type === "JsdocTypeVariadic" && left.element !== void 0 && (variadic = !0, left = left.element), left.type !== "JsdocTypeName")
throw new UnexpectedTypeError(left);
parser.consume(":");
let right = parser.parseType(Precedence.KEY_VALUE);
return {
type: "JsdocTypeKeyValue",
key: left.value,
right,
optional,
variadic
};
}
});
}
let jsdocBaseGrammar = [
...baseGrammar,
createFunctionParslet({
allowWithoutParenthesis: !0,
allowNamedParameters: ["this", "new"],
allowNoReturnType: !0,
allowNewAsFunctionKeyword: !1
}),
stringValueParslet,
createSpecialNamePathParslet({
allowedTypes: ["module", "external", "event"],
pathGrammar
}),
createVariadicParslet({
allowEnclosingBrackets: !0,
allowPostfix: !0
}),
createNameParslet({
allowedAdditionalTokens: ["keyof"]
}),
symbolParslet,
arrayBracketsParslet,
createNamePathParslet({
allowSquareBracketsOnAnyType: !1,
allowJsdocNamePaths: !0,
pathGrammar
})
], jsdocGrammar = [
...jsdocBaseGrammar,
createObjectParslet({
// jsdoc syntax allows full types as keys, so we need to pull in the full grammar here
// we leave out the object type deliberately
objectFieldGrammar: [
createNameParslet({
allowedAdditionalTokens: ["typeof", "module", "in"]
}),
createObjectFieldParslet({
allowSquaredProperties: !1,
allowKeyTypes: !0,
allowOptional: !1,
allowReadonly: !1
}),
...jsdocBaseGrammar
],
allowKeyTypes: !0
}),
createKeyValueParslet({
allowOptional: !0,
allowVariadic: !0
})
], typeOfParslet = composeParslet({
name: "typeOfParslet",
accept: (type) => type === "typeof",
parsePrefix: (parser) => (parser.consume("typeof"), {
type: "JsdocTypeTypeof",
element: parser.parseType(Precedence.KEY_OF_TYPE_OF)
})
}), objectFieldGrammar$1 = [
createNameParslet({
allowedAdditionalTokens: ["typeof", "module", "keyof", "event", "external", "in"]
}),
nullableParslet,
optionalParslet,
stringValueParslet,
numberParslet,
createObjectFieldParslet({
allowSquaredProperties: !1,
allowKeyTypes: !1,
allowOptional: !1,
allowReadonly: !1
})
], closureGrammar = [
...baseGrammar,
createObjectParslet({
allowKeyTypes: !1,
objectFieldGrammar: objectFieldGrammar$1
}),
createNameParslet({
allowedAdditionalTokens: ["event", "external", "in"]
}),
typeOfParslet,
createFunctionParslet({
allowWithoutParenthesis: !1,
allowNamedParameters: ["this", "new"],
allowNoReturnType: !0,
allowNewAsFunctionKeyword: !1
}),
createVariadicParslet({
allowEnclosingBrackets: !1,
allowPostfix: !1
}),
// additional name parslet is needed for some special cases
createNameParslet({
allowedAdditionalTokens: ["keyof"]
}),
createSpecialNamePathParslet({
allowedTypes: ["module"],
pathGrammar
}),
createNamePathParslet({
allowSquareBracketsOnAnyType: !1,
allowJsdocNamePaths: !0,
pathGrammar
}),
createKeyValueParslet({
allowOptional: !1,
allowVariadic: !1
}),
symbolParslet
], assertsParslet = composeParslet({
name: "assertsParslet",
accept: (type) => type === "asserts",
parsePrefix: (parser) => {
parser.consume("asserts");
let left = parser.parseIntermediateType(Precedence.SYMBOL);
if (left.type !== "JsdocTypeName")
throw new UnexpectedTypeError(left, "A typescript asserts always has to have a name on the left side.");
return parser.consume("is") ? {
type: "JsdocTypeAsserts",
left,
right: assertRootResult(parser.parseIntermediateType(Precedence.INFIX))
} : {
type: "JsdocTypeAssertsPlain",
element: left
};
}
});
function createTupleParslet({ allowQuestionMark }) {
return composeParslet({
name: "tupleParslet",
accept: (type) => type === "[",
parsePrefix: (parser) => {
parser.consume("[");
let result = {
type: "JsdocTypeTuple",
elements: []
};
if (parser.consume("]"))
return result;
let typeList = parser.parseIntermediateType(Precedence.ALL);
if (typeList.type === "JsdocTypeParameterList" ? typeList.elements[0].type === "JsdocTypeKeyValue" ? result.elements = typeList.elements.map(assertPlainKeyValueResult) : result.elements = typeList.elements.map(assertRootResult) : typeList.type === "JsdocTypeKeyValue" ? result.elements = [assertPlainKeyValueResult(typeList)] : result.elements = [assertRootResult(typeList)], !parser.consume("]"))
throw new Error("Unterminated '['");
if (result.elements.some((e) => e.type === "JsdocTypeUnknown"))
throw new Error("Question mark in tuple not allowed");
return result;
}
});
}
let keyOfParslet = composeParslet({
name: "keyOfParslet",
accept: (type) => type === "keyof",
parsePrefix: (parser) => (parser.consume("keyof"), {
type: "JsdocTypeKeyof",
element: assertRootResult(parser.parseType(Precedence.KEY_OF_TYPE_OF))
})
}), importParslet = composeParslet({
name: "importParslet",
accept: (type) => type === "import",
parsePrefix: (parser) => {
if (parser.consume("import"), !parser.consume("("))
throw new Error("Missing parenthesis after import keyword");
let path = parser.parseType(Precedence.PREFIX);
if (path.type !== "JsdocTypeStringValue")
throw new Error("Only string values are allowed as paths for imports");
if (!parser.consume(")"))
throw new Error("Missing closing parenthesis after import keyword");
return {
type: "JsdocTypeImport",
element: path
};
}
}), readonlyPropertyParslet = composeParslet({
name: "readonlyPropertyParslet",
accept: (type) => type === "readonly",
parsePrefix: (parser) => (parser.consume("readonly"), {
type: "JsdocTypeReadonlyProperty",
element: parser.parseIntermediateType(Precedence.KEY_VALUE)
})
}), arrowFunctionParslet = composeParslet({
name: "arrowFunctionParslet",
precedence: Precedence.ARROW,
accept: (type) => type === "=>",
parseInfix: (parser, left) => (parser.consume("=>"), {
type: "JsdocTypeFunction",
parameters: getParameters(left).map(assertPlainKeyValueOrNameResult),
arrow: !0,
constructor: !1,
parenthesis: !0,
returnType: parser.parseType(Precedence.OBJECT)
})
}), genericArrowFunctionParslet = composeParslet({
name: "genericArrowFunctionParslet",
accept: (type) => type === "<",
parsePrefix: (parser) => {
let typeParameters = [];
parser.consume("<");
do {
let defaultValue, name = parser.parseIntermediateType(Precedence.SYMBOL);
if (name.type === "JsdocTypeOptional" && (name = name.element, defaultValue = parser.parseType(Precedence.SYMBOL)), name.type !== "JsdocTypeName")
throw new UnexpectedTypeError(name);
let constraint;
parser.consume("extends") && (constraint = parser.parseType(Precedence.SYMBOL), constraint.type === "JsdocTypeOptional" && (constraint = constraint.element, defaultValue = parser.parseType(Precedence.SYMBOL)));
let typeParameter = {
type: "JsdocTypeTypeParameter",
name
};
if (constraint !== void 0 && (typeParameter.constraint = constraint), defaultValue !== void 0 && (typeParameter.defaultValue = defaultValue), typeParameters.push(typeParameter), parser.consume(">"))
break;
} while (parser.consume(","));
let functionBase = parser.parseIntermediateType(Precedence.SYMBOL);
return functionBase.typeParameters = typeParameters, functionBase;
}
}), intersectionParslet = composeParslet({
name: "intersectionParslet",
accept: (type) => type === "&",
precedence: Precedence.INTERSECTION,
parseInfix: (parser, left) => {
parser.consume("&");
let elements = [];
do
elements.push(parser.parseType(Precedence.INTERSECTION));
while (parser.consume("&"));
return {
type: "JsdocTypeIntersection",
elements: [assertRootResult(left), ...elements]
};
}
}), predicateParslet = composeParslet({
name: "predicateParslet",
precedence: Precedence.INFIX,
accept: (type) => type === "is",
parseInfix: (parser, left) => {
if (left.type !== "JsdocTypeName")
throw new UnexpectedTypeError(left, "A typescript predicate always has to have a name on the left side.");
return parser.consume("is"), {
type: "JsdocTypePredicate",
left,
right: assertRootResult(parser.parseIntermediateType(Precedence.INFIX))
};
}
}), objectSquaredPropertyParslet = composeParslet({
name: "objectSquareBracketPropertyParslet",
accept: (type) => type === "[",
parsePrefix: (parser) => {
if (parser.baseParser === void 0)
throw new Error("Only allowed inside object grammar");
parser.consume("[");
let key = parser.lexer.current.text;
parser.consume("Identifier");
let result;
if (parser.consume(":")) {
let parentParser = parser.baseParser;
parentParser.acceptLexerState(parser), result = {
type: "JsdocTypeIndexSignature",
key,
right: parentParser.parseType(Precedence.INDEX_BRACKETS)
}, parser.acceptLexerState(parentParser);
} else if (parser.consume("in")) {
let parentParser = parser.baseParser;
parentParser.acceptLexerState(parser), result = {
type: "JsdocTypeMappedType",
key,
right: parentParser.parseType(Precedence.ARRAY_BRACKETS)
}, parser.acceptLexerState(parentParser);
} else
throw new Error("Missing ':' or 'in' inside square bracketed property.");
if (!parser.consume("]"))
throw new Error("Unterminated square brackets");
return result;
}
}), readonlyArrayParslet = composeParslet({
name: "readonlyArrayParslet",
accept: (type) => type === "readonly",
parsePrefix: (parser) => (parser.consume("readonly"), {
type: "JsdocTypeReadonlyArray",
element: assertArrayOrTupleResult(parser.parseIntermediateType(Precedence.ALL))
})
}), conditionalParslet = composeParslet({
name: "conditionalParslet",
precedence: Precedence.INFIX,
accept: (type) => type === "extends",
parseInfix: (parser, left) => {
parser.consume("extends");
let extendsType = parser.parseType(Precedence.KEY_OF_TYPE_OF).element, trueType = parser.parseType(Precedence.INFIX);
return parser.consume(":"), {
type: "JsdocTypeConditional",
checksType: assertRootResult(left),
extendsType,
trueType,
falseType: parser.parseType(Precedence.INFIX)
};
}
}), objectFieldGrammar = [
readonlyPropertyParslet,
createNameParslet({
allowedAdditionalTokens: ["typeof", "module", "keyof", "event", "external", "in"]
}),
nullableParslet,
optionalParslet,
stringValueParslet,
numberParslet,
createObjectFieldParslet({
allowSquaredProperties: !0,
allowKeyTypes: !1,
allowOptional: