From 4fc49d14af68248cc45504c087a89e39568f756a Mon Sep 17 00:00:00 2001 From: srfsh Date: Sun, 8 Oct 2023 21:45:33 +0300 Subject: [PATCH] feat!: refactor a lot of stuff --- package.json | 5 +- pkg/core/src/index.ts | 6 + pkg/core/src/parser.ts | 69 ++- pkg/core/src/plugin.ts | 327 ++++++++-- pkg/core/src/slangroom.ts | 123 ++-- pkg/core/src/tokens.ts | 58 +- pkg/core/src/visitor.ts | 107 ++-- pkg/core/test/slangroom.ts | 100 ++- pkg/core/test/visitor.ts | 66 +- pkg/http/src/index.ts | 249 +------- pkg/http/src/lexer.ts | 5 + pkg/http/src/parser.ts | 63 ++ pkg/http/src/plugins.ts | 86 +++ pkg/http/src/tokens.ts | 34 ++ pkg/http/src/visitor.ts | 56 ++ pkg/http/test/e2e.ts | 91 ++- pkg/http/test/index.ts | 170 ------ pkg/http/test/plugins.ts | 126 ++++ pkg/http/test/visitor.ts | 21 + pkg/ignored/src/index.ts | 6 +- pkg/ignored/test/index.ts | 4 +- pkg/shared/src/tokens.ts | 67 -- pkg/shared/src/zenroom.ts | 52 +- pkg/shared/test/zenroom.ts | 59 +- pnpm-lock.yaml | 1178 +----------------------------------- 25 files changed, 1001 insertions(+), 2127 deletions(-) create mode 100644 pkg/http/src/lexer.ts create mode 100644 pkg/http/src/parser.ts create mode 100644 pkg/http/src/plugins.ts create mode 100644 pkg/http/src/tokens.ts create mode 100644 pkg/http/src/visitor.ts delete mode 100644 pkg/http/test/index.ts create mode 100644 pkg/http/test/plugins.ts create mode 100644 pkg/http/test/visitor.ts diff --git a/package.json b/package.json index 7bc38773..86938eb9 100644 --- a/package.json +++ b/package.json @@ -22,18 +22,15 @@ "cjs-fixup": "pnpm -F @slangroom/* exec sh -c \"echo '{\\\"type\\\":\\\"commonjs\\\"}' >build/cjs/package.json\"" }, "devDependencies": { - "@types/body-parser": "^1.19.3", - "@types/express": "^4.17.18", "@types/node": "^20.3.1", "@typescript-eslint/eslint-plugin": "^5.59.11", "@typescript-eslint/parser": "^5.59.11", "ava": "^5.3.1", - "body-parser": "^1.20.2", "c8": "^8.0.1", "esbuild": "^0.18.4", "eslint": "^8.43.0", "eslint-config-prettier": "^8.8.0", - "express": "^4.18.2", + "nock": "^13.3.3", "prettier": "^2.8.8", "ts-node": "^10.9.1", "tslib": "^2.5.3", diff --git a/pkg/core/src/index.ts b/pkg/core/src/index.ts index e69de29b..40ec40c6 100644 --- a/pkg/core/src/index.ts +++ b/pkg/core/src/index.ts @@ -0,0 +1,6 @@ +export * from '@slangroom/core/tokens'; +export * from '@slangroom/core/lexer'; +export * from '@slangroom/core/parser'; +export * from '@slangroom/core/visitor'; +export * from '@slangroom/core/plugin'; +export * from '@slangroom/core/slangroom'; diff --git a/pkg/core/src/parser.ts b/pkg/core/src/parser.ts index fb100634..35d8516f 100644 --- a/pkg/core/src/parser.ts +++ b/pkg/core/src/parser.ts @@ -10,7 +10,37 @@ import { Send, To, } from '@slangroom/core/tokens'; -import { CstParser, type IToken } from '@slangroom/deps/chevrotain'; +import { CstParser, type IToken, type CstNode } from '@slangroom/deps/chevrotain'; + +export type StatementCst = CstNode & { + children: { + connect?: ConnectCst; + sendpass: SendpassCst[]; + phrase: PhraseCst; + into?: IntoCst; + }; +}; + +export type ConnectCst = CstNode & { + children: { Identifier: [IToken] }; +}; + +export type SendpassCst = CstNode & { + children: ({ Send: [IToken] } | { Pass: [IToken] }) & { + phrase: PhraseCst; + Identifier: [IToken]; + }; +}; + +export type PhraseCst = CstNode & { + children: { + Buzzword: [IToken, ...IToken[]]; + }; +}; + +export type IntoCst = CstNode & { + children: { Identifier: [IToken] }; +}; const Parser = new (class extends CstParser { constructor() { @@ -20,13 +50,9 @@ const Parser = new (class extends CstParser { statement = this.RULE('statement', () => { this.OPTION1(() => this.SUBRULE(this.#connect)); - this.MANY(() => { - this.SUBRULE(this.#sendpass); - }); - this.SUBRULE(this.#buzzwords); - this.OPTION(() => { - this.SUBRULE(this.#into); - }); + this.MANY(() => this.SUBRULE(this.#sendpass)); + this.SUBRULE(this.#phrase); + this.OPTION2(() => this.SUBRULE(this.#into)); }); #connect = this.RULE('connect', () => { @@ -37,37 +63,30 @@ const Parser = new (class extends CstParser { }); #sendpass = this.RULE('sendpass', () => { - this.OR([ - { - ALT: () => this.CONSUME(Send), - }, - { - ALT: () => this.CONSUME(Pass), - }, - ]); - this.SUBRULE(this.#buzzwords); + this.OR([{ ALT: () => this.CONSUME(Send) }, { ALT: () => this.CONSUME(Pass) }]); + this.SUBRULE(this.#phrase); this.CONSUME(Identifier); this.CONSUME(And); }); + #phrase = this.RULE('phrase', () => { + this.AT_LEAST_ONE(() => this.CONSUME(Buzzword)); + }); + #into = this.RULE('into', () => { this.CONSUME(And); this.CONSUME(Output); this.CONSUME(Into); this.CONSUME(Identifier); }); - - #buzzwords = this.RULE('buzzwords', () => { - this.AT_LEAST_ONE(() => this.CONSUME(Buzzword)); - }); })(); export const CstVisitor = Parser.getBaseCstVisitorConstructor(); export const parse = (tokens: IToken[]) => { Parser.input = tokens; - - const res = Parser.statement(); - console.log(Parser.errors) - return res + return { + cst: Parser.statement(), + errors: Parser.errors, + }; }; diff --git a/pkg/core/src/plugin.ts b/pkg/core/src/plugin.ts index ccc7cb80..ea0013d0 100644 --- a/pkg/core/src/plugin.ts +++ b/pkg/core/src/plugin.ts @@ -1,82 +1,281 @@ -import type { Jsonable, JsonableObject, ZenroomParams } from '@slangroom/shared'; +import type { Jsonable, ZenParams } from '@slangroom/shared'; +import type { Statement } from '@slangroom/core'; -export class ExecParams { - #data: JsonableObject; - #keys: JsonableObject; +/** + * A Plugin definition. + * + * @example + * ```ts + * const myPlugin = async (ctx: PluginContext) => Promise { + * if (ctx.phrase !== "doesn't match with my definition") + * return ctx.fail("syntax error"); + * + * const filePath = ctx.fetch("path"); + * if (typeof filePath !== "string") + * return ctx.fail("file must be string")$ + * + * const [err, result] = writeFile(filePath, "hello, world!"); + * if (err) + * return ctx.fail(err); + * + * return ctx.pass(result); + * } + * ``` + */ +export type Plugin = (ctx: PluginContext) => PluginResult | Promise; - constructor(params: ZenroomParams) { - this.#data = params.data || {}; - this.#keys = params.keys || {}; +// Todo: Maybe we should adapt some sort of monad library. + +/** + * Result of a Plugin execution. + */ +export type PluginResult = ResultOk | ResultErr; +export type ResultOk = { ok: true; value: Jsonable }; +export type ResultErr = { ok: false; error: any }; + +/** + * The Plugin Context. It has every info a Plugin needs, plus some utilities. + */ +export type PluginContext = { + /** + * The Phrase part of a Statement. + */ + phrase: string; + + /** + * Gets the value of the Connect part of a Statement« if available. + * + * @returns The array of values of the Connect part (might be empty). + */ + getConnect(): string[]; + + /** + * Basically the same as {@link getConnect}, but throws if unavailable or empty. + * + * @returns The array of values of the Connect part (has at least one item); + * + * @throws {@link Error} if the part is unavailable. + */ + fetchConnect(): [string, ...string[]]; + + /** + * Gets the value of the parameter needed by the Plugin, if available. + * + * @returns the value of the parameter, or undefined if unavailable. + */ + get(name: string): undefined | Jsonable; + + /** + * Basically the same as {@link get}, but throws if unavailable. + * + * @param name - The name of the parameter. + * + * @returns the value of the parameter. + * + * @throws {@link Error} if {@link name} is unprovided. + */ + fetch(name: string): Jsonable; + + /** + * The utility function that makes a {@link Plugin} fail. Must be used with a + * `return` statement. + */ + fail(reason: any): PluginResult; + + /** + * The utility function that makes a {@link Plugin} pass/succeed. Must be used with + * a `return` statement. + */ + pass(result: Jsonable): PluginResult; +}; + +/** + * Concrete implementation of {@link PluginContext}. Used for production. + * + * @remark + * The lhs values are the parameter names passed to the {@link Plugin}. The rhs + * values are the identifiers provided to Zenroom. In a statement like + * `Given I pass object 'dataToPost' and pass proxy 'myProxy'`, the lhs values + * would be `object` and `proxy`, and the rhs values would be `'dataToPost'` and + * `'myProxy'`. + */ +export class PluginContextImpl implements PluginContext { + /** + * {@inheritDoc PluginContext.phrase} + */ + readonly phrase: string; + + /** + * The name of the identifier used to reference the Connection parameters + * (via {@link #zparams}). It is an rhs value. + */ + #connect: string | undefined = undefined; + + /** + * A map between parameters that should be provided to a statetment and + * identifiers. + * + * @remarks + * Such as `address => 'myAddress'` and `proxy => 'foobar'`. The ones on + * the lhs are what the statement needs, and the ones on the rhs are the + * identifiers provided to the contract (via [[#data]] or [[#keys]]). + */ + #bindings = new Map(); + + /** + * The ZenParams. + */ + #zparams: ZenParams = { data: {}, keys: {} }; + + constructor(stmt: Statement, zparams: ZenParams) { + this.phrase = stmt.phrase.toLowerCase(); + this.#connect = stmt.connect; + this.#bindings = stmt.bindings; + this.#zparams = zparams; } - get(key: string): Jsonable | undefined { - return this.#data[key] ? this.#data[key] : this.#keys[key]; + /** + * Gets the value referenced by {@link name} from {@link #zparams}. + */ + #getDataKeys(rhs: string): undefined | Jsonable { + return this.#zparams.data[rhs] ? this.#zparams.data[rhs] : this.#zparams.keys[rhs]; } - getThrow(key: string): Jsonable { - const res = this.#data[key] ? this.#data[key] : this.#keys[key]; - if(!res) - throw new Error(`Key ${key} not found`) - return res + /** + * {@inheritDoc PluginContext.pass} + */ + pass(result: Jsonable): PluginResult { + return { ok: true, value: result }; } - set(key: string, value: Jsonable) { - this.#data[key] = value; + /** + * {@inheritDoc PluginContext.fail} + */ + fail(reason: any): PluginResult { + return { ok: false, error: reason }; } - getKeys() { - return this.#keys + /** + * {@inheritDoc PluginContext.getConnect} + */ + getConnect(): string[] { + if (!this.#connect) return []; + const val = this.#getDataKeys(this.#connect); + if (typeof val === 'string') return [val]; + if (Array.isArray(val)) { + if (val.every((x) => typeof x === 'string')) return val as string[]; + else + throw new Error( + `the array referenced by ${this.#connect} must solely composed of strings` + ); + } + return []; } - getData() { - return this.#data + + /** + * {@inheritDoc PluginContext.fetchConnect} + */ + fetchConnect(): [string, ...string[]] { + const val = this.getConnect(); + if (val.length === 0) throw new Error('a connect is required'); + return val as [string, ...string[]]; } -} -export const buildNormalizedPharse = (phrase: string) => - phrase.toLowerCase(); + /** + * {@inheritDoc PluginContext.get} + */ + get(lhs: string): undefined | Jsonable { + const rhs = this.#bindings.get(lhs); + if (!rhs) return undefined; + return this.#getDataKeys(rhs); + } -export enum EvaluationResultKind { - Success, - Failure, + /** + * {@inheritDoc PluginContext.fetch} + */ + fetch(lhs: string): Jsonable { + const val = this.get(lhs); + if (!val) throw new Error(`the parameter isn't provided: ${lhs}`); + return val; + } } -export type EvaluationSuccess = { - kind: EvaluationResultKind.Success, - result: Jsonable -} +/** + * The implementation of {@link PluginContext} that must be used only for test! + * + * @remarks + * It provides shortucts to mimic a concrete implementation of + * {@link PluginContext}. + * + * @internal + */ +export class PluginContextTest implements PluginContext { + #connect: string[] = []; + #params = new Map(); + readonly phrase: string = ''; // not used but required by the interface -export type EvaluationFailure = { - kind: EvaluationResultKind.Failure, - error: any -} -export type EvaluationResult = EvaluationSuccess | EvaluationFailure - -export abstract class Plugin { - #bindings: Map = new Map() - #execParams: ExecParams = new ExecParams({}) - - // params: are the optional/mandatory params - protected buildParams(params: Map): Map { - const args = new Map() - params.forEach((required, param) => { - const binding = this.#bindings.get(param) - if(binding) { - return args.set(param, - this.#execParams.getThrow(binding || "")) - } else if(required) { - throw new Error("Unknown binding") - } - return - }) - return new Map(args) - } - - async execute(phrase: string, bindings: Map, - execParams: ExecParams) { - this.#bindings = bindings - this.#execParams = execParams - return await this.evaluate(phrase); - } - - abstract evaluate(phrase: string): Promise | EvaluationResult; + constructor(connect: string | string[], params: Record) { + this.#connect = typeof connect === 'string' ? [connect] : connect; + this.#params = new Map(Object.entries(params)); + } + + /** + * @constructor + */ + static connect(connect: string | string[]) { + return new this(connect, {}); + } + + /** + * @constructor + */ + static params(params: Record) { + return new this([], params); + } + + /** + * {@inheritDoc PluginContext.pass} + */ + pass(result: Jsonable): PluginResult { + return { ok: true, value: result }; + } + + /** + * {@inheritDoc PluginContext.fail} + */ + fail(reason: any): PluginResult { + return { ok: false, error: reason }; + } + + /** + * {@inheritDoc PluginContext.getConnect} + */ + getConnect(): string[] { + return this.#connect; + } + + /** + * {@inheritDoc PluginContext.fetchConnect} + */ + fetchConnect(): [string, ...string[]] { + const val = this.getConnect(); + if (val.length === 0) throw new Error('a connect is required'); + return val as [string, ...string[]]; + } + + /** + * {@inheritDoc PluginContext.get} + */ + get(name: string): undefined | Jsonable { + return this.#params.get(name); + } + + /** + * {@inheritDoc PluginContext.fetch} + */ + fetch(name: string): Jsonable { + const val = this.get(name); + if (!val) throw new Error(`the parameter isn't provided: ${name}`); + return val; + } } diff --git a/pkg/core/src/slangroom.ts b/pkg/core/src/slangroom.ts index 0605bda6..d0c5a34a 100644 --- a/pkg/core/src/slangroom.ts +++ b/pkg/core/src/slangroom.ts @@ -1,93 +1,84 @@ import { getIgnoredStatements } from '@slangroom/ignored'; -import { ZenroomParams, zencodeExec } from '@slangroom/shared'; +import { type ZenOutput, ZenParams, zencodeExec } from '@slangroom/shared'; import { - Plugin, - ExecParams, - buildNormalizedPharse, - EvaluationResult, - EvaluationResultKind, -} from '@slangroom/core/plugin'; -import { lex } from '@slangroom/core/lexer'; -import { parse } from '@slangroom/core/parser'; -import { visit, type Statement } from '@slangroom/core/visitor'; + lex, + parse, + visit, + PluginContextImpl, + type Plugin, + type StatementCst, + type Statement, +} from '@slangroom/core'; type Plugins = Plugin | Set | Array>; export class Slangroom { - #plugins: Plugin[] = []; + #plugins = new Set(); constructor(first: Plugins, ...rest: Plugins[]) { const recurse = (x: Plugins) => { if (Array.isArray(x) || x instanceof Set) x.forEach(recurse); - else { - this.#plugins.push(x); - } + else this.#plugins.add(x); }; [first, ...rest].forEach(recurse); } - async executePlugin(p: Statement, params: ExecParams) { - const normalizedBuzzwords = buildNormalizedPharse(p.buzzwords) - let result: EvaluationResult = { - kind: EvaluationResultKind.Failure, - error: "No plugin executed", - } - for(const plugin of this.#plugins) { - const bindings = new Map(p.bindings.entries()) - if(p.connect) { - bindings.set("connect", p.connect) - } - result = await plugin.execute(normalizedBuzzwords, bindings, params) - if(result.kind === EvaluationResultKind.Success) { - if(p.into) { - params.set(p.into, result.result) - } - break; - } - } - if(result.kind == EvaluationResultKind.Failure) { - throw new Error(result.error) - } - } - - async execute(contract: string, zparams: ZenroomParams) { + async execute(contract: string, optParams?: Partial): Promise { + const zparams = requirifyZenParams(optParams); + const givens: Statement[] = []; + const thens: Statement[] = []; const ignoreds = await getIgnoredStatements(contract, zparams); - const { givens, thens } = ignoreds.reduce( - (acc, cur) => { - const given = cur.split(/^\s*given\s+i\s+/i); - if (given[1]) { - acc.givens.push(astify(given[1])); - return acc; - } + ignoreds.forEach((x: string) => { + const given = x.split(/^\s*given\s+i\s+/i); + if (given[1]) { + const { ast, errors } = astify(given[1]); + if (!ast) throw errors; + givens.push(ast); + return; + } - const then = cur.split(/^\s*then\s+i\s+/i); - if (then[1]) acc.thens.push(astify(then[1])); - return acc; - }, - { givens: [] as Statement[], thens: [] as Statement[] } - ); + const then = x.split(/^\s*then\s+i\s+/i); + if (then[1]) { + const { ast, errors } = astify(then[1]); + if (!ast) throw errors; + thens.push(ast); + } + }); - const params = new ExecParams(zparams); + for (const g of givens) await this.#execute(g, zparams); - for (const g of givens) { - await this.executePlugin(g, params) - } + const zout = await zencodeExec(contract, zparams); - const zout = await zencodeExec(contract, {keys: params.getKeys(), data: params.getData()}); + const params: ZenParams = { data: zout.result, keys: zparams.keys }; + for (const t of thens) await this.#execute(t, params); - const thenParams = new ExecParams({data: zout.result, keys: params.getKeys()}) + return { result: params.data, logs: zout.logs }; + } - for (const t of thens) { - await this.executePlugin(t, thenParams) + async #execute(stmt: Statement, zparams: ZenParams) { + const ctx = new PluginContextImpl(stmt, zparams); + for (const p of this.#plugins) { + const result = await p(ctx); + if (result.ok) { + if (stmt.into) zparams.data[stmt.into] = result.value; + return; + } } - - return {result: thenParams.getData(), logs: zout.logs}; + throw new Error('no statements matched'); } } -const astify = (line: string) => { - const { tokens } = lex(line); - const cst = parse(tokens); - return visit(cst); +const requirifyZenParams = (params?: Partial): Required => { + if (!params) return { data: {}, keys: {} }; + if (!params.data) params.data = {}; + if (!params.keys) params.keys = {}; + return params as ZenParams; }; +export const astify = (line: string) => { + const lexed = lex(line); + if (lexed.errors.length) return { errors: lexed.errors }; + const parsed = parse(lexed.tokens); + if (parsed.errors.length) return { errors: parsed.errors }; + return { ast: visit(parsed.cst as StatementCst) }; +}; diff --git a/pkg/core/src/tokens.ts b/pkg/core/src/tokens.ts index b22be395..d4c4e534 100644 --- a/pkg/core/src/tokens.ts +++ b/pkg/core/src/tokens.ts @@ -1,13 +1,16 @@ -import { createToken, Lexer } from '@slangroom/deps/chevrotain'; +import { Whitespace, Comment } from '@slangroom/shared'; +import { createToken } from '@slangroom/deps/chevrotain'; -export const Save = createToken({ - name: 'Save', - pattern: /save/i, +export { Whitespace } from '@slangroom/shared'; + +export const Buzzword = createToken({ + name: 'Buzzword', + pattern: /[a-z0-9]+/i, }); -export const Read = createToken({ - name: 'Read', - pattern: /read/i, +export const Identifier = createToken({ + name: 'Identifier', + pattern: /'(?:[^\\']|\\(?:[bfnrtv'\\/]|u[0-9a-fA-F]{4}))*'/, }); export const Connect = createToken({ @@ -15,29 +18,19 @@ export const Connect = createToken({ pattern: /connect/i, }); -export const Pass = createToken({ - name: 'Pass', - pattern: /pass/i, -}); - -export const Send = createToken({ - name: 'Send', - pattern: /send/i, -}); - export const To = createToken({ name: 'To', pattern: /to/i, }); -export const And = createToken({ - name: 'And', - pattern: /and/i, +export const Send = createToken({ + name: 'Send', + pattern: /send/i, }); -export const Into = createToken({ - name: 'Into', - pattern: /into/i, +export const Pass = createToken({ + name: 'Pass', + pattern: /pass/i, }); export const Output = createToken({ @@ -45,20 +38,14 @@ export const Output = createToken({ pattern: /output/i, }); -export const Buzzword = createToken({ - name: 'Buzzword', - pattern: /[a-z0-9]+/i, -}); - -export const Identifier = createToken({ - name: 'Identifier', - pattern: /'(?:[^\\']|\\(?:[bfnrtv'\\/]|u[0-9a-fA-F]{4}))*'/, +export const Into = createToken({ + name: 'Into', + pattern: /into/i, }); -export const Whitespace = createToken({ - name: 'Whitespace', - pattern: /\s+/, - group: Lexer.SKIPPED, +export const And = createToken({ + name: 'And', + pattern: /and/i, }); export const allTokens = [ @@ -72,4 +59,5 @@ export const allTokens = [ Send, Pass, Buzzword, + Comment, ]; diff --git a/pkg/core/src/visitor.ts b/pkg/core/src/visitor.ts index 0ca127d7..41b5bb2f 100644 --- a/pkg/core/src/visitor.ts +++ b/pkg/core/src/visitor.ts @@ -1,69 +1,74 @@ -import { CstVisitor } from '@slangroom/core/parser'; -import type { CstNode } from '@slangroom/deps/chevrotain'; - -export enum ActionType { - Read, - Save, -} +import { + CstVisitor, + type StatementCst, + type PhraseCst, + type IntoCst, + type SendpassCst, + type ConnectCst, +} from '@slangroom/core'; +import type { IToken } from '@slangroom/deps/chevrotain'; export type Statement = { - connect?: string, - bindings: Map, - buzzwords: string, - into?: string, -} + connect?: string; + bindings: Map; + phrase: string; + into?: string; +}; -export class StatementBindings { - #bindings: Map; - constructor() { - this.#bindings = new Map(); +export class ErrorKeyExists extends Error { + constructor(key: string) { + super(`key already exists: ${key}`); + this.name = 'ErrorKeyExists'; } +} - get(key: string) { - return this.#bindings.get(key) - } - set(key: string, val: string) { - if(this.#bindings.has(key)) { - throw new Error("Duplicate key") - } - this.#bindings.set(key, val) - - } +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions +interface V { + visit(cst: StatementCst): ReturnType; + visit(cst: PhraseCst): ReturnType; + visit(cst: SendpassCst): ReturnType; + visit(cst: ConnectCst): ReturnType; + visit(cst: IntoCst): ReturnType; } -export const Visitor = new (class extends CstVisitor { +class V extends CstVisitor { constructor() { super(); this.validateVisitor(); } - statement(ctx: any) { - const node: Statement = { - buzzwords: this.visit(ctx.buzzwords), - bindings: new Map( - ctx.sendpass?.map((v: any) => this.visit(v))), - } - if(ctx.connect) { - node.connect = this.visit(ctx.connect) - } - if(ctx.into) { - node.into = this.visit(ctx.into) - } - return node + + statement(ctx: StatementCst['children']): Statement { + const stmt: Statement = { + phrase: this.visit(ctx.phrase), + bindings: new Map(), + }; + ctx.sendpass?.forEach((x: SendpassCst) => { + const [key, value] = this.visit(x); + if (stmt.bindings.has(key)) throw new ErrorKeyExists(key); + stmt.bindings.set(key, value); + }); + if (ctx.connect) stmt.connect = this.visit(ctx.connect); + if (ctx.into) stmt.into = this.visit(ctx.into); + return stmt; } - connect(ctx: any) { - return ctx.Identifier[0].image.slice(1,-1) + + phrase(ctx: PhraseCst['children']): string { + return ctx.Buzzword.map((x: IToken) => x.image).join(' '); } - sendpass(ctx: any) { - const identifier = ctx.Identifier[0].image.slice(1,-1) - return [this.visit(ctx.buzzwords), identifier] + + sendpass(ctx: SendpassCst['children']): [string, string] { + return [this.visit(ctx.phrase), ctx.Identifier[0].image.slice(1, -1)]; } - into(ctx: any) { - return ctx.Identifier[0].image.slice(1,-1) + + connect(ctx: ConnectCst['children']): string { + return ctx.Identifier[0].image.slice(1, -1); } - buzzwords(ctx: any) { - return ctx.Buzzword.map((v: any) => v.image).join(' '); + + into(ctx: IntoCst['children']): string { + return ctx.Identifier[0].image.slice(1, -1); } +} -})(); +export const Visitor = new V(); -export const visit = (cst: CstNode): Statement => Visitor.visit(cst); +export const visit = (cst: StatementCst): Statement => Visitor.visit(cst); diff --git a/pkg/core/test/slangroom.ts b/pkg/core/test/slangroom.ts index 53a4a748..b5fdbc9e 100644 --- a/pkg/core/test/slangroom.ts +++ b/pkg/core/test/slangroom.ts @@ -1,66 +1,36 @@ import test from 'ava'; -import { Plugin } from '../src/plugin.js'; -import { Slangroom } from '../src/slangroom.js'; -import { EvaluationResult, EvaluationResultKind } from '../src/plugin.js' +import { Slangroom, type PluginContext, type PluginResult } from '@slangroom/core'; -test("Runs all unknown statements", async (t) => { - let useR1 = false; - let useR2 = false; - let useR3 = false; +test('runs all unknown statements', async (t) => { + let usedP0 = false; + let usedP1 = false; + let usedP2 = false; - class PluginA extends Plugin { - async evaluate(phrase: string): Promise { - if(phrase == "a") { - useR1 = true; - return { - kind: EvaluationResultKind.Success, - result: "foo" - } - } - return { - kind: EvaluationResultKind.Failure, - error: "Unknown phrase" - } + const p0 = (ctx: PluginContext): PluginResult => { + if (ctx.phrase === 'a') { + usedP0 = true; + return ctx.pass('foo'); } - } - class PluginB extends Plugin { - async evaluate(phrase: string): Promise { - const args = this.buildParams(new Map([["a", true]])) - if(phrase == "b") { - useR2 = true - t.is(args.get("a"), "foo") - return { - kind: EvaluationResultKind.Success, - result: "bar" - } - } - return { - kind: EvaluationResultKind.Failure, - error: "Unknown phrase" - } - } - } - class PluginCD extends Plugin { - async evaluate(phrase: string): Promise { - const args = this.buildParams(new Map([["a", true]])) - if(phrase == "c d") { - useR3 = true - t.is(args.get("a"), "bar") - return { - kind: EvaluationResultKind.Success, - result: "foobar" - } - } - return { - kind: EvaluationResultKind.Failure, - error: "Unknown phrase" - } + return ctx.fail('Unkown phrase'); + }; + + const p1 = (ctx: PluginContext): PluginResult => { + if (ctx.phrase === 'b') { + usedP1 = true; + t.is(ctx.fetch('a'), 'foo'); + return ctx.pass('bar'); } - } + return ctx.fail('Unknown phrase'); + }; - const r1 = new PluginA() - const r2 = new PluginB() - const r3 = new PluginCD() + const p2 = (ctx: PluginContext): PluginResult => { + if (ctx.phrase === 'c d') { + usedP2 = true; + t.is(ctx.fetch('a'), 'bar'); + return ctx.pass('foobar'); + } + return ctx.fail('Unkown phrase'); + }; const script = ` Rule caller restroom-mw @@ -72,11 +42,11 @@ Then print 'a' Then I pass a 'a' and B and output into 'b' Then I pass a 'b' and c D Then I pass a 'b' and C d and output into 'mimmo' -` - const slangroom = new Slangroom(r1, [r2, r3]); - const res = await slangroom.execute(script, {}) - t.truthy(useR1, "r1 is not used") - t.truthy(useR2, "r2 is not used") - t.truthy(useR3, "r3 is not used") - t.deepEqual(res.result, { a: 'foo', b: 'bar', mimmo: 'foobar' }, res.logs) -}) +`; + const slangroom = new Slangroom(p0, [p1, new Set([p2])]); + const res = await slangroom.execute(script); + t.true(usedP0); + t.true(usedP1); + t.true(usedP2); + t.deepEqual(res.result, { a: 'foo', b: 'bar', mimmo: 'foobar' }, res.logs); +}); diff --git a/pkg/core/test/visitor.ts b/pkg/core/test/visitor.ts index 4120ec73..e7e53f6a 100644 --- a/pkg/core/test/visitor.ts +++ b/pkg/core/test/visitor.ts @@ -1,52 +1,58 @@ import test from 'ava'; -import { lex } from '@slangroom/core/lexer'; -import { parse } from '@slangroom/core/parser'; -import { visit } from '@slangroom/core/visitor'; +import { lex, parse, visit, ErrorKeyExists, type StatementCst } from '@slangroom/core'; const astify = (line: string) => { const { tokens } = lex(line); - const cst = parse(tokens); - return visit(cst); + const { cst } = parse(tokens); + return visit(cst as StatementCst); }; test('generated ast is correct', async (t) => { const cases = { 'read the ethereum balance': { - buzzwords: "read the ethereum balance", - bindings: new Map() + phrase: 'read the ethereum balance', + bindings: new Map(), }, "pass address 'addr' and send contract 'contract' and read the ethereum balance": { - buzzwords: "read the ethereum balance", + phrase: 'read the ethereum balance', bindings: new Map([ - ["address","addr"], - ["contract","contract"], - ]) + ['address', 'addr'], + ['contract', 'contract'], + ]), }, "connect to 'foo' and read the ethereum balance": { connect: 'foo', - buzzwords: "read the ethereum balance", - bindings: new Map() - }, - "connect to 'foo' and pass address 'addr' and send contract 'contract' and read the ethereum balance": { - connect: 'foo', - buzzwords: "read the ethereum balance", - bindings: new Map([ - ["address","addr"], - ["contract","contract"], - ]) - }, - "connect to 'foo' and pass address 'addr' and send contract 'contract' and read the ethereum balance and output into 'var'": { - connect: 'foo', - buzzwords: "read the ethereum balance", - bindings: new Map([ - ["address","addr"], - ["contract","contract"], - ]), - into: 'var', + phrase: 'read the ethereum balance', + bindings: new Map(), }, + "connect to 'foo' and pass address 'addr' and send contract 'contract' and read the ethereum balance": + { + connect: 'foo', + phrase: 'read the ethereum balance', + bindings: new Map([ + ['address', 'addr'], + ['contract', 'contract'], + ]), + }, + "connect to 'foo' and pass address 'addr' and send contract 'contract' and read the ethereum balance and output into 'var'": + { + connect: 'foo', + phrase: 'read the ethereum balance', + bindings: new Map([ + ['address', 'addr'], + ['contract', 'contract'], + ]), + into: 'var', + }, }; + for (const [line, astWant] of Object.entries(cases)) { const astHave = astify(line); t.deepEqual(astHave, astWant); } + + const err = t.throws(() => astify("pass same 'x' and pass same 'y' and does not matter"), { + instanceOf: ErrorKeyExists, + }) as ErrorKeyExists; + t.is(err.message, 'key already exists: same'); }); diff --git a/pkg/http/src/index.ts b/pkg/http/src/index.ts index 348f9e96..cbb8a2ae 100644 --- a/pkg/http/src/index.ts +++ b/pkg/http/src/index.ts @@ -1,244 +1,5 @@ -import { createToken, Lexer, CstParser } from "@slangroom/deps/chevrotain"; -import { JsonableArray, Jsonable } from "@slangroom/shared"; -import { - Plugin, - EvaluationResult, - EvaluationResultKind, -} from "@slangroom/core/plugin"; -import { Whitespace } from "@slangroom/shared/tokens" -import axios from "axios"; -import { createSyntaxDiagramsCode } from "@slangroom/deps/chevrotain"; -import fs from 'node:fs' - -export enum RequestMethod { - Get, - Post -} - -export enum RequestKind { - Default, - Parallel, - Sequential, - Same, -} - - -type RequestAST = { - method: RequestMethod - kind: RequestKind -} - - -const Get = createToken({ - name: "Get", - pattern: /get/i, -}); -const Post = createToken({ - name: "Post", - pattern: /post/i, -}); -const Do = createToken({ - name: "Do", - pattern: /do/i, -}); -const Parallel = createToken({ - name: "Parallel", - pattern: /parallel/i -}); -const Same = createToken({ - name: "Same", - pattern: /same/i, -}); -const Sequential = createToken({ - name: "Sequential", - pattern: /sequential/i, -}); - -const allTokens = [ - Whitespace, - Get, - Post, - Parallel, - Sequential, - Same, - Do, -]; -const StatementLexer = new Lexer(allTokens); -// ----------------- parser ----------------- -class StatementParser extends CstParser { - constructor() { - super(allTokens); - - this.performSelfAnalysis(); - } - - public method = this.RULE("method", () => { - this.OR([ - { ALT: () => this.CONSUME(Get) }, - { ALT: () => this.CONSUME(Post) }, - ]); - }) - - public kind = this.RULE("kind", () => { - this.OR([ - { ALT: () => this.CONSUME(Sequential) }, - { ALT: () => this.CONSUME(Parallel) }, - { ALT: () => this.CONSUME(Same) }, - ]); - }) - - public statement = this.RULE("statement", () => { - this.CONSUME(Do) - this.OPTION(() => this.SUBRULE(this.kind)) - this.SUBRULE(this.method) - }); -} - -const parser = new StatementParser(); -// ----------------- Interpreter ----------------- -const BaseCstVisitor = parser.getBaseCstVisitorConstructor(); - -class StatementInterpreter extends BaseCstVisitor { - constructor() { - super(); - this.validateVisitor(); - } - statement(ctx: any): RequestAST { - return { - method: this.visit(ctx.method), - kind: ctx.kind ? this.visit(ctx.kind) : RequestKind.Default - } - } - kind(ctx: any): RequestKind { - if(ctx.Sequential) { - return RequestKind.Sequential - } - if(ctx.Parallel) { - return RequestKind.Parallel - } - if(ctx.Same) { - return RequestKind.Same - } - throw new Error("Should not be here: unknown request kind") - } - - method(ctx: any): RequestMethod { - if(ctx.Post) { - return RequestMethod.Post - } - if(ctx.Get) { - return RequestMethod.Get - } - throw new Error("Should not be here: unknown request method") - } -} - -// We only need a single interpreter instance because our interpreter has no state. -const interpreter = new StatementInterpreter(); - -export const astify = (text: string) => { - const lexResult = StatementLexer.tokenize(text); - parser.input = lexResult.tokens; - const cst = parser.statement(); - const value = interpreter.visit(cst); - return { - value: value, - lexResult: lexResult, - parseErrors: parser.errors, - }; -} - -export const evaluate = async (ast: RequestAST, - args: Map): Promise => { - if(ast.kind == RequestKind.Default) { - let error: any = null; - const r = await axios.request({ - headers: {'Content-Type': 'application/json'}, - method: ast.method == RequestMethod.Get ? "get" : "post", - url: ((args.get("connect") as string) || ""), - data: JSON.stringify(args.get("object")), - validateStatus: () => true - }).catch((e) => error = e); - const zenResult = error - ? { status: error.code, error: "" } - : { status: r.status, result: r.data || "" } - return { - kind: EvaluationResultKind.Success, - result: zenResult, - }; - } else { - // TODO: check type of urls, body, ... all data from zenroom - let dataFz = (_i: number) => {_i; return args.get("object"); } - if(ast.kind == RequestKind.Parallel || ast.kind == RequestKind.Sequential) { - dataFz = (i: number) => (args.get("object") as JsonableArray)[i] - } - const urls = args.get("connect") as string[] - const reqs_promises = [] - - if(ast.kind == RequestKind.Sequential) { - throw new Error("Not yet implemented") - } else { - for(let i = 0; i < urls.length; i++) { - reqs_promises.push(axios.request({ - method: ast.method == RequestMethod.Get ? "get" : "post", - url: urls[i] || "", - data: dataFz(i), - validateStatus: () => true, - })) - } - const results: JsonableArray = new Array(reqs_promises.length) - const errors: { [key: number]: any} = {}; - const parallel_with_catch = reqs_promises.map((v, i) => v.catch( - (e) => errors[i] = e - )) - const parallel_results = await axios.all(parallel_with_catch) - parallel_results.map((r, i) => { - - const zenResult = errors[i] - ? { "status": errors[i].code, "result": "" } - : { "status": r.status, "result": r.data || ""} - results[i] = zenResult; - }); - return { - kind: EvaluationResultKind.Success, - result: results, - }; - } - } -} - - -const serializedGrammar = parser.getSerializedGastProductions(); - -// create the HTML Text -const htmlText = createSyntaxDiagramsCode(serializedGrammar); - -// Write the HTML file to disk -fs.writeFileSync("./generated_diagrams_http.html", htmlText); - -class HttpPlugin extends Plugin { - evaluate(phrase: string): Promise | EvaluationResult { - const ast = astify(phrase) - const paramsSpec: Map = new Map() - if(ast.parseErrors.length > 0) { - return { - kind: EvaluationResultKind.Failure, - error: ast.parseErrors - } - } - - paramsSpec.set("connect", true) - if(ast.value.kind == RequestKind.Parallel || - ast.value.kind == RequestKind.Sequential) { - paramsSpec.set("object", true) - } else { - paramsSpec.set("object", false) - } - - const args = this.buildParams(paramsSpec) - - return evaluate(ast.value, args) - } -} - -export default new HttpPlugin(); +export * from '@slangroom/http/tokens'; +export * from '@slangroom/http/lexer'; +export * from '@slangroom/http/parser'; +export * from '@slangroom/http/visitor'; +export * from '@slangroom/http/plugins'; diff --git a/pkg/http/src/lexer.ts b/pkg/http/src/lexer.ts new file mode 100644 index 00000000..18b9e597 --- /dev/null +++ b/pkg/http/src/lexer.ts @@ -0,0 +1,5 @@ +import { Lexer as L } from '@slangroom/deps/chevrotain'; +import { allTokens } from '@slangroom/http/tokens'; + +const Lexer = new L(allTokens); +export const lex = (line: string) => Lexer.tokenize(line); diff --git a/pkg/http/src/parser.ts b/pkg/http/src/parser.ts new file mode 100644 index 00000000..dad4c572 --- /dev/null +++ b/pkg/http/src/parser.ts @@ -0,0 +1,63 @@ +import { + CstParser, + type IToken, + type CstNode, + createSyntaxDiagramsCode, +} from '@slangroom/deps/chevrotain'; +import { allTokens, Do, Get, Post, Sequential, Parallel, Same } from '@slangroom/http'; +import fs from 'node:fs'; + +export type PhraseCst = CstNode & { + children: { + kind: KindCst; + method: MethodCst; + }; +}; + +export type KindCst = CstNode & { + children: { Sequential: [IToken] } | { Parallel: [IToken] } | { Same: [IToken] }; +}; + +export type MethodCst = CstNode & { + children: { Get: [IToken] } | { Post: [IToken] }; +}; + +const Parser = new (class extends CstParser { + constructor() { + super(allTokens); + this.performSelfAnalysis(); + } + + phrase = this.RULE('phrase', () => { + this.CONSUME(Do); + this.OPTION(() => this.SUBRULE(this.#kind)); + this.SUBRULE(this.#method); + }); + + #method = this.RULE('method', () => { + this.OR([{ ALT: () => this.CONSUME(Get) }, { ALT: () => this.CONSUME(Post) }]); + }); + + #kind = this.RULE('kind', () => { + this.OR([ + { ALT: () => this.CONSUME(Sequential) }, + { ALT: () => this.CONSUME(Parallel) }, + { ALT: () => this.CONSUME(Same) }, + ]); + }); +})(); + +export const CstVisitor = Parser.getBaseCstVisitorConstructor(); + +export const parse = (tokens: IToken[]) => { + Parser.input = tokens; + return { + cst: Parser.phrase(), + errors: Parser.errors, + }; +}; + +// TODO: get rid of these lines: +export const SerializedGrammar = Parser.getSerializedGastProductions(); +const htmlText = createSyntaxDiagramsCode(SerializedGrammar); +fs.writeFileSync('./generated_diagrams_http.html', htmlText); diff --git a/pkg/http/src/plugins.ts b/pkg/http/src/plugins.ts new file mode 100644 index 00000000..843da15b --- /dev/null +++ b/pkg/http/src/plugins.ts @@ -0,0 +1,86 @@ +import { JsonableArray } from '@slangroom/shared'; +import type { PluginContext, PluginResult } from '@slangroom/core'; +import { lex, parse, visit, RequestKind, RequestMethod, type PhraseCst } from '@slangroom/http'; +import axios from 'axios'; + +/** + * The default timeout of an HTTP request in milliseconds. + */ +export const DefaultTimeoutMs = 5000; + +const { request } = axios.create({ + headers: { 'Content-Type': 'application/json' }, + validateStatus: null, + timeout: DefaultTimeoutMs, +}); + +/** + * @internal + */ +export const astify = (text: string) => { + const lexed = lex(text); + if (lexed.errors.length) return { errors: lexed.errors }; + + const parsed = parse(lexed.tokens); + if (parsed.errors.length) return { errors: parsed.errors }; + + return { ast: visit(parsed.cst as PhraseCst) }; +}; + +/** + * @internal + */ +export const execute = async ( + ctx: PluginContext, + kind: RequestKind, + method: RequestMethod +): Promise => { + const url = ctx.fetchConnect()[0]; + if (kind === RequestKind.Default) { + let error: any = null; + const req = await request({ + url: url, + method: method, + data: ctx.get('object'), + }).catch((e) => (error = e)); + const zenResult = error + ? { status: error.code, error: '' } + : { status: req.status, result: req.data || '' }; + return ctx.pass(zenResult); + } else if (kind === RequestKind.Sequential) { + throw new Error('Not yet implemented'); + } else { + const reqs = []; + const urls = ctx.fetchConnect(); + if (kind === RequestKind.Parallel) { + // TODO: check type of body (needs to be JsonableArray of + // JsonableObject) + const objects = ctx.fetch('object') as JsonableArray; + for (const [i, u] of urls.entries()) + reqs.push(request({ url: u, method: method, data: objects[i] })); + } else { + // TODO: check type of body (needs to be JsonableObject) + const object = ctx.fetch('object') as JsonableArray; + for (const u of urls) reqs.push(request({ url: u, method: method, data: object })); + } + const results: JsonableArray = new Array(reqs.length); + const errors: { [key: number]: any } = {}; + const parallelWithCatch = reqs.map((v, i) => v.catch((e) => (errors[i] = e))); + const parallelResults = await axios.all(parallelWithCatch); + parallelResults.map((r, i) => { + const zenResult = errors[i] + ? { status: errors[i].code, result: '' } + : { status: r.status, result: r.data || '' }; + results[i] = zenResult; + }); + return ctx.pass(results); + } +}; + +const HttpPlugin = async (ctx: PluginContext): Promise => { + const { ast, errors } = astify(ctx.phrase); + if (!ast) return ctx.fail(errors); + return await execute(ctx, ast.kind, ast.method); +}; + +export const httpPlugins = new Set([HttpPlugin]); diff --git a/pkg/http/src/tokens.ts b/pkg/http/src/tokens.ts new file mode 100644 index 00000000..38737d77 --- /dev/null +++ b/pkg/http/src/tokens.ts @@ -0,0 +1,34 @@ +import { createToken } from '@slangroom/deps/chevrotain'; +import { Whitespace } from '@slangroom/shared'; + +export const Get = createToken({ + name: 'Get', + pattern: /get/i, +}); + +export const Post = createToken({ + name: 'Post', + pattern: /post/i, +}); + +export const Do = createToken({ + name: 'Do', + pattern: /do/i, +}); + +export const Parallel = createToken({ + name: 'Parallel', + pattern: /parallel/i, +}); + +export const Same = createToken({ + name: 'Same', + pattern: /same/i, +}); + +export const Sequential = createToken({ + name: 'Sequential', + pattern: /sequential/i, +}); + +export const allTokens = [Whitespace, Get, Post, Parallel, Sequential, Same, Do]; diff --git a/pkg/http/src/visitor.ts b/pkg/http/src/visitor.ts new file mode 100644 index 00000000..22135bff --- /dev/null +++ b/pkg/http/src/visitor.ts @@ -0,0 +1,56 @@ +import { CstVisitor, type KindCst, type MethodCst, type PhraseCst } from '@slangroom/http'; + +export type RequestAst = { + method: RequestMethod; + kind: RequestKind; +}; + +export enum RequestMethod { + Get = 'get', + Post = 'post', +} + +export enum RequestKind { + Default, + Parallel, + Sequential, + Same, +} + +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions +interface V { + visit(cst: PhraseCst): ReturnType; + visit(cst: KindCst): ReturnType; + visit(cst: MethodCst): ReturnType; +} + +class V extends CstVisitor { + constructor() { + super(); + this.validateVisitor(); + } + + phrase(ctx: PhraseCst['children']): RequestAst { + return { + method: this.visit(ctx.method), + kind: ctx.kind ? this.visit(ctx.kind) : RequestKind.Default, + }; + } + + kind(ctx: KindCst['children']): RequestKind { + if (ctx.Sequential) return RequestKind.Sequential; + if (ctx.Parallel) return RequestKind.Parallel; + if (ctx.Same) return RequestKind.Same; + throw new Error('Should not be here: unknown request kind'); + } + + method(ctx: MethodCst['children']): RequestMethod { + if (ctx.Post) return RequestMethod.Post; + if (ctx.Get) return RequestMethod.Get; + throw new Error('Should not be here: unknown request method'); + } +} + +const Visitor = new V(); + +export const visit = (cst: PhraseCst): RequestAst => Visitor.visit(cst); diff --git a/pkg/http/test/e2e.ts b/pkg/http/test/e2e.ts index 722c272e..c314555f 100644 --- a/pkg/http/test/e2e.ts +++ b/pkg/http/test/e2e.ts @@ -1,37 +1,22 @@ import test from 'ava'; -import express from "express"; -import bodyParser from "body-parser"; -import { Slangroom } from "@slangroom/core/slangroom" -import httpPlugin from "@slangroom/http" +import nock from 'nock'; +import { Slangroom } from '@slangroom/core/slangroom'; +import { httpPlugins } from '@slangroom/http'; -test.before(async () => { - const app = express(); - app.use(bodyParser.json()); - app.get("/greeting-es", (_req: any, res: any) => { - res.status(200).send({req: "Hola chico!"}); - }); - app.get("/greeting-en", (_req: any, res: any) => { - res.status(200).send({req: "Hi!"}); - }); - app.post("/sendresult", (req: any, res: any) => { - try { - if (req.body.req.includes("Hola")) { - res.status(200).send("received result"); - } else if (req.body.req.includes("Hi")) { - res.status(200).send("received result"); - } else { - res.status(500).send("Did not receive the result"); - } - } catch { - res - .status(505) - .send("Something is wrong with the result sent by zenroom"); - } - }); - app.listen(3021, () => console.log("Server up and running on ")); -}); +nock('http://localhost') + .get('/greeting-es') + .reply(200, { req: 'Hola chico!' }) + .get('/greeting-en') + .reply(200, { req: 'Hi!' }) + .post('/sendresult') + .reply((_, body: any) => { + const req = body['req']; + if (req?.includes('Hola') || req?.includes('Hi')) return [200, 'received result']; + return [500, 'Did not receive the result']; + }) + .persist(); -test("Full script that uses http plugin", async (t) => { +test('Full script that uses http plugin', async (t) => { const script = ` Rule caller restroom-mw Given I connect to 'greeting_es' and do get and output into 'es' @@ -49,25 +34,25 @@ When I move 'result_es' in 'string array' When I move 'result_en' in 'string array' Then print data Then I connect to 'final_endpoints' and send object 'string_array' and do parallel post and output into 'results' -` - const slangroom = new Slangroom(httpPlugin); - const res = await slangroom.execute(script, {data: { - greeting_es: "http://localhost:3021/greeting-es", - greeting_en: "http://localhost:3021/greeting-en", - final_endpoints: [ - "http://localhost:3021/sendresult", - "http://localhost:3021/sendresult", - ] - }}) - t.deepEqual(res.result, { - final_endpoints: [ - 'http://localhost:3021/sendresult', - 'http://localhost:3021/sendresult' - ], - string_array: [ { req: 'Hola chico!' }, { req: 'Hi!' } ], - results: [ - { status: 200, result: 'received result' }, - { status: 200, result: 'received result' } - ] - }, res.logs) -}) +`; + const slangroom = new Slangroom(httpPlugins); + const res = await slangroom.execute(script, { + data: { + greeting_es: 'http://localhost/greeting-es', + greeting_en: 'http://localhost/greeting-en', + final_endpoints: ['http://localhost/sendresult', 'http://localhost/sendresult'], + }, + }); + t.deepEqual( + res.result, + { + final_endpoints: ['http://localhost/sendresult', 'http://localhost/sendresult'], + string_array: [{ req: 'Hola chico!' }, { req: 'Hi!' }], + results: [ + { status: 200, result: 'received result' }, + { status: 200, result: 'received result' }, + ], + }, + res.logs + ); +}); diff --git a/pkg/http/test/index.ts b/pkg/http/test/index.ts deleted file mode 100644 index 0fa2cb96..00000000 --- a/pkg/http/test/index.ts +++ /dev/null @@ -1,170 +0,0 @@ -import test from 'ava'; -import express from "express"; -import bodyParser from "body-parser"; -import { EvaluationResultKind } from "@slangroom/core/plugin" -import { Jsonable } from "@slangroom/shared/jsonable" - -import { - astify, - evaluate, - RequestKind, - RequestMethod, -} from '@slangroom/http'; - -test.before(async () => { - const app = express(); - app.use(bodyParser.json()); - app.get("/normaljson", (_req: any, res: any) => { - const responsejson = { - userId: 1, - myArray: [1, 2, 3, 4, 5], - myStringArary: ["one", "two", "three"], - myJson: { - 1: "First property", - 2: 123, - // "3": true - }, - }; - res.status(200).send(responsejson); - }); - app.get("/booleanjson", (_req: any, res: any) => { - const responsejson = { - userId: 1, - myJson: { - 1: "First property", - 2: 123, - 3: true, - }, - }; - res.status(200).send(responsejson); - }); - app.post("/sendresult", (req: any, res: any) => { - try { - if (Object.keys(req.body).includes("myData")) { - res.status(200).send("received result"); - } else { - res.status(500).send("Did not receive the result"); - } - } catch { - res - .status(505) - .send("Something is wrong with the result sent by zenroom"); - } - }); - app.get("/storeoutput", (_req: any, res: any) => { - const output = { - mySharedSecret: [{ - x: "b6J49SRdmJ3xKSbm4/m1MnE4q4k9PV3QfGmJaXxzSqc=", - y: "CX25HWpn7wNVbii04JJzUuLGg3iV98RdfexlimnYy4s=", - }, - { - x: "r2c5Oqnv3nFDLxeji+t+VHyCbZIqwkPHIINS5e/XZms=", - y: "toxNY+pjSpHAwYb+XaecxrWn0JsI+QcHeJHcl1bxYSk=", - }, - { - x: "S5XL4Eccy5g9wfyYdzz814cQ+50sAK/n+UuqekJUdPQ=", - y: "MdH2wEsqwq2XtjSoK4oZdmM4FsbcR/3ByOsv0CWc90E=", - }, - { - x: "cE7y3I+33bf0Do+hpcoQeQKALKTsalAWOCke1+pYuAE=", - y: "UAmR+N61zlJKwW6KyoTXwf+4Z3raeWt4Gbax0lQFqME=", - }, - ], - }; - res.status(200).send(output); - }); - app.listen(3020, () => console.log("Server up and running on ")); -}); - -test("Simple GET", async (t) => { - const ast = astify("do get"); - t.deepEqual(ast.value, { method: RequestMethod.Get, kind: RequestKind.Default }) - const res = await evaluate(ast.value, new Map([["connect", "http://localhost:3020/normaljson"]])) - t.deepEqual(res, { - kind: EvaluationResultKind.Success, - result:{ - status: 200, - result:{ - userId: 1, - myArray: [1,2,3,4,5], - myStringArary: ["one","two","three"], - myJson: { - 1:"First property", - 2:123 - } - } - } - }) -}) -test("POST with data", async (t) => { - const ast = astify("do post"); - t.deepEqual(ast.value, { method: RequestMethod.Post, kind: RequestKind.Default }) - - const res = await evaluate(ast.value, new Map([["connect", "http://localhost:3020/sendresult"], ["object", {myData: "foobar"}]])) - - t.deepEqual(res, { - kind: EvaluationResultKind.Success, - result: {status: 200, result: "received result"}, - }) -}) -test("POSTs with data", async (t) => { - const ast = astify("do same post"); - t.deepEqual(ast.value, { method: RequestMethod.Post, kind: RequestKind.Same}) - - const res = await evaluate(ast.value, new Map([["connect", ["http://localhost:3020/sendresult", "http://localhost:3020/normaljson"]], ["object", {myData: "foobar"}]])) - t.deepEqual(res, { - kind: EvaluationResultKind.Success, - result: [ - { status: 200, result: 'received result' }, - { - status: 404, - result: '\n' + - '\n' + - '\n' + - '\n' + - 'Error\n' + - '\n' + - '\n' + - '
Cannot POST /normaljson
\n' + - '\n' + - '\n' - } - ] - - }) -}) -test("POSTs with custom different", async (t) => { - const ast = astify("do parallel post"); - - t.deepEqual(ast.value, { method: RequestMethod.Post, kind: RequestKind.Parallel }) - - const res = await evaluate(ast.value, - new Map([ - ["object", [{myData: "foobar"},{myData: "foobar"},{mData: "foobar"}]], - ["connect", [ - "http://localhost:3020/sendresult", - "http://localhost:3020/normaljson", - "http://localhost:3020/sendresult" - ]]])) - - t.deepEqual(res, { - kind: EvaluationResultKind.Success, - result: [ - { status: 200, result: 'received result' }, - { - status: 404, - result: '\n' + - '\n' + - '\n' + - '\n' + - 'Error\n' + - '\n' + - '\n' + - '
Cannot POST /normaljson
\n' + - '\n' + - '\n' - }, - { result: 'Did not receive the result', status: 500 }, - ] - }) -}) diff --git a/pkg/http/test/plugins.ts b/pkg/http/test/plugins.ts new file mode 100644 index 00000000..a15003a7 --- /dev/null +++ b/pkg/http/test/plugins.ts @@ -0,0 +1,126 @@ +import test from 'ava'; +import { PluginContextTest } from '@slangroom/core'; +import { astify, execute } from '@slangroom/http'; +import nock from 'nock'; + +nock('http://localhost') + .post('/normaljson') + .reply(404, "doesn't exist, mate") + .get('/normaljson') + .reply(200, { + userId: 1, + myArray: [1, 2, 3, 4, 5], + myStringArary: ['one', 'two', 'three'], + myJson: { + 1: 'First property', + 2: 123, + // "3": true + }, + }) + .get('/booleanjson') + .reply(200, { + userId: 1, + myJson: { + 1: 'First property', + 2: 123, + 3: true, + }, + }) + .post('/sendresult') + .reply((_, body: any) => { + if (body['myData']) return [200, 'received result']; + return [500, 'Did not receive the result']; + }) + .persist(); + +test('Simple GET', async (t) => { + const { ast } = astify('do get'); + if (!ast) { + t.fail(); + return; + } + + const ctx = PluginContextTest.connect('http://localhost/normaljson'); + const res = await execute(ctx, ast.kind, ast.method); + t.deepEqual(res, { + ok: true, + value: { + status: 200, + result: { + userId: 1, + myArray: [1, 2, 3, 4, 5], + myStringArary: ['one', 'two', 'three'], + myJson: { + 1: 'First property', + 2: 123, + }, + }, + }, + }); +}); + +test('single post with data', async (t) => { + const { ast } = astify('do post'); + if (!ast) { + t.fail(); + return; + } + + const ctx = new PluginContextTest('http://localhost/sendresult', { + object: { myData: 'foobar' }, + }); + const res = await execute(ctx, ast.kind, ast.method); + t.deepEqual(res, { + ok: true, + value: { status: 200, result: 'received result' }, + }); +}); + +test('multiple post with data', async (t) => { + const { ast } = astify('do same post'); + if (!ast) { + t.fail(); + return; + } + + const ctx = new PluginContextTest( + ['http://localhost/sendresult', 'http://localhost/normaljson'], + { + object: { myData: 'foobar' }, + } + ); + const res = await execute(ctx, ast.kind, ast.method); + t.deepEqual(res, { + ok: true, + value: [ + { status: 200, result: 'received result' }, + { status: 404, result: "doesn't exist, mate" }, + ], + }); +}); + +test('POSTs with custom different', async (t) => { + const { ast } = astify('do parallel post'); + if (!ast) { + t.fail(); + return; + } + + const ctx = new PluginContextTest( + [ + 'http://localhost/sendresult', + 'http://localhost/normaljson', + 'http://localhost/sendresult', + ], + { object: [{ myData: 'foobar' }, { myData: 'foobar' }, { mData: 'foobar' }] } + ); + const res = await execute(ctx, ast.kind, ast.method); + t.deepEqual(res, { + ok: true, + value: [ + { status: 200, result: 'received result' }, + { status: 404, result: "doesn't exist, mate" }, + { status: 500, result: 'Did not receive the result' }, + ], + }); +}); diff --git a/pkg/http/test/visitor.ts b/pkg/http/test/visitor.ts new file mode 100644 index 00000000..732c088e --- /dev/null +++ b/pkg/http/test/visitor.ts @@ -0,0 +1,21 @@ +import test from 'ava'; +import { lex, parse, type PhraseCst, RequestKind, RequestMethod, visit } from '@slangroom/http'; + +const astify = (line: string) => { + const { tokens } = lex(line); + const { cst } = parse(tokens); + return visit(cst as PhraseCst); +}; + +test('ast is okay', async (t) => { + const cases = { + 'do get ': { method: RequestMethod.Get, kind: RequestKind.Default }, + ' do post': { method: RequestMethod.Post, kind: RequestKind.Default }, + 'do same post': { method: RequestMethod.Post, kind: RequestKind.Same }, + ' do parallel post ': { method: RequestMethod.Post, kind: RequestKind.Parallel }, + }; + for (const [line, astWant] of Object.entries(cases)) { + const astHave = astify(line); + t.deepEqual(astHave, astWant); + } +}); diff --git a/pkg/ignored/src/index.ts b/pkg/ignored/src/index.ts index d8bbf450..d649cb43 100644 --- a/pkg/ignored/src/index.ts +++ b/pkg/ignored/src/index.ts @@ -1,6 +1,6 @@ import { Lexer } from '@slangroom/deps/chevrotain'; import { vocab } from '@slangroom/ignored/tokens'; -import { zencodeExec, type ZenroomParams } from '@slangroom/shared'; +import { zencodeExec, type ZenParams } from '@slangroom/shared'; const IgnoredLexer = new Lexer(vocab); @@ -16,7 +16,7 @@ const IgnoredLexer = new Lexer(vocab); */ export const getIgnoredStatements = async ( contract: string, - params?: ZenroomParams + params: ZenParams ): Promise => { // Since we want to get the list of ignored statements, we don't want to // throw if Zenroom execution fails (but we do fail if something other than @@ -29,7 +29,7 @@ export const getIgnoredStatements = async ( const zout = await zencodeExec(contract, params); logs = zout.logs; } catch (e) { - // Currently, only ZenroomError is available. + // Currently, only ZenError is available. // Normally, I'd let this code be, but we're trying to achieve 100% // coverage, so my "future-proof" code needs to be commented out here. // if (!(e instanceof ZenroomError)) diff --git a/pkg/ignored/test/index.ts b/pkg/ignored/test/index.ts index 84bbdfa5..b2820e70 100644 --- a/pkg/ignored/test/index.ts +++ b/pkg/ignored/test/index.ts @@ -17,7 +17,7 @@ When I write string 'test passed' in 'result' Then print the data `; // When I get the unknown statements - const ignoreds = await getIgnoredStatements(contract); + const ignoreds = await getIgnoredStatements(contract, { data: {}, keys: {} }); // Then it must be the given unknown statements t.deepEqual(ignoreds, uknowns); }); @@ -82,7 +82,7 @@ Then print the 'outputData.signature' }, }; // When I get the ignored statements - const ignoreds = await getIgnoredStatements(contract, { data: data }); + const ignoreds = await getIgnoredStatements(contract, { data: data, keys: {} }); // Then it must be equal to the statements of restroom t.deepEqual(ignoreds, [ "Given that I have an endpoint named 'endpoint'", diff --git a/pkg/shared/src/tokens.ts b/pkg/shared/src/tokens.ts index ed785aad..88da2dc9 100644 --- a/pkg/shared/src/tokens.ts +++ b/pkg/shared/src/tokens.ts @@ -19,70 +19,3 @@ export const Comment = createToken({ pattern: /#[^\n\r]*/, group: 'comments', }); - -/** - * The most selfish constants of all. The evilful. - * - * Unlike other statements, this must be case-sensitive. - */ -export const I = createToken({ - name: 'I', - pattern: /I/, -}); - -/** - * The statement that follows one of Given, When, or Then. - * - * It can optionally followed by itself, but the top of the list must be one of - * Given, When, or Then. - * - * Custom statements MUST run the And statements according to the following - * Given, When, or Then. - */ -export const And = createToken({ - name: 'And', - pattern: /and/i, -}); - -/** - * The Given (initial) stage of Zenroom contracts. - * - * Custom statements MUST run before the actual execution. - */ -export const Given = createToken({ - name: 'Given', - pattern: /given/i, -}); - -/** - * The When (middle) stage of Zenroom contracts. - * - * Custom statements MUST run before the actual execution. - */ -export const When = createToken({ - name: 'When', - pattern: /when/i, -}); - -/** - * The Then (last) stage of Zenroom contracts. - * - * Custom statements MUST run AFTER the actual execution. - */ -export const Then = createToken({ - name: 'Then', - pattern: /then/i, -}); - -/** - * Identifiers in single quotes, such as 'foo' and 'bar'. - * - * Escaped characters '\b', '\f', '\n', '\r', '\t', and '\v' are also - * accepted. - * Unicode characters of the format '\uXXXX' (where X is a hexedecimal - * digit) are also accepted. - */ -export const Identifier = createToken({ - name: 'Identifier', - pattern: /'(?:[^\\']|\\(?:[bfnrtv'\\/]|u[0-9a-fA-F]{4}))*'/, -}); diff --git a/pkg/shared/src/zenroom.ts b/pkg/shared/src/zenroom.ts index d93699fe..290c674f 100644 --- a/pkg/shared/src/zenroom.ts +++ b/pkg/shared/src/zenroom.ts @@ -1,10 +1,10 @@ -import { JsonableObject } from './jsonable.js'; +import type { JsonableObject } from '@slangroom/shared'; import { zencode_exec } from '@slangroom/deps/zenroom'; /** * Output of execution of a contract in Zenroom. */ -export type ZenroomOutput = { +export type ZenOutput = { result: JsonableObject; logs: string; }; @@ -14,7 +14,7 @@ export type ZenroomOutput = { * * The [message] contains the logs. */ -export class ZenroomError extends Error { +export class ZenError extends Error { constructor(logs: string) { super(logs); this.name = 'ZenroomError'; @@ -22,37 +22,16 @@ export class ZenroomError extends Error { } /** - * Zenroom parameters suitable for zencode_exec() (after each value's - * been piped to JSON.stringify()). + * Zenroom parameters suitable for [[zencode_exec]] (after the values of data + * and keys have been piped to [[JSON.stringify]]) */ -export type ZenroomParams = { data?: JsonableObject; keys?: JsonableObject }; +export type ZenParams = { data: JsonableObject; keys: JsonableObject }; -/** - * Like ZenroomParams, but each value's been piped into JSON.stringify(). - * - * Also, the keys are readonly since it makes little sense to mutate - * them after they're converted to JSON strings. - */ -export type ZenroomStringParams = { readonly [K in keyof ZenroomParams]?: string }; - -/** - * A utility that converts each value in ZenroomParams to a JSON string - * if possible. - * - * @param params is the ZenroomParams to be. - * @returns params with each value converted to a JSON string, or - * undefined if params' values are null or undefined. - */ -export const convZenParams = (params?: ZenroomParams): ZenroomStringParams => { - // We remove readonly here, and at the end, we put it back due to - // the return type. - const ret: { -readonly [k in keyof ZenroomStringParams]: ZenroomStringParams[k] } = {}; - for (const k in params) { - if (k == 'data' || k == 'keys') { - if (params[k]) ret[k] = JSON.stringify(params[k]); - } - } - return ret; +const stringify = (params: ZenParams) => { + return { + data: JSON.stringify(params.data), + keys: JSON.stringify(params.keys), + }; }; /** @@ -63,15 +42,12 @@ export const convZenParams = (params?: ZenroomParams): ZenroomStringParams => { * @returns the output of Zenroom. * @throws {ZenroomError} if execution of a contract fails. */ -export const zencodeExec = async ( - contract: string, - params?: ZenroomParams -): Promise => { +export const zencodeExec = async (contract: string, params: ZenParams): Promise => { let tmp: { result: string; logs: string }; try { - tmp = await zencode_exec(contract, convZenParams(params)); + tmp = await zencode_exec(contract, stringify(params)); } catch (e) { - throw new ZenroomError(e.logs); + throw new ZenError(e.logs); } // Due to the try-catch above, it is ensured that [tmp.result] is a JSON // string, whoose top-level value is a JSON Object. Thus, return's [result] diff --git a/pkg/shared/test/zenroom.ts b/pkg/shared/test/zenroom.ts index b6e77462..fb95e889 100644 --- a/pkg/shared/test/zenroom.ts +++ b/pkg/shared/test/zenroom.ts @@ -1,67 +1,16 @@ import test from 'ava'; -import { convZenParams, zencodeExec, ZenroomError } from '@slangroom/shared/zenroom'; - -test('convZenParams() works', (t) => { - // Since TS already covers our butts regarding type checks, we just - // need to convice the coverage here that all the code paths are - // taken. - - // Given I have a valid "data" and "keys" value - const data = { "doesn't really": 'matter' }; - const keys = { "doesn't": 'really matter' }; - - { - // When I provide an undefined params - const result = convZenParams(undefined); - // Then the result must be an empty object - t.deepEqual(result, {}); - } - - { - // When I provide empty params - const result = convZenParams({}); - // Then the result must be an empty object - t.deepEqual(result, {}); - } - - { - // When I provide only the "" - const result = convZenParams({ data: data }); - // Then the result must be JSON.strigify()'d "data" - t.deepEqual(result, { data: JSON.stringify(data) }); - } - - { - // When I provide only the "keys" - const result = convZenParams({ keys: keys }); - // Then the result must be JSON.strigify()'d "keys" - t.deepEqual(result, { keys: JSON.stringify(keys) }); - } - - { - // When I provide both the "data" and "keys" - const result = convZenParams({ data: data, keys: keys }); - // Then the result must be JSON.strigify()'d "keys" - t.deepEqual(result, { data: JSON.stringify(data), keys: JSON.stringify(keys) }); - } -}); +import { zencodeExec, ZenError } from '@slangroom/shared'; test("zencodeExec(): doesn't throw with valid input", async (t) => { - // Given I have a valid contract const contract = `Given I have nothing Then I print the string 'I love you' `; - // When I execute the contract - const { result } = await zencodeExec(contract); - // Then it must have a result, thus it's not an error + const { result } = await zencodeExec(contract, { data: {}, keys: {} }); t.deepEqual(result, { output: ['I_love_you'] }); }); test('zencodeExec(): throws with invalid input', async (t) => { - // Given I have an invalid contract const contract = "I'm invalid."; - // When I execute the contract - const promise = zencodeExec(contract); - // Then it must throw some errors - await t.throwsAsync(promise, { instanceOf: ZenroomError }); + const promise = zencodeExec(contract, { data: {}, keys: {} }); + await t.throwsAsync(promise, { instanceOf: ZenError }); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 384a1a8a..f1dcdeea 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: '6.1' +lockfileVersion: '6.0' settings: autoInstallPeers: true @@ -8,12 +8,6 @@ importers: .: devDependencies: - '@types/body-parser': - specifier: ^1.19.3 - version: 1.19.3 - '@types/express': - specifier: ^4.17.18 - version: 4.17.18 '@types/node': specifier: ^20.3.1 version: 20.3.1 @@ -26,9 +20,6 @@ importers: ava: specifier: ^5.3.1 version: 5.3.1 - body-parser: - specifier: ^1.20.2 - version: 1.20.2 c8: specifier: ^8.0.1 version: 8.0.1 @@ -41,9 +32,9 @@ importers: eslint-config-prettier: specifier: ^8.8.0 version: 8.8.0(eslint@8.43.0) - express: - specifier: ^4.18.2 - version: 4.18.2 + nock: + specifier: ^13.3.3 + version: 13.3.3 prettier: specifier: ^2.8.8 version: 2.8.8 @@ -84,21 +75,6 @@ importers: specifier: ^3.10.0 version: 3.10.0 - pkg/ethereum: - dependencies: - '@slangroom/core': - specifier: workspace:* - version: link:../core - '@slangroom/deps': - specifier: workspace:* - version: link:../deps - '@slangroom/shared': - specifier: workspace:* - version: link:../shared - web3: - specifier: ^4.1.2 - version: 4.1.2 - pkg/http: dependencies: '@slangroom/core': @@ -131,10 +107,6 @@ importers: packages: - /@adraffy/ens-normalize@1.10.0: - resolution: {integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==} - dev: false - /@bcoe/v8-coverage@0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true @@ -404,171 +376,6 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@ethereumjs/rlp@4.0.1: - resolution: {integrity: sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==} - engines: {node: '>=14'} - hasBin: true - dev: false - - /@ethersproject/abi@5.7.0: - resolution: {integrity: sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==} - dependencies: - '@ethersproject/address': 5.7.0 - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/constants': 5.7.0 - '@ethersproject/hash': 5.7.0 - '@ethersproject/keccak256': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/properties': 5.7.0 - '@ethersproject/strings': 5.7.0 - dev: false - - /@ethersproject/abstract-provider@5.7.0: - resolution: {integrity: sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==} - dependencies: - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/networks': 5.7.1 - '@ethersproject/properties': 5.7.0 - '@ethersproject/transactions': 5.7.0 - '@ethersproject/web': 5.7.1 - dev: false - - /@ethersproject/abstract-signer@5.7.0: - resolution: {integrity: sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==} - dependencies: - '@ethersproject/abstract-provider': 5.7.0 - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/properties': 5.7.0 - dev: false - - /@ethersproject/address@5.7.0: - resolution: {integrity: sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==} - dependencies: - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/keccak256': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/rlp': 5.7.0 - dev: false - - /@ethersproject/base64@5.7.0: - resolution: {integrity: sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==} - dependencies: - '@ethersproject/bytes': 5.7.0 - dev: false - - /@ethersproject/bignumber@5.7.0: - resolution: {integrity: sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==} - dependencies: - '@ethersproject/bytes': 5.7.0 - '@ethersproject/logger': 5.7.0 - bn.js: 5.2.1 - dev: false - - /@ethersproject/bytes@5.7.0: - resolution: {integrity: sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==} - dependencies: - '@ethersproject/logger': 5.7.0 - dev: false - - /@ethersproject/constants@5.7.0: - resolution: {integrity: sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==} - dependencies: - '@ethersproject/bignumber': 5.7.0 - dev: false - - /@ethersproject/hash@5.7.0: - resolution: {integrity: sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==} - dependencies: - '@ethersproject/abstract-signer': 5.7.0 - '@ethersproject/address': 5.7.0 - '@ethersproject/base64': 5.7.0 - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/keccak256': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/properties': 5.7.0 - '@ethersproject/strings': 5.7.0 - dev: false - - /@ethersproject/keccak256@5.7.0: - resolution: {integrity: sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==} - dependencies: - '@ethersproject/bytes': 5.7.0 - js-sha3: 0.8.0 - dev: false - - /@ethersproject/logger@5.7.0: - resolution: {integrity: sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==} - dev: false - - /@ethersproject/networks@5.7.1: - resolution: {integrity: sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==} - dependencies: - '@ethersproject/logger': 5.7.0 - dev: false - - /@ethersproject/properties@5.7.0: - resolution: {integrity: sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==} - dependencies: - '@ethersproject/logger': 5.7.0 - dev: false - - /@ethersproject/rlp@5.7.0: - resolution: {integrity: sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==} - dependencies: - '@ethersproject/bytes': 5.7.0 - '@ethersproject/logger': 5.7.0 - dev: false - - /@ethersproject/signing-key@5.7.0: - resolution: {integrity: sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==} - dependencies: - '@ethersproject/bytes': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/properties': 5.7.0 - bn.js: 5.2.1 - elliptic: 6.5.4 - hash.js: 1.1.7 - dev: false - - /@ethersproject/strings@5.7.0: - resolution: {integrity: sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==} - dependencies: - '@ethersproject/bytes': 5.7.0 - '@ethersproject/constants': 5.7.0 - '@ethersproject/logger': 5.7.0 - dev: false - - /@ethersproject/transactions@5.7.0: - resolution: {integrity: sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==} - dependencies: - '@ethersproject/address': 5.7.0 - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/constants': 5.7.0 - '@ethersproject/keccak256': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/properties': 5.7.0 - '@ethersproject/rlp': 5.7.0 - '@ethersproject/signing-key': 5.7.0 - dev: false - - /@ethersproject/web@5.7.1: - resolution: {integrity: sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==} - dependencies: - '@ethersproject/base64': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/properties': 5.7.0 - '@ethersproject/strings': 5.7.0 - dev: false - /@humanwhocodes/config-array@0.11.10: resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==} engines: {node: '>=10.10.0'} @@ -626,17 +433,6 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true - /@noble/curves@1.1.0: - resolution: {integrity: sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==} - dependencies: - '@noble/hashes': 1.3.1 - dev: false - - /@noble/hashes@1.3.1: - resolution: {integrity: sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==} - engines: {node: '>= 16'} - dev: false - /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -658,25 +454,6 @@ packages: fastq: 1.15.0 dev: true - /@scure/base@1.1.3: - resolution: {integrity: sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==} - dev: false - - /@scure/bip32@1.3.1: - resolution: {integrity: sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==} - dependencies: - '@noble/curves': 1.1.0 - '@noble/hashes': 1.3.1 - '@scure/base': 1.1.3 - dev: false - - /@scure/bip39@1.2.1: - resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==} - dependencies: - '@noble/hashes': 1.3.1 - '@scure/base': 1.1.3 - dev: false - /@tsconfig/node10@1.0.9: resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} dev: true @@ -693,41 +470,6 @@ packages: resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} dev: true - /@types/body-parser@1.19.3: - resolution: {integrity: sha512-oyl4jvAfTGX9Bt6Or4H9ni1Z447/tQuxnZsytsCaExKlmJiU8sFgnIBRzJUpKwB5eWn9HuBYlUlVA74q/yN0eQ==} - dependencies: - '@types/connect': 3.4.36 - '@types/node': 20.3.1 - dev: true - - /@types/connect@3.4.36: - resolution: {integrity: sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==} - dependencies: - '@types/node': 20.3.1 - dev: true - - /@types/express-serve-static-core@4.17.37: - resolution: {integrity: sha512-ZohaCYTgGFcOP7u6aJOhY9uIZQgZ2vxC2yWoArY+FeDXlqeH66ZVBjgvg+RLVAS/DWNq4Ap9ZXu1+SUQiiWYMg==} - dependencies: - '@types/node': 20.3.1 - '@types/qs': 6.9.8 - '@types/range-parser': 1.2.5 - '@types/send': 0.17.2 - dev: true - - /@types/express@4.17.18: - resolution: {integrity: sha512-Sxv8BSLLgsBYmcnGdGjjEjqET2U+AKAdCRODmMiq02FgjwuV75Ut85DRpvFjyw/Mk0vgUOliGRU0UUmuuZHByQ==} - dependencies: - '@types/body-parser': 1.19.3 - '@types/express-serve-static-core': 4.17.37 - '@types/qs': 6.9.8 - '@types/serve-static': 1.15.3 - dev: true - - /@types/http-errors@2.0.2: - resolution: {integrity: sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg==} - dev: true - /@types/istanbul-lib-coverage@2.0.4: resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} dev: true @@ -736,50 +478,14 @@ packages: resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} dev: true - /@types/mime@1.3.3: - resolution: {integrity: sha512-Ys+/St+2VF4+xuY6+kDIXGxbNRO0mesVg0bbxEfB97Od1Vjpjx9KD1qxs64Gcb3CWPirk9Xe+PT4YiiHQ9T+eg==} - dev: true - - /@types/mime@3.0.2: - resolution: {integrity: sha512-Wj+fqpTLtTbG7c0tH47dkahefpLKEbB+xAZuLq7b4/IDHPl/n6VoXcyUQ2bypFlbSwvCr0y+bD4euTTqTJsPxQ==} - dev: true - /@types/node@20.3.1: resolution: {integrity: sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==} - - /@types/qs@6.9.8: - resolution: {integrity: sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==} - dev: true - - /@types/range-parser@1.2.5: - resolution: {integrity: sha512-xrO9OoVPqFuYyR/loIHjnbvvyRZREYKLjxV4+dY6v3FQR3stQ9ZxIGkaclF7YhI9hfjpuTbu14hZEy94qKLtOA==} dev: true /@types/semver@7.5.0: resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} dev: true - /@types/send@0.17.2: - resolution: {integrity: sha512-aAG6yRf6r0wQ29bkS+x97BIs64ZLxeE/ARwyS6wrldMm3C1MdKwCcnnEwMC1slI8wuxJOpiUH9MioC0A0i+GJw==} - dependencies: - '@types/mime': 1.3.3 - '@types/node': 20.3.1 - dev: true - - /@types/serve-static@1.15.3: - resolution: {integrity: sha512-yVRvFsEMrv7s0lGhzrggJjNOSmZCdgCjw9xWrPr/kNNLp6FaDfMC1KaYl3TSJ0c58bECwNBMoQrZJ8hA8E1eFg==} - dependencies: - '@types/http-errors': 2.0.2 - '@types/mime': 3.0.2 - '@types/node': 20.3.1 - dev: true - - /@types/ws@8.5.3: - resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==} - dependencies: - '@types/node': 20.3.1 - dev: false - /@typescript-eslint/eslint-plugin@5.59.11(@typescript-eslint/parser@5.59.11)(eslint@8.43.0)(typescript@4.9.5): resolution: {integrity: sha512-XxuOfTkCUiOSyBWIvHlUraLw/JT/6Io1365RO6ZuI88STKMavJZPNMU0lFcUTeQXEhHiv64CbxYxBNoDVSmghg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -910,14 +616,6 @@ packages: eslint-visitor-keys: 3.4.1 dev: true - /accepts@1.3.8: - resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} - engines: {node: '>= 0.6'} - dependencies: - mime-types: 2.1.35 - negotiator: 0.6.3 - dev: true - /acorn-jsx@5.3.2(acorn@8.9.0): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -1007,10 +705,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /array-flatten@1.1.1: - resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} - dev: true - /array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} @@ -1087,11 +781,6 @@ packages: - supports-color dev: true - /available-typed-arrays@1.0.5: - resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} - engines: {node: '>= 0.4'} - dev: false - /axios@1.5.1: resolution: {integrity: sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==} dependencies: @@ -1115,54 +804,6 @@ packages: resolution: {integrity: sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==} dev: true - /bn.js@4.12.0: - resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} - dev: false - - /bn.js@5.2.1: - resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} - dev: false - - /body-parser@1.20.1: - resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.11.0 - raw-body: 2.5.1 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /body-parser@1.20.2: - resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.11.0 - raw-body: 2.5.2 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - dev: true - /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -1183,15 +824,6 @@ packages: fill-range: 7.0.1 dev: true - /brorand@1.1.0: - resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} - dev: false - - /bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - dev: true - /c8@8.0.1: resolution: {integrity: sha512-EINpopxZNH1mETuI0DzRA4MZpAUH+IFiRhnmFD3vFr3vdrgxqi3VfE3KL0AIL+zDq8rC9bZqwM/VDmmoe04y7w==} engines: {node: '>=12'} @@ -1211,12 +843,6 @@ packages: yargs-parser: 21.1.1 dev: true - /call-bind@1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} - dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.2.1 - /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -1362,18 +988,6 @@ packages: well-known-symbols: 2.0.0 dev: true - /content-disposition@0.5.4: - resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} - engines: {node: '>= 0.6'} - dependencies: - safe-buffer: 5.2.1 - dev: true - - /content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - dev: true - /convert-source-map@1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} dev: true @@ -1383,33 +997,10 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: true - /cookie-signature@1.0.6: - resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - dev: true - - /cookie@0.5.0: - resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} - engines: {node: '>= 0.6'} - dev: true - - /crc-32@1.2.2: - resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} - engines: {node: '>=0.8'} - hasBin: true - dev: false - /create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} dev: true - /cross-fetch@3.1.8: - resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} - dependencies: - node-fetch: 2.7.0 - transitivePeerDependencies: - - encoding - dev: false - /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -1433,17 +1024,6 @@ packages: time-zone: 1.0.0 dev: true - /debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.0.0 - dev: true - /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -1465,16 +1045,6 @@ packages: engines: {node: '>=0.4.0'} dev: false - /depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - dev: true - - /destroy@1.2.0: - resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - dev: true - /diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} @@ -1498,22 +1068,6 @@ packages: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} dev: true - /ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - dev: true - - /elliptic@6.5.4: - resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} - dependencies: - bn.js: 4.12.0 - brorand: 1.1.0 - hash.js: 1.1.7 - hmac-drbg: 1.0.1 - inherits: 2.0.4 - minimalistic-assert: 1.0.1 - minimalistic-crypto-utils: 1.0.1 - dev: false - /emittery@1.0.1: resolution: {integrity: sha512-2ID6FdrMD9KDLldGesP6317G78K7km/kMcwItRtVFva7I/cSEOIaLpewaUb+YLXVwdAp3Ctfxh/V5zIl1sj7dQ==} engines: {node: '>=14.16'} @@ -1527,11 +1081,6 @@ packages: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} dev: true - /encodeurl@1.0.2: - resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} - engines: {node: '>= 0.8'} - dev: true - /esbuild@0.18.4: resolution: {integrity: sha512-9rxWV/Cb2DMUXfe9aUsYtqg0KTlw146ElFH22kYeK9KVV1qT082X4lpmiKsa12ePiCcIcB686TQJxaGAa9TFvA==} engines: {node: '>=12'} @@ -1567,10 +1116,6 @@ packages: engines: {node: '>=6'} dev: true - /escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - dev: true - /escape-string-regexp@2.0.0: resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} engines: {node: '>=8'} @@ -1708,59 +1253,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - dev: true - - /ethereum-cryptography@2.1.2: - resolution: {integrity: sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==} - dependencies: - '@noble/curves': 1.1.0 - '@noble/hashes': 1.3.1 - '@scure/bip32': 1.3.1 - '@scure/bip39': 1.2.1 - dev: false - - /express@4.18.2: - resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} - engines: {node: '>= 0.10.0'} - dependencies: - accepts: 1.3.8 - array-flatten: 1.1.1 - body-parser: 1.20.1 - content-disposition: 0.5.4 - content-type: 1.0.5 - cookie: 0.5.0 - cookie-signature: 1.0.6 - debug: 2.6.9 - depd: 2.0.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 1.2.0 - fresh: 0.5.2 - http-errors: 2.0.0 - merge-descriptors: 1.0.1 - methods: 1.1.2 - on-finished: 2.4.1 - parseurl: 1.3.3 - path-to-regexp: 0.1.7 - proxy-addr: 2.0.7 - qs: 6.11.0 - range-parser: 1.2.1 - safe-buffer: 5.2.1 - send: 0.18.0 - serve-static: 1.15.0 - setprototypeof: 1.2.0 - statuses: 2.0.1 - type-is: 1.6.18 - utils-merge: 1.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - dev: true - /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true @@ -1827,21 +1319,6 @@ packages: to-regex-range: 5.0.1 dev: true - /finalhandler@1.2.0: - resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} - engines: {node: '>= 0.8'} - dependencies: - debug: 2.6.9 - encodeurl: 1.0.2 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.1 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - dev: true - /find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -1880,12 +1357,6 @@ packages: optional: true dev: false - /for-each@0.3.3: - resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - dependencies: - is-callable: 1.2.7 - dev: false - /foreground-child@2.0.0: resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} engines: {node: '>=8.0.0'} @@ -1903,16 +1374,6 @@ packages: mime-types: 2.1.35 dev: false - /forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - dev: true - - /fresh@0.5.2: - resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} - engines: {node: '>= 0.6'} - dev: true - /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} dev: true @@ -1925,22 +1386,11 @@ packages: dev: true optional: true - /function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - /get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} dev: true - /get-intrinsic@1.2.1: - resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} - dependencies: - function-bind: 1.1.1 - has: 1.0.3 - has-proto: 1.0.1 - has-symbols: 1.0.3 - /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1996,12 +1446,6 @@ packages: slash: 4.0.0 dev: true - /gopd@1.0.1: - resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} - dependencies: - get-intrinsic: 1.2.1 - dev: false - /grapheme-splitter@1.0.4: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} dev: true @@ -2015,64 +1459,10 @@ packages: engines: {node: '>=8'} dev: true - /has-proto@1.0.1: - resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} - engines: {node: '>= 0.4'} - - /has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} - - /has-tostringtag@1.0.0: - resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} - engines: {node: '>= 0.4'} - dependencies: - has-symbols: 1.0.3 - dev: false - - /has@1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} - dependencies: - function-bind: 1.1.1 - - /hash.js@1.1.7: - resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} - dependencies: - inherits: 2.0.4 - minimalistic-assert: 1.0.1 - dev: false - - /hmac-drbg@1.0.1: - resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} - dependencies: - hash.js: 1.1.7 - minimalistic-assert: 1.0.1 - minimalistic-crypto-utils: 1.0.1 - dev: false - /html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} dev: true - /http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.1 - toidentifier: 1.0.1 - dev: true - - /iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - dependencies: - safer-buffer: 2.1.2 - dev: true - /ignore-by-default@2.1.0: resolution: {integrity: sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==} engines: {node: '>=10 <11 || >=12 <13 || >=14'} @@ -2110,10 +1500,6 @@ packages: /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - /ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} dev: true /irregular-plurals@3.5.0: @@ -2121,14 +1507,6 @@ packages: engines: {node: '>=8'} dev: true - /is-arguments@1.1.1: - resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - has-tostringtag: 1.0.0 - dev: false - /is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -2136,11 +1514,6 @@ packages: binary-extensions: 2.2.0 dev: true - /is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - dev: false - /is-error@2.2.2: resolution: {integrity: sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==} dev: true @@ -2160,13 +1533,6 @@ packages: engines: {node: '>=12'} dev: true - /is-generator-function@1.0.10: - resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.0 - dev: false - /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -2193,13 +1559,6 @@ packages: resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} dev: true - /is-typed-array@1.1.12: - resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} - engines: {node: '>= 0.4'} - dependencies: - which-typed-array: 1.1.11 - dev: false - /is-unicode-supported@1.3.0: resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} engines: {node: '>=12'} @@ -2209,14 +1568,6 @@ packages: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true - /isomorphic-ws@5.0.0(ws@8.14.2): - resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} - peerDependencies: - ws: '*' - dependencies: - ws: 8.14.2 - dev: false - /istanbul-lib-coverage@3.2.0: resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} engines: {node: '>=8'} @@ -2239,10 +1590,6 @@ packages: istanbul-lib-report: 3.0.1 dev: true - /js-sha3@0.8.0: - resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} - dev: false - /js-string-escape@1.0.1: resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==} engines: {node: '>= 0.8'} @@ -2271,6 +1618,10 @@ packages: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} dev: true + /json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + dev: true + /jsonc-parser@3.2.0: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} dev: true @@ -2358,11 +1709,6 @@ packages: blueimp-md5: 2.19.0 dev: true - /media-typer@0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} - dev: true - /mem@9.0.2: resolution: {integrity: sha512-F2t4YIv9XQUBHt6AOJ0y7lSmP1+cY7Fm1DRh9GClTGzKST7UWLMx6ly9WZdLH/G/ppM5RL4MlQfRT71ri9t19A==} engines: {node: '>=12.20'} @@ -2371,20 +1717,11 @@ packages: mimic-fn: 4.0.0 dev: true - /merge-descriptors@1.0.1: - resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} - dev: true - /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} dev: true - /methods@1.1.2: - resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} - engines: {node: '>= 0.6'} - dev: true - /micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} @@ -2396,32 +1733,20 @@ packages: /mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} + dev: false /mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} dependencies: mime-db: 1.52.0 - - /mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} - hasBin: true - dev: true + dev: false /mimic-fn@4.0.0: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} dev: true - /minimalistic-assert@1.0.1: - resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} - dev: false - - /minimalistic-crypto-utils@1.0.1: - resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} - dev: false - /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: @@ -2435,10 +1760,6 @@ packages: brace-expansion: 2.0.1 dev: true - /ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - dev: true - /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} dev: true @@ -2455,22 +1776,17 @@ packages: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true - /negotiator@0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} - dev: true - - /node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true + /nock@13.3.3: + resolution: {integrity: sha512-z+KUlILy9SK/RjpeXDiDUEAq4T94ADPHE3qaRkf66mpEhzc/ytOMm3Bwdrbq6k1tMWkbdujiKim3G2tfQARuJw==} + engines: {node: '>= 10.13'} dependencies: - whatwg-url: 5.0.0 - dev: false + debug: 4.3.4 + json-stringify-safe: 5.0.1 + lodash: 4.17.21 + propagate: 2.0.1 + transitivePeerDependencies: + - supports-color + dev: true /nofilter@3.1.0: resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} @@ -2482,17 +1798,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /object-inspect@1.12.3: - resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} - dev: true - - /on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} - dependencies: - ee-first: 1.1.1 - dev: true - /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -2575,11 +1880,6 @@ packages: engines: {node: '>=12'} dev: true - /parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - dev: true - /path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -2600,10 +1900,6 @@ packages: engines: {node: '>=8'} dev: true - /path-to-regexp@0.1.7: - resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} - dev: true - /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -2647,12 +1943,9 @@ packages: parse-ms: 3.0.0 dev: true - /proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} - dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 + /propagate@2.0.1: + resolution: {integrity: sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==} + engines: {node: '>= 8'} dev: true /proxy-from-env@1.1.0: @@ -2664,42 +1957,10 @@ packages: engines: {node: '>=6'} dev: true - /qs@6.11.0: - resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} - engines: {node: '>=0.6'} - dependencies: - side-channel: 1.0.4 - dev: true - /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true - /range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - dev: true - - /raw-body@2.5.1: - resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} - engines: {node: '>= 0.8'} - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - dev: true - - /raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} - engines: {node: '>= 0.8'} - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - dev: true - /readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -2751,14 +2012,6 @@ packages: queue-microtask: 1.2.3 dev: true - /safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: true - - /safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - dev: true - /semver@7.5.2: resolution: {integrity: sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==} engines: {node: '>=10'} @@ -2775,27 +2028,6 @@ packages: lru-cache: 6.0.0 dev: true - /send@0.18.0: - resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} - engines: {node: '>= 0.8.0'} - dependencies: - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 0.5.2 - http-errors: 2.0.0 - mime: 1.6.0 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - dev: true - /serialize-error@7.0.1: resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} engines: {node: '>=10'} @@ -2803,26 +2035,6 @@ packages: type-fest: 0.13.1 dev: true - /serve-static@1.15.0: - resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} - engines: {node: '>= 0.8.0'} - dependencies: - encodeurl: 1.0.2 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 0.18.0 - transitivePeerDependencies: - - supports-color - dev: true - - /setimmediate@1.0.5: - resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} - dev: false - - /setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - dev: true - /shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2844,14 +2056,6 @@ packages: vscode-textmate: 8.0.0 dev: true - /side-channel@1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 - object-inspect: 1.12.3 - dev: true - /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: true @@ -2890,11 +2094,6 @@ packages: escape-string-regexp: 2.0.0 dev: true - /statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - dev: true - /string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -2979,15 +2178,6 @@ packages: is-number: 7.0.0 dev: true - /toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - dev: true - - /tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - dev: false - /ts-node@10.9.1(@types/node@20.3.1)(typescript@4.9.5): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true @@ -3054,14 +2244,6 @@ packages: engines: {node: '>=10'} dev: true - /type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} - dependencies: - media-typer: 0.3.0 - mime-types: 2.1.35 - dev: true - /typedoc@0.24.8(typescript@4.9.5): resolution: {integrity: sha512-ahJ6Cpcvxwaxfu4KtjA8qZNqS43wYt6JL27wYiIgl1vd38WW/KWX11YuAeZhuz9v+ttrutSsgK+XO1CjL1kA3w==} engines: {node: '>= 14.14'} @@ -3082,32 +2264,12 @@ packages: hasBin: true dev: true - /unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - dev: true - /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: punycode: 2.3.0 dev: true - /util@0.12.5: - resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} - dependencies: - inherits: 2.0.4 - is-arguments: 1.1.1 - is-generator-function: 1.0.10 - is-typed-array: 1.1.12 - which-typed-array: 1.1.11 - dev: false - - /utils-merge@1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} - dev: true - /v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} dev: true @@ -3121,11 +2283,6 @@ packages: convert-source-map: 1.9.0 dev: true - /vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - dev: true - /vscode-oniguruma@1.7.0: resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} dev: true @@ -3134,283 +2291,11 @@ packages: resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==} dev: true - /web3-core@4.2.0: - resolution: {integrity: sha512-pkZJx3HAY3b3CutaFarODFgK3TDvcXC4T0n8cpvwiZjDzakUUFAssVUDwrmFyCFKAo5kmfs6qWFW7BAZLJeBFA==} - engines: {node: '>=14', npm: '>=6.12.0'} - dependencies: - web3-errors: 1.1.2 - web3-eth-iban: 4.0.6 - web3-providers-http: 4.0.6 - web3-providers-ws: 4.0.6 - web3-types: 1.2.0 - web3-utils: 4.0.6 - web3-validator: 2.0.2 - optionalDependencies: - web3-providers-ipc: 4.0.6 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - dev: false - - /web3-errors@1.1.2: - resolution: {integrity: sha512-qlyuV5r6MzjLasIalVWBIIfW4Y7hBX2bZv8TRnXvI1EjiZ36zIFKgE9RF+/iRBjXmOsvIUQQ2Z9gMvYGfOwUwQ==} - engines: {node: '>=14', npm: '>=6.12.0'} - dependencies: - web3-types: 1.2.0 - dev: false - - /web3-eth-abi@4.1.2: - resolution: {integrity: sha512-s8gvjUwzb2ZnAef0Jy68pjmeshYIKBoYlVj/1yuuFP9t3io3oQQIEyGlaCx7P4ifsZ186gMa4QjCCeIt7HYm7Q==} - engines: {node: '>=14', npm: '>=6.12.0'} - dependencies: - '@ethersproject/abi': 5.7.0 - '@ethersproject/bignumber': 5.7.0 - web3-errors: 1.1.2 - web3-types: 1.2.0 - web3-utils: 4.0.6 - dev: false - - /web3-eth-accounts@4.0.6: - resolution: {integrity: sha512-xkOXXAEZs2CcR2v33CvFwtGJQS05ye7c3dlXcqwre91fhah9e6u4CPztpyR7HIKegWfIG1DRUwrcEqM2EMo4/w==} - engines: {node: '>=14', npm: '>=6.12.0'} - dependencies: - '@ethereumjs/rlp': 4.0.1 - crc-32: 1.2.2 - ethereum-cryptography: 2.1.2 - web3-errors: 1.1.2 - web3-types: 1.2.0 - web3-utils: 4.0.6 - web3-validator: 2.0.2 - dev: false - - /web3-eth-contract@4.1.0: - resolution: {integrity: sha512-e1eEXSwzNUaC5j0WWDqQ527fPFtIswoJZ/cov8mWvTQi3+dqyI590/6s7IF6A5CGew1RrewAqPMrR9m7WQt7hw==} - engines: {node: '>=14', npm: '>=6.12.0'} - dependencies: - web3-core: 4.2.0 - web3-errors: 1.1.2 - web3-eth: 4.2.0 - web3-eth-abi: 4.1.2 - web3-types: 1.2.0 - web3-utils: 4.0.6 - web3-validator: 2.0.2 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - dev: false - - /web3-eth-ens@4.0.6: - resolution: {integrity: sha512-ulEX1XRuTojcpWuSd5pk7+CWkE7Yrgi18TcgiQkz+ltQWOVlSHBjcQ/guA9MJoFPa2d3ADSdCbRQEZDZ8Lu3gw==} - engines: {node: '>=14', npm: '>=6.12.0'} - dependencies: - '@adraffy/ens-normalize': 1.10.0 - web3-core: 4.2.0 - web3-errors: 1.1.2 - web3-eth: 4.2.0 - web3-eth-contract: 4.1.0 - web3-net: 4.0.6 - web3-types: 1.2.0 - web3-utils: 4.0.6 - web3-validator: 2.0.2 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - dev: false - - /web3-eth-iban@4.0.6: - resolution: {integrity: sha512-q47MbmoYWdfoylHlKZkZRHiPYeiFWqRiHou/wTYJEeZa2D3NG0wuPWz3jeQdZ5NzmS85yh+p2hxa54azVT8qmw==} - engines: {node: '>=14', npm: '>=6.12.0'} - dependencies: - web3-errors: 1.1.2 - web3-types: 1.2.0 - web3-utils: 4.0.6 - web3-validator: 2.0.2 - dev: false - - /web3-eth-personal@4.0.6: - resolution: {integrity: sha512-QBIl5fH5GPzDfYWxOvOLghnPruopVFfgnYsRmxEu85WAFidBb+XCqIOLmKe4qfF5czPG7gA/7PCPdsPqGNlf7Q==} - engines: {node: '>=14', npm: '>=6.12.0'} - dependencies: - web3-core: 4.2.0 - web3-eth: 4.2.0 - web3-rpc-methods: 1.1.2 - web3-types: 1.2.0 - web3-utils: 4.0.6 - web3-validator: 2.0.2 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - dev: false - - /web3-eth@4.2.0: - resolution: {integrity: sha512-8YUEp5bq8j6KzlWpf856e0ZTXSNgJEYPg1gzzrmFC2+l0cjbul7vHnLA7DAsQGrIvXvvHvRp8da/8Ogm+G6FYQ==} - engines: {node: '>=14', npm: '>=6.12.0'} - dependencies: - setimmediate: 1.0.5 - web3-core: 4.2.0 - web3-errors: 1.1.2 - web3-eth-abi: 4.1.2 - web3-eth-accounts: 4.0.6 - web3-net: 4.0.6 - web3-providers-ws: 4.0.6 - web3-rpc-methods: 1.1.2 - web3-types: 1.2.0 - web3-utils: 4.0.6 - web3-validator: 2.0.2 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - dev: false - - /web3-net@4.0.6: - resolution: {integrity: sha512-Th4AtgpBgMdt76PmYyNBQxwAd2hAR8hIjhU4xjhqk1JATlXpcfgzyhegeAsvnSht4tcLnVQt6SN4ZVccllpd4A==} - engines: {node: '>=14', npm: '>=6.12.0'} - dependencies: - web3-core: 4.2.0 - web3-rpc-methods: 1.1.2 - web3-types: 1.2.0 - web3-utils: 4.0.6 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - dev: false - - /web3-providers-http@4.0.6: - resolution: {integrity: sha512-FnBw0X25Xu0FejOgY2Ra7WY4p3fSrHxZuQ5a4j0ytDCE+0wxKQN0BaLRC7+uigbVvwEziQwzrhe+tn8bYAQKXQ==} - engines: {node: '>=14', npm: '>=6.12.0'} - dependencies: - cross-fetch: 3.1.8 - web3-errors: 1.1.2 - web3-types: 1.2.0 - web3-utils: 4.0.6 - transitivePeerDependencies: - - encoding - dev: false - - /web3-providers-ipc@4.0.6: - resolution: {integrity: sha512-17Ky978qGgdSWtctc/WKj9kX+QUypk6arZLI/Rfmq4zQpoR5ngH38CGozRkXUonr9hITYNaLW82NB1SPi1pRPQ==} - engines: {node: '>=14', npm: '>=6.12.0'} - requiresBuild: true - dependencies: - web3-errors: 1.1.2 - web3-types: 1.2.0 - web3-utils: 4.0.6 - dev: false - optional: true - - /web3-providers-ws@4.0.6: - resolution: {integrity: sha512-0Q0SuKpr05gK+tUXdzPNmYlDV3exdqxnHx3f8p3cqz+v66J04EOT31bbETS0VcpDiQ9YaVS8FVSjT4PaseuNag==} - engines: {node: '>=14', npm: '>=6.12.0'} - dependencies: - '@types/ws': 8.5.3 - isomorphic-ws: 5.0.0(ws@8.14.2) - web3-errors: 1.1.2 - web3-types: 1.2.0 - web3-utils: 4.0.6 - ws: 8.14.2 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - dev: false - - /web3-rpc-methods@1.1.2: - resolution: {integrity: sha512-fzYp9eJyzq/UBzpP9kOQormelLfvl1kJnX5ucHv4T6kZaQfDuBt5XoYDtCDXSXVaz2MgTowsXwKEVAzN6h7+Ag==} - engines: {node: '>=14', npm: '>=6.12.0'} - dependencies: - web3-core: 4.2.0 - web3-types: 1.2.0 - web3-validator: 2.0.2 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - dev: false - - /web3-types@1.2.0: - resolution: {integrity: sha512-ljx8mrkrOI8fRqvgOdxfpKYoso6n7I8T9LsqXl+Mz2Db0L+2H15an0xgdoWYpKndTPiU2NKRWFiopYifBQzcxQ==} - engines: {node: '>=14', npm: '>=6.12.0'} - dev: false - - /web3-utils@4.0.6: - resolution: {integrity: sha512-nLVtMf9mWTX604XiQQkWZlHLCag9GdHfQtnGJDNaDssTLUx5SpOm1CjhKCHcVcAH/QazEsWcLqUAuyqwKST1kA==} - engines: {node: '>=14', npm: '>=6.12.0'} - dependencies: - ethereum-cryptography: 2.1.2 - web3-errors: 1.1.2 - web3-types: 1.2.0 - web3-validator: 2.0.2 - dev: false - - /web3-validator@2.0.2: - resolution: {integrity: sha512-9sQ5owd2UldTsva3o3htj2fTPpbmUwb4TfBXhjIkew8FyT0ss3DPI+j3p6XrfdxIVBEQ5r17YUakElDV99aW+A==} - engines: {node: '>=14', npm: '>=6.12.0'} - dependencies: - ethereum-cryptography: 2.1.2 - util: 0.12.5 - web3-errors: 1.1.2 - web3-types: 1.2.0 - zod: 3.22.2 - dev: false - - /web3@4.1.2: - resolution: {integrity: sha512-BTUCJU7LvL0JDvB1RCRtHe5jFZ0sVYVqHvlNbG4uzebZ6ebtX/CnwiyiJ08UOuvKWzHrZQ+7jPuYuF65BMAXnQ==} - engines: {node: '>=14.0.0', npm: '>=6.12.0'} - dependencies: - web3-core: 4.2.0 - web3-errors: 1.1.2 - web3-eth: 4.2.0 - web3-eth-abi: 4.1.2 - web3-eth-accounts: 4.0.6 - web3-eth-contract: 4.1.0 - web3-eth-ens: 4.0.6 - web3-eth-iban: 4.0.6 - web3-eth-personal: 4.0.6 - web3-net: 4.0.6 - web3-providers-http: 4.0.6 - web3-providers-ws: 4.0.6 - web3-rpc-methods: 1.1.2 - web3-types: 1.2.0 - web3-utils: 4.0.6 - web3-validator: 2.0.2 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - dev: false - - /webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - dev: false - /well-known-symbols@2.0.0: resolution: {integrity: sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==} engines: {node: '>=6'} dev: true - /whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - dev: false - - /which-typed-array@1.1.11: - resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==} - engines: {node: '>= 0.4'} - dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.2 - for-each: 0.3.3 - gopd: 1.0.1 - has-tostringtag: 1.0.0 - dev: false - /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -3445,19 +2330,6 @@ packages: signal-exit: 4.1.0 dev: true - /ws@8.14.2: - resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dev: false - /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -3503,7 +2375,3 @@ packages: /zenroom@3.10.0: resolution: {integrity: sha512-IaULB5zVo7pfC/tT2t5gz/nWK/v+j5rMrcX0lmiu/QMVMgUfmu61mf1vxTi4RJhfizu2R878IoX0Ua0783dpjg==} dev: false - - /zod@3.22.2: - resolution: {integrity: sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==} - dev: false