UNPKG

storybook

Version:

Storybook: Develop, document, and test UI components in isolation

1,201 lines (1,200 loc) • 117 kB
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: