diff --git a/packages/hoppscotch-app/components/environments/Add.vue b/packages/hoppscotch-app/components/environments/Add.vue index 2188289e7..f8da6289e 100644 --- a/packages/hoppscotch-app/components/environments/Add.vue +++ b/packages/hoppscotch-app/components/environments/Add.vue @@ -38,12 +38,18 @@ diff --git a/packages/hoppscotch-app/components/http/TestResultEnv.vue b/packages/hoppscotch-app/components/http/TestResultEnv.vue new file mode 100644 index 000000000..85920e9d8 --- /dev/null +++ b/packages/hoppscotch-app/components/http/TestResultEnv.vue @@ -0,0 +1,83 @@ + + + diff --git a/packages/hoppscotch-app/components/lenses/ResponseBodyRenderer.vue b/packages/hoppscotch-app/components/lenses/ResponseBodyRenderer.vue index 2c0406032..693e18c57 100644 --- a/packages/hoppscotch-app/components/lenses/ResponseBodyRenderer.vue +++ b/packages/hoppscotch-app/components/lenses/ResponseBodyRenderer.vue @@ -24,7 +24,11 @@ :label="$t('test.results')" :indicator=" testResults && - (testResults.expectResults.length || testResults.tests.length) + (testResults.expectResults.length || + testResults.tests.length || + testResults.envDiff.selected.additions.length || + testResults.envDiff.selected.updations.length || + testResults.envDiff.global.updations.length) ? true : false " diff --git a/packages/hoppscotch-app/helpers/RequestRunner.ts b/packages/hoppscotch-app/helpers/RequestRunner.ts index 2453926a1..5265e4142 100644 --- a/packages/hoppscotch-app/helpers/RequestRunner.ts +++ b/packages/hoppscotch-app/helpers/RequestRunner.ts @@ -1,10 +1,17 @@ import { Observable } from "rxjs" import { filter } from "rxjs/operators" import { chain, right, TaskEither } from "fp-ts/lib/TaskEither" -import { pipe } from "fp-ts/function" +import { flow, pipe } from "fp-ts/function" import * as O from "fp-ts/Option" -import { runTestScript, TestDescriptor } from "@hoppscotch/js-sandbox" +import * as A from "fp-ts/Array" +import { Environment } from "@hoppscotch/data" +import { + SandboxTestResult, + runTestScript, + TestDescriptor, +} from "@hoppscotch/js-sandbox" import { isRight } from "fp-ts/Either" +import cloneDeep from "lodash/cloneDeep" import { getCombinedEnvVariables, getFinalEnvsFromPreRequest, @@ -15,6 +22,14 @@ import { createRESTNetworkRequestStream } from "./network" import { HoppTestData, HoppTestResult } from "./types/HoppTestResult" import { isJSONContentType } from "./utils/contenttypes" import { getRESTRequest, setRESTTestResults } from "~/newstore/RESTSession" +import { + environmentsStore, + getCurrentEnvironment, + getEnviroment, + getGlobalVariables, + setGlobalEnvVariables, + updateEnvironment, +} from "~/newstore/environments" const getTestableBody = ( res: HoppRESTResponse & { type: "success" | "fail" } @@ -43,6 +58,11 @@ const getTestableBody = ( return x } +const combineEnvVariables = (env: { + global: Environment["variables"] + selected: Environment["variables"] +}) => [...env.selected, ...env.global] + export const runRESTRequest$ = (): TaskEither< string | Error, Observable @@ -55,7 +75,7 @@ export const runRESTRequest$ = (): TaskEither< chain((envs) => { const effectiveRequest = getEffectiveRESTRequest(getRESTRequest(), { name: "Env", - variables: envs, + variables: combineEnvVariables(envs), }) const stream = createRESTNetworkRequestStream(effectiveRequest) @@ -65,7 +85,7 @@ export const runRESTRequest$ = (): TaskEither< .pipe(filter((res) => res.type === "success" || res.type === "fail")) .subscribe(async (res) => { if (res.type === "success" || res.type === "fail") { - const runResult = await runTestScript(res.req.testScript, { + const runResult = await runTestScript(res.req.testScript, envs, { status: res.statusCode, body: getTestableBody(res), headers: res.headers, @@ -73,11 +93,38 @@ export const runRESTRequest$ = (): TaskEither< if (isRight(runResult)) { setRESTTestResults(translateToSandboxTestResults(runResult.right)) + + setGlobalEnvVariables(runResult.right.envs.global) + + if (environmentsStore.value.currentEnvironmentIndex !== -1) { + const env = getEnviroment( + environmentsStore.value.currentEnvironmentIndex + ) + updateEnvironment( + environmentsStore.value.currentEnvironmentIndex, + { + name: env.name, + variables: runResult.right.envs.selected, + } + ) + } } else { setRESTTestResults({ description: "", expectResults: [], tests: [], + envDiff: { + global: { + additions: [], + deletions: [], + updations: [], + }, + selected: { + additions: [], + deletions: [], + updations: [], + }, + }, scriptError: true, }) } @@ -90,8 +137,47 @@ export const runRESTRequest$ = (): TaskEither< }) ) +const getAddedEnvVariables = ( + current: Environment["variables"], + updated: Environment["variables"] +) => updated.filter((x) => current.findIndex((y) => y.key === x.key) === -1) + +const getRemovedEnvVariables = ( + current: Environment["variables"], + updated: Environment["variables"] +) => current.filter((x) => updated.findIndex((y) => y.key === x.key) === -1) + +const getUpdatedEnvVariables = ( + current: Environment["variables"], + updated: Environment["variables"] +) => + pipe( + updated, + A.filterMap( + flow( + O.of, + O.bindTo("env"), + O.bind("index", ({ env }) => + pipe( + current.findIndex((x) => x.key === env.key), + O.fromPredicate((x) => x !== -1) + ) + ), + O.chain( + O.fromPredicate( + ({ env, index }) => env.value !== current[index].value + ) + ), + O.map(({ env, index }) => ({ + ...env, + previousValue: current[index].value, + })) + ) + ) + ) + function translateToSandboxTestResults( - testDesc: TestDescriptor + testDesc: SandboxTestResult ): HoppTestResult { const translateChildTests = (child: TestDescriptor): HoppTestData => { return { @@ -100,10 +186,32 @@ function translateToSandboxTestResults( tests: child.children.map(translateChildTests), } } + + const globals = cloneDeep(getGlobalVariables()) + const env = cloneDeep(getCurrentEnvironment()) + return { description: "", - expectResults: testDesc.expectResults, - tests: testDesc.children.map(translateChildTests), + expectResults: testDesc.tests.expectResults, + tests: testDesc.tests.children.map(translateChildTests), scriptError: false, + envDiff: { + global: { + additions: getAddedEnvVariables(globals, testDesc.envs.global), + deletions: getRemovedEnvVariables(globals, testDesc.envs.global), + updations: getUpdatedEnvVariables(globals, testDesc.envs.global), + }, + selected: { + additions: getAddedEnvVariables(env.variables, testDesc.envs.selected), + deletions: getRemovedEnvVariables( + env.variables, + testDesc.envs.selected + ), + updations: getUpdatedEnvVariables( + env.variables, + testDesc.envs.selected + ), + }, + }, } } diff --git a/packages/hoppscotch-app/helpers/preRequest.ts b/packages/hoppscotch-app/helpers/preRequest.ts index 984230795..75c5f3832 100644 --- a/packages/hoppscotch-app/helpers/preRequest.ts +++ b/packages/hoppscotch-app/helpers/preRequest.ts @@ -1,29 +1,20 @@ import { runPreRequestScript } from "@hoppscotch/js-sandbox" +import { Environment } from "@hoppscotch/data" +import cloneDeep from "lodash/cloneDeep" import { getCurrentEnvironment, getGlobalVariables, } from "~/newstore/environments" -export const getCombinedEnvVariables = () => { - const variables: { key: string; value: string }[] = [...getGlobalVariables()] - - for (const variable of getCurrentEnvironment().variables) { - const index = variables.findIndex((v) => variable.key === v.key) - - if (index === -1) { - variables.push({ - key: variable.key, - value: variable.value, - }) - } else { - variables[index].value = variable.value - } - } - - return variables -} +export const getCombinedEnvVariables = () => ({ + global: cloneDeep(getGlobalVariables()), + selected: cloneDeep(getCurrentEnvironment().variables), +}) export const getFinalEnvsFromPreRequest = ( script: string, - envs: { key: string; value: string }[] + envs: { + global: Environment["variables"] + selected: Environment["variables"] + } ) => runPreRequestScript(script, envs) diff --git a/packages/hoppscotch-app/helpers/terndoc/pw-pre.json b/packages/hoppscotch-app/helpers/terndoc/pw-pre.json index a489a30c7..8a70a6c35 100644 --- a/packages/hoppscotch-app/helpers/terndoc/pw-pre.json +++ b/packages/hoppscotch-app/helpers/terndoc/pw-pre.json @@ -2,7 +2,10 @@ "!name": "pw-pre", "pw": { "env": { - "set": "fn(key: string, value: string)" + "set": "fn(key: string, value: string)", + "get": "fn(key: string) -> string", + "getResolve": "fn(key: string) -> string", + "resolve": "fn(value: string) -> string" } } } diff --git a/packages/hoppscotch-app/helpers/terndoc/pw-test.json b/packages/hoppscotch-app/helpers/terndoc/pw-test.json index 8bec91ba9..7c8616cdc 100644 --- a/packages/hoppscotch-app/helpers/terndoc/pw-test.json +++ b/packages/hoppscotch-app/helpers/terndoc/pw-test.json @@ -19,6 +19,12 @@ "headers": "?", "body": "?" }, + "env": { + "set": "fn(key: string, value: string)", + "get": "fn(key: string) -> string", + "getResolve": "fn(key: string) -> string", + "resolve": "fn(value: string) -> string" + }, "test": "fn(name: string, func: fn())" } } diff --git a/packages/hoppscotch-app/helpers/testSnippets.js b/packages/hoppscotch-app/helpers/testSnippets.js index 594caef19..002d39578 100644 --- a/packages/hoppscotch-app/helpers/testSnippets.js +++ b/packages/hoppscotch-app/helpers/testSnippets.js @@ -1,4 +1,9 @@ export default [ + { + name: "Environment: Set an environment variable", + script: `\n\n// Set an environment variable +pw.env.set("variable", "value");`, + }, { name: "Response: Status code is 200", script: `\n\n// Check status code is 200 diff --git a/packages/hoppscotch-app/helpers/types/HoppTestResult.ts b/packages/hoppscotch-app/helpers/types/HoppTestResult.ts index 31af5b58d..96bf69a51 100644 --- a/packages/hoppscotch-app/helpers/types/HoppTestResult.ts +++ b/packages/hoppscotch-app/helpers/types/HoppTestResult.ts @@ -1,3 +1,5 @@ +import { Environment } from "@hoppscotch/data" + export type HoppTestExpectResult = { status: "fail" | "pass" | "error" message: string @@ -14,4 +16,21 @@ export type HoppTestResult = { expectResults: HoppTestExpectResult[] description: string scriptError: boolean + + envDiff: { + global: { + additions: Environment["variables"] + updations: Array< + Environment["variables"][number] & { previousValue: string } + > + deletions: Environment["variables"] + } + selected: { + additions: Environment["variables"] + updations: Array< + Environment["variables"][number] & { previousValue: string } + > + deletions: Environment["variables"] + } + } } diff --git a/packages/hoppscotch-app/locales/en.json b/packages/hoppscotch-app/locales/en.json index c4ab67360..c6dce1f75 100644 --- a/packages/hoppscotch-app/locales/en.json +++ b/packages/hoppscotch-app/locales/en.json @@ -159,14 +159,19 @@ "tests": "There are no tests for this request" }, "environment": { + "added": "Environment addition", + "add_to_global": "Add to Global", "create_new": "Create new environment", + "deleted": "Environment deletion", "edit": "Edit Environment", "invalid_name": "Please provide a name for the environment", "nested_overflow": "nested environment variables are limited to 10 levels", "new": "New Environment", "no_environment": "No environment", + "no_environment_description": "No environments were selected. Choose what to do with the following variables.", "select": "Select environment", "title": "Environments", + "updated": "Environment updation", "variable_list": "Variable List" }, "error": { @@ -468,7 +473,7 @@ }, "state": { "bulk_mode": "Bulk edit", - "bulk_mode_placeholder": "Entries are separated by newline\nKeys and values are separated by :\nPrepend # to any row you want to add but keep disabled", + "bulk_mode_placeholder": "Entries are separated by newline Keys and values are separated by : Prepend # to any row you want to add but keep disabled", "cleared": "Cleared", "connected": "Connected", "connected_to": "Connected to {name}", diff --git a/packages/hoppscotch-app/package.json b/packages/hoppscotch-app/package.json index 837acb1e5..0c0dfaf19 100644 --- a/packages/hoppscotch-app/package.json +++ b/packages/hoppscotch-app/package.json @@ -57,7 +57,7 @@ "@codemirror/view": "^0.19.0", "@hoppscotch/codemirror-lang-graphql": "workspace:^0.1.0", "@hoppscotch/data": "workspace:^0.4.0", - "@hoppscotch/js-sandbox": "workspace:^1.0.0", + "@hoppscotch/js-sandbox": "workspace:^2.0.0", "@nuxtjs/axios": "^5.13.6", "@nuxtjs/composition-api": "^0.31.0", "@nuxtjs/gtm": "^2.4.0", diff --git a/packages/hoppscotch-js-sandbox/package.json b/packages/hoppscotch-js-sandbox/package.json index f1cdd4371..bc561b77a 100644 --- a/packages/hoppscotch-js-sandbox/package.json +++ b/packages/hoppscotch-js-sandbox/package.json @@ -1,6 +1,6 @@ { "name": "@hoppscotch/js-sandbox", - "version": "1.0.0", + "version": "2.0.0", "description": "JavaScript sandboxes for running external scripts used by Hoppscotch clients", "main": "./lib/index.js", "types": "./lib/", @@ -35,7 +35,8 @@ "dependencies": { "fp-ts": "^2.11.8", "lodash": "^4.17.21", - "quickjs-emscripten": "^0.15.0" + "quickjs-emscripten": "^0.15.0", + "@hoppscotch/data": "workspace:^0.4.0" }, "devDependencies": { "@digitak/esrun": "^3.1.2", diff --git a/packages/hoppscotch-js-sandbox/src/__tests__/preRequest.spec.ts b/packages/hoppscotch-js-sandbox/src/__tests__/preRequest.spec.ts index f92e34245..051c456fd 100644 --- a/packages/hoppscotch-js-sandbox/src/__tests__/preRequest.spec.ts +++ b/packages/hoppscotch-js-sandbox/src/__tests__/preRequest.spec.ts @@ -8,15 +8,21 @@ describe("execPreRequestScript", () => { ` pw.env.set("bob", "newbob") `, - [ - { key: "bob", value: "oldbob" }, - { key: "foo", value: "bar" }, - ] + { + global: [], + selected: [ + { key: "bob", value: "oldbob" }, + { key: "foo", value: "bar" }, + ], + } )() - ).resolves.toEqualRight([ - { key: "bob", value: "newbob" }, - { key: "foo", value: "bar" }, - ]) + ).resolves.toEqualRight({ + global: [], + selected: [ + { key: "bob", value: "newbob" }, + { key: "foo", value: "bar" }, + ], + }) }) test("fails if the key is not a string", () => { @@ -25,10 +31,13 @@ describe("execPreRequestScript", () => { ` pw.env.set(10, "newbob") `, - [ - { key: "bob", value: "oldbob" }, - { key: "foo", value: "bar" }, - ] + { + global: [], + selected: [ + { key: "bob", value: "oldbob" }, + { key: "foo", value: "bar" }, + ], + } )() ).resolves.toBeLeft() }) @@ -39,10 +48,13 @@ describe("execPreRequestScript", () => { ` pw.env.set("bob", 10) `, - [ - { key: "bob", value: "oldbob" }, - { key: "foo", value: "bar" }, - ] + { + global: [], + selected: [ + { key: "bob", value: "oldbob" }, + { key: "foo", value: "bar" }, + ], + } )() ).resolves.toBeLeft() }) @@ -51,12 +63,15 @@ describe("execPreRequestScript", () => { return expect( execPreRequestScript( ` - pw.env.set("bob", + pw.env.set("bob", `, - [ - { key: "bob", value: "oldbob" }, - { key: "foo", value: "bar" }, - ] + { + global: [], + selected: [ + { key: "bob", value: "oldbob" }, + { key: "foo", value: "bar" }, + ], + } )() ).resolves.toBeLeft() }) @@ -67,8 +82,11 @@ describe("execPreRequestScript", () => { ` pw.env.set("foo", "bar") `, - [] + { selected: [], global: [] } )() - ).resolves.toEqualRight([{ key: "foo", value: "bar" }]) + ).resolves.toEqualRight({ + global: [], + selected: [{ key: "foo", value: "bar" }], + }) }) }) diff --git a/packages/hoppscotch-js-sandbox/src/__tests__/testing/envs/get.spec.ts b/packages/hoppscotch-js-sandbox/src/__tests__/testing/envs/get.spec.ts new file mode 100644 index 000000000..36fcf7b0e --- /dev/null +++ b/packages/hoppscotch-js-sandbox/src/__tests__/testing/envs/get.spec.ts @@ -0,0 +1,178 @@ +import * as TE from "fp-ts/TaskEither" +import { pipe } from "fp-ts/function" +import { execTestScript, TestResponse, TestResult } from "../../../test-runner" + +import "@relmify/jest-fp-ts" + +const fakeResponse: TestResponse = { + status: 200, + body: "hoi", + headers: [], +} + +const func = (script: string, envs: TestResult["envs"]) => + pipe( + execTestScript(script, envs, fakeResponse), + TE.map((x) => x.tests) + ) + +describe("pw.env.get", () => { + test("returns the correct value for an existing selected environment value", () => { + return expect( + func( + ` + const data = pw.env.get("a") + pw.expect(data).toBe("b") + `, + { + global: [], + selected: [ + { + key: "a", + value: "b", + }, + ], + } + )() + ).resolves.toEqualRight([ + expect.objectContaining({ + expectResults: [ + { + status: "pass", + message: "Expected 'b' to be 'b'", + }, + ], + }), + ]) + }) + + test("returns the correct value for an existing global environment value", () => { + return expect( + func( + ` + const data = pw.env.get("a") + pw.expect(data).toBe("b") + `, + { + global: [ + { + key: "a", + value: "b", + }, + ], + selected: [], + } + )() + ).resolves.toEqualRight([ + expect.objectContaining({ + expectResults: [ + { + status: "pass", + message: "Expected 'b' to be 'b'", + }, + ], + }), + ]) + }) + + test("returns undefined for a key that is not present in both selected or environment", () => { + return expect( + func( + ` + const data = pw.env.get("a") + pw.expect(data).toBe(undefined) + `, + { + global: [], + selected: [], + } + )() + ).resolves.toEqualRight([ + expect.objectContaining({ + expectResults: [ + { + status: "pass", + message: "Expected 'undefined' to be 'undefined'", + }, + ], + }), + ]) + }) + + test("returns the value defined in selected environment if it is also present in global", () => { + return expect( + func( + ` + const data = pw.env.get("a") + pw.expect(data).toBe("selected val") + `, + { + global: [ + { + key: "a", + value: "global val", + }, + ], + selected: [ + { + key: "a", + value: "selected val", + }, + ], + } + )() + ).resolves.toEqualRight([ + expect.objectContaining({ + expectResults: [ + { + status: "pass", + message: "Expected 'selected val' to be 'selected val'", + }, + ], + }), + ]) + }) + + test("does not resolve environment values", () => { + return expect( + func( + ` + const data = pw.env.get("a") + pw.expect(data).toBe("<>") + `, + { + global: [], + selected: [ + { + key: "a", + value: "<>", + }, + ], + } + )() + ).resolves.toEqualRight([ + expect.objectContaining({ + expectResults: [ + { + status: "pass", + message: "Expected '<>' to be '<>'", + }, + ], + }), + ]) + }) + + test("errors if the key is not a string", () => { + return expect( + func( + ` + const data = pw.env.get(5) + `, + { + global: [], + selected: [], + } + )() + ).resolves.toBeLeft() + }) +}) diff --git a/packages/hoppscotch-js-sandbox/src/__tests__/testing/envs/getResolve.spec.ts b/packages/hoppscotch-js-sandbox/src/__tests__/testing/envs/getResolve.spec.ts new file mode 100644 index 000000000..bb4d400f5 --- /dev/null +++ b/packages/hoppscotch-js-sandbox/src/__tests__/testing/envs/getResolve.spec.ts @@ -0,0 +1,215 @@ +import * as TE from "fp-ts/TaskEither" +import { pipe } from "fp-ts/function" +import { execTestScript, TestResponse, TestResult } from "../../../test-runner" + +import "@relmify/jest-fp-ts" + +const fakeResponse: TestResponse = { + status: 200, + body: "hoi", + headers: [], +} + +const func = (script: string, envs: TestResult["envs"]) => + pipe( + execTestScript(script, envs, fakeResponse), + TE.map((x) => x.tests) + ) + +describe("pw.env.getResolve", () => { + test("returns the correct value for an existing selected environment value", () => { + return expect( + func( + ` + const data = pw.env.getResolve("a") + pw.expect(data).toBe("b") + `, + { + global: [], + selected: [ + { + key: "a", + value: "b", + }, + ], + } + )() + ).resolves.toEqualRight([ + expect.objectContaining({ + expectResults: [ + { + status: "pass", + message: "Expected 'b' to be 'b'", + }, + ], + }), + ]) + }) + + test("returns the correct value for an existing global environment value", () => { + return expect( + func( + ` + const data = pw.env.getResolve("a") + pw.expect(data).toBe("b") + `, + { + global: [ + { + key: "a", + value: "b", + }, + ], + selected: [], + } + )() + ).resolves.toEqualRight([ + expect.objectContaining({ + expectResults: [ + { + status: "pass", + message: "Expected 'b' to be 'b'", + }, + ], + }), + ]) + }) + + test("returns undefined for a key that is not present in both selected or environment", () => { + return expect( + func( + ` + const data = pw.env.getResolve("a") + pw.expect(data).toBe(undefined) + `, + { + global: [], + selected: [], + } + )() + ).resolves.toEqualRight([ + expect.objectContaining({ + expectResults: [ + { + status: "pass", + message: "Expected 'undefined' to be 'undefined'", + }, + ], + }), + ]) + }) + + test("returns the value defined in selected environment if it is also present in global", () => { + return expect( + func( + ` + const data = pw.env.getResolve("a") + pw.expect(data).toBe("selected val") + `, + { + global: [ + { + key: "a", + value: "global val", + }, + ], + selected: [ + { + key: "a", + value: "selected val", + }, + ], + } + )() + ).resolves.toEqualRight([ + expect.objectContaining({ + expectResults: [ + { + status: "pass", + message: "Expected 'selected val' to be 'selected val'", + }, + ], + }), + ]) + }) + + test("resolve environment values", () => { + return expect( + func( + ` + const data = pw.env.getResolve("a") + pw.expect(data).toBe("there") + `, + { + global: [], + selected: [ + { + key: "a", + value: "<>", + }, + { + key: "hello", + value: "there", + }, + ], + } + )() + ).resolves.toEqualRight([ + expect.objectContaining({ + expectResults: [ + { + status: "pass", + message: "Expected 'there' to be 'there'", + }, + ], + }), + ]) + }) + + test("returns unresolved value on infinite loop in resolution", () => { + return expect( + func( + ` + const data = pw.env.getResolve("a") + pw.expect(data).toBe("<>") + `, + { + global: [], + selected: [ + { + key: "a", + value: "<>", + }, + { + key: "hello", + value: "<>", + }, + ], + } + )() + ).resolves.toEqualRight([ + expect.objectContaining({ + expectResults: [ + { + status: "pass", + message: "Expected '<>' to be '<>'", + }, + ], + }), + ]) + }) + + test("errors if the key is not a string", () => { + return expect( + func( + ` + const data = pw.env.getResolve(5) + `, + { + global: [], + selected: [], + } + )() + ).resolves.toBeLeft() + }) +}) diff --git a/packages/hoppscotch-js-sandbox/src/__tests__/testing/envs/resolve.spec.ts b/packages/hoppscotch-js-sandbox/src/__tests__/testing/envs/resolve.spec.ts new file mode 100644 index 000000000..887926e16 --- /dev/null +++ b/packages/hoppscotch-js-sandbox/src/__tests__/testing/envs/resolve.spec.ts @@ -0,0 +1,156 @@ +import { pipe } from "fp-ts/function" +import * as TE from "fp-ts/TaskEither" +import { execTestScript, TestResponse, TestResult } from "../../../test-runner" + +const fakeResponse: TestResponse = { + status: 200, + body: "hoi", + headers: [], +} + +const func = (script: string, envs: TestResult["envs"]) => + pipe( + execTestScript(script, envs, fakeResponse), + TE.map((x) => x.tests) + ) + +describe("pw.env.resolve", () => { + test("value should be a string", () => { + return expect( + func( + ` + pw.env.resolve(5) + `, + { + global: [], + selected: [], + } + )() + ).resolves.toBeLeft() + }) + + test("resolves global variables correctly", () => { + return expect( + func( + ` + const data = pw.env.resolve("<>") + pw.expect(data).toBe("there") + `, + { + global: [ + { + key: "hello", + value: "there", + }, + ], + selected: [], + } + )() + ).resolves.toEqualRight([ + expect.objectContaining({ + expectResults: [ + { + status: "pass", + message: "Expected 'there' to be 'there'", + }, + ], + }), + ]) + }) + + test("resolves selected env variables correctly", () => { + return expect( + func( + ` + const data = pw.env.resolve("<>") + pw.expect(data).toBe("there") + `, + { + global: [], + selected: [ + { + key: "hello", + value: "there", + }, + ], + } + )() + ).resolves.toEqualRight([ + expect.objectContaining({ + expectResults: [ + { + status: "pass", + message: "Expected 'there' to be 'there'", + }, + ], + }), + ]) + }) + + test("chooses selected env variable over global variables when both have same variable", () => { + return expect( + func( + ` + const data = pw.env.resolve("<>") + pw.expect(data).toBe("there") + `, + { + global: [ + { + key: "hello", + value: "yo", + }, + ], + selected: [ + { + key: "hello", + value: "there", + }, + ], + } + )() + ).resolves.toEqualRight([ + expect.objectContaining({ + expectResults: [ + { + status: "pass", + message: "Expected 'there' to be 'there'", + }, + ], + }), + ]) + }) + + test("if infinite loop in resolution, abandons resolutions altogether", () => { + return expect( + func( + ` + const data = pw.env.resolve("<>") + pw.expect(data).toBe("<>") + `, + { + global: [], + selected: [ + { + key: "hello", + value: "<>", + }, + { + key: "there", + value: "<>", + }, + ], + } + )() + ).resolves.toEqualRight([ + expect.objectContaining({ + expectResults: [ + { + status: "pass", + message: "Expected '<>' to be '<>'", + }, + ], + }), + ]) + }) +}) diff --git a/packages/hoppscotch-js-sandbox/src/__tests__/testing/envs/set.spec.ts b/packages/hoppscotch-js-sandbox/src/__tests__/testing/envs/set.spec.ts new file mode 100644 index 000000000..8643ce432 --- /dev/null +++ b/packages/hoppscotch-js-sandbox/src/__tests__/testing/envs/set.spec.ts @@ -0,0 +1,208 @@ +import * as TE from "fp-ts/TaskEither" +import { pipe } from "fp-ts/function" +import { execTestScript, TestResponse, TestResult } from "../../../test-runner" + +const fakeResponse: TestResponse = { + status: 200, + body: "hoi", + headers: [], +} + +const func = (script: string, envs: TestResult["envs"]) => + pipe( + execTestScript(script, envs, fakeResponse), + TE.map((x) => x.envs) + ) + +const funcTest = (script: string, envs: TestResult["envs"]) => + pipe( + execTestScript(script, envs, fakeResponse), + TE.map((x) => x.tests) + ) + +describe("pw.env.set", () => { + test("updates the selected environment variable correctly", () => { + return expect( + func( + ` + pw.env.set("a", "c") + `, + { + global: [], + selected: [ + { + key: "a", + value: "b", + }, + ], + } + )() + ).resolves.toEqualRight( + expect.objectContaining({ + selected: [ + { + key: "a", + value: "c", + }, + ], + }) + ) + }) + + test("updates the global environment variable correctly", () => { + return expect( + func( + ` + pw.env.set("a", "c") + `, + { + global: [ + { + key: "a", + value: "b", + }, + ], + selected: [], + } + )() + ).resolves.toEqualRight( + expect.objectContaining({ + global: [ + { + key: "a", + value: "c", + }, + ], + }) + ) + }) + + test("updates the selected environment if env present in both", () => { + return expect( + func( + ` + pw.env.set("a", "c") + `, + { + global: [ + { + key: "a", + value: "b", + }, + ], + selected: [ + { + key: "a", + value: "d", + }, + ], + } + )() + ).resolves.toEqualRight( + expect.objectContaining({ + global: [ + { + key: "a", + value: "b", + }, + ], + selected: [ + { + key: "a", + value: "c", + }, + ], + }) + ) + }) + + test("non existent keys are created in the selected environment", () => { + return expect( + func( + ` + pw.env.set("a", "c") + `, + { + global: [], + selected: [], + } + )() + ).resolves.toEqualRight( + expect.objectContaining({ + global: [], + selected: [ + { + key: "a", + value: "c", + }, + ], + }) + ) + }) + + test("keys should be a string", () => { + return expect( + func( + ` + pw.env.set(5, "c") + `, + { + global: [], + selected: [], + } + )() + ).resolves.toBeLeft() + }) + + test("values should be a string", () => { + return expect( + func( + ` + pw.env.set("a", 5) + `, + { + global: [], + selected: [], + } + )() + ).resolves.toBeLeft() + }) + + test("both keys and values should be strings", () => { + return expect( + func( + ` + pw.env.set(5, 5) + `, + { + global: [], + selected: [], + } + )() + ).resolves.toBeLeft() + }) + + test("set environment values are reflected in the script execution", () => { + return expect( + funcTest( + ` + pw.env.set("a", "b") + pw.expect(pw.env.get("a")).toBe("b") + `, + { + global: [], + selected: [], + } + )() + ).resolves.toEqualRight([ + expect.objectContaining({ + expectResults: [ + { + status: "pass", + message: "Expected 'b' to be 'b'", + }, + ], + }), + ]) + }) +}) diff --git a/packages/hoppscotch-js-sandbox/src/__tests__/testing/expect/toBe.spec.ts b/packages/hoppscotch-js-sandbox/src/__tests__/testing/expect/toBe.spec.ts index 46ce4f4d6..8187f99db 100644 --- a/packages/hoppscotch-js-sandbox/src/__tests__/testing/expect/toBe.spec.ts +++ b/packages/hoppscotch-js-sandbox/src/__tests__/testing/expect/toBe.spec.ts @@ -1,3 +1,5 @@ +import * as TE from "fp-ts/TaskEither" +import { pipe } from "fp-ts/function" import { execTestScript, TestResponse } from "../../../test-runner" import "@relmify/jest-fp-ts" @@ -7,11 +9,17 @@ const fakeResponse: TestResponse = { headers: [], } +const func = (script: string, res: TestResponse) => + pipe( + execTestScript(script, { global: [], selected: [] }, res), + TE.map((x) => x.tests) + ) + describe("toBe", () => { describe("general assertion (no negation)", () => { test("expect equals expected passes assertion", () => { return expect( - execTestScript( + func( ` pw.expect(2).toBe(2) `, @@ -28,7 +36,7 @@ describe("toBe", () => { test("expect not equals expected fails assertion", () => { return expect( - execTestScript( + func( ` pw.expect(2).toBe(4) `, @@ -47,7 +55,7 @@ describe("toBe", () => { describe("general assertion (with negation)", () => { test("expect equals expected fails assertion", () => { return expect( - execTestScript( + func( ` pw.expect(2).not.toBe(2) `, @@ -67,7 +75,7 @@ describe("toBe", () => { test("expect not equals expected passes assertion", () => { return expect( - execTestScript( + func( ` pw.expect(2).not.toBe(4) `, @@ -89,7 +97,7 @@ describe("toBe", () => { test("strict checks types", () => { return expect( - execTestScript( + func( ` pw.expect(2).toBe("2") `, diff --git a/packages/hoppscotch-js-sandbox/src/__tests__/testing/expect/toBeLevelxxx.spec.ts b/packages/hoppscotch-js-sandbox/src/__tests__/testing/expect/toBeLevelxxx.spec.ts index a57c83f9b..fdd694a00 100644 --- a/packages/hoppscotch-js-sandbox/src/__tests__/testing/expect/toBeLevelxxx.spec.ts +++ b/packages/hoppscotch-js-sandbox/src/__tests__/testing/expect/toBeLevelxxx.spec.ts @@ -1,3 +1,5 @@ +import * as TE from "fp-ts/TaskEither" +import { pipe } from "fp-ts/function" import { execTestScript, TestResponse } from "../../../test-runner" import "@relmify/jest-fp-ts" @@ -7,11 +9,17 @@ const fakeResponse: TestResponse = { headers: [], } +const func = (script: string, res: TestResponse) => + pipe( + execTestScript(script, { global: [], selected: [] }, res), + TE.map((x) => x.tests) + ) + describe("toBeLevel2xx", () => { test("assertion passes for 200 series with no negation", async () => { for (let i = 200; i < 300; i++) { await expect( - execTestScript(`pw.expect(${i}).toBeLevel2xx()`, fakeResponse)() + func(`pw.expect(${i}).toBeLevel2xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -28,7 +36,7 @@ describe("toBeLevel2xx", () => { test("assertion fails for non 200 series with no negation", async () => { for (let i = 300; i < 500; i++) { await expect( - execTestScript(`pw.expect(${i}).toBeLevel2xx()`, fakeResponse)() + func(`pw.expect(${i}).toBeLevel2xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -44,7 +52,7 @@ describe("toBeLevel2xx", () => { test("give error if the expect value was not a number with no negation", async () => { await expect( - execTestScript(`pw.expect("foo").toBeLevel2xx()`, fakeResponse)() + func(`pw.expect("foo").toBeLevel2xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -61,7 +69,7 @@ describe("toBeLevel2xx", () => { test("assertion fails for 200 series with negation", async () => { for (let i = 200; i < 300; i++) { await expect( - execTestScript(`pw.expect(${i}).not.toBeLevel2xx()`, fakeResponse)() + func(`pw.expect(${i}).not.toBeLevel2xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -78,7 +86,7 @@ describe("toBeLevel2xx", () => { test("assertion passes for non 200 series with negation", async () => { for (let i = 300; i < 500; i++) { await expect( - execTestScript(`pw.expect(${i}).not.toBeLevel2xx()`, fakeResponse)() + func(`pw.expect(${i}).not.toBeLevel2xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -94,7 +102,7 @@ describe("toBeLevel2xx", () => { test("give error if the expect value was not a number with negation", async () => { await expect( - execTestScript(`pw.expect("foo").not.toBeLevel2xx()`, fakeResponse)() + func(`pw.expect("foo").not.toBeLevel2xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -113,7 +121,7 @@ describe("toBeLevel3xx", () => { test("assertion passes for 300 series with no negation", async () => { for (let i = 300; i < 400; i++) { await expect( - execTestScript(`pw.expect(${i}).toBeLevel3xx()`, fakeResponse)() + func(`pw.expect(${i}).toBeLevel3xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -130,7 +138,7 @@ describe("toBeLevel3xx", () => { test("assertion fails for non 300 series with no negation", async () => { for (let i = 400; i < 500; i++) { await expect( - execTestScript(`pw.expect(${i}).toBeLevel3xx()`, fakeResponse)() + func(`pw.expect(${i}).toBeLevel3xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -146,7 +154,7 @@ describe("toBeLevel3xx", () => { test("give error if the expect value is not a number without negation", () => { return expect( - execTestScript(`pw.expect("foo").toBeLevel3xx()`, fakeResponse)() + func(`pw.expect("foo").toBeLevel3xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -163,7 +171,7 @@ describe("toBeLevel3xx", () => { test("assertion fails for 400 series with negation", async () => { for (let i = 300; i < 400; i++) { await expect( - execTestScript(`pw.expect(${i}).not.toBeLevel3xx()`, fakeResponse)() + func(`pw.expect(${i}).not.toBeLevel3xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -180,7 +188,7 @@ describe("toBeLevel3xx", () => { test("assertion passes for non 200 series with negation", async () => { for (let i = 400; i < 500; i++) { await expect( - execTestScript(`pw.expect(${i}).not.toBeLevel3xx()`, fakeResponse)() + func(`pw.expect(${i}).not.toBeLevel3xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -196,7 +204,7 @@ describe("toBeLevel3xx", () => { test("give error if the expect value is not a number with negation", () => { return expect( - execTestScript(`pw.expect("foo").not.toBeLevel3xx()`, fakeResponse)() + func(`pw.expect("foo").not.toBeLevel3xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -215,7 +223,7 @@ describe("toBeLevel4xx", () => { test("assertion passes for 400 series with no negation", async () => { for (let i = 400; i < 500; i++) { await expect( - execTestScript(`pw.expect(${i}).toBeLevel4xx()`, fakeResponse)() + func(`pw.expect(${i}).toBeLevel4xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -232,7 +240,7 @@ describe("toBeLevel4xx", () => { test("assertion fails for non 400 series with no negation", async () => { for (let i = 500; i < 600; i++) { await expect( - execTestScript(`pw.expect(${i}).toBeLevel4xx()`, fakeResponse)() + func(`pw.expect(${i}).toBeLevel4xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -248,7 +256,7 @@ describe("toBeLevel4xx", () => { test("give error if the expected value is not a number without negation", () => { return expect( - execTestScript(`pw.expect("foo").toBeLevel4xx()`, fakeResponse)() + func(`pw.expect("foo").toBeLevel4xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -265,7 +273,7 @@ describe("toBeLevel4xx", () => { test("assertion fails for 400 series with negation", async () => { for (let i = 400; i < 500; i++) { await expect( - execTestScript(`pw.expect(${i}).not.toBeLevel4xx()`, fakeResponse)() + func(`pw.expect(${i}).not.toBeLevel4xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -282,7 +290,7 @@ describe("toBeLevel4xx", () => { test("assertion passes for non 400 series with negation", async () => { for (let i = 500; i < 600; i++) { await expect( - execTestScript(`pw.expect(${i}).not.toBeLevel4xx()`, fakeResponse)() + func(`pw.expect(${i}).not.toBeLevel4xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -298,7 +306,7 @@ describe("toBeLevel4xx", () => { test("give error if the expected value is not a number with negation", () => { return expect( - execTestScript(`pw.expect("foo").not.toBeLevel4xx()`, fakeResponse)() + func(`pw.expect("foo").not.toBeLevel4xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -317,7 +325,7 @@ describe("toBeLevel5xx", () => { test("assertion passes for 500 series with no negation", async () => { for (let i = 500; i < 600; i++) { await expect( - execTestScript(`pw.expect(${i}).toBeLevel5xx()`, fakeResponse)() + func(`pw.expect(${i}).toBeLevel5xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -334,7 +342,7 @@ describe("toBeLevel5xx", () => { test("assertion fails for non 500 series with no negation", async () => { for (let i = 200; i < 500; i++) { await expect( - execTestScript(`pw.expect(${i}).toBeLevel5xx()`, fakeResponse)() + func(`pw.expect(${i}).toBeLevel5xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -350,7 +358,7 @@ describe("toBeLevel5xx", () => { test("give error if the expect value is not a number with no negation", () => { return expect( - execTestScript(`pw.expect("foo").toBeLevel5xx()`, fakeResponse)() + func(`pw.expect("foo").toBeLevel5xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -367,7 +375,7 @@ describe("toBeLevel5xx", () => { test("assertion fails for 500 series with negation", async () => { for (let i = 500; i < 600; i++) { await expect( - execTestScript(`pw.expect(${i}).not.toBeLevel5xx()`, fakeResponse)() + func(`pw.expect(${i}).not.toBeLevel5xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -384,7 +392,7 @@ describe("toBeLevel5xx", () => { test("assertion passes for non 500 series with negation", async () => { for (let i = 200; i < 500; i++) { await expect( - execTestScript(`pw.expect(${i}).not.toBeLevel5xx()`, fakeResponse)() + func(`pw.expect(${i}).not.toBeLevel5xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ @@ -400,7 +408,7 @@ describe("toBeLevel5xx", () => { test("give error if the expect value is not a number with negation", () => { return expect( - execTestScript(`pw.expect("foo").not.toBeLevel5xx()`, fakeResponse)() + func(`pw.expect("foo").not.toBeLevel5xx()`, fakeResponse)() ).resolves.toEqualRight([ expect.objectContaining({ expectResults: [ diff --git a/packages/hoppscotch-js-sandbox/src/__tests__/testing/expect/toBeType.spec.ts b/packages/hoppscotch-js-sandbox/src/__tests__/testing/expect/toBeType.spec.ts index 2aa3b1bb5..b0fe9bd5a 100644 --- a/packages/hoppscotch-js-sandbox/src/__tests__/testing/expect/toBeType.spec.ts +++ b/packages/hoppscotch-js-sandbox/src/__tests__/testing/expect/toBeType.spec.ts @@ -1,3 +1,5 @@ +import * as TE from "fp-ts/TaskEither" +import { pipe } from "fp-ts/function" import { execTestScript, TestResponse } from "../../../test-runner" const fakeResponse: TestResponse = { @@ -6,10 +8,16 @@ const fakeResponse: TestResponse = { headers: [], } +const func = (script: string, res: TestResponse) => + pipe( + execTestScript(script, { global: [], selected: [] }, res), + TE.map((x) => x.tests) + ) + describe("toBeType", () => { test("asserts true for valid type expectations with no negation", () => { return expect( - execTestScript( + func( ` pw.expect(2).toBeType("number") pw.expect("2").toBeType("string") @@ -40,7 +48,7 @@ describe("toBeType", () => { test("asserts false for invalid type expectations with no negation", () => { return expect( - execTestScript( + func( ` pw.expect(2).toBeType("string") pw.expect("2").toBeType("number") @@ -71,7 +79,7 @@ describe("toBeType", () => { test("asserts false for valid type expectations with negation", () => { return expect( - execTestScript( + func( ` pw.expect(2).not.toBeType("number") pw.expect("2").not.toBeType("string") @@ -105,7 +113,7 @@ describe("toBeType", () => { test("asserts true for invalid type expectations with negation", () => { return expect( - execTestScript( + func( ` pw.expect(2).not.toBeType("string") pw.expect("2").not.toBeType("number") @@ -139,7 +147,7 @@ describe("toBeType", () => { test("gives error for invalid type names without negation", () => { return expect( - execTestScript( + func( ` pw.expect(2).toBeType("foo") pw.expect("2").toBeType("bar") @@ -179,7 +187,7 @@ describe("toBeType", () => { test("gives error for invalid type names with negation", () => { return expect( - execTestScript( + func( ` pw.expect(2).not.toBeType("foo") pw.expect("2").not.toBeType("bar") diff --git a/packages/hoppscotch-js-sandbox/src/__tests__/testing/expect/toHaveLength.spec.ts b/packages/hoppscotch-js-sandbox/src/__tests__/testing/expect/toHaveLength.spec.ts index c8e00c640..5d456b632 100644 --- a/packages/hoppscotch-js-sandbox/src/__tests__/testing/expect/toHaveLength.spec.ts +++ b/packages/hoppscotch-js-sandbox/src/__tests__/testing/expect/toHaveLength.spec.ts @@ -1,3 +1,5 @@ +import * as TE from "fp-ts/TaskEither" +import { pipe } from "fp-ts/function" import { execTestScript, TestResponse } from "../../../test-runner" const fakeResponse: TestResponse = { @@ -6,10 +8,16 @@ const fakeResponse: TestResponse = { headers: [], } +const func = (script: string, res: TestResponse) => + pipe( + execTestScript(script, { global: [], selected: [] }, res), + TE.map((x) => x.tests) + ) + describe("toHaveLength", () => { test("asserts true for valid lengths with no negation", () => { return expect( - execTestScript( + func( ` pw.expect([1, 2, 3, 4]).toHaveLength(4) pw.expect([]).toHaveLength(0) @@ -28,7 +36,7 @@ describe("toHaveLength", () => { test("asserts false for invalid lengths with no negation", () => { return expect( - execTestScript( + func( ` pw.expect([]).toHaveLength(4) pw.expect([1, 2, 3, 4]).toHaveLength(0) @@ -47,7 +55,7 @@ describe("toHaveLength", () => { test("asserts false for valid lengths with negation", () => { return expect( - execTestScript( + func( ` pw.expect([1, 2, 3, 4]).not.toHaveLength(4) pw.expect([]).not.toHaveLength(0) @@ -72,7 +80,7 @@ describe("toHaveLength", () => { test("asserts true for invalid lengths with negation", () => { return expect( - execTestScript( + func( ` pw.expect([]).not.toHaveLength(4) pw.expect([1, 2, 3, 4]).not.toHaveLength(0) @@ -97,7 +105,7 @@ describe("toHaveLength", () => { test("gives error if not called on an array or a string with no negation", () => { return expect( - execTestScript( + func( ` pw.expect(5).toHaveLength(0) pw.expect(true).toHaveLength(0) @@ -124,7 +132,7 @@ describe("toHaveLength", () => { test("gives error if not called on an array or a string with negation", () => { return expect( - execTestScript( + func( ` pw.expect(5).not.toHaveLength(0) pw.expect(true).not.toHaveLength(0) @@ -151,7 +159,7 @@ describe("toHaveLength", () => { test("gives an error if toHaveLength parameter is not a number without negation", () => { return expect( - execTestScript( + func( ` pw.expect([1, 2, 3, 4]).toHaveLength("a") `, @@ -171,7 +179,7 @@ describe("toHaveLength", () => { test("gives an error if toHaveLength parameter is not a number with negation", () => { return expect( - execTestScript( + func( ` pw.expect([1, 2, 3, 4]).not.toHaveLength("a") `, diff --git a/packages/hoppscotch-js-sandbox/src/__tests__/testing/test-runner.spec.ts b/packages/hoppscotch-js-sandbox/src/__tests__/testing/test-runner.spec.ts index d9a8c1460..0eb32570f 100644 --- a/packages/hoppscotch-js-sandbox/src/__tests__/testing/test-runner.spec.ts +++ b/packages/hoppscotch-js-sandbox/src/__tests__/testing/test-runner.spec.ts @@ -1,3 +1,5 @@ +import * as TE from "fp-ts/TaskEither" +import { pipe } from "fp-ts/function" import { execTestScript, TestResponse } from "../../test-runner" const fakeResponse: TestResponse = { @@ -6,10 +8,16 @@ const fakeResponse: TestResponse = { headers: [], } +const func = (script: string, res: TestResponse) => + pipe( + execTestScript(script, { global: [], selected: [] }, res), + TE.map((x) => x.tests) + ) + describe("execTestScript function behavior", () => { test("returns a resolved promise for a valid test scripts with all green", () => { return expect( - execTestScript( + func( ` pw.test("Arithmetic operations", () => { const size = 500 + 500; @@ -26,7 +34,7 @@ describe("execTestScript function behavior", () => { test("resolves for tests with failed expectations", () => { return expect( - execTestScript( + func( ` pw.test("Arithmetic operations", () => { const size = 500 + 500; @@ -44,7 +52,7 @@ describe("execTestScript function behavior", () => { // TODO: We need a more concrete behavior for this test("rejects for invalid syntax on tests", () => { return expect( - execTestScript( + func( ` pw.test("Arithmetic operations", () => { const size = 500 + 500; diff --git a/packages/hoppscotch-js-sandbox/src/index.ts b/packages/hoppscotch-js-sandbox/src/index.ts index 4a9df9191..a41a29fac 100644 --- a/packages/hoppscotch-js-sandbox/src/index.ts +++ b/packages/hoppscotch-js-sandbox/src/index.ts @@ -1,22 +1,34 @@ -import { pipe } from "fp-ts/lib/function" -import { chain, right } from "fp-ts/lib/TaskEither" +import { pipe } from "fp-ts/function" +import * as TE from "fp-ts/TaskEither" import { execPreRequestScript } from "./preRequest" import { execTestScript, TestResponse, TestDescriptor as _TestDescriptor, + TestResult, } from "./test-runner" export type TestDescriptor = _TestDescriptor +export type SandboxTestResult = TestResult & { tests: TestDescriptor } + /** * Executes a given test script on the test-runner sandbox * @param testScript The string of the script to run * @returns A TaskEither with an error message or a TestDescriptor with the final status */ -export const runTestScript = (testScript: string, response: TestResponse) => +export const runTestScript = ( + testScript: string, + envs: TestResult["envs"], + response: TestResponse +) => pipe( - execTestScript(testScript, response), - chain((results) => right(results[0])) // execTestScript returns an array of descriptors with a single element (extract that) + execTestScript(testScript, envs, response), + TE.chain((results) => + TE.right({ + envs: results.envs, + tests: results.tests[0], + }) + ) // execTestScript returns an array of descriptors with a single element (extract that) ) /** diff --git a/packages/hoppscotch-js-sandbox/src/preRequest.ts b/packages/hoppscotch-js-sandbox/src/preRequest.ts index 4ff79eb7f..3c61576bf 100644 --- a/packages/hoppscotch-js-sandbox/src/preRequest.ts +++ b/packages/hoppscotch-js-sandbox/src/preRequest.ts @@ -1,63 +1,148 @@ -import { pipe } from "fp-ts/lib/function" -import { chain, TaskEither, tryCatch, right, left } from "fp-ts/lib/TaskEither" +import { pipe } from "fp-ts/function" +import * as O from "fp-ts/Option" +import * as E from "fp-ts/Either" +import * as TE from "fp-ts/lib/TaskEither" import * as qjs from "quickjs-emscripten" -import clone from "lodash/clone" +import cloneDeep from "lodash/clone" +import { Environment, parseTemplateStringE } from "@hoppscotch/data" +import { getEnv, setEnv } from "./utils" -type EnvEntry = { - key: string - value: string +type Envs = { + global: Environment["variables"] + selected: Environment["variables"] } export const execPreRequestScript = ( preRequestScript: string, - env: EnvEntry[] -): TaskEither => + envs: Envs +): TE.TaskEither => pipe( - tryCatch( + TE.tryCatch( async () => await qjs.getQuickJS(), (reason) => `QuickJS initialization failed: ${reason}` ), - chain((QuickJS) => { - const finalEnv = clone(env) + TE.chain((QuickJS) => { + let currentEnvs = cloneDeep(envs) const vm = QuickJS.createVm() const pwHandle = vm.newObject() + // Environment management APIs + // TODO: Unified Implementation const envHandle = vm.newObject() - const envSetFuncHandle = vm.newFunction( - "set", - (keyHandle, valueHandle) => { - const key = vm.dump(keyHandle) - const value = vm.dump(valueHandle) - - if (typeof key !== "string") - return { - error: vm.newString("Expected key to be a string"), - } - - if (typeof value !== "string") - return { - error: vm.newString("Expected value to be a string"), - } - - const keyIndex = finalEnv.findIndex((env) => env.key === key) - - if (keyIndex === -1) { - finalEnv.push({ key, value }) - } else { - finalEnv[keyIndex] = { key, value } - } + const envGetHandle = vm.newFunction("get", (keyHandle) => { + const key: unknown = vm.dump(keyHandle) + if (typeof key !== "string") { return { - value: vm.undefined, + error: vm.newString("Expected key to be a string"), } } - ) - vm.setProp(envHandle, "set", envSetFuncHandle) - envSetFuncHandle.dispose() + const result = pipe( + getEnv(key, currentEnvs), + O.match( + () => vm.undefined, + ({ value }) => vm.newString(value) + ) + ) + + return { + value: result, + } + }) + + const envGetResolveHandle = vm.newFunction("getResolve", (keyHandle) => { + const key: unknown = vm.dump(keyHandle) + + if (typeof key !== "string") { + return { + error: vm.newString("Expected key to be a string"), + } + } + + const result = pipe( + getEnv(key, currentEnvs), + E.fromOption(() => "INVALID_KEY" as const), + + E.map(({ value }) => + pipe( + parseTemplateStringE(value, [...envs.selected, ...envs.global]), + // If the recursive resolution failed, return the unresolved value + E.getOrElse(() => value) + ) + ), + + // Create a new VM String + // NOTE: Do not shorten this to map(vm.newString) apparently it breaks it + E.map((x) => vm.newString(x)), + + E.getOrElse(() => vm.undefined) + ) + + return { + value: result, + } + }) + + const envSetHandle = vm.newFunction("set", (keyHandle, valueHandle) => { + const key: unknown = vm.dump(keyHandle) + const value: unknown = vm.dump(valueHandle) + + if (typeof key !== "string") { + return { + error: vm.newString("Expected key to be a string"), + } + } + + if (typeof value !== "string") { + return { + error: vm.newString("Expected value to be a string"), + } + } + + currentEnvs = setEnv(key, value, currentEnvs) + + return { + value: vm.undefined, + } + }) + + const envResolveHandle = vm.newFunction("resolve", (valueHandle) => { + const value: unknown = vm.dump(valueHandle) + + if (typeof value !== "string") { + return { + error: vm.newString("Expected value to be a string"), + } + } + + const result = pipe( + parseTemplateStringE(value, [ + ...currentEnvs.selected, + ...currentEnvs.global, + ]), + E.getOrElse(() => value) + ) + + return { + value: vm.newString(result), + } + }) + + vm.setProp(envHandle, "resolve", envResolveHandle) + envResolveHandle.dispose() + + vm.setProp(envHandle, "set", envSetHandle) + envSetHandle.dispose() + + vm.setProp(envHandle, "getResolve", envGetResolveHandle) + envGetResolveHandle.dispose() + + vm.setProp(envHandle, "get", envGetHandle) + envGetHandle.dispose() vm.setProp(pwHandle, "env", envHandle) envHandle.dispose() @@ -71,11 +156,11 @@ export const execPreRequestScript = ( const errorData = vm.dump(evalRes.error) evalRes.error.dispose() - return left(errorData) + return TE.left(errorData) } vm.dispose() - return right(finalEnv) + return TE.right(currentEnvs) }) ) diff --git a/packages/hoppscotch-js-sandbox/src/test-runner.ts b/packages/hoppscotch-js-sandbox/src/test-runner.ts index 58f584375..9967266f8 100644 --- a/packages/hoppscotch-js-sandbox/src/test-runner.ts +++ b/packages/hoppscotch-js-sandbox/src/test-runner.ts @@ -1,8 +1,11 @@ -import { isLeft } from "fp-ts/lib/Either" -import { pipe } from "fp-ts/lib/function" -import { TaskEither, tryCatch, chain, right, left } from "fp-ts/lib/TaskEither" +import * as O from "fp-ts/Option" +import * as E from "fp-ts/Either" +import * as TE from "fp-ts/TaskEither" +import { pipe } from "fp-ts/function" import * as qjs from "quickjs-emscripten" -import { marshalObjectToVM } from "./utils" +import { Environment, parseTemplateStringE } from "@hoppscotch/data" +import cloneDeep from "lodash/cloneDeep" +import { getEnv, marshalObjectToVM, setEnv } from "./utils" /** * The response object structure exposed to the test script @@ -44,6 +47,17 @@ export type TestDescriptor = { children: TestDescriptor[] } +/** + * Defines the result of a test script execution + */ +export type TestResult = { + tests: TestDescriptor[] + envs: { + global: Environment["variables"] + selected: Environment["variables"] + } +} + /** * Creates an Expectation object for use inside the sandbox * @param vm The QuickJS sandbox VM instance @@ -325,16 +339,19 @@ function createExpectation( export const execTestScript = ( testScript: string, + envs: TestResult["envs"], response: TestResponse -): TaskEither => +): TE.TaskEither => pipe( - tryCatch( + TE.tryCatch( async () => await qjs.getQuickJS(), (reason) => `QuickJS initialization failed: ${reason}` ), - chain( + TE.chain( // TODO: Make this more functional ? (QuickJS) => { + let currentEnvs = cloneDeep(envs) + const vm = QuickJS.createVm() const pwHandle = vm.newObject() @@ -374,8 +391,10 @@ export const execTestScript = ( // Marshal response object const responseObjHandle = marshalObjectToVM(vm, response) - if (isLeft(responseObjHandle)) - return left(`Response marshalling failed: ${responseObjHandle.left}`) + if (E.isLeft(responseObjHandle)) + return TE.left( + `Response marshalling failed: ${responseObjHandle.left}` + ) vm.setProp(pwHandle, "response", responseObjHandle.right) responseObjHandle.right.dispose() @@ -386,6 +405,131 @@ export const execTestScript = ( vm.setProp(pwHandle, "test", testFuncHandle) testFuncHandle.dispose() + // Environment management APIs + // TODO: Unified Implementation + const envHandle = vm.newObject() + + const envGetHandle = vm.newFunction("get", (keyHandle) => { + const key: unknown = vm.dump(keyHandle) + + if (typeof key !== "string") { + return { + error: vm.newString("Expected key to be a string"), + } + } + + const result = pipe( + getEnv(key, currentEnvs), + O.match( + () => vm.undefined, + ({ value }) => vm.newString(value) + ) + ) + + return { + value: result, + } + }) + + const envGetResolveHandle = vm.newFunction( + "getResolve", + (keyHandle) => { + const key: unknown = vm.dump(keyHandle) + + if (typeof key !== "string") { + return { + error: vm.newString("Expected key to be a string"), + } + } + + const result = pipe( + getEnv(key, currentEnvs), + E.fromOption(() => "INVALID_KEY" as const), + + E.map(({ value }) => + pipe( + parseTemplateStringE(value, [ + ...envs.selected, + ...envs.global, + ]), + // If the recursive resolution failed, return the unresolved value + E.getOrElse(() => value) + ) + ), + + // Create a new VM String + // NOTE: Do not shorten this to map(vm.newString) apparently it breaks it + E.map((x) => vm.newString(x)), + + E.getOrElse(() => vm.undefined) + ) + + return { + value: result, + } + } + ) + + const envSetHandle = vm.newFunction("set", (keyHandle, valueHandle) => { + const key: unknown = vm.dump(keyHandle) + const value: unknown = vm.dump(valueHandle) + + if (typeof key !== "string") { + return { + error: vm.newString("Expected key to be a string"), + } + } + + if (typeof value !== "string") { + return { + error: vm.newString("Expected value to be a string"), + } + } + + currentEnvs = setEnv(key, value, currentEnvs) + + return { + value: vm.undefined, + } + }) + + const envResolveHandle = vm.newFunction("resolve", (valueHandle) => { + const value: unknown = vm.dump(valueHandle) + + if (typeof value !== "string") { + return { + error: vm.newString("Expected value to be a string"), + } + } + + const result = pipe( + parseTemplateStringE(value, [ + ...currentEnvs.selected, + ...currentEnvs.global, + ]), + E.getOrElse(() => value) + ) + + return { + value: vm.newString(result), + } + }) + + vm.setProp(envHandle, "resolve", envResolveHandle) + envResolveHandle.dispose() + + vm.setProp(envHandle, "set", envSetHandle) + envSetHandle.dispose() + + vm.setProp(envHandle, "getResolve", envGetResolveHandle) + envGetResolveHandle.dispose() + + vm.setProp(envHandle, "get", envGetHandle) + envGetHandle.dispose() + + vm.setProp(pwHandle, "env", envHandle) + envHandle.dispose() + vm.setProp(vm.global, "pw", pwHandle) pwHandle.dispose() @@ -395,12 +539,15 @@ export const execTestScript = ( const errorData = vm.dump(evalRes.error) evalRes.error.dispose() - return left(`Script evaluation failed: ${errorData}`) + return TE.left(`Script evaluation failed: ${errorData}`) } vm.dispose() - return right(testRunStack) + return TE.right({ + tests: testRunStack, + envs: currentEnvs, + }) } ) ) diff --git a/packages/hoppscotch-js-sandbox/src/utils.ts b/packages/hoppscotch-js-sandbox/src/utils.ts index 90b2d4848..e5ea14064 100644 --- a/packages/hoppscotch-js-sandbox/src/utils.ts +++ b/packages/hoppscotch-js-sandbox/src/utils.ts @@ -1,16 +1,18 @@ -import { Either, left, right } from "fp-ts/lib/Either" +import * as O from "fp-ts/Option" +import * as E from "fp-ts/Either" import * as QuickJS from "quickjs-emscripten" +import { TestResult } from "./test-runner" export function marshalObjectToVM( vm: QuickJS.QuickJSVm, obj: object -): Either { +): E.Either { let jsonString try { jsonString = JSON.stringify(obj) } catch (e) { - return left("Marshaling stringification failed") + return E.left("Marshaling stringification failed") } const vmStringHandle = vm.newString(jsonString) @@ -26,7 +28,7 @@ export function marshalObjectToVM( if (parseResultHandle.error) { parseResultHandle.error.dispose() - return left("Marshaling failed") + return E.left("Marshaling failed") } const resultHandle = vm.unwrapResult(parseResultHandle) @@ -35,5 +37,53 @@ export function marshalObjectToVM( parseFuncHandle.dispose() jsonHandle.dispose() - return right(resultHandle) + return E.right(resultHandle) +} + +export function getEnv(envName: string, envs: TestResult["envs"]) { + return O.fromNullable( + envs.selected.find((x) => x.key === envName) ?? + envs.global.find((x) => x.key === envName) + ) +} + +export function setEnv( + envName: string, + envValue: string, + envs: TestResult["envs"] +): TestResult["envs"] { + const indexInSelected = envs.selected.findIndex((x) => x.key === envName) + + // Found the match in selected + if (indexInSelected >= 0) { + envs.selected[indexInSelected].value = envValue + + return { + global: envs.global, + selected: envs.selected, + } + } + + const indexInGlobal = envs.global.findIndex((x) => x.key == envName) + + // Found a match in globals + if (indexInGlobal >= 0) { + envs.global[indexInGlobal].value = envValue + + return { + global: envs.global, + selected: envs.selected, + } + } + + // Didn't find in both places, create a new variable in selected + envs.selected.push({ + key: envName, + value: envValue, + }) + + return { + global: envs.global, + selected: envs.selected, + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a8beda605..fc6baff56 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,9 +35,9 @@ importers: devDependencies: '@lezer/generator': 0.15.4 mocha: 9.2.1 - rollup: 2.67.3 - rollup-plugin-dts: 4.1.0_rollup@2.67.3+typescript@4.5.5 - rollup-plugin-ts: 2.0.5_rollup@2.67.3+typescript@4.5.5 + rollup: 2.68.0 + rollup-plugin-dts: 4.1.0_rollup@2.68.0+typescript@4.5.5 + rollup-plugin-ts: 2.0.5_rollup@2.68.0+typescript@4.5.5 typescript: 4.5.5 packages/hoppscotch-app: @@ -76,7 +76,7 @@ importers: '@graphql-typed-document-node/core': ^3.1.1 '@hoppscotch/codemirror-lang-graphql': workspace:^0.1.0 '@hoppscotch/data': workspace:^0.4.0 - '@hoppscotch/js-sandbox': workspace:^1.0.0 + '@hoppscotch/js-sandbox': workspace:^2.0.0 '@nuxt/types': ^2.15.8 '@nuxt/typescript-build': ^2.1.0 '@nuxtjs/axios': ^5.13.6 @@ -345,6 +345,7 @@ importers: packages/hoppscotch-js-sandbox: specifiers: '@digitak/esrun': ^3.1.2 + '@hoppscotch/data': workspace:^0.4.0 '@relmify/jest-fp-ts': ^1.1.1 '@types/jest': ^27.4.0 '@types/lodash': ^4.14.178 @@ -363,6 +364,7 @@ importers: ts-jest: ^27.1.3 typescript: ^4.5.5 dependencies: + '@hoppscotch/data': link:../hoppscotch-data fp-ts: 2.11.8 lodash: 4.17.21 quickjs-emscripten: 0.15.0 @@ -468,6 +470,29 @@ packages: resolution: {integrity: sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==} engines: {node: '>=6.9.0'} + /@babel/core/7.17.4: + resolution: {integrity: sha512-R9x5r4t4+hBqZTmioSnkrW+I6NmbojwjGT8p4G2Gw1thWbXIHGDnmGdLdFw0/7ljucdIrNRp7Npgb4CyBYzzJg==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.1.2 + '@babel/code-frame': 7.16.7 + '@babel/generator': 7.17.3 + '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.17.4 + '@babel/helper-module-transforms': 7.16.7 + '@babel/helpers': 7.17.2 + '@babel/parser': 7.17.3 + '@babel/template': 7.16.7 + '@babel/traverse': 7.17.3 + '@babel/types': 7.17.0 + convert-source-map: 1.8.0 + debug: 4.3.3 + gensync: 1.0.0-beta.2 + json5: 2.2.0 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/core/7.17.5: resolution: {integrity: sha512-/BBMw4EvjmyquN5O+t5eh0+YqB3XXJkYD2cjKpYtWOfFy4lQ4UozNSmxAcWT8r2XtZs0ewG+zrfsqeR15i1ajA==} engines: {node: '>=6.9.0'} @@ -532,27 +557,27 @@ packages: resolution: {integrity: sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.16.8 + '@babel/types': 7.17.0 /@babel/helper-builder-binary-assignment-operator-visitor/7.16.7: resolution: {integrity: sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-explode-assignable-expression': 7.16.7 - '@babel/types': 7.16.8 + '@babel/types': 7.17.0 - /@babel/helper-compilation-targets/7.16.0_@babel+core@7.17.5: - resolution: {integrity: sha512-S7iaOT1SYlqK0sQaCi21RX4+13hmdmnxIEAnQUB/eh7GeAnRjOUgTYpLkUOiRXzD+yog1JxP0qyAQZ7ZxVxLVg==} + /@babel/helper-compilation-targets/7.16.7_@babel+core@7.17.4: + resolution: {integrity: sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/compat-data': 7.16.8 - '@babel/core': 7.17.5 + '@babel/compat-data': 7.17.0 + '@babel/core': 7.17.4 '@babel/helper-validator-option': 7.16.7 - browserslist: 4.17.5 + browserslist: 4.19.1 semver: 6.3.0 - dev: false + dev: true /@babel/helper-compilation-targets/7.16.7_@babel+core@7.17.5: resolution: {integrity: sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==} @@ -616,7 +641,7 @@ packages: '@babel/core': ^7.4.0-0 dependencies: '@babel/core': 7.17.5 - '@babel/helper-compilation-targets': 7.16.0_@babel+core@7.17.5 + '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.17.5 '@babel/helper-module-imports': 7.16.7 '@babel/helper-plugin-utils': 7.16.7 '@babel/traverse': 7.17.3 @@ -637,7 +662,7 @@ packages: '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.17.5 '@babel/helper-module-imports': 7.16.7 '@babel/helper-plugin-utils': 7.16.7 - '@babel/traverse': 7.16.10 + '@babel/traverse': 7.17.3 debug: 4.3.3 lodash.debounce: 4.0.8 resolve: 1.20.0 @@ -655,15 +680,15 @@ packages: resolution: {integrity: sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.16.8 + '@babel/types': 7.17.0 /@babel/helper-function-name/7.16.0: resolution: {integrity: sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-get-function-arity': 7.16.0 - '@babel/template': 7.16.0 - '@babel/types': 7.16.8 + '@babel/template': 7.16.7 + '@babel/types': 7.17.0 /@babel/helper-function-name/7.16.7: resolution: {integrity: sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==} @@ -677,7 +702,7 @@ packages: resolution: {integrity: sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.16.8 + '@babel/types': 7.17.0 /@babel/helper-get-function-arity/7.16.7: resolution: {integrity: sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==} @@ -689,7 +714,7 @@ packages: resolution: {integrity: sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.16.8 + '@babel/types': 7.17.0 /@babel/helper-hoist-variables/7.16.7: resolution: {integrity: sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==} @@ -701,7 +726,7 @@ packages: resolution: {integrity: sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.16.8 + '@babel/types': 7.17.0 /@babel/helper-module-imports/7.16.0: resolution: {integrity: sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==} @@ -735,7 +760,7 @@ packages: resolution: {integrity: sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.16.8 + '@babel/types': 7.17.0 /@babel/helper-plugin-utils/7.16.7: resolution: {integrity: sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==} @@ -747,7 +772,7 @@ packages: dependencies: '@babel/helper-annotate-as-pure': 7.16.7 '@babel/helper-wrap-function': 7.16.8 - '@babel/types': 7.16.8 + '@babel/types': 7.17.0 transitivePeerDependencies: - supports-color @@ -758,8 +783,8 @@ packages: '@babel/helper-environment-visitor': 7.16.7 '@babel/helper-member-expression-to-functions': 7.16.7 '@babel/helper-optimise-call-expression': 7.16.7 - '@babel/traverse': 7.16.10 - '@babel/types': 7.16.8 + '@babel/traverse': 7.17.3 + '@babel/types': 7.17.0 transitivePeerDependencies: - supports-color @@ -773,13 +798,13 @@ packages: resolution: {integrity: sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.16.8 + '@babel/types': 7.17.0 /@babel/helper-split-export-declaration/7.16.0: resolution: {integrity: sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.16.8 + '@babel/types': 7.17.0 /@babel/helper-split-export-declaration/7.16.7: resolution: {integrity: sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==} @@ -806,8 +831,8 @@ packages: dependencies: '@babel/helper-function-name': 7.16.7 '@babel/template': 7.16.7 - '@babel/traverse': 7.17.0 - '@babel/types': 7.16.8 + '@babel/traverse': 7.17.3 + '@babel/types': 7.17.0 transitivePeerDependencies: - supports-color @@ -1073,6 +1098,15 @@ packages: '@babel/helper-create-regexp-features-plugin': 7.16.7_@babel+core@7.17.5 '@babel/helper-plugin-utils': 7.16.7 + /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.17.4: + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.17.4 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.17.5: resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: @@ -1081,6 +1115,15 @@ packages: '@babel/core': 7.17.5 '@babel/helper-plugin-utils': 7.16.7 + /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.17.4: + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.17.4 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.17.5: resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} peerDependencies: @@ -1090,6 +1133,15 @@ packages: '@babel/helper-plugin-utils': 7.16.7 dev: true + /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.17.4: + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.17.4 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.17.5: resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} peerDependencies: @@ -1143,6 +1195,15 @@ packages: '@babel/helper-plugin-utils': 7.16.7 dev: true + /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.17.4: + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.17.4 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.17.5: resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: @@ -1152,6 +1213,15 @@ packages: '@babel/helper-plugin-utils': 7.16.7 dev: true + /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.17.4: + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.17.4 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.17.5: resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: @@ -1180,6 +1250,15 @@ packages: '@babel/helper-plugin-utils': 7.16.7 dev: true + /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.17.4: + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.17.4 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.17.5: resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: @@ -1188,6 +1267,15 @@ packages: '@babel/core': 7.17.5 '@babel/helper-plugin-utils': 7.16.7 + /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.17.4: + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.17.4 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.17.5: resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} peerDependencies: @@ -1196,6 +1284,15 @@ packages: '@babel/core': 7.17.5 '@babel/helper-plugin-utils': 7.16.7 + /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.17.4: + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.17.4 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.17.5: resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: @@ -1204,6 +1301,15 @@ packages: '@babel/core': 7.17.5 '@babel/helper-plugin-utils': 7.16.7 + /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.17.4: + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.17.4 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.17.5: resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} peerDependencies: @@ -1212,6 +1318,15 @@ packages: '@babel/core': 7.17.5 '@babel/helper-plugin-utils': 7.16.7 + /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.17.4: + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.17.4 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.17.5: resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} peerDependencies: @@ -1220,6 +1335,15 @@ packages: '@babel/core': 7.17.5 '@babel/helper-plugin-utils': 7.16.7 + /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.17.4: + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.17.4 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.17.5: resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} peerDependencies: @@ -1237,6 +1361,16 @@ packages: '@babel/core': 7.17.5 '@babel/helper-plugin-utils': 7.16.7 + /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.17.4: + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.17.4 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.17.5: resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} engines: {node: '>=6.9.0'} @@ -1246,13 +1380,13 @@ packages: '@babel/core': 7.17.5 '@babel/helper-plugin-utils': 7.16.7 - /@babel/plugin-syntax-typescript/7.16.7_@babel+core@7.17.5: + /@babel/plugin-syntax-typescript/7.16.7_@babel+core@7.17.4: resolution: {integrity: sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.17.4 '@babel/helper-plugin-utils': 7.16.7 dev: true @@ -1762,14 +1896,6 @@ packages: regenerator-runtime: 0.13.9 dev: true - /@babel/template/7.16.0: - resolution: {integrity: sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.16.7 - '@babel/parser': 7.16.2 - '@babel/types': 7.16.8 - /@babel/template/7.16.7: resolution: {integrity: sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==} engines: {node: '>=6.9.0'} @@ -1789,35 +1915,18 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.16.7 - '@babel/generator': 7.16.5 + '@babel/generator': 7.17.3 '@babel/helper-function-name': 7.16.0 '@babel/helper-hoist-variables': 7.16.0 '@babel/helper-split-export-declaration': 7.16.0 - '@babel/parser': 7.16.2 - '@babel/types': 7.16.8 + '@babel/parser': 7.17.3 + '@babel/types': 7.17.0 debug: 4.3.3 globals: 11.12.0 transitivePeerDependencies: - supports-color dev: false - /@babel/traverse/7.16.10: - resolution: {integrity: sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.16.7 - '@babel/generator': 7.17.0 - '@babel/helper-environment-visitor': 7.16.7 - '@babel/helper-function-name': 7.16.7 - '@babel/helper-hoist-variables': 7.16.7 - '@babel/helper-split-export-declaration': 7.16.7 - '@babel/parser': 7.17.0 - '@babel/types': 7.16.8 - debug: 4.3.3 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - /@babel/traverse/7.17.0: resolution: {integrity: sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg==} engines: {node: '>=6.9.0'} @@ -2407,7 +2516,7 @@ packages: '@firebase/component': 0.5.10 '@firebase/util': 1.4.3 node-fetch: 2.6.7 - selenium-webdriver: 4.1.1 + selenium-webdriver: 4.1.0 tslib: 2.3.1 transitivePeerDependencies: - '@firebase/app' @@ -2536,8 +2645,8 @@ packages: '@firebase/logger': 0.3.2 '@firebase/util': 1.4.3 '@firebase/webchannel-wrapper': 0.6.1 - '@grpc/grpc-js': 1.5.5 - '@grpc/proto-loader': 0.6.9 + '@grpc/grpc-js': 1.4.4 + '@grpc/proto-loader': 0.6.7 node-fetch: 2.6.7 tslib: 2.3.1 transitivePeerDependencies: @@ -3256,6 +3365,7 @@ packages: transitivePeerDependencies: - '@types/node' - bufferutil + - encoding - utf-8-validate /@graphql-tools/url-loader/7.7.1_513fa8d9b2f26199a756d05da6b3722c: @@ -3339,16 +3449,16 @@ packages: dependencies: graphql: 15.7.2 - /@grpc/grpc-js/1.5.5: - resolution: {integrity: sha512-FTd27ItHlsSG/7hp62xgI9YnqSwRbHRSVmDVR8DwOoC+6t8JhHRXe2JL0U8N9GLc0jS0HrtEbO/KP5+G0ebjLQ==} + /@grpc/grpc-js/1.4.4: + resolution: {integrity: sha512-a6222b7Dl6fIlMgzVl7e+NiRoLiZFbpcwvBH2Oli56Bn7W4/3Ld+86hK4ffPn5rx2DlDidmIcvIJiOQXyhv9gA==} engines: {node: ^8.13.0 || >=10.10.0} dependencies: - '@grpc/proto-loader': 0.6.9 + '@grpc/proto-loader': 0.6.7 '@types/node': 17.0.18 dev: false - /@grpc/proto-loader/0.6.9: - resolution: {integrity: sha512-UlcCS8VbsU9d3XTXGiEVFonN7hXk+oMXZtoHHG2oSA1/GcDP1q6OUgs20PzHDGizzyi8ufGSUDlk3O2NyY7leg==} + /@grpc/proto-loader/0.6.7: + resolution: {integrity: sha512-QzTPIyJxU0u+r2qGe8VMl3j/W2ryhEvBv7hc42OjYfthSj370fUrb7na65rG6w3YLZS/fb8p89iTBobfWGDgdw==} engines: {node: '>=6'} hasBin: true dependencies: @@ -3386,7 +3496,7 @@ packages: resolution: {integrity: sha512-rnfA0ScyBXyp9xsSD4EAMGeOh1yv/AE7fhqdAdSOr5X8N39azz257umfRtzNT9sHXAKSSzpCVhIbMAkp5c/gjQ==} engines: {node: '>= 10.0'} dependencies: - '@babel/parser': 7.16.2 + '@babel/parser': 7.17.3 dev: false /@intlify/vue-i18n-loader/1.1.0: @@ -3575,7 +3685,7 @@ packages: resolution: {integrity: sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.17.4 '@jest/types': 27.5.1 babel-plugin-istanbul: 6.1.1 chalk: 4.1.2 @@ -3716,7 +3826,7 @@ packages: dependencies: '@babel/compat-data': 7.16.0 '@babel/core': 7.17.5 - '@babel/helper-compilation-targets': 7.16.0_@babel+core@7.17.5 + '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.17.5 '@babel/helper-module-imports': 7.16.0 '@babel/plugin-proposal-class-properties': 7.16.7_@babel+core@7.17.5 '@babel/plugin-proposal-decorators': 7.16.0_@babel+core@7.17.5 @@ -3754,6 +3864,7 @@ packages: upath: 2.0.1 transitivePeerDependencies: - bufferutil + - encoding - supports-color - typescript - utf-8-validate @@ -3866,11 +3977,11 @@ packages: ufo: 0.7.9 dev: false - /@nuxt/kit-edge/3.0.0-27420403.16e2a54: - resolution: {integrity: sha512-W7/2Hd+lbJfDOK7qTOLSu1VFjpZlC/VsfE/wLbbX3BG2UTn3DsGQe3ksqdmGWn9o2XEWJ9snNMroXJPNrqEUkg==} + /@nuxt/kit-edge/3.0.0-27424151.dbab979: + resolution: {integrity: sha512-xAw7gQ7N6afxHeYXwqogjD3Xme0lP7HE2pORZ91R8v5xRMiiGIsvaXbjZ0u/CXga/kuA2Yn6Yn9kQsPcPAIDOA==} engines: {node: ^14.16.0 || ^16.11.0 || ^17.0.0} dependencies: - '@nuxt/schema': /@nuxt/schema-edge/3.0.0-27420403.16e2a54 + '@nuxt/schema': /@nuxt/schema-edge/3.0.0-27424151.dbab979 c12: 0.1.3 consola: 2.15.3 defu: 5.0.1 @@ -3905,11 +4016,13 @@ packages: dependencies: chalk: 4.1.2 consola: 2.15.3 - node-fetch: 2.6.6 + node-fetch: 2.6.7 + transitivePeerDependencies: + - encoding dev: false - /@nuxt/schema-edge/3.0.0-27420403.16e2a54: - resolution: {integrity: sha512-CDITD834JnlVHj72z6eGyU/Ezr1h52fv+xk3jybfgo0td38ANqT+vWKlLyBJf089Sd2pAP+SIWCIpfwjoknMKw==} + /@nuxt/schema-edge/3.0.0-27424151.dbab979: + resolution: {integrity: sha512-XrS8fPE+5OH4om6zcfKnhhE0Jeu4D5ime36G4tclz1spddNg3j6PwLDsJ03bX4L0KOGk8i+kijsTDZD4Vk632g==} engines: {node: ^14.16.0 || ^16.11.0 || ^17.0.0} dependencies: c12: 0.1.3 @@ -3962,10 +4075,12 @@ packages: is-docker: 2.2.1 jiti: 1.12.9 nanoid: 3.1.30 - node-fetch: 2.6.6 + node-fetch: 2.6.7 parse-git-config: 3.0.0 rc9: 1.2.0 std-env: 2.3.1 + transitivePeerDependencies: + - encoding dev: false /@nuxt/types/2.15.8_sass@1.49.7: @@ -4033,7 +4148,7 @@ packages: /@nuxt/vue-app/2.15.8: resolution: {integrity: sha512-FJf9FSMPsWT3BqkS37zEuPTxLKzSg2EIwp1sP8Eou25eE08qxRfe2PwTVA8HnXUPNdpz2uk/T9DlNw+JraiFRQ==} dependencies: - node-fetch: 2.6.6 + node-fetch: 2.6.7 ufo: 0.7.9 unfetch: 4.2.0 vue: 2.6.14 @@ -4043,6 +4158,8 @@ packages: vue-router: 3.5.3 vue-template-compiler: 2.6.14 vuex: 3.6.2_vue@2.6.14 + transitivePeerDependencies: + - encoding dev: false /@nuxt/vue-renderer/2.15.8: @@ -4710,7 +4827,7 @@ packages: /@types/babel__core/7.1.18: resolution: {integrity: sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ==} dependencies: - '@babel/parser': 7.17.0 + '@babel/parser': 7.17.3 '@babel/types': 7.17.0 '@types/babel__generator': 7.6.4 '@types/babel__template': 7.4.1 @@ -4720,7 +4837,7 @@ packages: /@types/babel__generator/7.6.3: resolution: {integrity: sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==} dependencies: - '@babel/types': 7.16.0 + '@babel/types': 7.17.0 dev: true /@types/babel__generator/7.6.4: @@ -4732,7 +4849,7 @@ packages: /@types/babel__template/7.4.1: resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} dependencies: - '@babel/parser': 7.17.0 + '@babel/parser': 7.17.3 '@babel/types': 7.17.0 dev: true @@ -4746,7 +4863,7 @@ packages: resolution: {integrity: sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==} dependencies: '@types/connect': 3.4.34 - '@types/node': 17.0.6 + '@types/node': 17.0.18 dev: true /@types/browserslist/4.15.0: @@ -4761,14 +4878,14 @@ packages: dependencies: '@types/http-cache-semantics': 4.0.1 '@types/keyv': 3.1.3 - '@types/node': 17.0.6 + '@types/node': 17.0.18 '@types/responselike': 1.0.0 dev: true /@types/clean-css/4.2.5: resolution: {integrity: sha512-NEzjkGGpbs9S9fgC4abuBvTpVwE3i+Acu9BBod3PUyjDVZcNsGx61b8r2PphR61QGPnn0JHVs5ey6/I4eTrkxw==} dependencies: - '@types/node': 17.0.6 + '@types/node': 17.0.18 source-map: 0.6.1 dev: true @@ -4824,7 +4941,7 @@ packages: /@types/express-serve-static-core/4.17.24: resolution: {integrity: sha512-3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA==} dependencies: - '@types/node': 17.0.6 + '@types/node': 17.0.18 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 dev: true @@ -4873,7 +4990,7 @@ packages: /@types/http-proxy/1.17.7: resolution: {integrity: sha512-9hdj6iXH64tHSLTY+Vt2eYOGzSogC+JQ2H7bdPWkuh7KXP5qLllWx++t+K9Wk556c3dkDdPws/SpMRi0sdCT1w==} dependencies: - '@types/node': 17.0.6 + '@types/node': 17.0.18 dev: false /@types/httpsnippet/1.23.1: @@ -4929,7 +5046,7 @@ packages: /@types/keyv/3.1.3: resolution: {integrity: sha512-FXCJgyyN3ivVgRoml4h94G/p3kY+u/B86La+QptcqJaWtBWtmc6TtkNfS40n9bIvyLteHh7zXOtgbobORKPbDg==} dependencies: - '@types/node': 17.0.6 + '@types/node': 17.0.18 dev: true /@types/less/3.0.2: @@ -4955,7 +5072,7 @@ packages: /@types/node-sass/4.11.2: resolution: {integrity: sha512-pOFlTw/OtZda4e+yMjq6/QYuvY0RDMQ+mxXdWj7rfSyf18V8hS4SfgurO+MasAkQsv6Wt6edOGlwh5QqJml9gw==} dependencies: - '@types/node': 17.0.6 + '@types/node': 17.0.18 dev: true /@types/node/12.20.12: @@ -4970,10 +5087,6 @@ packages: resolution: {integrity: sha512-Ezv33Rl4mIi6YdSHfIRNBd4Q9kUe5okiaw/ikvJiJDmuQZNW5kfdg7+oQPF8NO6sTcr3woIpj3jANzTXdvEZXA==} dev: true - /@types/node/17.0.15: - resolution: {integrity: sha512-zWt4SDDv1S9WRBNxLFxFRHxdD9tvH8f5/kg5/IaLFdnSNXsDY4eL3Q3XXN+VxUnWIhyVFDwcsmAprvwXoM/ClA==} - dev: false - /@types/node/17.0.18: resolution: {integrity: sha512-eKj4f/BsN/qcculZiRSujogjvp5O/k4lOW5m35NopjZM/QwLOR075a8pJW5hD+Rtdm2DaCVPENS6KtSQnUD6BA==} @@ -5029,7 +5142,7 @@ packages: /@types/responselike/1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: - '@types/node': 17.0.6 + '@types/node': 17.0.18 dev: true /@types/sass-loader/8.0.1: @@ -5043,13 +5156,13 @@ packages: /@types/sass/1.43.0: resolution: {integrity: sha512-DPSXNJ1rYLo88GyF9tuB4bsYGfpKI1a4+wOQmc+LI1SUoocm9QLRSpz0GxxuyjmJsYFIQo/dDlRSSpIXngff+w==} dependencies: - '@types/node': 17.0.6 + '@types/node': 17.0.18 dev: true /@types/sax/1.2.3: resolution: {integrity: sha512-+QSw6Tqvs/KQpZX8DvIl3hZSjNFLW/OqE5nlyHXtTwODaJvioN2rOWpBNEWZp2HZUFhOh+VohmJku/WxEXU2XA==} dependencies: - '@types/node': 17.0.6 + '@types/node': 17.0.18 dev: false /@types/semver/7.3.9: @@ -5152,7 +5265,7 @@ packages: /@types/webpack-sources/3.2.0: resolution: {integrity: sha512-Ft7YH3lEVRQ6ls8k4Ff1oB4jN6oy/XmU6tQISKdhfh+1mR+viZFphS6WL0IrtDOzvefmJg5a0s7ZQoRXwqTEFg==} dependencies: - '@types/node': 17.0.6 + '@types/node': 17.0.18 '@types/source-list-map': 0.1.2 source-map: 0.7.3 @@ -5170,7 +5283,7 @@ packages: /@types/webpack/4.41.31: resolution: {integrity: sha512-/i0J7sepXFIp1ZT7FjUGi1eXMCg8HCCzLJEQkKsOtbJFontsJLolBcDC+3qxn5pPwiCt1G0ZdRmYRzNBtvpuGQ==} dependencies: - '@types/node': 17.0.15 + '@types/node': 17.0.18 '@types/tapable': 1.0.8 '@types/uglify-js': 3.13.1 '@types/webpack-sources': 3.2.0 @@ -5181,7 +5294,7 @@ packages: /@types/websocket/1.0.4: resolution: {integrity: sha512-qn1LkcFEKK8RPp459jkjzsfpbsx36BBt3oC3pITYtkoBw/aVX+EZFa5j3ThCRTNpLFvIMr5dSTD4RaMdilIOpA==} dependencies: - '@types/node': 17.0.6 + '@types/node': 17.0.18 /@types/websocket/1.0.5: resolution: {integrity: sha512-NbsqiNX9CnEfC1Z0Vf4mE1SgAJ07JnRYcNex7AJ9zAVzmiGHmjKFEk7O4TJIsgv2B1sLEb6owKFZrACwdYngsQ==} @@ -5593,7 +5706,7 @@ packages: /@vue/compiler-core/3.2.23: resolution: {integrity: sha512-4ZhiI/orx+7EJ1B+0zjgvXMV2uRN+XBfG06UN2sJfND9rH5gtEQT3QmO4erum1o6Irl7y754W8/KSaDJh4EUQg==} dependencies: - '@babel/parser': 7.17.0 + '@babel/parser': 7.17.3 '@vue/shared': 3.2.23 estree-walker: 2.0.2 source-map: 0.6.1 @@ -5628,7 +5741,7 @@ packages: /@vue/ref-transform/3.2.23: resolution: {integrity: sha512-gW0GD2PSAs/th7mC7tPB/UwpIQxclbApVtsDtscDmOJXb2+cdu60ny+SuHNgfrlUT/JqWKQHq7jFKO4woxLNaA==} dependencies: - '@babel/parser': 7.17.0 + '@babel/parser': 7.17.3 '@vue/compiler-core': 3.2.23 '@vue/shared': 3.2.23 estree-walker: 2.0.2 @@ -6319,6 +6432,25 @@ packages: '@babel/core': 7.17.5 dev: true + /babel-jest/27.5.1_@babel+core@7.17.4: + resolution: {integrity: sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + dependencies: + '@babel/core': 7.17.4 + '@jest/transform': 27.5.1 + '@jest/types': 27.5.1 + '@types/babel__core': 7.1.18 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 27.5.1_@babel+core@7.17.4 + chalk: 4.1.2 + graceful-fs: 4.2.9 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: true + /babel-jest/27.5.1_@babel+core@7.17.5: resolution: {integrity: sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -6490,6 +6622,26 @@ packages: babel-types: 6.26.0 dev: true + /babel-preset-current-node-syntax/1.0.1_@babel+core@7.17.4: + resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.17.4 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.17.4 + '@babel/plugin-syntax-bigint': 7.8.3_@babel+core@7.17.4 + '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.17.4 + '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.17.4 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.17.4 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.17.4 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.17.4 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.17.4 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.17.4 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.17.4 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.17.4 + '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.17.4 + dev: true + /babel-preset-current-node-syntax/1.0.1_@babel+core@7.17.5: resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} peerDependencies: @@ -6547,6 +6699,17 @@ packages: - supports-color dev: true + /babel-preset-jest/27.5.1_@babel+core@7.17.4: + resolution: {integrity: sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.17.4 + babel-plugin-jest-hoist: 27.5.1 + babel-preset-current-node-syntax: 1.0.1_@babel+core@7.17.4 + dev: true + /babel-preset-jest/27.5.1_@babel+core@7.17.5: resolution: {integrity: sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -7870,8 +8033,10 @@ packages: abort-controller: 3.0.0 form-data-encoder: 1.7.1 formdata-node: 4.3.1 - node-fetch: 2.6.6 + node-fetch: 2.6.7 undici: 4.12.1 + transitivePeerDependencies: + - encoding /cross-undici-fetch/0.1.24: resolution: {integrity: sha512-83KDV6+8pYCn51zSM2cFAwqQ5UQtDaPm89RkUwHxEMDq/cdqYgqo1q+2eM/Xhmd8HeAsGTtecsC4crrQkCn0zg==} @@ -10327,7 +10492,7 @@ packages: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.0.4 + minimatch: 3.1.0 once: 1.4.0 path-is-absolute: 1.0.1 @@ -10477,6 +10642,7 @@ packages: transitivePeerDependencies: - '@types/node' - bufferutil + - encoding - typescript - utf-8-validate @@ -10502,6 +10668,7 @@ packages: transitivePeerDependencies: - '@types/node' - bufferutil + - encoding - typescript - utf-8-validate dev: false @@ -10516,6 +10683,7 @@ packages: transitivePeerDependencies: - '@types/node' - bufferutil + - encoding - typescript - utf-8-validate dev: false @@ -10539,6 +10707,7 @@ packages: transitivePeerDependencies: - '@types/node' - bufferutil + - encoding - typescript - utf-8-validate dev: false @@ -11725,7 +11894,7 @@ packages: resolution: {integrity: sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==} engines: {node: '>=8'} dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.17.4 '@babel/parser': 7.17.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.0 @@ -11840,10 +12009,10 @@ packages: ts-node: optional: true dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.17.4 '@jest/test-sequencer': 27.5.1 '@jest/types': 27.5.1 - babel-jest: 27.5.1_@babel+core@7.17.5 + babel-jest: 27.5.1_@babel+core@7.17.4 chalk: 4.1.2 ci-info: 3.3.0 deepmerge: 4.2.2 @@ -12189,16 +12358,16 @@ packages: resolution: {integrity: sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.17.4 '@babel/generator': 7.17.0 - '@babel/plugin-syntax-typescript': 7.16.7_@babel+core@7.17.5 + '@babel/plugin-syntax-typescript': 7.16.7_@babel+core@7.17.4 '@babel/traverse': 7.17.0 '@babel/types': 7.17.0 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 '@types/babel__traverse': 7.14.2 '@types/prettier': 2.4.4 - babel-preset-current-node-syntax: 1.0.1_@babel+core@7.17.5 + babel-preset-current-node-syntax: 1.0.1_@babel+core@7.17.4 chalk: 4.1.2 expect: 27.5.1 graceful-fs: 4.2.9 @@ -12256,7 +12425,7 @@ packages: resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 17.0.6 + '@types/node': 17.0.18 merge-stream: 2.0.0 supports-color: 7.2.0 @@ -12264,7 +12433,7 @@ packages: resolution: {integrity: sha512-0QMy/zPovLfUPyHuOuuU4E+kGACXXE84nRnq6lBVI9GJg5DCBiA97SATi+ZP8CpiJwEQy1oCPjRBf8AnLjN+Ag==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 17.0.6 + '@types/node': 17.0.18 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true @@ -12490,7 +12659,7 @@ packages: /jsonfile/4.0.0: resolution: {integrity: sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=} optionalDependencies: - graceful-fs: 4.2.8 + graceful-fs: 4.2.9 dev: false /jsonfile/6.1.0: @@ -13651,12 +13820,6 @@ packages: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} - /node-fetch/2.6.6: - resolution: {integrity: sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==} - engines: {node: 4.x || >=6.0.0} - dependencies: - whatwg-url: 5.0.0 - /node-fetch/2.6.7: resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} engines: {node: 4.x || >=6.0.0} @@ -13865,7 +14028,7 @@ packages: /nuxt-windicss/2.2.5: resolution: {integrity: sha512-0T21d/SLCxla5gwtwSgisncnbDc2uuUXOu/qYNKEvh8URw8t9y7qZ1Z+gwyCDqORxBrqSzgXXZ7aLOntfPBHNQ==} dependencies: - '@nuxt/kit': /@nuxt/kit-edge/3.0.0-27420403.16e2a54 + '@nuxt/kit': /@nuxt/kit-edge/3.0.0-27424151.dbab979 '@windicss/plugin-utils': 1.7.1 consola: 2.15.3 defu: 5.0.1 @@ -13907,6 +14070,7 @@ packages: transitivePeerDependencies: - bufferutil - consola + - encoding - supports-color - typescript - utf-8-validate @@ -15970,7 +16134,7 @@ packages: inherits: 2.0.4 dev: false - /rollup-plugin-dts/4.1.0_rollup@2.67.3+typescript@4.5.5: + /rollup-plugin-dts/4.1.0_rollup@2.68.0+typescript@4.5.5: resolution: {integrity: sha512-rriXIm3jdUiYeiAAd1Fv+x2AxK6Kq6IybB2Z/IdoAW95fb4uRUurYsEYKa8L1seedezDeJhy8cfo8FEL9aZzqg==} engines: {node: '>=v12.22.7'} peerDependencies: @@ -15978,13 +16142,13 @@ packages: typescript: ~4.1 || ~4.2 || ~4.3 || ~4.4 || ~4.5 dependencies: magic-string: 0.25.7 - rollup: 2.67.3 + rollup: 2.68.0 typescript: 4.5.5 optionalDependencies: '@babel/code-frame': 7.16.7 dev: true - /rollup-plugin-ts/2.0.5_rollup@2.67.3+typescript@4.5.5: + /rollup-plugin-ts/2.0.5_rollup@2.68.0+typescript@4.5.5: resolution: {integrity: sha512-yLfu46XsheAEDs+OxCMnHszble9pYwGYDML82lpMw3x/65kgwd9UQSkPX0HZGk+6L+MN8hFgqeh+SPmv+uOz1w==} engines: {node: '>=10.0.0', npm: '>=7.0.0', pnpm: '>=3.2.0', yarn: '>=1.13'} peerDependencies: @@ -16018,7 +16182,7 @@ packages: compatfactory: 0.0.12_typescript@4.5.5 crosspath: 1.0.0 magic-string: 0.25.7 - rollup: 2.67.3 + rollup: 2.68.0 ts-clone-node: 0.3.30_typescript@4.5.5 tslib: 2.3.1 typescript: 4.5.5 @@ -16032,8 +16196,8 @@ packages: fsevents: 2.3.2 dev: true - /rollup/2.67.3: - resolution: {integrity: sha512-G/x1vUwbGtP6O5ZM8/sWr8+p7YfZhI18pPqMRtMYMWSbHjKZ/ajHGiM+GWNTlWyOR0EHIdT8LHU+Z4ciIZ1oBw==} + /rollup/2.68.0: + resolution: {integrity: sha512-XrMKOYK7oQcTio4wyTz466mucnd8LzkiZLozZ4Rz0zQD+HeX4nUK4B8GrTX/2EvN2/vBF/i2WnaXboPxo0JylA==} engines: {node: '>=10.0.0'} hasBin: true optionalDependencies: @@ -16208,8 +16372,8 @@ packages: - utf-8-validate dev: false - /selenium-webdriver/4.1.1: - resolution: {integrity: sha512-Fr9e9LC6zvD6/j7NO8M1M/NVxFX67abHcxDJoP5w2KN/Xb1SyYLjMVPGgD14U2TOiKe4XKHf42OmFw9g2JgCBQ==} + /selenium-webdriver/4.1.0: + resolution: {integrity: sha512-kUDH4N8WruYprTzvug4Pl73Th+WKb5YiLz8z/anOpHyUNUdM3UzrdTOxmSNaf9AczzBeY+qXihzku8D1lMaKOg==} engines: {node: '>= 10.15.0'} dependencies: jszip: 3.7.1 @@ -17342,7 +17506,9 @@ packages: engines: {node: '>=8'} dependencies: buffer: 5.7.1 - node-fetch: 2.6.6 + node-fetch: 2.6.7 + transitivePeerDependencies: + - encoding /table/6.8.0: resolution: {integrity: sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==} @@ -18095,9 +18261,9 @@ packages: dependencies: '@antfu/utils': 0.3.0 '@babel/core': 7.17.5 - '@babel/generator': 7.17.0 - '@babel/parser': 7.17.0 - '@babel/traverse': 7.17.0 + '@babel/generator': 7.17.3 + '@babel/parser': 7.17.3 + '@babel/traverse': 7.17.3 '@babel/types': 7.17.0 '@rollup/pluginutils': 4.1.1 '@vue/compiler-core': 3.2.23 @@ -19126,11 +19292,11 @@ packages: /yargs-parser/20.2.4: resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} engines: {node: '>=10'} + dev: true /yargs-parser/20.2.9: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'} - dev: true /yargs-parser/21.0.0: resolution: {integrity: sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA==} @@ -19173,7 +19339,7 @@ packages: require-directory: 2.1.1 string-width: 4.2.3 y18n: 5.0.8 - yargs-parser: 20.2.4 + yargs-parser: 20.2.9 /yargs/17.3.1: resolution: {integrity: sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==}