How to use AstArgument method in wpt

Best JavaScript code snippet using wpt

parser.ts

Source:parser.ts Github

copy

Full Screen

1import { AdapterRef } from '@core/adapters';2import {3 AstArgumentImpl,4 CommandAstImpl,5 CommandContainer,6 isGenericToken,7 isNumberToken,8 isParameterToken,9 isPrefixToken,10 NullToken,11 TokenImpl,12 TokenPositionImpl,13} from '@core/command';14import {15 AstArgument,16 AstCommand,17 AstPrefix,18 BOOLEAN_LIKE_VALUES,19 ChannelMentionToken,20 CodeBlock,21 CodeBlockToken,22 CommandAst,23 CommandParameterType,24 CommandPipeline,25 CommandRoute,26 CommandTokenKind,27 DateParameterOptions,28 EmoteToken,29 GenericToken,30 GuildCtx,31 isFlagSet,32 isNil,33 NumberToken,34 ParameterConfiguration,35 ParameterToken,36 Parsable,37 ParsedAstArguments,38 Parser,39 RoleMentionToken,40 StringBuilder,41 StringExpandableToken,42 StringLikeToken,43 StringLiteralToken,44 StringTemplateToken,45 Token,46 TokenWithValue,47 UserMentionToken,48} from '@watsonjs/common';49import { Injector } from '@watsonjs/di';50import { Channel, Client, Emoji, Message, Role, User } from 'discord.js';51import { DateTime } from 'luxon';52import { format, URL } from 'url';53import { ParsingException } from '../exceptions/parsing.exception';54import { AstCommandImpl, AstPrefixImpl } from './ast';55import { CommandTokenizer } from './tokenizer';56type ParseFn<T> = (57 token: Token,58 param: ParameterConfiguration,59 ctx: ClosureCtx,60 configuration?: any,61 ...args: any[]62) => T | Promise<T>;63/**64 * Makes the passing of65 * closure reference arguments66 * a little easier67 */68interface ClosureCtx {69 nextTokenFn: NextTokenFn;70 peekTokenFn: PeekTokenFn;71 ungetTokenFn: UngetTokenFn;72 injector: Injector;73}74const STRING_LIKE_TOKEN_FLAGS =75 CommandTokenKind.Generic |76 CommandTokenKind.StringExpandable |77 CommandTokenKind.StringLiteral |78 CommandTokenKind.StringTemplate;79/**80 * A map of parameter types and the81 * token kinds they accept.82 */83const PARAMETER_TOKEN_MAP = {84 [CommandParameterType.String]: STRING_LIKE_TOKEN_FLAGS,85 [CommandParameterType.StringExpandable]: CommandTokenKind.StringExpandable,86 [CommandParameterType.StringLiteral]: CommandTokenKind.StringLiteral,87 [CommandParameterType.StringTemplate]: CommandTokenKind.StringTemplate,88 [CommandParameterType.Boolean]: STRING_LIKE_TOKEN_FLAGS,89 [CommandParameterType.Number]:90 STRING_LIKE_TOKEN_FLAGS | CommandTokenKind.Number,91 [CommandParameterType.URL]: STRING_LIKE_TOKEN_FLAGS,92 [CommandParameterType.Date]: STRING_LIKE_TOKEN_FLAGS,93 [CommandParameterType.Channel]:94 STRING_LIKE_TOKEN_FLAGS | CommandTokenKind.ChannelMention,95 [CommandParameterType.Role]:96 STRING_LIKE_TOKEN_FLAGS | CommandTokenKind.RoleMention,97 [CommandParameterType.User]:98 STRING_LIKE_TOKEN_FLAGS | CommandTokenKind.UserMention,99 [CommandParameterType.Emote]: CommandTokenKind.Emote,100 [CommandParameterType.CodeBlock]: CommandTokenKind.CodeBlock,101};102export type NextTokenFn = () => Token | null;103export type PeekTokenFn = () => Token | null;104export type UngetTokenFn = (token: Token) => void;105export class CommandParser implements Parser<CommandAst> {106 constructor(private _commandContainer: CommandContainer) {}107 public parseMessageTokens(message: Message, prefixLength: number) {108 const { content } = message;109 const tokenizer = new CommandTokenizer(this);110 return tokenizer.tokenize(content, prefixLength);111 }112 public async parseMessage(113 message: Message,114 prefixLength: number,115 pipeLine: CommandPipeline116 ): Promise<CommandAst> {117 const tokens = this.parseMessageTokens(message, prefixLength);118 return this.parseInput(tokens, pipeLine);119 }120 public async parseInput(121 tokens: Token<any>[],122 pipeLine: CommandPipeline123 ): Promise<CommandAst> {124 /**125 * These methods allow us to change the126 * state of `tokens` in this lexical scope127 * throughout the parser as well as in `Parsables`.128 *129 * ??? WHY ???130 * Doing this we can use one parser instance131 * across the app and still allow users to132 * update references to a token or such through133 * a function.134 */135 const nextTokenFn = (): Token | null => tokens.shift() ?? null;136 const peekTokenFn = () => tokens[0];137 const ungetTokenFn = (token: Token): void => {138 tokens.unshift(token);139 };140 const closureCtx: ClosureCtx = {141 injector: pipeLine.getInjector(),142 nextTokenFn,143 peekTokenFn,144 ungetTokenFn,145 };146 const prefixAst = this.getPrefixAst(nextTokenFn);147 const { commandAst, routeRef } = this.getCommandAst(closureCtx);148 const parsedArguments = await this.getArgumentsAst(routeRef, closureCtx);149 return new CommandAstImpl()150 .applyPrefix(prefixAst)151 .applyCommand(commandAst)152 .applyArguments(parsedArguments);153 }154 /** @Section Check Prefix */155 public getPrefixAst(nextTokenFn: NextTokenFn): AstPrefix {156 const prefixToken = nextTokenFn();157 if (!prefixToken) {158 throw new ParsingException(null, null, "No prefix present");159 }160 if (!isPrefixToken(prefixToken)) {161 throw new ParsingException(162 prefixToken,163 null,164 "No valid prefixToken found"165 );166 }167 return new AstPrefixImpl(prefixToken);168 }169 /** @Section Resolve Command Used */170 public getCommandAst(ctx: ClosureCtx): {171 routeRef: CommandRoute;172 commandAst: AstCommand;173 } {174 const commandToken = ctx.nextTokenFn();175 if (isNil(commandToken)) {176 throw new ParsingException(commandToken, null, "No command found");177 }178 const { text: commandText, kind } = commandToken;179 if (kind !== CommandTokenKind.Generic) {180 throw new Error("No command specified");181 }182 const routeRef = this._commandContainer.get(commandText!.toLowerCase());183 if (isNil(routeRef)) {184 throw new Error("No matching command found");185 }186 const astCommand = new AstCommandImpl(commandToken);187 const resolvedRouteRef = this.resolveSubCommand(routeRef, astCommand, ctx);188 return {189 routeRef: resolvedRouteRef,190 commandAst: astCommand,191 };192 }193 /**194 * Resolves a command route using195 * the parsed command tokens to find196 * the deepest nested command.197 */198 public resolveSubCommand(199 route: CommandRoute,200 astCommand: AstCommand,201 ctx: ClosureCtx202 ): CommandRoute {203 const { nextTokenFn, ungetTokenFn } = ctx;204 let routeRef = route;205 while (!isNil(routeRef.children)) {206 const { children } = routeRef;207 const nextToken = nextTokenFn();208 if (isNil(nextToken)) {209 break;210 }211 if (!isGenericToken(nextToken)) {212 ungetTokenFn(nextToken);213 break;214 }215 const { text } = nextToken;216 const childRef = children.get(text!.toLowerCase());217 if (isNil(childRef)) {218 ungetTokenFn(nextToken);219 break;220 }221 const { caseSensitive } = childRef.configuration;222 if (caseSensitive) {223 const hasName = childRef.hasName(text!, true);224 if (!hasName) {225 /**226 * TODO:227 * This might break bots where228 * there is a sub command which229 * requires a case sensitive name230 * but also an argument that is231 * the same string but in lower case:232 *233 * !help User - lists help for all user commands234 * !help user - Gets help for the user command235 * -----------------------------------------------236 * Should we just accept the last matched route237 * and interpret this token as an argument?238 */239 throw new Error(240 "Command was matched but does not have correct casing"241 );242 }243 }244 astCommand.applySubCommand(nextToken);245 routeRef = childRef;246 }247 return routeRef;248 }249 /** @Section Parse Arguments */250 public async getArgumentsAst(251 route: CommandRoute,252 ctx: ClosureCtx253 ): Promise<ParsedAstArguments> {254 const { params } = route;255 const { peekTokenFn } = ctx;256 const astArguments = new Map<string, AstArgument | null>();257 const parsedArguments: ParameterConfiguration[] = [];258 while (parsedArguments.length < params.length) {259 const argumentAst = await this.parseNextParameter(260 route,261 parsedArguments,262 ctx263 );264 const { name } = parsedArguments[parsedArguments.length - 1];265 astArguments.set(name, argumentAst);266 }267 // Clean up overflowing tokens268 if (!isNil(peekTokenFn())) {269 this.cleanUpTokenOverflow(astArguments, parsedArguments, ctx);270 }271 return astArguments;272 }273 /**274 * !help user @username @otherUser hey, you thingies275 *276 */277 public async parseNextParameter<T extends any = any>(278 route: CommandRoute,279 parsedParams: ParameterConfiguration[],280 ctx: ClosureCtx281 ): Promise<AstArgument<T>> {282 const { nextTokenFn } = ctx;283 const token = nextTokenFn();284 const param = this.getNextParameter(route, parsedParams)!;285 if (isNil(token)) {286 return this.parseEmptyNextToken<T>(param, parsedParams);287 }288 if (isParameterToken(token)) {289 return this.parseParameterToken<T>(route, token, parsedParams, ctx);290 }291 /**292 * At this point the next token will be a293 * regular text token in the command message:294 *295 * !help -All user296 * ^297 */298 const { configuration, optional, default: defaultValue } = param;299 const parseFn = await this.getParseFn(param, ctx);300 let parsed: T;301 this.validateArgumentToken(token, param);302 try {303 parsed = (await parseFn(token, param, ctx, configuration)) as T;304 } catch (err: unknown) {305 if (optional) {306 return new AstArgumentImpl(307 new NullToken(),308 param,309 null310 ) as AstArgument<T>;311 }312 if (defaultValue) {313 const text = defaultValue?.toString() ?? null;314 return new AstArgumentImpl(new NullToken(text), param, text);315 }316 throw err;317 }318 return new AstArgumentImpl(token, param, parsed);319 }320 private async parseParameterToken<T extends any = any>(321 route: CommandRoute,322 paramToken: Token,323 parsedParams: ParameterConfiguration[],324 ctx: ClosureCtx325 ): Promise<AstArgument<T>> {326 const { peekTokenFn, nextTokenFn } = ctx;327 const argumentOrParameter = peekTokenFn();328 const param = this.getParameterInRouteFromToken(329 paramToken as ParameterToken,330 route331 );332 parsedParams.push(param);333 // Checking for switch parameter334 if (param.paramType === CommandParameterType.Boolean) {335 // Argument was used as switch336 if (isNil(argumentOrParameter) || isParameterToken(argumentOrParameter)) {337 parsedParams.push(param);338 return new AstArgumentImpl(paramToken, param, true) as AstArgument<T>;339 }340 if (this.isBooleanToken(argumentOrParameter)) {341 parsedParams.push(param);342 return this.parseToBoolean(343 argumentOrParameter as GenericToken,344 param345 ) as AstArgumentImpl<T>;346 }347 const { kind, position } = argumentOrParameter;348 throw new ParsingException(349 paramToken,350 param,351 `Unexpected token at position ${position}. Expected BOOLEAN got ${kind}`352 );353 }354 /** The parameter had no values */355 if (isNil(argumentOrParameter) || isParameterToken(argumentOrParameter)) {356 return this.parseEmptyNextToken(param, parsedParams);357 }358 const parseFn = await this.getParseFn<T>(param, ctx);359 const { hungry, configuration } = param;360 if (hungry) {361 return this.parseHungryArguments<T>(param, parseFn, ctx);362 }363 this.validateArgumentToken(argumentOrParameter, param);364 /** Pops `argumentOrParameter` off the tokens array */365 nextTokenFn();366 const parsed = await parseFn(367 argumentOrParameter,368 param,369 ctx,370 configuration371 );372 return new AstArgumentImpl(argumentOrParameter, param, parsed);373 }374 private async parseHungryArguments<T extends any = any>(375 param: ParameterConfiguration,376 parseFn: ParseFn<T>,377 ctx: ClosureCtx378 ): Promise<AstArgument<T>> {379 const { peekTokenFn, nextTokenFn, ungetTokenFn } = ctx;380 const { configuration, paramType } = param;381 const parsedArguments: any[] = [];382 const parsedTokens: Token[] = [];383 while (!isNil(peekTokenFn())) {384 const argumentOrParameter = nextTokenFn()!;385 // We've reached a new parameter386 if (isParameterToken(argumentOrParameter)) {387 ungetTokenFn(argumentOrParameter);388 const hungryToken = this.createHungryToken(parsedTokens);389 return new AstArgumentImpl(390 hungryToken,391 param,392 parsedArguments393 ) as AstArgumentImpl<T>;394 }395 this.validateArgumentToken(argumentOrParameter, param);396 const parsed = await parseFn(397 argumentOrParameter,398 param,399 ctx,400 configuration401 );402 parsedArguments.push(parsed);403 parsedTokens.push(argumentOrParameter);404 }405 const hungryToken = this.createHungryToken(parsedTokens);406 return new AstArgumentImpl(407 hungryToken,408 param,409 parsedArguments410 ) as AstArgumentImpl<T>;411 }412 private validateArgumentToken(413 token: Token,414 param: ParameterConfiguration415 ): void {416 const { name, paramType } = param;417 const { kind, position } = token;418 const validKinds = PARAMETER_TOKEN_MAP[paramType];419 if (!isFlagSet(kind, validKinds)) {420 throw new ParsingException(421 token,422 param,423 `Unexpected token "${token}" at position ${position} while parsing "${name}".`424 );425 }426 }427 private parseEmptyNextToken<T = any>(428 param: ParameterConfiguration,429 parsedParams: ParameterConfiguration[]430 ): AstArgument<T> {431 const { name, optional, default: defaultValue } = param;432 parsedParams.push(param);433 if (optional) {434 return new AstArgumentImpl(435 new NullToken(),436 param,437 null438 ) as AstArgument<T>;439 }440 if (defaultValue) {441 const defaultString: null | string = defaultValue?.toString() ?? null;442 return new AstArgumentImpl(443 new NullToken(defaultString),444 param,445 defaultValue446 );447 }448 throw new ParsingException(449 null,450 param,451 `Could not find required parameter with name ${name} in the command message`452 );453 }454 /**455 * If there are generic tokens at the end of456 * the token list which we didn't parse457 * before we add them to the last argument458 * parsed, given it was a generic token.459 */460 private cleanUpTokenOverflow(461 argumentAst: Map<string, AstArgument | null>,462 parsedArguments: ParameterConfiguration[],463 ctx: ClosureCtx464 ) {465 const { nextTokenFn, peekTokenFn } = ctx;466 let token = peekTokenFn()!;467 const { name, paramType } = parsedArguments[parsedArguments.length - 1];468 /**469 * We only append to `String` parameters470 * as all the other ones should be encapsulated471 * in `"`.472 */473 if (paramType !== CommandParameterType.String) {474 return;475 }476 const argumentToExpand = argumentAst.get(name)!;477 const { position } = argumentToExpand;478 const previousToken = new TokenImpl(CommandTokenKind.None, null, position);479 while (!isNil(peekTokenFn())) {480 token = nextTokenFn()!;481 /**482 * Right now we ignore non483 * generic tokens as we don't484 * have a way to concatenate485 * them with a previous token.486 */487 if (!isFlagSet(token.kind, STRING_LIKE_TOKEN_FLAGS)) {488 return;489 }490 const value = this.getValueFromStringLikeToken(token);491 argumentToExpand.value += ` ${value}`;492 argumentToExpand.text += token.text;493 }494 const { position: updatedPosition } = this.createHungryToken([495 previousToken,496 token,497 ]);498 argumentToExpand.position = updatedPosition;499 }500 /**501 * Returns the next parameter that502 * should be processed by the parser.503 */504 private getNextParameter(505 route: CommandRoute,506 parsedParams: ParameterConfiguration[]507 ): ParameterConfiguration | null {508 const { params } = route;509 for (let i = 0; i < params.length; i++) {510 const param = params[i];511 for (let y = 0; y < parsedParams.length; y++) {512 const parsed = parsedParams[y];513 if (parsed === param) {514 return param;515 }516 }517 }518 return null;519 }520 public async getParseFn<T>(521 param: ParameterConfiguration,522 ctx: ClosureCtx523 ): Promise<ParseFn<T>> {524 let fn: Function;525 const { paramType } = param;526 switch (paramType) {527 case CommandParameterType.Boolean:528 fn = this.parseToBoolean;529 break;530 case CommandParameterType.Number:531 fn = this.parseToNumber;532 break;533 case CommandParameterType.String:534 fn = this.parseToString;535 break;536 case CommandParameterType.StringExpandable:537 fn = this.parseToStringExpandable;538 break;539 case CommandParameterType.StringLiteral:540 fn = this.parseToStringLiteral;541 break;542 case CommandParameterType.StringTemplate:543 fn = this.parseToStringTemplate;544 break;545 case CommandParameterType.URL:546 fn = this.parseToUrl;547 break;548 case CommandParameterType.Date:549 fn = this.parseToDate;550 break;551 case CommandParameterType.Channel:552 fn = this.parseToChannel;553 break;554 case CommandParameterType.Role:555 fn = this.parseToRole;556 break;557 case CommandParameterType.User:558 fn = this.parseToUser;559 break;560 case CommandParameterType.Emote:561 fn = this.parseToEmote;562 break;563 case CommandParameterType.CodeBlock:564 fn = this.parseToCodeBlock;565 break;566 case CommandParameterType.Custom:567 const { injector, nextTokenFn, peekTokenFn, ungetTokenFn } = ctx;568 const parsableRef = await injector.get(param.type as typeof Parsable);569 parsableRef.parser = this;570 parsableRef.nextToken = nextTokenFn;571 parsableRef.peekToken = peekTokenFn;572 parsableRef.ungetToken = ungetTokenFn;573 // In this case we don't want574 // to bind the function to the575 // `this` context of the parser.576 return parsableRef.parse.bind(parsableRef) as ParseFn<T>;577 }578 return fn!.bind(this);579 }580 private isBooleanToken(argument: Token): boolean {581 const value = (argument as TokenWithValue).value;582 if (isNil(value)) {583 return false;584 }585 const lowerCaseValue = value.toLowerCase();586 for (let i = 0; i < BOOLEAN_LIKE_VALUES.length; i++) {587 const booleanValue = BOOLEAN_LIKE_VALUES[i];588 if (lowerCaseValue === booleanValue) {589 return true;590 }591 }592 return false;593 }594 private getParameterInRouteFromToken(595 token: ParameterToken,596 route: CommandRoute597 ) {598 const { value } = token;599 const { params } = route;600 for (let i = 0; i < params.length; i++) {601 const param = params[i];602 const { name } = param;603 if (name.toLowerCase() === value.toLowerCase()) {604 return param;605 }606 }607 throw new ParsingException(608 token,609 null,610 `A parameter cannot be found that matches parameter name "${value}" at position ${token.position}`611 );612 }613 public parseToDate(614 token: StringLikeToken,615 param: ParameterConfiguration,616 ctx: ClosureCtx,617 options: DateParameterOptions618 ): AstArgument<DateTime> {619 const { format, options: formatOptions } = options;620 const argument = new AstArgumentImpl<DateTime>(token, param);621 const dateString = this.getValueFromStringLikeToken(token);622 if (isNil(format)) {623 return argument.withValue(DateTime.fromISO(dateString, formatOptions));624 }625 return argument.withValue(626 DateTime.fromFormat(dateString, format, formatOptions)627 );628 }629 public async parseToUser(630 token: StringLikeToken | UserMentionToken,631 param: ParameterConfiguration,632 ctx: ClosureCtx633 ): Promise<AstArgument<User>> {634 const { injector } = ctx;635 const { client } = await injector.get(AdapterRef);636 let userId: string;637 if (token.kind !== CommandTokenKind.UserMention) {638 userId = token.text!;639 } else {640 userId = (token as UserMentionToken).value;641 }642 const user = await (<Client>client).users.fetch(userId);643 return new AstArgumentImpl(token, param, user);644 }645 public async parseToRole(646 token: StringLikeToken | RoleMentionToken,647 param: ParameterConfiguration,648 ctx: ClosureCtx649 ): Promise<AstArgument<Role>> {650 const { injector } = ctx;651 const guild = await injector.get(GuildCtx);652 let roleId: string;653 if (token.kind !== CommandTokenKind.RoleMention) {654 roleId = token.text!;655 } else {656 roleId = (token as RoleMentionToken).value;657 }658 const role = await guild.roles.fetch(roleId);659 return new AstArgumentImpl(token, param, role!);660 }661 public async parseToChannel(662 token: StringLikeToken | ChannelMentionToken,663 param: ParameterConfiguration,664 ctx: ClosureCtx665 ): Promise<AstArgument<Channel>> {666 const { injector } = ctx;667 const guild = await injector.get(GuildCtx);668 let channelId: string;669 if (token.kind !== CommandTokenKind.ChannelMention) {670 channelId = token.text!;671 } else {672 channelId = (token as ChannelMentionToken).value;673 }674 const channel = guild.channels.resolve(channelId);675 return new AstArgumentImpl(token, param, channel!);676 }677 public async parseToEmote(678 token: StringLikeToken | EmoteToken,679 param: ParameterConfiguration,680 ctx: ClosureCtx681 ): Promise<AstArgument<Emoji>> {682 const { injector } = ctx;683 const { client } = await injector.get(AdapterRef);684 const argument = new AstArgumentImpl(token, param);685 let emojiId: string;686 if (token.kind !== CommandTokenKind.Emote) {687 emojiId = token.text!;688 } else {689 const idOrIsEmote = (token as EmoteToken).value;690 if (isNil(idOrIsEmote)) {691 return argument.withValue(token.text);692 }693 emojiId = idOrIsEmote;694 }695 const emoji = (<Client>client).emojis.resolve(emojiId);696 return argument.withValue(emoji!);697 }698 public parseToString(699 token: StringLikeToken,700 param: ParameterConfiguration701 ): AstArgument<string> {702 const value = this.getValueFromStringLikeToken(token);703 return new AstArgumentImpl<string>(token, param, value);704 }705 public parseToCodeBlock(706 token: CodeBlockToken,707 param: ParameterConfiguration708 ): AstArgument<CodeBlock> {709 const argument = new AstArgumentImpl<CodeBlock>(token, param);710 const { language, text, value } = token;711 const codeBlock: CodeBlock = {712 code: value,713 language: language,714 raw: text!,715 };716 return argument.withValue(codeBlock);717 }718 // In the future we might allow719 // for variables in strings720 // or other templating features721 public parseToStringExpandable(722 token: StringExpandableToken,723 param: ParameterConfiguration724 ): AstArgument<string> {725 const argument = new AstArgumentImpl<string>(token, param);726 return argument.withValue(token.value);727 }728 public parseToStringLiteral(729 token: StringLiteralToken,730 param: ParameterConfiguration731 ): AstArgument<string> {732 const argument = new AstArgumentImpl<string>(token, param);733 return argument.withValue(token.value);734 }735 public parseToStringTemplate(736 token: StringTemplateToken,737 param: ParameterConfiguration738 ): AstArgument<string> {739 const argument = new AstArgumentImpl<string>(token, param);740 return argument.withValue(token.value);741 }742 public parseToBoolean(743 token: StringLikeToken,744 param: ParameterConfiguration745 ): AstArgument<boolean> {746 const boolean = this.getValueFromStringLikeToken(token);747 const inferBooleanLikeValue = () => {748 const lowerCaseValue = boolean.toLowerCase();749 for (let i = 0; i < BOOLEAN_LIKE_VALUES.length; i++) {750 const { name, value } = BOOLEAN_LIKE_VALUES[i];751 if (lowerCaseValue === name) {752 return value;753 }754 }755 return null;756 };757 const booleanLikeValue = inferBooleanLikeValue();758 const argument = new AstArgumentImpl<boolean>(token, param);759 if (!isNil(booleanLikeValue)) {760 return argument.withValue(booleanLikeValue);761 }762 return argument.withValue(Boolean(boolean));763 }764 public parseToNumber(765 token: StringLikeToken | NumberToken,766 param: ParameterConfiguration767 ): AstArgument<number> {768 const argument = new AstArgumentImpl<number>(token, param);769 const { text, position } = token;770 const checkNaN = (number: number) => {771 if (isNaN(number)) {772 throw new ParsingException(773 token,774 param,775 `Unexpected token "${text}" at position ${position}. Expected Number got NaN.`776 );777 }778 };779 if (isNumberToken(token)) {780 const number = token.value;781 checkNaN(number);782 return argument.withValue(number);783 }784 const value = this.getValueFromStringLikeToken(token);785 const number = Number(value);786 checkNaN(number);787 return argument.withValue(number);788 }789 public parseToUrl(790 token: StringLikeToken,791 param: ParameterConfiguration792 ): AstArgument<URL> {793 const url = this.getValueFromStringLikeToken(token);794 let parsed: URL;795 try {796 parsed = new URL(url);797 } catch (err) {798 throw new ParsingException(799 token,800 param,801 `Failed to parse token "${url}" of kind "${token.kind}" type URL`802 );803 }804 return new AstArgumentImpl<URL>(token, param, parsed);805 }806 private getValueFromStringLikeToken(token: StringLikeToken): string {807 return isGenericToken(token)808 ? (token.text as string)809 : ((token as StringLiteralToken).value as string);810 }811 private expectNextTokenToBeOfKind(812 peekToken: PeekTokenFn,813 ...validKinds: CommandTokenKind[]814 ): CommandTokenKind {815 const token = peekToken() ?? {};816 const { kind, position } = token as Token;817 for (let i = 0; i < validKinds.length; i++) {818 const kind = validKinds[i];819 if (kind === kind) {820 return kind;821 }822 }823 throw new ParsingException(824 token as Token,825 null,826 `Expected token at position ${position} to be one of ${validKinds.join(827 ", "828 )} but got ${kind}`829 );830 }831 /** @Section Utilities */832 private createHungryToken(tokens: Token[]): Token {833 const [{ position: firstPosition, kind }] = tokens;834 const { position: lastPosition } = tokens[tokens.length - 1];835 const { tokenStart } = firstPosition;836 const { tokenEnd } = lastPosition;837 const sb = new StringBuilder();838 for (let i = 0; i < tokens.length; i++) {839 const { text } = tokens[i];840 sb.append(text!);841 sb.append(" ");842 }843 const tokenText = sb.toString();844 const tokenPosition = new TokenPositionImpl(845 tokenText,846 tokenStart,847 tokenEnd848 );849 return new TokenImpl(kind, sb.toString(), tokenPosition);850 }...

Full Screen

Full Screen

ast.ts

Source:ast.ts Github

copy

Full Screen

1/*2 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one3 * or more contributor license agreements. Licensed under the Elastic License4 * 2.0 and the Server Side Public License, v 1; you may not use this file except5 * in compliance with, at your election, the Elastic License 2.0 or the Server6 * Side Public License, v 1.7 */8export type AstNode = Ast | AstFunction | AstArgument;9// eslint-disable-next-line @typescript-eslint/consistent-type-definitions10export type Ast = {11 type: 'expression';12 chain: AstFunction[];13};14// eslint-disable-next-line @typescript-eslint/consistent-type-definitions15export type AstFunction = {16 type: 'function';17 function: string;18 arguments: Record<string, AstArgument[]>;19};20export type AstArgument = string | boolean | number | Ast;21interface WithMeta<T> {22 start: number;23 end: number;24 text: string;25 node: T;26}27type Replace<T, R> = Pick<T, Exclude<keyof T, keyof R>> & R;28type WrapAstArgumentWithMeta<T> = T extends Ast ? AstWithMeta : WithMeta<T>;29export type AstArgumentWithMeta = WrapAstArgumentWithMeta<AstArgument>;30export type AstFunctionWithMeta = WithMeta<31 Replace<32 AstFunction,33 {34 arguments: {35 [key: string]: AstArgumentWithMeta[];36 };37 }38 >39>;40export type AstWithMeta = WithMeta<41 Replace<42 Ast,43 {44 chain: AstFunctionWithMeta[];45 }46 >47>;48export function isAstWithMeta(value: any): value is AstWithMeta {49 return typeof value?.node === 'object';50}51export function isAst(value: any): value is Ast {52 return typeof value === 'object' && value?.type === 'expression';...

Full Screen

Full Screen

AstDeclareFunction.ts

Source:AstDeclareFunction.ts Github

copy

Full Screen

1import { Location } from 'earley';2import { AstArgument } from './AstArgument';3import { CodeGenerator } from '../CodeGenerator';4import { TypeChecker } from '../TypeChecker';5export class AstDeclareFunction {6 type: any = null; // calculated later7 hasBody = false; // Set to true during type checking if sub is later8 used = false;9 /** @constructor */10 constructor(11 public location: Location,12 public name: string,13 public args: AstArgument[],14 public isFunction: boolean,15 readonly typeName?: string16 ) {17 // this.locus = locus;18 // this.name = name;19 // this.args = args; // array of AstArgument20 // this.isFunction = isFunction;21 this.type = null; // calculated later22 this.hasBody = false; // Set to true during type checking if sub is later23 // implemented.24 this.used = false;25 }26 accept(visitor: CodeGenerator | TypeChecker) {27 visitor.visitDeclareFunction(this);28 }...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1var wpt = require('webpagetest');2 videoParams: {3 },4 timelineParams: {5 },6 browserUserAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36',7 browserConnectionExtraHeaders: {8 },

Full Screen

Using AI Code Generation

copy

Full Screen

1var wpt = require('webpagetest');2var api = new wpt('API_KEY');3var options = {4 videoParams: {5 },6 lighthouseConfig: {7 settings: {8 }9 },10 lighthouseThrottling: {11 },12 lighthouseBudget: {

Full Screen

Using AI Code Generation

copy

Full Screen

1var wpt = require('./wpt.js');2var wpt = new WebPageTest('www.webpagetest.org', 'APIKEY');3wpt.runTest(url, { location: 'Dulles:Chrome', runs: 1, pollResults: 1, firstViewOnly: 1 }, function(err, data) {4 if (err) return console.error(err);5 console.log('Test status: ' + data.statusText);6 console.log('View the test at: ' + data.data.userUrl);7});

Full Screen

Using AI Code Generation

copy

Full Screen

1var wptools = require('wptools');2var wiki = new wptools('Barack Obama');3wiki.get(function(err, resp) {4 if (!err) {5 console.log(resp.data.image[0]);6 }7});8var wptools = require('wptools');9var wiki = new wptools('Barack Obama');10wiki.get(function(err, resp) {11 if (!err) {12 console.log(resp.data.image[0]);13 }14});15var wptools = require('wptools');16var wiki = new wptools('Barack Obama');17wiki.get(function(err, resp) {18 if (!err) {19 console.log(resp.data.image[0]);20 }21});22var wptools = require('wptools');23var wiki = new wptools('Barack Obama');24wiki.get(function(err, resp) {25 if (!err) {26 console.log(resp.data.image[0]);27 }28});29var wptools = require('wptools');30var wiki = new wptools('Barack Obama');31wiki.get(function(err, resp) {32 if (!err) {33 console.log(resp.data.image[0]);34 }35});36var wptools = require('wptools');37var wiki = new wptools('Barack Obama');38wiki.get(function(err, resp) {39 if (!err) {40 console.log(resp.data.image[0]);41 }42});43var wptools = require('wptools');44var wiki = new wptools('Barack Obama');45wiki.get(function(err, resp) {46 if (!err) {47 console.log(resp.data.image[0]);48 }49});50var wptools = require('wptools');51var wiki = new wptools('Barack Obama');52wiki.get(function(err,

Full Screen

Using AI Code Generation

copy

Full Screen

1import AstArgument from 'wpt/ast/ast-argument.js';2import AstExpression from 'wpt/ast/ast-expression.js';3import AstIdentifier from 'wpt/ast/ast-identifier.js';4import AstLiteral from 'wpt/ast/ast-literal.js';5import AstMemberExpression from 'wpt/ast/ast-member-expression.js';6import AstNewExpression from 'wpt/ast/ast-new-expression.js';7import AstObjectExpression from 'wpt/ast/ast-object-expression.js';8import AstProgram from 'wpt/ast/ast-program.js';9import AstProperty from 'wpt/ast/ast-property.js';10import AstSequenceExpression from 'wpt/ast/ast-sequence-expression.js';11import AstStatement from 'wpt/ast/ast-statement.js';12import AstVariableDeclaration from 'wpt/ast/ast-variable-declaration.js';13import AstVariableDeclarator from 'wpt/ast/ast-variable-declarator.js';14var program = new AstProgram('Program', 'Program', 'Program');15program.body = [];16var body = program.body;17var varDecl = new AstVariableDeclaration('VariableDeclaration', 'VariableDeclaration', 'VariableDeclaration');18varDecl.declarations = [];19varDecl.kind = 'var';20var decl = new AstVariableDeclarator('VariableDeclarator', 'VariableDeclarator', 'VariableDeclarator');21decl.init = new AstLiteral('Literal', 'Literal', 'Literal', '1');22decl.id = new AstIdentifier('Identifier', 'Identifier', 'Identifier', 'a');23varDecl.declarations.push(decl);24body.push(varDecl);25varDecl = new AstVariableDeclaration('VariableDeclaration', 'VariableDeclaration', 'VariableDeclaration');26varDecl.declarations = [];27varDecl.kind = 'var';28decl = new AstVariableDeclarator('VariableDeclarator', 'VariableDeclarator', 'VariableDeclarator');29decl.init = new AstIdentifier('Identifier', 'Identifier', 'Identifier', 'a');30decl.id = new AstIdentifier('Identifier', 'Identifier', 'Identifier', 'b');31varDecl.declarations.push(decl);32body.push(varDecl);

Full Screen

Using AI Code Generation

copy

Full Screen

1var wptools = require('wptools');2var fs = require('fs');3var wiki = new wptools();4wiki.setPage('Barack Obama');5wiki.setLang('en');6wiki.setFormat('json');7wiki.setArguments('action', 'parse');8wiki.setCallback(function (err, data) {9 if (err) {10 console.log(err);11 } else {12 console.log(data);13 }14});15wiki.AstArgument();16var wptools = require('wptools');17var fs = require('fs');18var wiki = new wptools();19wiki.setPage('Barack Obama');20wiki.setLang('en');21wiki.setFormat('json');22wiki.setArguments('action', 'parse');23wiki.setCallback(function (err, data) {24 if (err) {25 console.log(err);26 } else {27 console.log(data);28 }29});30wiki.AstCallback();

Full Screen

Using AI Code Generation

copy

Full Screen

1var wptoolkit = require('wptoolkit');2var wp = new wptoolkit();3 if (!error && response.statusCode == 200) {4 }5})6var wptoolkit = require('wptoolkit');7var wp = new wptoolkit();8 if (!error && response.statusCode == 200) {9 }10})11var wptoolkit = require('wptoolkit');12var wp = new wptoolkit();13 if (!error && response.statusCode == 200) {14 }15})16var wptoolkit = require('wptoolkit');17var wp = new wptoolkit();18 if (!error && response.statusCode == 200) {19 }20})21var wptoolkit = require('wptoolkit');22var wp = new wptoolkit();23 if (!error && response.statusCode == 200) {24 }25})

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run wpt automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful