botframework-streaming
Version:
Streaming library for the Microsoft Bot Framework
1,373 lines (1,372 loc) • 4.85 MB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __typeError = (msg) => {
throw TypeError(msg);
};
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __esm = (fn, res) => function __init() {
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
var __privateWrapper = (obj, member, setter, getter) => ({
set _(value) {
__privateSet(obj, member, value, setter);
},
get _() {
return __privateGet(obj, member, getter);
}
});
// ../../node_modules/jsdoc-type-pratt-parser/dist/index.js
var require_dist = __commonJS({
"../../node_modules/jsdoc-type-pratt-parser/dist/index.js"(exports2, module3) {
(function(global2, factory) {
typeof exports2 === "object" && typeof module3 !== "undefined" ? factory(exports2) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global2 = typeof globalThis !== "undefined" ? globalThis : global2 || self, factory(global2.jtpp = {}));
})(exports2, function(exports3) {
"use strict";
function tokenToString(token) {
if (token.text !== void 0 && token.text !== "") {
return `'${token.type}' with value '${token.text}'`;
} else {
return `'${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}'.`;
if (message !== void 0) {
error += ` Message: ${message}`;
}
super(error);
Object.setPrototypeOf(this, UnexpectedTypeError.prototype);
}
}
function makePunctuationRule(type) {
return (text) => {
if (text.startsWith(type)) {
return { type, text: type };
} else {
return null;
}
};
}
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);
}
const identifierStartRegex = /[$_\p{ID_Start}]|\\u\p{Hex_Digit}{4}|\\u\{0*(?:\p{Hex_Digit}{1,5}|10\p{Hex_Digit}{4})\}/u;
const identifierContinueRegex = /[$\-\p{ID_Continue}\u200C\u200D]|\\u\p{Hex_Digit}{4}|\\u\{0*(?:\p{Hex_Digit}{1,5}|10\p{Hex_Digit}{4})\}/u;
function getIdentifier2(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);
}
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;
}
const identifierRule = (text) => {
const value = getIdentifier2(text);
if (value == null) {
return null;
}
return {
type: "Identifier",
text: value
};
};
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
};
};
}
const stringValueRule = (text) => {
const value = getQuoted(text);
if (value == null) {
return null;
}
return {
type: "StringValue",
text: value
};
};
const eofRule = (text) => {
if (text.length > 0) {
return null;
}
return {
type: "EOF",
text: ""
};
};
const numberRule = (text) => {
const value = getNumber(text);
if (value === null) {
return null;
}
return {
type: "Number",
text: value
};
};
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("external"),
makeKeyWordRule("typeof"),
makeKeyWordRule("keyof"),
makeKeyWordRule("readonly"),
makeKeyWordRule("import"),
makeKeyWordRule("is"),
makeKeyWordRule("in"),
makeKeyWordRule("asserts"),
numberRule,
identifierRule,
stringValueRule
];
const breakingWhitespaceRegex = /^\s*\n\s*/;
class Lexer {
static create(text) {
const current2 = this.read(text);
text = current2.text;
const next = this.read(text);
text = next.text;
return new Lexer(text, void 0, current2.token, next.token);
}
constructor(text, previous, current2, next) {
this.text = "";
this.text = text;
this.previous = previous;
this.current = current2;
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);
}
}
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") {
throw new UnexpectedTypeError(result);
}
return result;
}
function assertPlainKeyValueOrRootResult(result) {
if (result.type === "JsdocTypeKeyValue") {
return assertPlainKeyValueResult(result);
}
return assertRootResult(result);
}
function assertPlainKeyValueOrNameResult(result) {
if (result.type === "JsdocTypeName") {
return result;
}
return 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 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 Parser3 {
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(types2) {
if (!Array.isArray(types2)) {
types2 = [types2];
}
if (types2.includes(this.lexer.current.type)) {
this._lexer = this.lexer.advance();
return true;
} else {
return false;
}
}
acceptLexerState(parser) {
this._lexer = parser.lexer;
}
}
function isQuestionMarkUnknownType(next) {
return next === "EOF" || next === "|" || next === "," || next === ")" || next === ">";
}
const nullableParslet = (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"
}
};
}
};
function composeParslet(options) {
const parslet = (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;
};
Object.defineProperty(parslet, "name", {
value: options.name
});
return parslet;
}
const optionalParslet = composeParslet({
name: "optionalParslet",
accept: (type) => type === "=",
precedence: Precedence.OPTIONAL,
parsePrefix: (parser) => {
parser.consume("=");
return {
type: "JsdocTypeOptional",
element: parser.parseType(Precedence.OPTIONAL),
meta: {
position: "prefix"
}
};
},
parseInfix: (parser, left) => {
parser.consume("=");
return {
type: "JsdocTypeOptional",
element: assertRootResult(left),
meta: {
position: "suffix"
}
};
}
});
const numberParslet = composeParslet({
name: "numberParslet",
accept: (type) => type === "Number",
parsePrefix: (parser) => {
const value = parseFloat(parser.lexer.current.text);
parser.consume("Number");
return {
type: "JsdocTypeNumber",
value
};
}
});
const parenthesisParslet = composeParslet({
name: "parenthesisParslet",
accept: (type) => type === "(",
parsePrefix: (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)
};
}
});
const 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);
}
});
const notNullableParslet = composeParslet({
name: "notNullableParslet",
accept: (type) => type === "!",
precedence: Precedence.NULLABLE,
parsePrefix: (parser) => {
parser.consume("!");
return {
type: "JsdocTypeNotNullable",
element: parser.parseType(Precedence.NULLABLE),
meta: {
position: "prefix"
}
};
},
parseInfix: (parser, left) => {
parser.consume("!");
return {
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) => {
const elements = [
assertPlainKeyValueOrRootResult(left)
];
parser.consume(",");
do {
try {
const next = parser.parseIntermediateType(Precedence.PARAMETER_LIST);
elements.push(assertPlainKeyValueOrRootResult(next));
} catch (e2) {
if (allowTrailingComma && e2 instanceof NoParsletFoundError) {
break;
} else {
throw e2;
}
}
} while (parser.consume(","));
if (elements.length > 0 && elements.slice(0, -1).some((e2) => e2.type === "JsdocTypeVariadic")) {
throw new Error("Only the last parameter may be a rest parameter");
}
return {
type: "JsdocTypeParameterList",
elements
};
}
});
}
const genericParslet = composeParslet({
name: "genericParslet",
accept: (type, next) => type === "<" || type === "." && next === "<",
precedence: Precedence.GENERIC,
parseInfix: (parser, left) => {
const dot = parser.consume(".");
parser.consume("<");
const objects = [];
do {
objects.push(parser.parseType(Precedence.PARAMETER_LIST));
} while (parser.consume(","));
if (!parser.consume(">")) {
throw new Error("Unterminated generic parameter list");
}
return {
type: "JsdocTypeGeneric",
left: assertRootResult(left),
elements: objects,
meta: {
brackets: "angle",
dot
}
};
}
});
const unionParslet = composeParslet({
name: "unionParslet",
accept: (type) => type === "|",
precedence: Precedence.UNION,
parseInfix: (parser, left) => {
parser.consume("|");
const elements = [];
do {
elements.push(parser.parseType(Precedence.UNION));
} while (parser.consume("|"));
return {
type: "JsdocTypeUnion",
elements: [assertRootResult(left), ...elements]
};
}
});
const baseGrammar = [
nullableParslet,
optionalParslet,
numberParslet,
parenthesisParslet,
specialTypesParslet,
notNullableParslet,
createParameterListParslet({
allowTrailingComma: true
}),
genericParslet,
unionParslet,
optionalParslet
];
function createNamePathParslet({ allowSquareBracketsOnAnyType, allowJsdocNamePaths, pathGrammar: pathGrammar2 }) {
return 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 Parser3(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
};
};
}
function createNameParslet({ allowedAdditionalTokens }) {
return composeParslet({
name: "nameParslet",
accept: (type) => type === "Identifier" || type === "this" || type === "new" || allowedAdditionalTokens.includes(type),
parsePrefix: (parser) => {
const { type, text } = parser.lexer.current;
parser.consume(type);
return {
type: "JsdocTypeName",
value: text
};
}
});
}
const stringValueParslet = composeParslet({
name: "stringValueParslet",
accept: (type) => type === "StringValue",
parsePrefix: (parser) => {
const text = parser.lexer.current.text;
parser.consume("StringValue");
return {
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) => {
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 Parser3(pathGrammar2, parser.lexer, parser);
const moduleResult = moduleParser.parseInfixIntermediateType(result, Precedence.ALL);
parser.acceptLexerState(moduleParser);
return assertRootResult(moduleResult);
}
});
}
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((p2) => assertPlainKeyValueOrRootResult(p2));
}
function getUnnamedParameters(value) {
const parameters = getParameters(value);
if (parameters.some((p2) => p2.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) => {
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 p2 of result.parameters) {
if (p2.type === "JsdocTypeKeyValue" && !allowNamedParameters.includes(p2.key)) {
throw new Error(`only allowed named parameters are ${allowNamedParameters.join(", ")} but got ${p2.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("...");
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 (e2) {
if (e2 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 e2;
}
}
},
parseInfix: allowPostfix ? (parser, left) => {
parser.consume("...");
return {
type: "JsdocTypeVariadic",
element: assertRootResult(left),
meta: {
position: "suffix",
squareBrackets: false
}
};
} : void 0
});
}
const 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("(");
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;
}
});
const arrayBracketsParslet = composeParslet({
name: "arrayBracketsParslet",
precedence: Precedence.ARRAY_BRACKETS,
accept: (type, next) => type === "[" && next === "]",
parseInfix: (parser, left) => {
parser.consume("[");
parser.consume("]");
return {
type: "JsdocTypeGeneric",
left: {
type: "JsdocTypeName",
value: "Array"
},
elements: [
assertRootResult(left)
],
meta: {
brackets: "square",
dot: false
}
};
}
});
function createObjectParslet({ objectFieldGrammar: objectFieldGrammar2, allowKeyTypes }) {
return composeParslet({
name: "objectParslet",
accept: (type) => type === "{",
parsePrefix: (parser) => {
parser.consume("{");
const result = {
type: "JsdocTypeObject",
meta: {
separator: "comma"
},
elements: []
};
if (!parser.consume("}")) {
let separator;
const fieldParser = new Parser3(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";
} 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 (!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 = 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
};
}
}
});
}
function createKeyValueParslet({ allowOptional, allowVariadic }) {
return composeParslet({
name: "keyValueParslet",
precedence: Precedence.KEY_VALUE,
accept: (type) => type === ":",
parseInfix: (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
};
}
});
}
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: ["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: (type) => type === "typeof",
parsePrefix: (parser) => {
parser.consume("typeof");
return {
type: "JsdocTypeTypeof",
element: assertRootResult(parser.parseType(Precedence.KEY_OF_TYPE_OF))
};
}
});
const objectFieldGrammar$1 = [
createNameParslet({
allowedAdditionalTokens: ["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: (type) => type === "asserts",
parsePrefix: (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.");
}
parser.consume("is");
return {
type: "JsdocTypeAsserts",
left,
right: assertRootResult(parser.parseIntermediateType(Precedence.INFIX))
};
}
});
function createTupleParslet({ allowQuestionMark }) {
return composeParslet({
name: "tupleParslet",
accept: (type) => type === "[",
parsePrefix: (parser) => {
parser.consume("[");
const result = {
type: "JsdocTypeTuple",
elements: []
};
if (parser.consume("]")) {
return result;
}
const typeList = parser.parseIntermediateType(Precedence.ALL);
if (typeList.type === "JsdocTypeParameterList") {
if (typeList.elements[0].type === "JsdocTypeKeyValue") {
result.elements = typeList.elements.map(assertPlainKeyValueResult);
} else {
result.elements = typeList.elements.map(assertRootResult);
}
} else {
if (typeList.type === "JsdocTypeKeyValue") {
result.elements = [assertPlainKeyValueResult(typeList)];
} else {
result.elements = [assertRootResult(typeList)];
}
}
if (!parser.consume("]")) {
throw new Error("Unterminated '['");
}
if (!allowQuestionMark && result.elements.some((e2) => e2.type === "JsdocTypeUnknown")) {
throw new Error("Question mark in tuple not allowed");
}
return result;
}
});
}
const keyOfParslet = composeParslet({
name: "keyOfParslet",
accept: (type) => type === "keyof",
parsePrefix: (parser) => {
parser.consume("keyof");
return {
type: "JsdocTypeKeyof",
element: assertRootResult(parser.parseType(Precedence.KEY_OF_TYPE_OF))
};
}
});
const importParslet = composeParslet({
name: "importParslet",
accept: (type) => type === "import",
parsePrefix: