storybook
Version:
Storybook: Develop, document, and test UI components in isolation
1,330 lines (1,329 loc) • 144 kB
JavaScript
import {
mapValues
} from "./chunk-UTNZYD2N.js";
import {
isPlainObject
} from "./chunk-FSBVR7H5.js";
import {
__commonJS,
__name,
__toESM
} from "./chunk-MM7DTO55.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 !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.jtpp = {}));
})(exports, function(exports2) {
"use strict";
function tokenToString(token) {
if (token.text !== void 0 && token.text !== "") {
return `'${token.type}' with value '${token.text}'`;
} else {
return `'${token.type}'`;
}
}
__name(tokenToString, "tokenToString");
const _NoParsletFoundError = 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;
}
};
__name(_NoParsletFoundError, "NoParsletFoundError");
let NoParsletFoundError = _NoParsletFoundError;
const _EarlyEndOfParseError = 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;
}
};
__name(_EarlyEndOfParseError, "EarlyEndOfParseError");
let EarlyEndOfParseError = _EarlyEndOfParseError;
const _UnexpectedTypeError = class _UnexpectedTypeError extends Error {
constructor(result, message) {
let error = `Unexpected type: '${result.type}'.`;
if (message !== void 0) {
error += ` Message: ${message}`;
}
super(error);
Object.setPrototypeOf(this, _UnexpectedTypeError.prototype);
}
};
__name(_UnexpectedTypeError, "UnexpectedTypeError");
let UnexpectedTypeError = _UnexpectedTypeError;
function makePunctuationRule(type) {
return (text) => {
if (text.startsWith(type)) {
return { type, text: type };
} else {
return null;
}
};
}
__name(makePunctuationRule, "makePunctuationRule");
function getQuoted(text) {
let position = 0;
let char;
const mark = text[0];
let escaped = false;
if (mark !== "'" && mark !== '"') {
return null;
}
while (position < text.length) {
position++;
char = text[position];
if (!escaped && char === mark) {
position++;
break;
}
escaped = !escaped && char === "\\";
}
if (char !== mark) {
throw new Error("Unterminated String");
}
return text.slice(0, position);
}
__name(getQuoted, "getQuoted");
const identifierStartRegex = new RegExp("[$_\\p{ID_Start}]|\\\\u\\p{Hex_Digit}{4}|\\\\u\\{0*(?:\\p{Hex_Digit}{1,5}|10\\p{Hex_Digit}{4})\\}", "u");
const 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 {
char = text[position];
if (!identifierContinueRegex.test(char)) {
break;
}
position++;
} while (position < text.length);
return text.slice(0, position);
}
__name(getIdentifier, "getIdentifier");
const 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;
}
__name(getNumber, "getNumber");
const identifierRule = /* @__PURE__ */ __name((text) => {
const value = getIdentifier(text);
if (value == null) {
return null;
}
return {
type: "Identifier",
text: value
};
}, "identifierRule");
function makeKeyWordRule(type) {
return (text) => {
if (!text.startsWith(type)) {
return null;
}
const prepends = text[type.length];
if (prepends !== void 0 && identifierContinueRegex.test(prepends)) {
return null;
}
return {
type,
text: type
};
};
}
__name(makeKeyWordRule, "makeKeyWordRule");
const stringValueRule = /* @__PURE__ */ __name((text) => {
const value = getQuoted(text);
if (value == null) {
return null;
}
return {
type: "StringValue",
text: value
};
}, "stringValueRule");
const eofRule = /* @__PURE__ */ __name((text) => {
if (text.length > 0) {
return null;
}
return {
type: "EOF",
text: ""
};
}, "eofRule");
const numberRule = /* @__PURE__ */ __name((text) => {
const value = getNumber(text);
if (value === null) {
return null;
}
return {
type: "Number",
text: value
};
}, "numberRule");
const 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
];
const breakingWhitespaceRegex = /^\s*\n\s*/;
const _Lexer = class _Lexer {
static create(text) {
const current = this.read(text);
text = current.text;
const next = this.read(text);
text = next.text;
return 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 = false) {
startOfLine = startOfLine || breakingWhitespaceRegex.test(text);
text = text.trim();
for (const rule of rules) {
const partial = rule(text);
if (partial !== null) {
const token = Object.assign(Object.assign({}, partial), { startOfLine });
text = text.slice(token.text.length);
return { text, token };
}
}
throw new Error("Unexpected Token " + text);
}
advance() {
const next = _Lexer.read(this.text);
return new _Lexer(next.text, this.current, this.next, next.token);
}
};
__name(_Lexer, "Lexer");
let Lexer = _Lexer;
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;
}
__name(assertRootResult, "assertRootResult");
function assertPlainKeyValueOrRootResult(result) {
if (result.type === "JsdocTypeKeyValue") {
return assertPlainKeyValueResult(result);
}
return assertRootResult(result);
}
__name(assertPlainKeyValueOrRootResult, "assertPlainKeyValueOrRootResult");
function assertPlainKeyValueOrNameResult(result) {
if (result.type === "JsdocTypeName") {
return result;
}
return assertPlainKeyValueResult(result);
}
__name(assertPlainKeyValueOrNameResult, "assertPlainKeyValueOrNameResult");
function assertPlainKeyValueResult(result) {
if (result.type !== "JsdocTypeKeyValue") {
throw new UnexpectedTypeError(result);
}
return result;
}
__name(assertPlainKeyValueResult, "assertPlainKeyValueResult");
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;
}
__name(assertNumberOrVariadicNameResult, "assertNumberOrVariadicNameResult");
function assertArrayOrTupleResult(result) {
if (result.type === "JsdocTypeTuple") {
return result;
}
if (result.type === "JsdocTypeGeneric" && result.meta.brackets === "square") {
return result;
}
throw new UnexpectedTypeError(result);
}
__name(assertArrayOrTupleResult, "assertArrayOrTupleResult");
function isSquaredProperty(result) {
return result.type === "JsdocTypeIndexSignature" || result.type === "JsdocTypeMappedType";
}
__name(isSquaredProperty, "isSquaredProperty");
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 = {}));
const _Parser = class _Parser {
constructor(grammar, textOrLexer, baseParser) {
this.grammar = grammar;
if (typeof textOrLexer === "string") {
this._lexer = Lexer.create(textOrLexer);
} else {
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() {
const 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) {
const 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);
while (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 (const parslet of this.grammar) {
const 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) {
if (!Array.isArray(types)) {
types = [types];
}
if (types.includes(this.lexer.current.type)) {
this._lexer = this.lexer.advance();
return true;
} else {
return false;
}
}
acceptLexerState(parser) {
this._lexer = parser.lexer;
}
};
__name(_Parser, "Parser");
let Parser = _Parser;
function isQuestionMarkUnknownType(next) {
return next === "}" || next === "EOF" || next === "|" || next === "," || next === ")" || next === ">";
}
__name(isQuestionMarkUnknownType, "isQuestionMarkUnknownType");
const nullableParslet = /* @__PURE__ */ __name((parser, precedence, left) => {
const type = parser.lexer.current.type;
const next = parser.lexer.next.type;
const accept = left == null && type === "?" && !isQuestionMarkUnknownType(next) || left != null && type === "?";
if (!accept) {
return null;
}
parser.consume("?");
if (left == null) {
return {
type: "JsdocTypeNullable",
element: parser.parseType(Precedence.NULLABLE),
meta: {
position: "prefix"
}
};
} else {
return {
type: "JsdocTypeNullable",
element: assertRootResult(left),
meta: {
position: "suffix"
}
};
}
}, "nullableParslet");
function composeParslet(options) {
const parslet = /* @__PURE__ */ __name((parser, curPrecedence, left) => {
const type = parser.lexer.current.type;
const next = parser.lexer.next.type;
if (left === null) {
if ("parsePrefix" in options) {
if (options.accept(type, next)) {
return options.parsePrefix(parser);
}
}
} else {
if ("parseInfix" in options) {
if (options.precedence > curPrecedence && options.accept(type, next)) {
return options.parseInfix(parser, left);
}
}
}
return null;
}, "parslet");
Object.defineProperty(parslet, "name", {
value: options.name
});
return parslet;
}
__name(composeParslet, "composeParslet");
const optionalParslet = composeParslet({
name: "optionalParslet",
accept: /* @__PURE__ */ __name((type) => type === "=", "accept"),
precedence: Precedence.OPTIONAL,
parsePrefix: /* @__PURE__ */ __name((parser) => {
parser.consume("=");
return {
type: "JsdocTypeOptional",
element: parser.parseType(Precedence.OPTIONAL),
meta: {
position: "prefix"
}
};
}, "parsePrefix"),
parseInfix: /* @__PURE__ */ __name((parser, left) => {
parser.consume("=");
return {
type: "JsdocTypeOptional",
element: assertRootResult(left),
meta: {
position: "suffix"
}
};
}, "parseInfix")
});
const numberParslet = composeParslet({
name: "numberParslet",
accept: /* @__PURE__ */ __name((type) => type === "Number", "accept"),
parsePrefix: /* @__PURE__ */ __name((parser) => {
const value = parseFloat(parser.lexer.current.text);
parser.consume("Number");
return {
type: "JsdocTypeNumber",
value
};
}, "parsePrefix")
});
const parenthesisParslet = composeParslet({
name: "parenthesisParslet",
accept: /* @__PURE__ */ __name((type) => type === "(", "accept"),
parsePrefix: /* @__PURE__ */ __name((parser) => {
parser.consume("(");
if (parser.consume(")")) {
return {
type: "JsdocTypeParameterList",
elements: []
};
}
const result = parser.parseIntermediateType(Precedence.ALL);
if (!parser.consume(")")) {
throw new Error("Unterminated parenthesis");
}
if (result.type === "JsdocTypeParameterList") {
return result;
} else if (result.type === "JsdocTypeKeyValue") {
return {
type: "JsdocTypeParameterList",
elements: [result]
};
}
return {
type: "JsdocTypeParenthesis",
element: assertRootResult(result)
};
}, "parsePrefix")
});
const specialTypesParslet = composeParslet({
name: "specialTypesParslet",
accept: /* @__PURE__ */ __name((type, next) => type === "?" && isQuestionMarkUnknownType(next) || type === "null" || type === "undefined" || type === "*", "accept"),
parsePrefix: /* @__PURE__ */ __name((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);
}, "parsePrefix")
});
const notNullableParslet = composeParslet({
name: "notNullableParslet",
accept: /* @__PURE__ */ __name((type) => type === "!", "accept"),
precedence: Precedence.NULLABLE,
parsePrefix: /* @__PURE__ */ __name((parser) => {
parser.consume("!");
return {
type: "JsdocTypeNotNullable",
element: parser.parseType(Precedence.NULLABLE),
meta: {
position: "prefix"
}
};
}, "parsePrefix"),
parseInfix: /* @__PURE__ */ __name((parser, left) => {
parser.consume("!");
return {
type: "JsdocTypeNotNullable",
element: assertRootResult(left),
meta: {
position: "suffix"
}
};
}, "parseInfix")
});
function createParameterListParslet({ allowTrailingComma }) {
return composeParslet({
name: "parameterListParslet",
accept: /* @__PURE__ */ __name((type) => type === ",", "accept"),
precedence: Precedence.PARAMETER_LIST,
parseInfix: /* @__PURE__ */ __name((parser, left) => {
const elements = [
assertPlainKeyValueOrRootResult(left)
];
parser.consume(",");
do {
try {
const next = parser.parseIntermediateType(Precedence.PARAMETER_LIST);
elements.push(assertPlainKeyValueOrRootResult(next));
} catch (e) {
if (e instanceof NoParsletFoundError) {
break;
} else {
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
};
}, "parseInfix")
});
}
__name(createParameterListParslet, "createParameterListParslet");
const genericParslet = composeParslet({
name: "genericParslet",
accept: /* @__PURE__ */ __name((type, next) => type === "<" || type === "." && next === "<", "accept"),
precedence: Precedence.GENERIC,
parseInfix: /* @__PURE__ */ __name((parser, left) => {
const dot = parser.consume(".");
parser.consume("<");
const objects = [];
let infer = false;
if (parser.consume("infer")) {
infer = true;
const 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: true } : {}), { meta: {
brackets: "angle",
dot
} });
}, "parseInfix")
});
const unionParslet = composeParslet({
name: "unionParslet",
accept: /* @__PURE__ */ __name((type) => type === "|", "accept"),
precedence: Precedence.UNION,
parseInfix: /* @__PURE__ */ __name((parser, left) => {
parser.consume("|");
const elements = [];
do {
elements.push(parser.parseType(Precedence.UNION));
} while (parser.consume("|"));
return {
type: "JsdocTypeUnion",
elements: [assertRootResult(left), ...elements]
};
}, "parseInfix")
});
const baseGrammar = [
nullableParslet,
optionalParslet,
numberParslet,
parenthesisParslet,
specialTypesParslet,
notNullableParslet,
createParameterListParslet({
allowTrailingComma: true
}),
genericParslet,
unionParslet,
optionalParslet
];
function createNamePathParslet({ allowSquareBracketsOnAnyType, allowJsdocNamePaths, pathGrammar: pathGrammar2 }) {
return /* @__PURE__ */ __name(function namePathParslet(parser, precedence, left) {
if (left == null || precedence >= Precedence.NAME_PATH) {
return null;
}
const type = parser.lexer.current.type;
const next = parser.lexer.next.type;
const accept = type === "." && next !== "<" || type === "[" && (allowSquareBracketsOnAnyType || left.type === "JsdocTypeName") || allowJsdocNamePaths && (type === "~" || type === "#");
if (!accept) {
return null;
}
let pathType;
let brackets = false;
if (parser.consume(".")) {
pathType = "property";
} else if (parser.consume("[")) {
pathType = "property-brackets";
brackets = true;
} else if (parser.consume("~")) {
pathType = "inner";
} else {
parser.consume("#");
pathType = "instance";
}
const pathParser = pathGrammar2 !== null ? new Parser(pathGrammar2, parser.lexer, parser) : parser;
const 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("]")) {
const 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
};
}, "namePathParslet");
}
__name(createNamePathParslet, "createNamePathParslet");
function createNameParslet({ allowedAdditionalTokens }) {
return composeParslet({
name: "nameParslet",
accept: /* @__PURE__ */ __name((type) => type === "Identifier" || type === "this" || type === "new" || allowedAdditionalTokens.includes(type), "accept"),
parsePrefix: /* @__PURE__ */ __name((parser) => {
const { type, text } = parser.lexer.current;
parser.consume(type);
return {
type: "JsdocTypeName",
value: text
};
}, "parsePrefix")
});
}
__name(createNameParslet, "createNameParslet");
const stringValueParslet = composeParslet({
name: "stringValueParslet",
accept: /* @__PURE__ */ __name((type) => type === "StringValue", "accept"),
parsePrefix: /* @__PURE__ */ __name((parser) => {
const text = parser.lexer.current.text;
parser.consume("StringValue");
return {
type: "JsdocTypeStringValue",
value: text.slice(1, -1),
meta: {
quote: text[0] === "'" ? "single" : "double"
}
};
}, "parsePrefix")
});
function createSpecialNamePathParslet({ pathGrammar: pathGrammar2, allowedTypes }) {
return composeParslet({
name: "specialNamePathParslet",
accept: /* @__PURE__ */ __name((type) => allowedTypes.includes(type), "accept"),
parsePrefix: /* @__PURE__ */ __name((parser) => {
const type = parser.lexer.current.type;
parser.consume(type);
if (!parser.consume(":")) {
return {
type: "JsdocTypeName",
value: type
};
}
let result;
let 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 = "";
const allowed = ["Identifier", "@", "/"];
while (allowed.some((type2) => parser.consume(type2))) {
value += token.text;
token = parser.lexer.current;
}
result = {
type: "JsdocTypeSpecialNamePath",
value,
specialType: type,
meta: {
quote: void 0
}
};
}
const moduleParser = new Parser(pathGrammar2, parser.lexer, parser);
const moduleResult = moduleParser.parseInfixIntermediateType(result, Precedence.ALL);
parser.acceptLexerState(moduleParser);
return assertRootResult(moduleResult);
}, "parsePrefix")
});
}
__name(createSpecialNamePathParslet, "createSpecialNamePathParslet");
const basePathGrammar = [
createNameParslet({
allowedAdditionalTokens: ["external", "module"]
}),
stringValueParslet,
numberParslet,
createNamePathParslet({
allowSquareBracketsOnAnyType: false,
allowJsdocNamePaths: true,
pathGrammar: null
})
];
const 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));
}
__name(getParameters, "getParameters");
function getUnnamedParameters(value) {
const parameters = getParameters(value);
if (parameters.some((p) => p.type === "JsdocTypeKeyValue")) {
throw new Error("No parameter should be named");
}
return parameters;
}
__name(getUnnamedParameters, "getUnnamedParameters");
function createFunctionParslet({ allowNamedParameters, allowNoReturnType, allowWithoutParenthesis, allowNewAsFunctionKeyword }) {
return composeParslet({
name: "functionParslet",
accept: /* @__PURE__ */ __name((type, next) => type === "function" || allowNewAsFunctionKeyword && type === "new" && next === "(", "accept"),
parsePrefix: /* @__PURE__ */ __name((parser) => {
const newKeyword = parser.consume("new");
parser.consume("function");
const 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: false,
constructor: newKeyword,
parenthesis: hasParenthesis
};
const value = parser.parseIntermediateType(Precedence.FUNCTION);
if (allowNamedParameters === void 0) {
result.parameters = getUnnamedParameters(value);
} else if (newKeyword && value.type === "JsdocTypeFunction" && value.arrow) {
result = value;
result.constructor = true;
return result;
} else {
result.parameters = getParameters(value);
for (const 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;
}, "parsePrefix")
});
}
__name(createFunctionParslet, "createFunctionParslet");
function createVariadicParslet({ allowPostfix, allowEnclosingBrackets }) {
return composeParslet({
name: "variadicParslet",
accept: /* @__PURE__ */ __name((type) => type === "...", "accept"),
precedence: Precedence.PREFIX,
parsePrefix: /* @__PURE__ */ __name((parser) => {
parser.consume("...");
const brackets = allowEnclosingBrackets && parser.consume("[");
try {
const 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: false
}
};
} else {
throw e;
}
}
}, "parsePrefix"),
parseInfix: allowPostfix ? (parser, left) => {
parser.consume("...");
return {
type: "JsdocTypeVariadic",
element: assertRootResult(left),
meta: {
position: "suffix",
squareBrackets: false
}
};
} : void 0
});
}
__name(createVariadicParslet, "createVariadicParslet");
const symbolParslet = composeParslet({
name: "symbolParslet",
accept: /* @__PURE__ */ __name((type) => type === "(", "accept"),
precedence: Precedence.SYMBOL,
parseInfix: /* @__PURE__ */ __name((parser, left) => {
if (left.type !== "JsdocTypeName") {
throw new Error("Symbol expects a name on the left side. (Reacting on '(')");
}
parser.consume("(");
const result = {
type: "JsdocTypeSymbol",
value: left.value
};
if (!parser.consume(")")) {
const next = parser.parseIntermediateType(Precedence.SYMBOL);
result.element = assertNumberOrVariadicNameResult(next);
if (!parser.consume(")")) {
throw new Error("Symbol does not end after value");
}
}
return result;
}, "parseInfix")
});
const arrayBracketsParslet = composeParslet({
name: "arrayBracketsParslet",
precedence: Precedence.ARRAY_BRACKETS,
accept: /* @__PURE__ */ __name((type, next) => type === "[" && next === "]", "accept"),
parseInfix: /* @__PURE__ */ __name((parser, left) => {
parser.consume("[");
parser.consume("]");
return {
type: "JsdocTypeGeneric",
left: {
type: "JsdocTypeName",
value: "Array"
},
elements: [
assertRootResult(left)
],
meta: {
brackets: "square",
dot: false
}
};
}, "parseInfix")
});
function createObjectParslet({ objectFieldGrammar: objectFieldGrammar2, allowKeyTypes }) {
return composeParslet({
name: "objectParslet",
accept: /* @__PURE__ */ __name((type) => type === "{", "accept"),
parsePrefix: /* @__PURE__ */ __name((parser) => {
parser.consume("{");
const result = {
type: "JsdocTypeObject",
meta: {
separator: "comma"
},
elements: []
};
if (!parser.consume("}")) {
let separator;
const fieldParser = new Parser(objectFieldGrammar2, parser.lexer, parser);
while (true) {
fieldParser.acceptLexerState(parser);
let field = fieldParser.parseIntermediateType(Precedence.OBJECT);
parser.acceptLexerState(fieldParser);
if (field === void 0 && allowKeyTypes) {
field = parser.parseIntermediateType(Precedence.OBJECT);
}
let optional = false;
if (field.type === "JsdocTypeNullable") {
optional = true;
field = field.element;
}
if (field.type === "JsdocTypeNumber" || field.type === "JsdocTypeName" || field.type === "JsdocTypeStringValue") {
let quote2;
if (field.type === "JsdocTypeStringValue") {
quote2 = field.meta.quote;
}
result.elements.push({
type: "JsdocTypeObjectField",
key: field.value.toString(),
right: void 0,
optional,
readonly: false,
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;
}
const type = parser.lexer.current.type;
if (type === "}") {
break;
}
}
result.meta.separator = separator !== null && separator !== void 0 ? separator : "comma";
if (separator === "linebreak") {
result.meta.propertyIndent = " ";
}
if (!parser.consume("}")) {
throw new Error("Unterminated record type. Missing '}'");
}
}
return result;
}, "parsePrefix")
});
}
__name(createObjectParslet, "createObjectParslet");
function createObjectFieldParslet({ allowSquaredProperties, allowKeyTypes, allowReadonly, allowOptional }) {
return composeParslet({
name: "objectFieldParslet",
precedence: Precedence.KEY_VALUE,
accept: /* @__PURE__ */ __name((type) => type === ":", "accept"),
parseInfix: /* @__PURE__ */ __name((parser, left) => {
var _a;
let optional = false;
let readonlyProperty = false;
if (allowOptional && left.type === "JsdocTypeNullable") {
optional = true;
left = left.element;
}
if (allowReadonly && left.type === "JsdocTypeReadonlyProperty") {
readonlyProperty = true;
left = left.element;
}
const parentParser = (_a = parser.baseParser) !== null && _a !== void 0 ? _a : parser;
parentParser.acceptLexerState(parser);
if (left.type === "JsdocTypeNumber" || left.type === "JsdocTypeName" || left.type === "JsdocTypeStringValue" || isSquaredProperty(left)) {
if (isSquaredProperty(left) && !allowSquaredProperties) {
throw new UnexpectedTypeError(left);
}
parentParser.consume(":");
let quote2;
if (left.type === "JsdocTypeStringValue") {
quote2 = left.meta.quote;
}
const right = parentParser.parseType(Precedence.KEY_VALUE);
parser.acceptLexerState(parentParser);
return {
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(":");
const right = parentParser.parseType(Precedence.KEY_VALUE);
parser.acceptLexerState(parentParser);
return {
type: "JsdocTypeJsdocObjectField",
left: assertRootResult(left),
right
};
}
}, "parseInfix")
});
}
__name(createObjectFieldParslet, "createObjectFieldParslet");
function createKeyValueParslet({ allowOptional, allowVariadic }) {
return composeParslet({
name: "keyValueParslet",
precedence: Precedence.KEY_VALUE,
accept: /* @__PURE__ */ __name((type) => type === ":", "accept"),
parseInfix: /* @__PURE__ */ __name((parser, left) => {
let optional = false;
let variadic = false;
if (allowOptional && left.type === "JsdocTypeNullable") {
optional = true;
left = left.element;
}
if (allowVariadic && left.type === "JsdocTypeVariadic" && left.element !== void 0) {
variadic = true;
left = left.element;
}
if (left.type !== "JsdocTypeName") {
throw new UnexpectedTypeError(left);
}
parser.consume(":");
const right = parser.parseType(Precedence.KEY_VALUE);
return {
type: "JsdocTypeKeyValue",
key: left.value,
right,
optional,
variadic
};
}, "parseInfix")
});
}
__name(createKeyValueParslet, "createKeyValueParslet");
const jsdocBaseGrammar = [
...baseGrammar,
createFunctionParslet({
allowWithoutParenthesis: true,
allowNamedParameters: ["this", "new"],
allowNoReturnType: true,
allowNewAsFunctionKeyword: false
}),
stringValueParslet,
createSpecialNamePathParslet({
allowedTypes: ["module", "external", "event"],
pathGrammar
}),
createVariadicParslet({
allowEnclosingBrackets: true,
allowPostfix: true
}),
createNameParslet({
allowedAdditionalTokens: ["keyof"]
}),
symbolParslet,
arrayBracketsParslet,
createNamePathParslet({
allowSquareBracketsOnAnyType: false,
allowJsdocNamePaths: true,
pathGrammar
})
];
const 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: false,
allowKeyTypes: true,
allowOptional: false,
allowReadonly: false
}),
...jsdocBaseGrammar
],
allowKeyTypes: true
}),
createKeyValueParslet({
allowOptional: true,
allowVariadic: true
})
];
const typeOfParslet = composeParslet({
name: "typeOfParslet",
accept: /* @__PURE__ */ __name((type) => type === "typeof", "accept"),
parsePrefix: /* @__PURE__ */ __name((parser) => {
parser.consume("typeof");
return {
type: "JsdocTypeTypeof",
element: parser.parseType(Precedence.KEY_OF_TYPE_OF)
};
}, "parsePrefix")
});
const objectFieldGrammar$1 = [
createNameParslet({
allowedAdditionalTokens: ["typeof", "module", "keyof", "event", "external", "in"]
}),
nullableParslet,
optionalParslet,
stringValueParslet,
numberParslet,
createObjectFieldParslet({
allowSquaredProperties: false,
allowKeyTypes: false,
allowOptional: false,
allowReadonly: false
})
];
const closureGrammar = [
...baseGrammar,
createObjectParslet({
allowKeyTypes: false,
objectFieldGrammar: objectFieldGrammar$1
}),
createNameParslet({
allowedAdditionalTokens: ["event", "external", "in"]
}),
typeOfParslet,
createFunctionParslet({
allowWithoutParenthesis: false,
allowNamedParameters: ["this", "new"],
allowNoReturnType: true,
allowNewAsFunctionKeyword: false
}),
createVariadicParslet({
allowEnclosingBrackets: false,
allowPostfix: false
}),
// additional name parslet is needed for some special cases
createNameParslet({
allowedAdditionalTokens: ["keyof"]
}),
createSpecialNamePathParslet({
allowedTypes: ["module"],
pathGrammar
}),
createNamePathParslet({
allowSquareBracketsOnAnyType: false,
allowJsdocNamePaths: true,
pathGrammar
}),
createKeyValueParslet({
allowOptional: false,
allowVariadic: false
}),
symbolParslet
];
const assertsParslet = composeParslet({
name: "assertsParslet",
accept: /* @__PURE__ */ __name((type) => type === "asserts", "accept"),
parsePrefix: /* @__PURE__ */ __name((parser) => {
parser.consume("asserts");
const 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.");
}
if (!parser.consume("is")) {
return