diff --git a/Cargo.lock b/Cargo.lock index 557c8111..df22c6f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -253,9 +253,9 @@ dependencies = [ [[package]] name = "brotli" -version = "3.3.4" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" +checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -264,9 +264,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.3.4" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" +checksum = "da74e2b81409b1b743f8f0c62cc6254afefb8b8e50bbfe3735550f7aeefa3448" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -549,9 +549,9 @@ dependencies = [ [[package]] name = "csv" -version = "1.2.2" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626ae34994d3d8d668f4269922248239db4ae42d538b14c398b74a52208e8086" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" dependencies = [ "csv-core", "itoa", @@ -561,9 +561,9 @@ dependencies = [ [[package]] name = "csv-core" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" dependencies = [ "memchr", ] @@ -692,9 +692,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +checksum = "add4f07d43996f76ef320709726a556a9d4f965d9410d8d0271132d2f8293480" dependencies = [ "errno-dragonfly", "libc", @@ -1249,9 +1249,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" +checksum = "3852614a3bd9ca9804678ba6be5e3b8ce76dfc902cae004e3e0c44051b6e88db" [[package]] name = "lock_api" @@ -1280,9 +1280,9 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" [[package]] name = "memchr" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "minimal-lexical" @@ -1723,9 +1723,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.5" +version = "1.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff" dependencies = [ "aho-corasick", "memchr", @@ -1735,9 +1735,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" dependencies = [ "aho-corasick", "memchr", @@ -1788,9 +1788,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.14" +version = "0.38.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f" +checksum = "d2f9da0cbd88f9f09e7814e388301c8414c51c62aa6ce1e4b5c551d49d96e531" dependencies = [ "bitflags 2.4.0", "errno", @@ -2025,15 +2025,15 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "sval" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53219a43817adbb1d53e6d0dd8ba8242f9a8f144b876945f3cbca6282cc0f603" +checksum = "9f9150edabce0ada1e9b44f98d52817ba0fba9d572898da47e354a14a3eb406d" [[package]] name = "sval_buffer" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ea974e4cf17f8eedd11c8bcbdddad28a65f9faadeea62e0f092f031518a6e01" +checksum = "4fb08e361c8fbbc37fb3d08dc067a98207062d083ee5ef0b21e3739b16e69892" dependencies = [ "sval", "sval_ref", @@ -2041,18 +2041,18 @@ dependencies = [ [[package]] name = "sval_dynamic" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb8bf9bfe769973b5ab924d3da1bc0e0f6b40c877c25cdd8eadba7b9bd32319a" +checksum = "ae417f3812ea4403cd0cc0819628427ef6e099d5f482d80ed4e0f92836c51a85" dependencies = [ "sval", ] [[package]] name = "sval_fmt" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "856e81b22a368aa8be4ba32c13301d2f350f0026b94126ebc41b0fcf14a4d89d" +checksum = "97a898ac59b0f7a0344d0ac0f408908f545d422ffbfe46522a5cdff3ed391650" dependencies = [ "itoa", "ryu", @@ -2061,9 +2061,9 @@ dependencies = [ [[package]] name = "sval_json" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afe2fd273a8b25b7f924ed8bfaaf54812d81d27b300d5c4f890f41bba96f7e5" +checksum = "c63eda4f68a4df3d58f0c9805983560c1de8bf414800a990be25e433d1cccc8c" dependencies = [ "itoa", "ryu", @@ -2072,18 +2072,18 @@ dependencies = [ [[package]] name = "sval_ref" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416a04f4aa4be4fea8badd65a92a18f7a1082447513616866c0bd2c84c7d86aa" +checksum = "87e59d69dac5af4c6b87c79b52581a5b9ab9cc2d019775dea318967ea3c3effd" dependencies = [ "sval", ] [[package]] name = "sval_serde" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60e14464ea11b8e017b21481f7f5982d49a150bb8c27bf4edc1eb8694a61cf50" +checksum = "93d72e44618c14d0f8aff885af8184a3579ffa0d9ad5b1fbffc59f85d6739982" dependencies = [ "serde", "sval", diff --git a/agent/package.json b/agent/package.json index 67f2c637..0cd5d610 100644 --- a/agent/package.json +++ b/agent/package.json @@ -1,6 +1,6 @@ { "name": "@fs/ppaas-agent", - "version": "3.0.0", + "version": "3.0.1", "description": "Agent Service for running pewpew tests", "main": "dist/src/app.js", "scripts": { @@ -38,7 +38,8 @@ "dotenv-flow": "^3.2.0", "expiry-map": "^2.0.0", "express": "^4.18.2", - "rimraf": "^5.0.0" + "rimraf": "^5.0.0", + "semver": "^7.5.2" }, "devDependencies": { "@aws-sdk/client-s3": "^3.363.0", @@ -49,6 +50,7 @@ "@types/express": "^4.17.17", "@types/mocha": "^10.0.0", "@types/node": "^20.0.0", + "@types/semver": "^7.5.0", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", "axios": "~1.5.0", diff --git a/agent/src/pewpewtest.ts b/agent/src/pewpewtest.ts index cc51aebc..bddb85ee 100644 --- a/agent/src/pewpewtest.ts +++ b/agent/src/pewpewtest.ts @@ -23,6 +23,7 @@ import fs from "fs/promises"; import { getHostname } from "./util/util"; import { join as pathJoin } from "path"; import { platform } from "os"; +import semver from "semver"; logger.config.LogFileName = "ppaas-agent"; const logConfig = logger.config; @@ -87,18 +88,8 @@ export function versionGreaterThan (currentVersion: string, compareVersion: stri if (currentVersion === "latest") { return true; } // If the compareVersion is latest, then only currrentVersion=latest is greater if (compareVersion === "latest") { return false; } - // compareVersion cannot be a beta; - if (!/^\d+\.\d+\.\d+$/.test(compareVersion)) { - throw new Error("compareVersion cannot be a beta"); - } - const currentMatch: string[] | null = currentVersion.match(/^(\d+\.\d+\.\d+)(.*)/); - // If we can't find a version string 0.0.0 at the beginning, we don't know - if (!currentMatch) { - return false; - } - const version = currentMatch[1]; - const beta = currentMatch[2]; - return beta !== "" ? version > compareVersion : version >= compareVersion; + + return semver.gt(currentVersion, compareVersion); } // Export for testing diff --git a/agent/test/pewpewtest.spec.ts b/agent/test/pewpewtest.spec.ts index 17d7cf74..17b6cb2c 100644 --- a/agent/test/pewpewtest.spec.ts +++ b/agent/test/pewpewtest.spec.ts @@ -139,23 +139,14 @@ describe("PewPewTest", () => { done(); }); - it("compare version cannot be a beta", (done: Mocha.Done) => { - try { - versionGreaterThan("0.5.5", "0.5.4-beta"); - done(new Error("Should have failed.")); - } catch (error) { - expect(`${error}`).include("compareVersion cannot be a beta"); - done(); - } + it("compare version patch greater than", (done: Mocha.Done) => { + expect(versionGreaterThan("0.5.5", "0.5.6-preview1")).to.equal(false); + done(); }); - it("compare version cannot be a beta", (done: Mocha.Done) => { - try { - expect(versionGreaterThan("0.5.10-preview1", "0.5.5")).to.equal(true); - done(new Error("Should have failed.")); - } catch (error) { - done(); - } + it("compare version patch less than", (done: Mocha.Done) => { + expect(versionGreaterThan("0.5.5", "0.5.5-preview1")).to.equal(true); + done(); }); }); diff --git a/common/package.json b/common/package.json index e9fb1d09..b6908a6e 100644 --- a/common/package.json +++ b/common/package.json @@ -1,6 +1,6 @@ { "name": "@fs/ppaas-common", - "version": "3.0.0", + "version": "3.0.1", "description": "Common Code for the PewPewController and PewPewAgent", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", diff --git a/common/src/yamlparser.ts b/common/src/yamlparser.ts index 21ce3b5b..9472c3ea 100644 --- a/common/src/yamlparser.ts +++ b/common/src/yamlparser.ts @@ -6,11 +6,20 @@ import { readFile } from "fs/promises"; export function parseEnvVarFromError (error: any): string | undefined { if (typeof error === "string") { // Format is IndexingIntoJson\("VARIABLE", Null) - const match = error.match(/MissingEnvironmentVariable\("([^"]*)", Marker/); - log("parseYamlFile match: " + JSON.stringify(match), LogLevel.DEBUG, match); - if (match && match.length > 1) { - const expectedVariable = match[1]; - log("parseYamlFile missing variable: " + expectedVariable, LogLevel.DEBUG); + // MissingEnvironmentVariable\("VARIABLE", Marker + // Envs(MissingVar(MissingEnvVar("VARIABLE")))) + const matchLegacy = error.match(/MissingEnvironmentVariable\("([^"]*)", Marker/); + log("parseYamlFile match: " + JSON.stringify(matchLegacy), LogLevel.DEBUG, matchLegacy); + if (matchLegacy && matchLegacy.length > 1) { + const expectedVariable = matchLegacy[1]; + log("parseYamlFile missing legacy variable: " + expectedVariable, LogLevel.DEBUG); + return expectedVariable; + } + const matchScripting = error.match(/MissingEnvVar\("([^"]*)"\)/); + log("parseYamlFile match: " + JSON.stringify(matchScripting), LogLevel.DEBUG, matchScripting); + if (matchScripting && matchScripting.length > 1) { + const expectedVariable = matchScripting[1]; + log("parseYamlFile missing scripting variable: " + expectedVariable, LogLevel.DEBUG); return expectedVariable; } } @@ -19,11 +28,19 @@ export function parseEnvVarFromError (error: any): string | undefined { export function parseDurationFromError (error: any): string | undefined { if (typeof error === "string") { - // Format is IndexingIntoJson\("VARIABLE", Null) - const match = error.match(/InvalidDuration\("([^"]*)"/); - log("parseYamlFile match: " + JSON.stringify(match), LogLevel.DEBUG, match); - if (match && match.length > 1) { - const duration = match[1]; + // Format is InvalidDuration\("value" + // error: DurationError(\"value\") + const matchLegacy = error.match(/InvalidDuration\("([^"]*)"/); + log("parseYamlFile match: " + JSON.stringify(matchLegacy), LogLevel.DEBUG, matchLegacy); + if (matchLegacy && matchLegacy.length > 1) { + const duration = matchLegacy[1]; + log("parseYamlFile InvalidDuration: " + duration, LogLevel.DEBUG); + return duration; + } + const matchScripting = error.match(/DurationError\("([^"]*)"\)/); + log("parseYamlFile match: " + JSON.stringify(matchScripting), LogLevel.DEBUG, matchScripting); + if (matchScripting && matchScripting.length > 1) { + const duration = matchScripting[1]; log("parseYamlFile InvalidDuration: " + duration, LogLevel.DEBUG); return duration; } @@ -33,11 +50,19 @@ export function parseDurationFromError (error: any): string | undefined { export function parsePeakLoadFromError (error: any): string | undefined { if (typeof error === "string") { - // Format is IndexingIntoJson\("VARIABLE", Null) - const match = error.match(/InvalidPeakLoad\("([^"]*)"/); - log("parseYamlFile match: " + JSON.stringify(match), LogLevel.DEBUG, match); - if (match && match.length > 1) { - const peakLoad = match[1]; + // Format is InvalidPeakLoad\("VALUE" + // HitsPerMinute\", from: \"VALUE\", error: Invalid + const matchLegacy = error.match(/InvalidPeakLoad\("([^"]*)"/); + log("parseYamlFile match: " + JSON.stringify(matchLegacy), LogLevel.DEBUG, matchLegacy); + if (matchLegacy && matchLegacy.length > 1) { + const peakLoad = matchLegacy[1]; + log("parseYamlFile InvalidPeakLoad: " + peakLoad, LogLevel.DEBUG); + return peakLoad; + } + const matchScripting = error.match(/HitsPerMinute", from: "([^"]*)", error: Invalid/); + log("parseYamlFile match: " + JSON.stringify(matchScripting), LogLevel.DEBUG, matchScripting); + if (matchScripting && matchScripting.length > 1) { + const peakLoad = matchScripting[1]; log("parseYamlFile InvalidPeakLoad: " + peakLoad, LogLevel.DEBUG); return peakLoad; } @@ -61,7 +86,7 @@ export class YamlParser { this.loggerFileNames = loggerFileNames; } - public static async parseYamlFile (filepath: string, environmentVariables: EnvironmentVariables): Promise { + public static async parseYamlFile (filepath: string, environmentVariables: EnvironmentVariables, validateLegacyOnly?: boolean): Promise { let config: Config | undefined; try { const fileBuffer: Buffer = await readFile(filepath); @@ -80,8 +105,8 @@ export class YamlParser { config = new Config( fileBuffer, varMap, - typeof logConfig.LoggingLevel === "number" ? undefined : logConfig.LoggingLevel - // TODO: Add version checker + typeof logConfig.LoggingLevel === "number" ? undefined : logConfig.LoggingLevel, + validateLegacyOnly ); yamlValid = true; } catch (error: unknown) { diff --git a/common/test/basicwithenv.yaml b/common/test/basicwithenv.yaml index b6d2f4da..cd42ac91 100644 --- a/common/test/basicwithenv.yaml +++ b/common/test/basicwithenv.yaml @@ -1,8 +1,9 @@ vars: rampTime: 1m - loadTime: 1m + loadTime: ${LOAD_TIME} serviceUrlAgent: ${SERVICE_URL_AGENT} test: ${parseInt("${TEST}")} + peak_load: ${PEAK_LOAD} load_pattern: - linear: from: 1% @@ -28,4 +29,4 @@ config: endpoints: - method: GET url: http://${serviceUrlAgent}/healthcheck - peak_load: 30hpm + peak_load: ${peak_load} diff --git a/common/test/scriptingwithenv.yaml b/common/test/scriptingwithenv.yaml index ee25703b..7aef7086 100644 --- a/common/test/scriptingwithenv.yaml +++ b/common/test/scriptingwithenv.yaml @@ -1,8 +1,9 @@ vars: rampTime: 1m - loadTime: 1m + loadTime: ${e:LOAD_TIME} serviceUrlAgent: ${e:SERVICE_URL_AGENT} test: '${x:parseInt(${e:TEST})}' + peak_load: ${e:PEAK_LOAD} load_pattern: - !linear from: 1% @@ -28,4 +29,4 @@ config: endpoints: - method: GET url: http://${v:serviceUrlAgent}/healthcheck - peak_load: 30hpm + peak_load: ${v:peak_load} diff --git a/common/test/yamlparser.spec.ts b/common/test/yamlparser.spec.ts index a5d92cf1..905c1446 100644 --- a/common/test/yamlparser.spec.ts +++ b/common/test/yamlparser.spec.ts @@ -67,7 +67,7 @@ describe("YamlParser", () => { .then((_yamlParser: YamlParser) => done(new Error("This should not parse"))) .catch((error) => { try { - expect(`${error}`).to.include("missingEnvironmentVariables=SERVICE_URL_AGENT,TEST"); + expect(`${error}`).to.include("missingEnvironmentVariables=LOAD_TIME,PEAK_LOAD,SERVICE_URL_AGENT,TEST"); } catch (err) { done(err); return; @@ -82,7 +82,7 @@ describe("YamlParser", () => { .catch((error) => { log("error", LogLevel.WARN, error); try { - expect(`${error}`).to.include("MissingEnvVar(\"SERVICE_URL_AGENT\""); + expect(`${error}`).to.include("missingEnvironmentVariables=LOAD_TIME,PEAK_LOAD,SERVICE_URL_AGENT,TEST"); } catch (err) { done(err); return; @@ -95,7 +95,7 @@ describe("YamlParser", () => { describe("parseYamlFile should parse valid files", () => { describe("legacy files", () => { it(BASIC_FILEPATH + " should be valid", (done: Mocha.Done) => { - YamlParser.parseYamlFile(BASIC_FILEPATH, {}) + YamlParser.parseYamlFile(BASIC_FILEPATH, {}, true) .then((yamlParser: YamlParser) => { expect(yamlParser).to.not.equal(undefined); expect(yamlParser.getBucketSizeMs(), "getBucketSizeMs").to.equal(60000); @@ -107,6 +107,21 @@ describe("YamlParser", () => { .catch((error) => done(error)); }); + it(BASIC_FILEPATH + " should be invalid parsed as scripting", (done: Mocha.Done) => { + YamlParser.parseYamlFile(BASIC_FILEPATH, {}, false) + .then((_yamlParser: YamlParser) => done(new Error("This should not parse"))) + .catch((error) => { + log("scripting error", LogLevel.WARN, error); + try { + expect(`${error}`).to.include("YamlParse(Error"); + } catch (err) { + done(err); + return; + } + done(); + }); + }); + it(BASIC_FILEPATH_WITH_VARS + " should be valid", (done: Mocha.Done) => { YamlParser.parseYamlFile(BASIC_FILEPATH_WITH_VARS, {}) .then((yamlParser: YamlParser) => { @@ -134,7 +149,7 @@ describe("YamlParser", () => { }); it(BASIC_FILEPATH_WITH_ENV + " should be valid", (done: Mocha.Done) => { - YamlParser.parseYamlFile(BASIC_FILEPATH_WITH_ENV, { SERVICE_URL_AGENT: "127.0.0.1", TEST: "true" }) + YamlParser.parseYamlFile(BASIC_FILEPATH_WITH_ENV, { SERVICE_URL_AGENT: "127.0.0.1", TEST: "15", PEAK_LOAD: "30hpm", LOAD_TIME: "1m" }) .then((yamlParser: YamlParser) => { expect(yamlParser).to.not.equal(undefined); expect(yamlParser.getBucketSizeMs(), "getBucketSizeMs").to.equal(60000); @@ -147,7 +162,7 @@ describe("YamlParser", () => { }); it(BASIC_FILEPATH_WITH_ENV + " should be valid with extra variables", (done: Mocha.Done) => { - YamlParser.parseYamlFile(BASIC_FILEPATH_WITH_ENV, { SERVICE_URL_AGENT: "127.0.0.1", TEST: "true", NOT_NEEDED: "true", ALSO_NOT_NEEDED: "false" }) + YamlParser.parseYamlFile(BASIC_FILEPATH_WITH_ENV, { SERVICE_URL_AGENT: "127.0.0.1", TEST: "15", PEAK_LOAD: "30hpm", LOAD_TIME: "1m", NOT_NEEDED: "true", ALSO_NOT_NEEDED: "false" }) .then((yamlParser: YamlParser) => { expect(yamlParser).to.not.equal(undefined); expect(yamlParser.getBucketSizeMs(), "getBucketSizeMs").to.equal(60000); @@ -201,7 +216,7 @@ describe("YamlParser", () => { describe("scripting files", () => { it(SCRIPTING_FILEPATH + " should be valid", (done: Mocha.Done) => { - YamlParser.parseYamlFile(SCRIPTING_FILEPATH, {}) + YamlParser.parseYamlFile(SCRIPTING_FILEPATH, {}, false) .then((yamlParser: YamlParser) => { expect(yamlParser).to.not.equal(undefined); expect(yamlParser.getBucketSizeMs(), "getBucketSizeMs").to.equal(60000); @@ -213,6 +228,21 @@ describe("YamlParser", () => { .catch((error) => done(error)); }); + it(SCRIPTING_FILEPATH + " should be invalid parsed as legacy", (done: Mocha.Done) => { + YamlParser.parseYamlFile(SCRIPTING_FILEPATH, {}, true) + .then((_yamlParser: YamlParser) => done(new Error("This should not parse"))) + .catch((error) => { + log("legacy error", LogLevel.WARN, error); + try { + expect(`${error}`).to.include("UnrecognizedKey"); + } catch (err) { + done(err); + return; + } + done(); + }); + }); + it(SCRIPTING_FILEPATH_WITH_VARS + " should be valid", (done: Mocha.Done) => { YamlParser.parseYamlFile(SCRIPTING_FILEPATH_WITH_VARS, {}) .then((yamlParser: YamlParser) => { @@ -240,7 +270,7 @@ describe("YamlParser", () => { }); it(SCRIPTING_FILEPATH_WITH_ENV + " should be valid", (done: Mocha.Done) => { - YamlParser.parseYamlFile(SCRIPTING_FILEPATH_WITH_ENV, { SERVICE_URL_AGENT: "127.0.0.1", TEST: "true" }) + YamlParser.parseYamlFile(SCRIPTING_FILEPATH_WITH_ENV, { SERVICE_URL_AGENT: "127.0.0.1", TEST: "15", PEAK_LOAD: "30hpm", LOAD_TIME: "1m" }) .then((yamlParser: YamlParser) => { expect(yamlParser).to.not.equal(undefined); expect(yamlParser.getBucketSizeMs(), "getBucketSizeMs").to.equal(60000); @@ -253,7 +283,7 @@ describe("YamlParser", () => { }); it(SCRIPTING_FILEPATH_WITH_ENV + " should be valid with extra variables", (done: Mocha.Done) => { - YamlParser.parseYamlFile(SCRIPTING_FILEPATH_WITH_ENV, { SERVICE_URL_AGENT: "127.0.0.1", TEST: "true", NOT_NEEDED: "true", ALSO_NOT_NEEDED: "false" }) + YamlParser.parseYamlFile(SCRIPTING_FILEPATH_WITH_ENV, { SERVICE_URL_AGENT: "127.0.0.1", TEST: "15", PEAK_LOAD: "30hpm", LOAD_TIME: "1m", NOT_NEEDED: "true", ALSO_NOT_NEEDED: "false" }) .then((yamlParser: YamlParser) => { expect(yamlParser).to.not.equal(undefined); expect(yamlParser.getBucketSizeMs(), "getBucketSizeMs").to.equal(60000); diff --git a/controller/.gitignore b/controller/.gitignore index 6d7e1aa1..47b2bd5e 100644 --- a/controller/.gitignore +++ b/controller/.gitignore @@ -11,6 +11,7 @@ system-test-encrypt-key* /.nyc_output /test/pewpew +/test/scripting/pewpew /test/password.txt /pewpew-okta-creds-db /pewpew-okta-creds-db-np diff --git a/controller/README.md b/controller/README.md index 7facb505..b4bdead7 100644 --- a/controller/README.md +++ b/controller/README.md @@ -61,10 +61,6 @@ To start the server, run one of the following commands: # production start, must be built first with npm run build http://localhost:8081 $ npm start - - # production start, must be built first with npm run build http://localhost:8082 - $ npm run start2 - ``` Use http://localhost:8081/healthcheck/ after running the above command. diff --git a/controller/acceptance/pewpew.spec.ts b/controller/acceptance/pewpew.spec.ts index d4b36512..4c368b1c 100644 --- a/controller/acceptance/pewpew.spec.ts +++ b/controller/acceptance/pewpew.spec.ts @@ -32,8 +32,8 @@ async function fetch ( // Re-create these here so we don't have to run yamlparser.spec by importing it const UNIT_TEST_FOLDER = process.env.UNIT_TEST_FOLDER || "test"; -const PEWPEW_FILEPATH = path.join(UNIT_TEST_FOLDER, "pewpew.zip"); -const PEWPEW_SCRIPTING_FILEPATH = path.join(UNIT_TEST_FOLDER, "pewpew_scripting.zip"); +const PEWPEW_LEGACY_FILEPATH = path.join(UNIT_TEST_FOLDER, "pewpew.zip"); +const PEWPEW_SCRIPTING_FILEPATH = path.join(UNIT_TEST_FOLDER, "scripting/pewpew.zip"); // Beanstalk __URL const integrationUrl = "http://" + (process.env.BUILD_APP_URL || `localhost:${process.env.PORT || "8081"}`); @@ -94,11 +94,11 @@ describe("PewPew API Integration", () => { }); describe("POST /pewpew", () => { - it("POST /pewpew should respond 200 OK", (done: Mocha.Done) => { - const filename: string = path.basename(PEWPEW_FILEPATH); + it("POST /pewpew legacy should respond 200 OK", (done: Mocha.Done) => { + const filename: string = path.basename(PEWPEW_LEGACY_FILEPATH); const formData: FormDataPewPew = { additionalFiles: { - value: createReadStream(PEWPEW_FILEPATH), + value: createReadStream(PEWPEW_LEGACY_FILEPATH), options: { filename } } }; @@ -121,7 +121,7 @@ describe("PewPew API Integration", () => { expect(body.message).to.not.equal(undefined); expect(body.message).to.include("PewPew uploaded, version"); expect(body.message).to.not.include("as latest"); - const match: RegExpMatchArray | null = body.message.match(/PewPew uploaded, version: (\d+\.\d+\.\d+)/); + const match: RegExpMatchArray | null = body.message.match(/PewPew uploaded, version: (\d+\.\d+\.\d+(-[a-zA-Z0-9]+)?)/); log(`pewpew match: ${match}`, LogLevel.DEBUG, match); expect(match, "pewpew match").to.not.equal(null); expect(match!.length, "pewpew match.length").to.be.greaterThan(1); @@ -143,10 +143,10 @@ describe("PewPew API Integration", () => { }); it("POST /pewpew as latest should respond 200 OK", (done: Mocha.Done) => { - const filename: string = path.basename(PEWPEW_FILEPATH); + const filename: string = path.basename(PEWPEW_LEGACY_FILEPATH); const formData: FormDataPewPew = { additionalFiles: [{ - value: createReadStream(PEWPEW_FILEPATH), + value: createReadStream(PEWPEW_LEGACY_FILEPATH), options: { filename } }], latest: "true" @@ -212,7 +212,7 @@ describe("PewPew API Integration", () => { expect(body.message).to.not.equal(undefined); expect(body.message).to.include("PewPew uploaded, version"); expect(body.message).to.not.include("as latest"); - const match: RegExpMatchArray | null = body.message.match(/PewPew uploaded, version: (\d+\.\d+\.\d+)/); + const match: RegExpMatchArray | null = body.message.match(/PewPew uploaded, version: (\d+\.\d+\.\d+(-[a-zA-Z0-9]+)?)/); log(`pewpew match: ${match}`, LogLevel.DEBUG, match); expect(match, "pewpew match").to.not.equal(null); expect(match!.length, "pewpew match.length").to.be.greaterThan(1); @@ -252,13 +252,12 @@ describe("PewPew API Integration", () => { }); describe("DELETE /pewpew", () => { - after(async () => { - // Put the version back + const uploadLegacyPewpew = async () => { try { - const filename: string = path.basename(PEWPEW_FILEPATH); + const filename: string = path.basename(PEWPEW_LEGACY_FILEPATH); const formData: FormDataPewPew = { additionalFiles: { - value: createReadStream(PEWPEW_FILEPATH), + value: createReadStream(PEWPEW_LEGACY_FILEPATH), options: { filename } } }; @@ -279,7 +278,7 @@ describe("PewPew API Integration", () => { expect(typeof body.message).to.equal("string"); expect(body.message).to.include("PewPew uploaded, version"); expect(body.message).to.not.include("as latest"); - const match: RegExpMatchArray | null = body.message.match(/PewPew uploaded, version: (\d+\.\d+\.\d+)/); + const match: RegExpMatchArray | null = body.message.match(/PewPew uploaded, version: (\d+\.\d+\.\d+(-[a-zA-Z0-9]+)?)/); log(`pewpew match: ${match}`, LogLevel.DEBUG, match); expect(match, "pewpew match").to.not.equal(null); expect(match!.length, "pewpew match.length").to.be.greaterThan(1); @@ -294,8 +293,21 @@ describe("PewPew API Integration", () => { } log("sharedPewPewVersions: " + sharedPewPewVersions, LogLevel.DEBUG); } catch (error) { + log("deletePewPew uploadLegacyPewpew error", LogLevel.ERROR, error); throw error; } + }; + + beforeEach(async () => { + if (uploadedPewPewVersion) { + return; + } + await uploadLegacyPewpew(); + }); + + after(async () => { + // Put the version back + await uploadLegacyPewpew(); }); it("DELETE /pewpew should respond 200 OK", (done: Mocha.Done) => { @@ -303,10 +315,11 @@ describe("PewPew API Integration", () => { const deleteVersion = uploadedPewPewVersion; const deleteURL = `${url}?version=${deleteVersion}`; log("DELETE URL", LogLevel.DEBUG, { deleteURL }); + // Reset it since it's been deleted + uploadedPewPewVersion = undefined; fetch(deleteURL, { method: "DELETE" }).then((res: Response) => { log("DELETE /pewpew res", LogLevel.DEBUG, res); expect(res.status).to.equal(200); - uploadedPewPewVersion = undefined; const body: TestManagerError = res.data; log("body: " + res.data, LogLevel.DEBUG, body); expect(body).to.not.equal(undefined); diff --git a/controller/acceptance/test.spec.ts b/controller/acceptance/test.spec.ts index ab9e4369..87e0b03f 100644 --- a/controller/acceptance/test.spec.ts +++ b/controller/acceptance/test.spec.ts @@ -47,6 +47,7 @@ const BASIC_FILEPATH_HEADERS_ALL = path.join(UNIT_TEST_FOLDER, "basicheadersall. export const SCRIPTING_FILEPATH = path.join(UNIT_TEST_FOLDER, "scripting.yaml"); const SCRIPTING_FILEPATH_WITH_ENV = path.join(UNIT_TEST_FOLDER, "scriptingwithenv.yaml"); const SCRIPTING_FILEPATH_WITH_FILES = path.join(UNIT_TEST_FOLDER, "scriptingwithfiles.yaml"); +const SCRIPTING_FILEPATH_NO_PEAK_LOAD = path.join(UNIT_TEST_FOLDER, "scriptingnopeakload.yaml"); const SCRIPTING_FILEPATH_HEADERS_ALL = path.join(UNIT_TEST_FOLDER, "scriptingheadersall.yaml"); const NOT_YAML_FILEPATH = path.join(UNIT_TEST_FOLDER, "text.txt"); const NOT_YAML_FILEPATH2 = path.join(UNIT_TEST_FOLDER, "text2.txt"); @@ -240,7 +241,7 @@ describe("Test API Integration", () => { let testIdWithVersion: string | undefined; let url: string; let queueName: string = "unittests"; - let numberedVersion: string; + let legacyVersion: string; let scriptingVersion: string; before(async () => { @@ -255,12 +256,12 @@ describe("Test API Integration", () => { expect(sharedPewPewVersions, "sharedPewPewVersions").to.not.equal(undefined); expect(sharedPewPewVersions!.length, "sharedPewPewVersions.length").to.be.greaterThan(0); const scriptingRegex = /^0\.6\./; - numberedVersion = sharedPewPewVersions!.find((pewpewVersion: string) => + legacyVersion = sharedPewPewVersions!.find((pewpewVersion: string) => pewpewVersion !== latestPewPewVersion && !scriptingRegex.test(pewpewVersion)) || ""; - expect(numberedVersion).to.not.equal(undefined); - expect(numberedVersion).to.not.equal(""); - expect(scriptingRegex.test(numberedVersion), `${scriptingRegex}.test("${numberedVersion}")`).to.equal(false); - log("numberedVersion", LogLevel.DEBUG, { numberedVersion }); + expect(legacyVersion).to.not.equal(undefined); + expect(legacyVersion).to.not.equal(""); + expect(scriptingRegex.test(legacyVersion), `${scriptingRegex}.test("${legacyVersion}")`).to.equal(false); + log("legacyVersion", LogLevel.DEBUG, { legacyVersion }); scriptingVersion = sharedPewPewVersions!.find((pewpewVersion: string) => scriptingRegex.test(pewpewVersion)) || ""; expect(scriptingVersion).to.not.equal(undefined); @@ -348,7 +349,7 @@ describe("Test API Integration", () => { }); }); - it("POST /test with version numbered should respond 200 OK", (done: Mocha.Done) => { + it("POST /test with version legacy should respond 200 OK", (done: Mocha.Done) => { const filename: string = path.basename(basicFilepath); const environmentVariables: EnvironmentVariablesFile = { PROFILE: { value: "version", hidden: false } @@ -358,7 +359,7 @@ describe("Test API Integration", () => { value: createReadStream(basicFilepath), options: { filename } }, - version: numberedVersion, + version: legacyVersion, environmentVariables: JSON.stringify(environmentVariables), queueName }; @@ -419,36 +420,36 @@ describe("Test API Integration", () => { }); }); - // it("POST /test with version scripting should respond 400 Bad Request", (done: Mocha.Done) => { - // const filename: string = path.basename(basicFilepath); - // const formData: FormDataPost = { - // yamlFile: { - // value: createReadStream(basicFilepath), - // options: { filename } - // }, - // version: scriptingVersion, - // queueName - // }; - // const data = convertFormDataPostToFormData(formData); - // const headers = data.getHeaders(); - // log("POST formData", LogLevel.DEBUG, { test: formData, headers }); - // fetch(url, { - // method: "POST", - // data, - // headers - // }).then((res: Response) => { - // log("POST /test res", LogLevel.DEBUG, res); - // const bodyText = JSON.stringify(res.data); - // expect(res.status, bodyText).to.equal(400); - // log("body: " + bodyText, LogLevel.DEBUG, bodyText); - // expect(bodyText).to.not.equal(undefined); - // expect(bodyText).to.include("invalid version"); - // done(); - // }).catch((error) => { - // log("POST /test error", LogLevel.ERROR, error); - // done(error); - // }); - // }); + it("POST /test with version scripting should respond 400 Bad Request", (done: Mocha.Done) => { + const filename: string = path.basename(basicFilepath); + const formData: FormDataPost = { + yamlFile: { + value: createReadStream(basicFilepath), + options: { filename } + }, + version: scriptingVersion, + queueName + }; + const data = convertFormDataPostToFormData(formData); + const headers = data.getHeaders(); + log("POST formData", LogLevel.DEBUG, { test: formData, headers }); + fetch(url, { + method: "POST", + data, + headers + }).then((res: Response) => { + log("POST /test res", LogLevel.DEBUG, res); + const bodyText = JSON.stringify(res.data); + expect(res.status, bodyText).to.equal(400); + log("body: " + bodyText, LogLevel.DEBUG, bodyText); + expect(bodyText).to.not.equal(undefined); + expect(bodyText).to.include("failed to parse"); + done(); + }).catch((error) => { + log("POST /test error", LogLevel.ERROR, error); + done(error); + }); + }); it("POST /test with extra options should respond 200 OK", (done: Mocha.Done) => { const filename: string = path.basename(basicFilepath); @@ -1576,7 +1577,8 @@ describe("Test API Integration", () => { const scriptingFilepath: string = SCRIPTING_FILEPATH; const scriptingFilepathWithEnv: string = SCRIPTING_FILEPATH_WITH_ENV; - it("POST /test with version numbered should respond 200 OK", (done: Mocha.Done) => { + // Can't currently test latest since if an agent tries to run it, it will fail + it("POST /test with version scripting should respond 200 OK", (done: Mocha.Done) => { const filename: string = path.basename(scriptingFilepath); const formData: FormDataPost = { yamlFile: { @@ -1611,36 +1613,36 @@ describe("Test API Integration", () => { }); }); - // it("POST /test with version non-scripting should respond 400 Bad Request", (done: Mocha.Done) => { - // const filename: string = path.basename(scriptingFilepath); - // const formData: FormDataPost = { - // yamlFile: { - // value: createReadStream(scriptingFilepath), - // options: { filename } - // }, - // version: numberedVersion, - // queueName - // }; - // const data = convertFormDataPostToFormData(formData); - // const headers = data.getHeaders(); - // log("POST formData", LogLevel.DEBUG, { test: formData, headers }); - // fetch(url, { - // method: "POST", - // data, - // headers - // }).then((res: Response) => { - // log("POST /test res", LogLevel.DEBUG, res); - // const bodyText = JSON.stringify(res.data); - // expect(res.status, bodyText).to.equal(400); - // log("body: " + bodyText, LogLevel.DEBUG, bodyText); - // expect(bodyText).to.not.equal(undefined); - // expect(bodyText).to.include("invalid version"); - // done(); - // }).catch((error) => { - // log("POST /test error", LogLevel.ERROR, error); - // done(error); - // }); - // }); + it("POST /test with version legacy should respond 400 Bad Request", (done: Mocha.Done) => { + const filename: string = path.basename(scriptingFilepath); + const formData: FormDataPost = { + yamlFile: { + value: createReadStream(scriptingFilepath), + options: { filename } + }, + version: legacyVersion, + queueName + }; + const data = convertFormDataPostToFormData(formData); + const headers = data.getHeaders(); + log("POST formData", LogLevel.DEBUG, { test: formData, headers }); + fetch(url, { + method: "POST", + data, + headers + }).then((res: Response) => { + log("POST /test res", LogLevel.DEBUG, res); + const bodyText = JSON.stringify(res.data); + expect(res.status, bodyText).to.equal(400); + log("body: " + bodyText, LogLevel.DEBUG, bodyText); + expect(bodyText).to.not.equal(undefined); + expect(bodyText).to.include("failed to parse"); + done(); + }).catch((error) => { + log("POST /test error", LogLevel.ERROR, error); + done(error); + }); + }); it("POST /test with extra options should respond 200 OK", (done: Mocha.Done) => { const filename: string = path.basename(scriptingFilepath); @@ -1839,6 +1841,40 @@ describe("Test API Integration", () => { }); }); + it("POST /test with no peak load should respond 200 OK", (done: Mocha.Done) => { + const filepath: string = SCRIPTING_FILEPATH_NO_PEAK_LOAD; + const filename: string = path.basename(filepath); + const formData: FormDataPost = { + yamlFile: { + value: createReadStream(filepath), + options: { filename } + }, + queueName + }; + const data = convertFormDataPostToFormData(formData); + const headers = data.getHeaders(); + log("POST formData", LogLevel.DEBUG, { test: formData, headers }); + fetch(url, { + method: "POST", + data, + headers + }).then((res: Response) => { + log("POST /test res", LogLevel.DEBUG, res); + const bodyText = JSON.stringify(res.data); + expect(res.status, bodyText).to.equal(200); + const body = JSON.parse(bodyText); + log("body: " + bodyText, LogLevel.DEBUG, body); + expect(body).to.not.equal(undefined); + expect(body.testId).to.not.equal(undefined); + expect(body.s3Folder).to.not.equal(undefined); + expect(body.status).to.equal(TestStatus.Created); + done(); + }).catch((error) => { + log("POST /test error", LogLevel.ERROR, error); + done(error); + }); + }); + it("POST /test with headers_all should respond 200 OK", (done: Mocha.Done) => { const filepath: string = SCRIPTING_FILEPATH_HEADERS_ALL; const filename: string = path.basename(filepath); @@ -2025,7 +2061,7 @@ describe("Test API Integration", () => { expect(test.yamlFile, "yamlFile").to.equal(path.basename(basicFilepath)); expect(test.queueName, "queueName").to.equal(queueName); expect(test.additionalFiles, "additionalFiles").to.equal(undefined); - expect(test.version, "version").to.equal(numberedVersion); + expect(test.version, "version").to.equal(legacyVersion); expect(test.environmentVariables, "environmentVariables").to.not.equal(undefined); expect(Object.keys(test.environmentVariables).length, "environmentVariables.keys.length: " + Object.keys(test.environmentVariables)).to.equal(1); expect(test.restartOnFailure, "restartOnFailure").to.equal(undefined); diff --git a/controller/components/StartTestForm/index.tsx b/controller/components/StartTestForm/index.tsx index 8a011f4a..4859ae1b 100644 --- a/controller/components/StartTestForm/index.tsx +++ b/controller/components/StartTestForm/index.tsx @@ -59,14 +59,11 @@ const UploadTestButton = styled.button` text-align: center; `; -const Alight = styled.a` - color: lightblue; -`; const notAuthorizedMessageOpenId = (username?: string | null): JSX.Element =>

{`'${username}'` || "User"} is not authorized to run tests.
- Please use the DPT Tools Portal and request 'Performance Test - User' permission if you need to be able to run tests. + Please request 'Pewpew - User' permission if you need to be able to run tests.

DO NOT request 'Non Prod' Permissions. Those are for internal authentication testing only.
diff --git a/controller/components/TestInfo/story.tsx b/controller/components/TestInfo/story.tsx index 22e807e7..6096706e 100644 --- a/controller/components/TestInfo/story.tsx +++ b/controller/components/TestInfo/story.tsx @@ -5,6 +5,7 @@ import { PpaasTestId } from "@fs/ppaas-common/dist/src/ppaastestid"; import React from "react"; import { TestData } from "../../types/testmanager"; import { TestStatus } from "@fs/ppaas-common/dist/types"; +import { latestPewPewVersion } from "../../pages/api/util/clientutil"; /** * Developing and visually testing components in isolation before composing them in your app is useful. @@ -40,7 +41,7 @@ const fullTest: Required = { lastUpdated: new Date(Date.now() - 300000), lastChecked: new Date(Date.now() - 100000), errors: ["error1", "error2", "error3"], - version: "latest", + version: latestPewPewVersion, queueName: "unittest", userId: "bruno.madrigal@pewpew.org" }; diff --git a/controller/integration/pewpew.spec.ts b/controller/integration/pewpew.spec.ts index 75b85d64..339d239c 100644 --- a/controller/integration/pewpew.spec.ts +++ b/controller/integration/pewpew.spec.ts @@ -12,38 +12,64 @@ import { waitForSecrets } from "../pages/api/util/secrets"; logger.config.LogFileName = "ppaas-controller"; const UNIT_TEST_FOLDER = process.env.UNIT_TEST_FOLDER || "test"; -const PEWPEW_FILEPATH = path.join(UNIT_TEST_FOLDER, "pewpew.zip"); +const PEWPEW_LEGACY_FILEPATH = path.join(UNIT_TEST_FOLDER, "pewpew.zip"); +const PEWPEW_SCRIPTING_FILEPATH = path.join(UNIT_TEST_FOLDER, "scripting/pewpew.zip"); const authAdmin: AuthPermissions = { authPermission: AuthPermission.Admin, token: "admin1" }; -const pewpewZipFile: File = createFormidableFile( - path.basename(PEWPEW_FILEPATH), - PEWPEW_FILEPATH, - "unittest", - 1, - null -); let sharedPewPewVersions: string[] | undefined; let uploadedPewPewVersion: string | undefined; // Used for delete describe("PewPew Util Integration", () => { - let files: Files = {}; + let filesLegacyPewpew: Files = {}; + let filesScriptingPewpew: Files = {}; + before(async () => { - const filename: string = pewpewZipFile.originalFilename!; + // Legacy Pewpew binary + const legacyPewpewZipFile: File = createFormidableFile( + path.basename(PEWPEW_LEGACY_FILEPATH), + PEWPEW_LEGACY_FILEPATH, + "unittest", + 1, + null + ); try { - const unzippedFiles: File[] = await unzipFile(pewpewZipFile); + const filename: string = legacyPewpewZipFile.originalFilename!; + const unzippedFiles: File[] = await unzipFile(legacyPewpewZipFile); log("unzipped " + filename, LogLevel.DEBUG, unzippedFiles); - files = { + filesLegacyPewpew = { additionalFiles: unzippedFiles as any as File }; - log("new files " + filename, LogLevel.DEBUG, files); + log("legacy files " + filename, LogLevel.DEBUG, filesLegacyPewpew); } catch (error) { - log("Error unzipping " + filename, LogLevel.ERROR, error); + log("Error unzipping " + legacyPewpewZipFile.originalFilename, LogLevel.ERROR, error); throw error; } + + // Scripting Pewpew binary + const scriptingPewpewZipFile: File = createFormidableFile( + path.basename(PEWPEW_SCRIPTING_FILEPATH), + PEWPEW_SCRIPTING_FILEPATH, + "unittest", + 1, + null + ); + try { + const filename: string = scriptingPewpewZipFile.originalFilename!; + const unzippedFiles: File[] = await unzipFile(scriptingPewpewZipFile); + log("unzipped " + filename, LogLevel.DEBUG, unzippedFiles); + filesScriptingPewpew = { + additionalFiles: unzippedFiles as any as File + }; + log("scripting files " + filename, LogLevel.DEBUG, filesScriptingPewpew); + } catch (error) { + log("Error unzipping " + scriptingPewpewZipFile.originalFilename, LogLevel.ERROR, error); + throw error; + } + await waitForSecrets(); }); @@ -69,10 +95,10 @@ describe("PewPew Util Integration", () => { }); describe("postPewPew", () => { - it("postPewPew should respond 200 OK", (done: Mocha.Done) => { + it("postPewPew legacy should respond 200 OK", (done: Mocha.Done) => { const parsedForm: ParsedForm = { fields: {}, - files + files: filesLegacyPewpew }; log("postPewPew parsedForm", LogLevel.DEBUG, parsedForm); postPewPew(parsedForm, authAdmin).then((res: ErrorResponse) => { @@ -84,7 +110,7 @@ describe("PewPew Util Integration", () => { expect(body.message).to.not.equal(undefined); expect(body.message).to.include("PewPew uploaded, version"); expect(body.message).to.not.include("as latest"); - const match: RegExpMatchArray | null = body.message.match(/PewPew uploaded, version: (\d+\.\d+\.\d+)/); + const match: RegExpMatchArray | null = body.message.match(/PewPew uploaded, version: (\d+\.\d+\.\d+(-[a-zA-Z0-9]+)?)/); log(`pewpew match: ${match}`, LogLevel.DEBUG, match); expect(match, "pewpew match").to.not.equal(null); expect(match!.length, "pewpew match.length").to.be.greaterThan(1); @@ -109,7 +135,7 @@ describe("PewPew Util Integration", () => { fields: { latest: "true" }, - files + files: filesLegacyPewpew }; log("postPewPew parsedForm", LogLevel.DEBUG, parsedForm); postPewPew(parsedForm, authAdmin).then((res: ErrorResponse) => { @@ -135,6 +161,40 @@ describe("PewPew Util Integration", () => { done(error); }); }); + + it("postPewPew scripting should respond 200 OK", (done: Mocha.Done) => { + const parsedForm: ParsedForm = { + fields: {}, + files: filesScriptingPewpew + }; + log("postPewPew parsedForm", LogLevel.DEBUG, parsedForm); + postPewPew(parsedForm, authAdmin).then((res: ErrorResponse) => { + log("postPewPew res", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(200); + const body: TestManagerError = res.json; + log("body: " + JSON.stringify(body), LogLevel.DEBUG, body); + expect(body).to.not.equal(undefined); + expect(body.message).to.not.equal(undefined); + expect(body.message).to.include("PewPew uploaded, version"); + expect(body.message).to.not.include("as latest"); + const match: RegExpMatchArray | null = body.message.match(/PewPew uploaded, version: (\d+\.\d+\.\d+(-[a-zA-Z0-9]+)?)/); + log(`pewpew match: ${match}`, LogLevel.DEBUG, match); + expect(match, "pewpew match").to.not.equal(null); + expect(match!.length, "pewpew match.length").to.be.greaterThan(1); + const version: string = match![1]; + // If this runs before the other acceptance tests populate the shared pewpew versions + if (!sharedPewPewVersions) { + sharedPewPewVersions = [version]; + } else if (!sharedPewPewVersions.includes(version)) { + sharedPewPewVersions.push(version); + } + log("sharedPewPewVersions: " + sharedPewPewVersions, LogLevel.DEBUG); + done(); + }).catch((error) => { + log("postPewPew error", LogLevel.ERROR, error); + done(error); + }); + }); }); describe("getPewpew", () => { @@ -156,14 +216,11 @@ describe("PewPew Util Integration", () => { }); describe("deletePewPew", () => { - beforeEach(async () => { - if (uploadedPewPewVersion) { - return; - } + const uploadLegacyPewpew = async () => { try { const parsedForm: ParsedForm = { fields: {}, - files + files: filesLegacyPewpew }; log("postPewPew parsedForm", LogLevel.DEBUG, parsedForm); const res: ErrorResponse = await postPewPew(parsedForm, authAdmin); @@ -175,7 +232,7 @@ describe("PewPew Util Integration", () => { expect(body.message).to.not.equal(undefined); expect(body.message).to.include("PewPew uploaded, version"); expect(body.message).to.not.include("as latest"); - const match: RegExpMatchArray | null = body.message.match(/PewPew uploaded, version: (\d+\.\d+\.\d+)/); + const match: RegExpMatchArray | null = body.message.match(/PewPew uploaded, version: (\d+\.\d+\.\d+(-[a-zA-Z0-9]+)?)/); log(`pewpew match: ${match}`, LogLevel.DEBUG, match); expect(match, "pewpew match").to.not.equal(null); expect(match!.length, "pewpew match.length").to.be.greaterThan(1); @@ -189,9 +246,20 @@ describe("PewPew Util Integration", () => { sharedPewPewVersions = s3Versions; expect(s3Versions).to.include(version); } catch (error) { - log("deletePewPew beforeEach error", LogLevel.ERROR, error); + log("deletePewPew uploadLegacyPewpew error", LogLevel.ERROR, error); throw error; } + }; + + beforeEach(async () => { + if (uploadedPewPewVersion) { + return; + } + await uploadLegacyPewpew(); + }); + + after(async () => { + await uploadLegacyPewpew(); }); it("deletePewPew should respond 200 OK", (done: Mocha.Done) => { diff --git a/controller/integration/testmanager.spec.ts b/controller/integration/testmanager.spec.ts index 5016a509..3e2b2053 100644 --- a/controller/integration/testmanager.spec.ts +++ b/controller/integration/testmanager.spec.ts @@ -39,11 +39,16 @@ export const UNIT_TEST_FOLDER: string = path.resolve(process.env.UNIT_TEST_FOLDE const BASIC_YAML_FILE: string = "basic.yaml"; const BASIC_FILEPATH = path.join(UNIT_TEST_FOLDER, "basic.yaml"); const BASIC_FILEPATH_WITH_ENV = path.join(UNIT_TEST_FOLDER, "basicwithenv.yaml"); -export const BASIC_FILEPATH_WITH_FILES = path.join(UNIT_TEST_FOLDER, "basicwithfiles.yaml"); +const BASIC_FILEPATH_WITH_FILES = path.join(UNIT_TEST_FOLDER, "basicwithfiles.yaml"); const BASIC_FILEPATH_NO_PEAK_LOAD = path.join(UNIT_TEST_FOLDER, "basicnopeakload.yaml"); const BASIC_FILEPATH_HEADERS_ALL = path.join(UNIT_TEST_FOLDER, "basicheadersall.yaml"); -export const BASIC_FILEPATH_NOT_YAML = path.join(UNIT_TEST_FOLDER, "text.txt"); -export const BASIC_FILEPATH_NOT_YAML2 = path.join(UNIT_TEST_FOLDER, "text2.txt"); +const SCRIPTING_FILEPATH = path.join(UNIT_TEST_FOLDER, "scripting.yaml"); +const SCRIPTING_FILEPATH_WITH_ENV = path.join(UNIT_TEST_FOLDER, "scriptingwithenv.yaml"); +const SCRIPTING_FILEPATH_WITH_FILES = path.join(UNIT_TEST_FOLDER, "scriptingwithfiles.yaml"); +const SCRIPTING_FILEPATH_NO_PEAK_LOAD = path.join(UNIT_TEST_FOLDER, "scriptingnopeakload.yaml"); +const SCRIPTING_FILEPATH_HEADERS_ALL = path.join(UNIT_TEST_FOLDER, "scriptingheadersall.yaml"); +const NOT_YAML_FILEPATH = path.join(UNIT_TEST_FOLDER, "text.txt"); +const NOT_YAML_FILEPATH2 = path.join(UNIT_TEST_FOLDER, "text2.txt"); const PEWPEWYAML_FILEPATH = path.join(UNIT_TEST_FOLDER, "pewpew.yaml"); const SETTINGSYAML_FILEPATH = path.join(UNIT_TEST_FOLDER, "settings.yaml"); @@ -91,7 +96,8 @@ describe("TestManager Integration", () => { let testIdWithVersion: string | undefined; let testIdMissingEnv: string | undefined; let queueName: string = "unittests"; - let numberedVersion: string | undefined; + let legacyVersion: string | undefined; + let scriptingVersion: string | undefined; before(async () => { try { @@ -122,9 +128,21 @@ describe("TestManager Integration", () => { log("sharedPewPewVersions", LogLevel.DEBUG, sharedPewPewVersions); expect(sharedPewPewVersions, "sharedPewPewVersions").to.not.equal(undefined); expect(sharedPewPewVersions!.length, "sharedPewPewVersions.length").to.be.greaterThan(0); - numberedVersion = sharedPewPewVersions!.find((pewpewVersion: string) => pewpewVersion !== latestPewPewVersion); - expect(numberedVersion).to.not.equal(undefined); - log("numberedVersion", LogLevel.DEBUG, { numberedVersion }); + + const scriptingRegex = /^0\.6\./; + legacyVersion = sharedPewPewVersions!.find((pewpewVersion: string) => + pewpewVersion !== latestPewPewVersion && !scriptingRegex.test(pewpewVersion)) || ""; + expect(legacyVersion).to.not.equal(undefined); + expect(legacyVersion).to.not.equal(""); + expect(scriptingRegex.test(legacyVersion), `${scriptingRegex}.test("${legacyVersion}")`).to.equal(false); + log("legacyVersion", LogLevel.DEBUG, { legacyVersion }); + scriptingVersion = sharedPewPewVersions!.find((pewpewVersion: string) => + scriptingRegex.test(pewpewVersion)) || ""; + expect(scriptingVersion).to.not.equal(undefined); + expect(scriptingVersion).to.not.equal(""); + expect(scriptingRegex.test(scriptingVersion), `${scriptingRegex}.test("${scriptingVersion}")`).to.equal(true); + log("scriptingVersion", LogLevel.DEBUG, { scriptingVersion }); + const basicFilenameWithEnv = path.basename(BASIC_FILEPATH_WITH_ENV); const ppaasTestIdWithEnv: PpaasTestId = PpaasTestId.makeTestId(basicFilenameWithEnv); await new PpaasS3File({ @@ -140,6 +158,7 @@ describe("TestManager Integration", () => { }); describe("POST /test", () => { + describe("POST legacy files", () => { const basicFiles: Files = { yamlFile: createFileObject(BASIC_FILEPATH) }; const basicFields: Fields = { queueName }; const basicParsedForm: ParsedForm = { @@ -211,17 +230,17 @@ describe("TestManager Integration", () => { }); }); - it("postTest with version numbered should respond 200 OK", (done: Mocha.Done) => { - expect(numberedVersion).to.not.equal(undefined); - log("postTest version, sharedQueueNames, sharedPewPewVersions", LogLevel.DEBUG, { numberedVersion, sharedQueueNames , sharedPewPewVersions }); + it("postTest with version legacy should respond 200 OK", (done: Mocha.Done) => { + expect(legacyVersion).to.not.equal(undefined); + log("postTest version, sharedPewPewVersions", LogLevel.DEBUG, { legacyVersion, sharedPewPewVersions }); const parsedForm: ParsedForm = { files: basicFiles, fields: { ...basicFields, - version: numberedVersion! + version: legacyVersion! } }; - log("postTest parsedForm numbered", LogLevel.DEBUG, { parsedForm }); + log("postTest parsedForm legacy", LogLevel.DEBUG, { parsedForm }); TestManager.postTest(parsedForm, authAdmin, UNIT_TEST_FOLDER).then((res: ErrorResponse | TestDataResponse) => { log("postTest res", LogLevel.DEBUG, res); expect(res.status, JSON.stringify(res.json)).to.equal(200); @@ -244,6 +263,33 @@ describe("TestManager Integration", () => { }); }); + it("postTest with version scripting should respond 400 Bad Request", (done: Mocha.Done) => { + expect(scriptingVersion).to.not.equal(undefined); + const parsedForm: ParsedForm = { + files: basicFiles, + fields: { + ...basicFields, + version: scriptingVersion! + } + }; + log("postTest parsedForm basic as scripting", LogLevel.DEBUG, { parsedForm }); + TestManager.postTest(parsedForm, authAdmin, UNIT_TEST_FOLDER).then((res: ErrorResponse | TestDataResponse) => { + log("postTest res", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(400); + log("body: " + JSON.stringify(res.json), LogLevel.DEBUG, res.json); + const body: TestManagerError = res.json as TestManagerError; + expect(body).to.not.equal(undefined); + expect(body.message).to.not.equal(undefined); + expect(body.message).to.include("failed to parse"); + expect(body.error).to.not.equal(undefined); + expect(body.error).to.include("YamlParse"); + done(); + }).catch((error) => { + log("postTest error", LogLevel.ERROR, error); + done(error); + }); + }); + it("postTest with version bogus should respond 400 Bad Request", (done: Mocha.Done) => { const parsedForm: ParsedForm = { files: basicFiles, @@ -277,7 +323,7 @@ describe("TestManager Integration", () => { const parsedForm: ParsedForm = { files: { ...basicFiles, - additionalFiles: createFileObject(BASIC_FILEPATH_NOT_YAML) + additionalFiles: createFileObject(NOT_YAML_FILEPATH) }, fields: { ...basicFields, @@ -348,11 +394,11 @@ describe("TestManager Integration", () => { }); it("postTest missing files should respond 400 Bad Request", (done: Mocha.Done) => { - const extrafilename: string = path.basename(BASIC_FILEPATH_NOT_YAML2); + const extrafilename: string = path.basename(NOT_YAML_FILEPATH2); const parsedForm: ParsedForm = { files: { yamlFile: createFileObject(BASIC_FILEPATH_WITH_FILES), - additionalFiles: createFileObject(BASIC_FILEPATH_NOT_YAML) + additionalFiles: createFileObject(NOT_YAML_FILEPATH) }, fields: basicFields }; @@ -468,7 +514,7 @@ describe("TestManager Integration", () => { const parsedForm: ParsedForm = { files: { yamlFile: createFileObject(BASIC_FILEPATH_WITH_FILES), - additionalFiles: [createFileObject(BASIC_FILEPATH_NOT_YAML), createFileObject(BASIC_FILEPATH_NOT_YAML2)] as any as File + additionalFiles: [createFileObject(NOT_YAML_FILEPATH), createFileObject(NOT_YAML_FILEPATH2)] as any as File }, fields: basicFields }; @@ -628,7 +674,7 @@ describe("TestManager Integration", () => { const parsedForm: ParsedForm = { files: { yamlFile: createFileObject(BASIC_FILEPATH_WITH_FILES), - additionalFiles: [createFileObject(BASIC_FILEPATH_NOT_YAML), createFileObject(BASIC_FILEPATH_NOT_YAML2)] as any as File + additionalFiles: [createFileObject(NOT_YAML_FILEPATH), createFileObject(NOT_YAML_FILEPATH2)] as any as File }, fields: { ...basicFields, @@ -1072,8 +1118,8 @@ describe("TestManager Integration", () => { // In this case, even though the previous test has the files, if we don't pass them in to the fields it should fail it("postTest missing files prior testId should respond 400 Bad Request", (done: Mocha.Done) => { expect(testIdWithFiles, "testIdWithFiles").to.not.equal(undefined); - const extrafilename: string = path.basename(BASIC_FILEPATH_NOT_YAML); - const extrafilename2: string = path.basename(BASIC_FILEPATH_NOT_YAML2); + const extrafilename: string = path.basename(NOT_YAML_FILEPATH); + const extrafilename2: string = path.basename(NOT_YAML_FILEPATH2); const parsedForm: ParsedForm = { files: {}, fields: { @@ -1102,7 +1148,7 @@ describe("TestManager Integration", () => { // This test the prior test doesn't even need the files, but the new yaml does it("postTest missing files prior testId, new yaml needs files should respond 400 Bad Request", (done: Mocha.Done) => { expect(sharedPpaasTestId, "sharedPpaasTestId").to.not.equal(undefined); - const extrafilename: string = path.basename(BASIC_FILEPATH_NOT_YAML); + const extrafilename: string = path.basename(NOT_YAML_FILEPATH); const parsedForm: ParsedForm = { files: { yamlFile: createFileObject(BASIC_FILEPATH_WITH_FILES) }, fields: { @@ -1129,8 +1175,8 @@ describe("TestManager Integration", () => { // Now we pass in the prior files it("postTest with files prior testId should respond 200 Ok", (done: Mocha.Done) => { expect(testIdWithFiles, "testIdWithFiles").to.not.equal(undefined); - const extrafilename: string = path.basename(BASIC_FILEPATH_NOT_YAML); - const extrafilename2: string = path.basename(BASIC_FILEPATH_NOT_YAML2); + const extrafilename: string = path.basename(NOT_YAML_FILEPATH); + const extrafilename2: string = path.basename(NOT_YAML_FILEPATH2); const parsedForm: ParsedForm = { files: {}, fields: { @@ -1174,11 +1220,11 @@ describe("TestManager Integration", () => { // Now we pass in the prior files it("postTest with files prior testId one changed file should respond 200 Ok", (done: Mocha.Done) => { expect(testIdWithFiles, "testIdWithFiles").to.not.equal(undefined); - const extrafilename: string = path.basename(BASIC_FILEPATH_NOT_YAML); - const extrafilename2: string = path.basename(BASIC_FILEPATH_NOT_YAML2); + const extrafilename: string = path.basename(NOT_YAML_FILEPATH); + const extrafilename2: string = path.basename(NOT_YAML_FILEPATH2); const parsedForm: ParsedForm = { files: { - additionalFiles: createFileObject(BASIC_FILEPATH_NOT_YAML) + additionalFiles: createFileObject(NOT_YAML_FILEPATH) }, fields: { ...basicFields, @@ -1367,6 +1413,42 @@ describe("TestManager Integration", () => { }); }); + it("postTest editSchedule new date missing hidden vars should respond 400 Bad Request", (done: Mocha.Done) => { + expect(sharedScheduledWithVarsTestData, "sharedScheduledWithVarsTestData").to.not.equal(undefined); + const testId: string = sharedScheduledWithVarsTestData!.testId; + const scheduleDate: number = Date.now() + 1600000; + const sameVars: EnvironmentVariablesFile = { + ...defaultEnvironmentVariablesFromPrior, + TEST2: "true" + }; + const parsedForm: ParsedForm = { + files: {}, + fields: { + ...basicFields, + testId, + yamlFile: path.basename(BASIC_FILEPATH_WITH_ENV), + environmentVariables: JSON.stringify(sameVars), + scheduleDate: "" + scheduleDate + } + }; + log("postTest parsedForm with vars", LogLevel.DEBUG, { parsedForm }); + TestManager.postTest(parsedForm, authAdmin, UNIT_TEST_FOLDER, true).then((res: ErrorResponse | TestDataResponse) => { + log("postTest res missing hidden vars", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(400); + log("body: " + JSON.stringify(res.json), LogLevel.DEBUG, res.json); + const body: TestManagerError = res.json as TestManagerError; + expect(body).to.not.equal(undefined); + expect(body.message).to.not.equal(undefined); + expect(body.message).to.include("failed to parse"); + expect(body.error).to.not.equal(undefined); + expect(body.error).to.include("missingEnvironmentVariables=TEST1"); + done(); + }).catch((error) => { + log("postTest error", LogLevel.ERROR, error); + done(error); + }); + }); + it("postTest editSchedule new date with vars should respond 200 OK", (done: Mocha.Done) => { expect(sharedScheduledWithVarsTestData, "sharedScheduledWithVarsTestData").to.not.equal(undefined); const testId: string = sharedScheduledWithVarsTestData!.testId; @@ -1435,8 +1517,8 @@ describe("TestManager Integration", () => { const s3Folder: string = sharedScheduledWithFilesTestData!.s3Folder; sharedScheduledWithFilesTestData = undefined; // Wipe it out since we're messing with it const scheduleDate: number = Date.now() + 600000; - const extrafilename: string = path.basename(BASIC_FILEPATH_NOT_YAML); - const extrafilename2: string = path.basename(BASIC_FILEPATH_NOT_YAML2); + const extrafilename: string = path.basename(NOT_YAML_FILEPATH); + const extrafilename2: string = path.basename(NOT_YAML_FILEPATH2); const parsedForm: ParsedForm = { files: {}, fields: { @@ -1611,6 +1693,534 @@ describe("TestManager Integration", () => { }); }); + describe("POST scripting files", () => { + const scriptingFiles: Files = { yamlFile: createFileObject(SCRIPTING_FILEPATH) }; + const scriptingFields: Fields = { queueName }; + const scriptingParsedForm: ParsedForm = { + files: scriptingFiles, + fields: scriptingFields + }; + before(() => { + if (!queueName) { + expect(sharedQueueNames, "sharedQueueNames").to.not.equal(undefined); + expect(sharedQueueNames!.length, "sharedQueueNames.length").to.be.greaterThan(0); + queueName = sharedQueueNames![0]; + } + scriptingFields.queueName = queueName; + expect(scriptingVersion, "scriptingVersion").to.not.equal(undefined); + scriptingFields.version = scriptingVersion!; + scriptingParsedForm.fields = scriptingFields; + log("postTest sharedQueueNames", LogLevel.DEBUG, sharedQueueNames); + }); + + describe("POST /test new test", () => { + it("postTest should respond 200 OK", (done: Mocha.Done) => { + log("postTest parsedForm", LogLevel.DEBUG, { scriptingParsedForm }); + TestManager.postTest(scriptingParsedForm, authAdmin, UNIT_TEST_FOLDER).then((res: ErrorResponse | TestDataResponse) => { + log("postTest res", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(200); + const body: TestData = res.json as TestData; + log("body: " + JSON.stringify(res.json), LogLevel.DEBUG, body); + expect(body).to.not.equal(undefined); + expect(body.testId).to.not.equal(undefined); + expect(body.s3Folder).to.not.equal(undefined); + expect(body.status).to.equal(TestStatus.Created); + expect(body.userId).to.equal(authAdmin.userId); + done(); + }).catch((error) => { + log("postTest error", LogLevel.ERROR, error); + done(error); + }); + }); + + it("postTest with version latest should respond 200 OK", (done: Mocha.Done) => { + const parsedForm: ParsedForm = { + files: scriptingFiles, + fields: { + ...scriptingFields, + version: latestPewPewVersion + } + }; + log("postTest parsedForm latest", LogLevel.DEBUG, { parsedForm }); + TestManager.postTest(parsedForm, authAdmin, UNIT_TEST_FOLDER).then((res: ErrorResponse | TestDataResponse) => { + log("postTest res", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(200); + const body: TestData = res.json as TestData; + log("body: " + JSON.stringify(res.json), LogLevel.DEBUG, body); + expect(body).to.not.equal(undefined); + expect(body.testId).to.not.equal(undefined); + expect(body.s3Folder).to.not.equal(undefined); + expect(body.status).to.equal(TestStatus.Created); + expect(body.userId).to.equal(authAdmin.userId); + done(); + }).catch((error) => { + log("postTest error", LogLevel.ERROR, error); + done(error); + }); + }); + + it("postTest with version scripting should respond 200 OK", (done: Mocha.Done) => { + expect(scriptingVersion, "scriptingVersion").to.not.equal(undefined); + log("postTest version, sharedPewPewVersions", LogLevel.DEBUG, { scriptingVersion, sharedPewPewVersions }); + const parsedForm: ParsedForm = { + files: scriptingFiles, + fields: { + ...scriptingFields, + version: scriptingVersion! + } + }; + log("postTest parsedForm scripting", LogLevel.DEBUG, { parsedForm }); + TestManager.postTest(parsedForm, authAdmin, UNIT_TEST_FOLDER).then((res: ErrorResponse | TestDataResponse) => { + log("postTest res", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(200); + const body: TestData = res.json as TestData; + log("body: " + JSON.stringify(res.json), LogLevel.DEBUG, body); + expect(body).to.not.equal(undefined); + expect(body.testId).to.not.equal(undefined); + expect(body.s3Folder).to.not.equal(undefined); + expect(body.status).to.equal(TestStatus.Created); + expect(body.userId).to.equal(authAdmin.userId); + done(); + }).catch((error) => { + log("postTest error", LogLevel.ERROR, error); + done(error); + }); + }); + + it("postTest with version legacy should respond 400 Bad Request", (done: Mocha.Done) => { + expect(legacyVersion, "legacyVersion").to.not.equal(undefined); + const parsedForm: ParsedForm = { + files: scriptingFiles, + fields: { + ...scriptingFields, + version: legacyVersion! + } + }; + log("postTest parsedForm scripting as scripting", LogLevel.DEBUG, { parsedForm }); + TestManager.postTest(parsedForm, authAdmin, UNIT_TEST_FOLDER).then((res: ErrorResponse | TestDataResponse) => { + log("postTest res", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(400); + log("body: " + JSON.stringify(res.json), LogLevel.DEBUG, res.json); + const body: TestManagerError = res.json as TestManagerError; + expect(body).to.not.equal(undefined); + expect(body.message).to.not.equal(undefined); + expect(body.message).to.include("failed to parse"); + expect(body.error).to.not.equal(undefined); + expect(body.error).to.include("UnrecognizedKey"); + done(); + }).catch((error) => { + log("postTest error", LogLevel.ERROR, error); + done(error); + }); + }); + + it("postTest with version bogus should respond 400 Bad Request", (done: Mocha.Done) => { + const parsedForm: ParsedForm = { + files: scriptingFiles, + fields: { + ...scriptingFields, + version: "bogus" + } + }; + log("postTest parsedForm bogus", LogLevel.DEBUG, { parsedForm }); + TestManager.postTest(parsedForm, authAdmin, UNIT_TEST_FOLDER).then((res: ErrorResponse | TestDataResponse) => { + log("postTest res", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(400); + log("body: " + JSON.stringify(res.json), LogLevel.DEBUG, res.json); + const body: TestManagerError = res.json as TestManagerError; + expect(body).to.not.equal(undefined); + expect(body.message).to.not.equal(undefined); + expect(body.message).to.include("invalid version"); + done(); + }).catch((error) => { + log("postTest error", LogLevel.ERROR, error); + done(error); + }); + }); + + it("postTest with extra options should respond 200 OK", (done: Mocha.Done) => { + const environmentVariables: EnvironmentVariablesFile = { + ...defaultEnvironmentVariables, + NOT_NEEDED: { value: "true", hidden: false }, + ALSO_NOT_NEEDED: { value: "false", hidden: true } + }; + const parsedForm: ParsedForm = { + files: { + ...scriptingFiles, + additionalFiles: createFileObject(NOT_YAML_FILEPATH) + }, + fields: { + ...scriptingFields, + restartOnFailure: "true", + environmentVariables: JSON.stringify(environmentVariables) + } + }; + log("postTest parsedForm extra options", LogLevel.DEBUG, { parsedForm }); + TestManager.postTest(parsedForm, authAdmin, UNIT_TEST_FOLDER).then((res: ErrorResponse | TestDataResponse) => { + log("postTest res", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(200); + const body: TestData = res.json as TestData; + log("body: " + JSON.stringify(res.json), LogLevel.DEBUG, body); + expect(body).to.not.equal(undefined); + expect(body.testId).to.not.equal(undefined); + expect(body.s3Folder).to.not.equal(undefined); + expect(body.status).to.equal(TestStatus.Created); + expect(body.userId).to.equal(authAdmin.userId); + const s3Folder = PpaasTestId.getFromTestId(body.testId).s3Folder; + new PpaasEncryptEnvironmentFile({ s3Folder, environmentVariablesFile: undefined }).download(true) + .then((ppaasEncryptEnvironmentFile: PpaasEncryptEnvironmentFile) => { + const fileContents: string | undefined = ppaasEncryptEnvironmentFile.getFileContents(); + const expectedEnvironmentVariables = JSON.stringify(PpaasEncryptEnvironmentFile.filterEnvironmentVariables(environmentVariables)); + expect(fileContents, "PpaasEncryptEnvironmentFile fileContents").to.equal(expectedEnvironmentVariables); + const variablesFile: EnvironmentVariablesFile | undefined = ppaasEncryptEnvironmentFile.getEnvironmentVariablesFile(); + expect(variablesFile).to.not.equal(undefined); + if (variablesFile === undefined) { return; } + expect(Object.keys(variablesFile).length, "Object.keys(variablesFile).length").to.equal(Object.keys(environmentVariables).length); + for (const [variableName, variableValue] of Object.entries(environmentVariables)) { + if (typeof variableValue === "string" || variableValue.hidden) { + expect(JSON.stringify(variablesFile[variableName]), `variablesFile[${variableName}]`).to.equal(JSON.stringify({ hidden: true })); + } else { + expect(JSON.stringify(variablesFile[variableName]), `variablesFile[${variableName}]`).to.equal(JSON.stringify(variableValue)); + } + } + done(); + }).catch((error) => { + log("PpaasEncryptEnvironmentFile download error", LogLevel.ERROR, error); + done(error); + }); + }).catch((error) => { + log("postTest error", LogLevel.ERROR, error); + done(error); + }); + }); + + it("postTest missing vars should respond 400 Bad Request", (done: Mocha.Done) => { + const parsedForm: ParsedForm = { + files: { yamlFile: createFileObject(SCRIPTING_FILEPATH_WITH_ENV) }, + fields: scriptingFields + }; + log("postTest parsedForm missing vars", LogLevel.DEBUG, { parsedForm }); + TestManager.postTest(parsedForm, authAdmin, UNIT_TEST_FOLDER).then((res: ErrorResponse | TestDataResponse) => { + log("postTest res", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(400); + log("body: " + JSON.stringify(res.json), LogLevel.DEBUG, res.json); + const body: TestManagerError = res.json as TestManagerError; + expect(body).to.not.equal(undefined); + expect(body.message).to.not.equal(undefined); + expect(body.message).to.include("failed to parse"); + expect(body.error).to.not.equal(undefined); + expect(body.error).to.include("SERVICE_URL_AGENT"); + done(); + }).catch((error) => { + log("postTest error", LogLevel.ERROR, error); + done(error); + }); + }); + + it("postTest missing files should respond 400 Bad Request", (done: Mocha.Done) => { + const extrafilename: string = path.basename(NOT_YAML_FILEPATH2); + const parsedForm: ParsedForm = { + files: { + yamlFile: createFileObject(SCRIPTING_FILEPATH_WITH_FILES), + additionalFiles: createFileObject(NOT_YAML_FILEPATH) + }, + fields: scriptingFields + }; + log("postTest parsedForm missing files", LogLevel.DEBUG, { parsedForm }); + TestManager.postTest(parsedForm, authAdmin, UNIT_TEST_FOLDER).then((res: ErrorResponse | TestDataResponse) => { + log("postTest res", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(400); + log("body: " + JSON.stringify(res.json), LogLevel.DEBUG, res.json); + const body: TestManagerError = res.json as TestManagerError; + expect(body).to.not.equal(undefined); + expect(body.message).to.not.equal(undefined); + expect(body.message).to.include(extrafilename); + done(); + }).catch((error) => { + log("postTest error", LogLevel.ERROR, error); + done(error); + }); + }); + + it("postTest with vars should respond 200 OK", (done: Mocha.Done) => { + const parsedForm: ParsedForm = { + files: { yamlFile: createFileObject(SCRIPTING_FILEPATH_WITH_ENV) }, + fields: { + ...scriptingFields, + environmentVariables: JSON.stringify(defaultEnvironmentVariables) + } + }; + log("postTest parsedForm with vars", LogLevel.DEBUG, { parsedForm }); + TestManager.postTest(parsedForm, authAdmin, UNIT_TEST_FOLDER).then((res: ErrorResponse | TestDataResponse) => { + log("postTest res", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(200); + const body: TestData = res.json as TestData; + log("body: " + JSON.stringify(res.json), LogLevel.DEBUG, body); + expect(body).to.not.equal(undefined); + expect(body.testId).to.not.equal(undefined); + expect(body.s3Folder).to.not.equal(undefined); + expect(body.status).to.equal(TestStatus.Created); + expect(body.userId).to.equal(authAdmin.userId); + const s3Folder = PpaasTestId.getFromTestId(body.testId).s3Folder; + new PpaasEncryptEnvironmentFile({ s3Folder, environmentVariablesFile: undefined }).download(true) + .then((ppaasEncryptEnvironmentFile: PpaasEncryptEnvironmentFile) => { + const fileContents: string | undefined = ppaasEncryptEnvironmentFile.getFileContents(); + const expectedEnvironmentVariables = JSON.stringify(PpaasEncryptEnvironmentFile.filterEnvironmentVariables(defaultEnvironmentVariables)); + expect(fileContents, "PpaasEncryptEnvironmentFile fileContents").to.equal(expectedEnvironmentVariables); + const variablesFile: EnvironmentVariablesFile | undefined = ppaasEncryptEnvironmentFile.getEnvironmentVariablesFile(); + expect(variablesFile).to.not.equal(undefined); + if (variablesFile === undefined) { return; } + expect(Object.keys(variablesFile).length, "Object.keys(variablesFile).length").to.equal(Object.keys(defaultEnvironmentVariables).length); + for (const [variableName, variableValue] of Object.entries(defaultEnvironmentVariables)) { + if (typeof variableValue === "string" || variableValue.hidden) { + expect(JSON.stringify(variablesFile[variableName]), `variablesFile[${variableName}]`).to.equal(JSON.stringify({ hidden: true })); + } else { + expect(JSON.stringify(variablesFile[variableName]), `variablesFile[${variableName}]`).to.equal(JSON.stringify(variableValue)); + } + } + done(); + }).catch((error) => { + log("PpaasEncryptEnvironmentFile download error", LogLevel.ERROR, error); + done(error); + }); + }).catch((error) => { + log("postTest error", LogLevel.ERROR, error); + done(error); + }); + }); + + it("postTest with files should respond 200 OK", (done: Mocha.Done) => { + const parsedForm: ParsedForm = { + files: { + yamlFile: createFileObject(SCRIPTING_FILEPATH_WITH_FILES), + additionalFiles: [createFileObject(NOT_YAML_FILEPATH), createFileObject(NOT_YAML_FILEPATH2)] as any as File + }, + fields: scriptingFields + }; + log("postTest parsedForm with files", LogLevel.DEBUG, { parsedForm }); + TestManager.postTest(parsedForm, authAdmin, UNIT_TEST_FOLDER).then((res: ErrorResponse | TestDataResponse) => { + log("postTest res", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(200); + const body: TestData = res.json as TestData; + log("body: " + JSON.stringify(res.json), LogLevel.DEBUG, body); + expect(body).to.not.equal(undefined); + expect(body.testId).to.not.equal(undefined); + expect(body.s3Folder).to.not.equal(undefined); + expect(body.status).to.equal(TestStatus.Created); + expect(body.userId).to.equal(authAdmin.userId); + done(); + }).catch((error) => { + log("postTest error", LogLevel.ERROR, error); + done(error); + }); + }); + + it("postTest with no peak load should respond 200 OK", (done: Mocha.Done) => { + const parsedForm: ParsedForm = { + files: { yamlFile: createFileObject(SCRIPTING_FILEPATH_NO_PEAK_LOAD) }, + fields: scriptingFields + }; + log("postTest parsedForm no peak load", LogLevel.DEBUG, { parsedForm }); + TestManager.postTest(parsedForm, authAdmin, UNIT_TEST_FOLDER).then((res: ErrorResponse | TestDataResponse) => { + log("postTest res", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(200); + const body: TestData = res.json as TestData; + log("body: " + JSON.stringify(res.json), LogLevel.DEBUG, body); + expect(body).to.not.equal(undefined); + expect(body.testId).to.not.equal(undefined); + expect(body.s3Folder).to.not.equal(undefined); + expect(body.status).to.equal(TestStatus.Created); + expect(body.userId).to.equal(authAdmin.userId); + done(); + }).catch((error) => { + log("postTest error", LogLevel.ERROR, error); + done(error); + }); + }); + + it("postTest with headers_all should respond 200 OK", (done: Mocha.Done) => { + const parsedForm: ParsedForm = { + files: { yamlFile: createFileObject(SCRIPTING_FILEPATH_HEADERS_ALL) }, + fields: scriptingFields + }; + log("postTest parsedForm headers_all", LogLevel.DEBUG, { parsedForm }); + TestManager.postTest(parsedForm, authAdmin, UNIT_TEST_FOLDER).then((res: ErrorResponse | TestDataResponse) => { + log("postTest res", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(200); + const body: TestData = res.json as TestData; + log("body: " + JSON.stringify(res.json), LogLevel.DEBUG, body); + expect(body).to.not.equal(undefined); + expect(body.testId).to.not.equal(undefined); + expect(body.s3Folder).to.not.equal(undefined); + expect(body.status).to.equal(TestStatus.Created); + expect(body.userId).to.equal(authAdmin.userId); + done(); + }).catch((error) => { + log("postTest error", LogLevel.ERROR, error); + done(error); + }); + }); + }); + + describe("POST /test scheduled", () => { + it("postTest scheduled should respond 200 OK", (done: Mocha.Done) => { + const scheduleDate: number = Date.now() + 600000; + const parsedForm: ParsedForm = { + files: scriptingFiles, + fields: { + ...scriptingFields, + scheduleDate: "" + scheduleDate + } + }; + log("postTest parsedForm scheduled", LogLevel.DEBUG, { parsedForm }); + TestManager.postTest(parsedForm, authAdmin, UNIT_TEST_FOLDER).then((res: ErrorResponse | TestDataResponse) => { + log("postTest res", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(200); + const body: TestData = res.json as TestData; + log("body: " + JSON.stringify(res.json), LogLevel.DEBUG, body); + expect(body, "body").to.not.equal(undefined); + expect(body.testId, "testId").to.not.equal(undefined); + expect(body.s3Folder, "s3Folder").to.not.equal(undefined); + expect(body.status, "status").to.equal(TestStatus.Scheduled); + expect(body.userId).to.equal(authAdmin.userId); + expect(body.startTime, "startTime").to.equal(scheduleDate); + expect(body.endTime, "endTime").to.be.greaterThan(scheduleDate); + const ppaasTestId = PpaasTestId.getFromTestId(body.testId); + // We can't re-use the schedule date for the testId since we don't want conflicts if you schedule the same test twice + expect(ppaasTestId.date.getTime(), "ppaasTestId.date").to.not.equal(scheduleDate); + done(); + }).catch((error) => { + log("postTest error", LogLevel.ERROR, error); + done(error); + }); + }); + + it("postTest scheduled with vars should respond 200 OK", (done: Mocha.Done) => { + const scheduleDate: number = Date.now() + 600000; + const parsedForm: ParsedForm = { + files: { yamlFile: createFileObject(SCRIPTING_FILEPATH_WITH_ENV) }, + fields: { + ...scriptingFields, + environmentVariables: JSON.stringify(defaultEnvironmentVariables), + scheduleDate: "" + scheduleDate + } + }; + log("postTest parsedForm scheduled with vars", LogLevel.DEBUG, { parsedForm }); + TestManager.postTest(parsedForm, authAdmin, UNIT_TEST_FOLDER).then((res: ErrorResponse | TestDataResponse) => { + log("postTest res", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(200); + const body: TestData = res.json as TestData; + log("body: " + JSON.stringify(res.json), LogLevel.DEBUG, body); + expect(body).to.not.equal(undefined); + expect(body.testId).to.not.equal(undefined); + expect(body.s3Folder).to.not.equal(undefined); + expect(body.status).to.equal(TestStatus.Scheduled); + expect(body.userId).to.equal(authAdmin.userId); + const s3Folder = PpaasTestId.getFromTestId(body.testId).s3Folder; + new PpaasEncryptEnvironmentFile({ s3Folder, environmentVariablesFile: undefined }).download(true) + .then((ppaasEncryptEnvironmentFile: PpaasEncryptEnvironmentFile) => { + const fileContents: string | undefined = ppaasEncryptEnvironmentFile.getFileContents(); + const expectedEnvironmentVariables = JSON.stringify(PpaasEncryptEnvironmentFile.filterEnvironmentVariables(defaultEnvironmentVariables)); + expect(fileContents, "PpaasEncryptEnvironmentFile fileContents").to.equal(expectedEnvironmentVariables); + const variablesFile: EnvironmentVariablesFile | undefined = ppaasEncryptEnvironmentFile.getEnvironmentVariablesFile(); + expect(variablesFile).to.not.equal(undefined); + if (variablesFile === undefined) { return; } + expect(Object.keys(variablesFile).length, "Object.keys(variablesFile).length").to.equal(Object.keys(defaultEnvironmentVariables).length); + for (const [variableName, variableValue] of Object.entries(defaultEnvironmentVariables)) { + if (typeof variableValue === "string" || variableValue.hidden) { + expect(JSON.stringify(variablesFile[variableName]), `variablesFile[${variableName}]`).to.equal(JSON.stringify({ hidden: true })); + } else { + expect(JSON.stringify(variablesFile[variableName]), `variablesFile[${variableName}]`).to.equal(JSON.stringify(variableValue)); + } + } + done(); + }).catch((error) => { + log("PpaasEncryptEnvironmentFile download error", LogLevel.ERROR, error); + done(error); + }); + }).catch((error) => { + log("postTest error", LogLevel.ERROR, error); + done(error); + }); + }); + + it("postTest scheduled with files should respond 200 OK", (done: Mocha.Done) => { + const scheduleDate: number = Date.now() + 600000; + const parsedForm: ParsedForm = { + files: { + yamlFile: createFileObject(SCRIPTING_FILEPATH_WITH_FILES), + additionalFiles: [createFileObject(NOT_YAML_FILEPATH), createFileObject(NOT_YAML_FILEPATH2)] as any as File + }, + fields: { + ...scriptingFields, + scheduleDate: "" + scheduleDate + } + }; + log("postTest parsedForm with files", LogLevel.DEBUG, { parsedForm }); + TestManager.postTest(parsedForm, authAdmin, UNIT_TEST_FOLDER).then((res: ErrorResponse | TestDataResponse) => { + log("postTest res", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(200); + const body: TestData = res.json as TestData; + log("body: " + JSON.stringify(res.json), LogLevel.DEBUG, body); + expect(body).to.not.equal(undefined); + expect(body.testId).to.not.equal(undefined); + expect(body.s3Folder).to.not.equal(undefined); + expect(body.status).to.equal(TestStatus.Scheduled); + expect(body.userId).to.equal(authAdmin.userId); + done(); + }).catch((error) => { + log("postTest error", LogLevel.ERROR, error); + done(error); + }); + }); + + it("postTest scheduled recurring should respond 200 OK", (done: Mocha.Done) => { + const scheduleDate: number = Date.now() + 600000; + const endDate: number = Date.now() + (7 * 24 * 60 * 60000); + const parsedForm: ParsedForm = { + files: scriptingFiles, + fields: { + ...scriptingFields, + scheduleDate: "" + scheduleDate, + endDate: "" + endDate, + daysOfWeek: JSON.stringify(everyDaysOfWeek) + } + }; + log("postTest parsedForm scheduled recurring", LogLevel.DEBUG, { parsedForm }); + TestManager.postTest(parsedForm, authAdmin, UNIT_TEST_FOLDER).then((res: ErrorResponse | TestDataResponse) => { + log("postTest res", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(200); + const body: TestData = res.json as TestData; + log("body: " + JSON.stringify(res.json), LogLevel.DEBUG, body); + expect(body, "body").to.not.equal(undefined); + expect(body.testId, "testId").to.not.equal(undefined); + expect(body.s3Folder, "s3Folder").to.not.equal(undefined); + expect(body.status, "status").to.equal(TestStatus.Scheduled); + expect(body.userId).to.equal(authAdmin.userId); + expect(body.startTime, "startTime").to.equal(scheduleDate); + expect(body.endTime, "endTime").to.be.greaterThan(scheduleDate); + const ppaasTestId = PpaasTestId.getFromTestId(body.testId); + // We can't re-use the schedule date for the testId since we don't want conflicts if you schedule the same test twice + expect(ppaasTestId.date.getTime(), "ppaasTestId.date").to.not.equal(scheduleDate); + // If this runs before the other acceptance tests populate the shared data + TestScheduler.getCalendarEvents().then((calendarEvents: EventInput[]) => { + + const event: EventInput | undefined = calendarEvents.find((value: EventInput) => value.id === body.testId); + expect(event, "event found").to.not.equal(undefined); + expect(event!.startRecur, "event.startRecur").to.equal(scheduleDate); + expect(event!.daysOfWeek, "event.daysOfWeek").to.not.equal(undefined); + expect(JSON.stringify(event!.daysOfWeek), "event.daysOfWeek").to.equal(JSON.stringify(everyDaysOfWeek)); + done(); + }).catch((error) => done(error)); + }).catch((error) => { + log("postTest error", LogLevel.ERROR, error); + done(error); + }); + }); + + }); + }); + }); describe("GET /test", () => { it("getAllTest should respond 200 OK", (done: Mocha.Done) => { @@ -1768,7 +2378,7 @@ describe("TestManager Integration", () => { expect(test.yamlFile, "yamlFile").to.equal(BASIC_YAML_FILE); expect(test.queueName, "queueName").to.equal(queueName); expect(test.additionalFiles, "additionalFiles").to.equal(undefined); - expect(test.version, "version").to.equal(numberedVersion); + expect(test.version, "version").to.equal(legacyVersion); expect(test.environmentVariables, "environmentVariables").to.not.equal(undefined); expect(Object.keys(test.environmentVariables).length, "environmentVariables.length: " + Object.keys(test.environmentVariables)).to.equal(0); expect(test.restartOnFailure, "restartOnFailure").to.equal(undefined); diff --git a/controller/next.config.js b/controller/next.config.js index 8a39a704..8e7d25e2 100644 --- a/controller/next.config.js +++ b/controller/next.config.js @@ -95,6 +95,7 @@ const nextConfig = { publicRuntimeConfig: { // These are sent to the client and the server and are set at run time LoggingLevel: process.env.LoggingLevel, APPLICATION_NAME: process.env.APPLICATION_NAME, + SYSTEM_NAME: process.env.SYSTEM_NAME, FS_SITE: process.env.FS_SITE, NODE_ENV: process.env.NODE_ENV, BASE_PATH: process.env.BASE_PATH, @@ -126,6 +127,8 @@ const nextConfig = { // @ts-ignore APPLICATION_NAME: process.env.APPLICATION_NAME, // @ts-ignore + SYSTEM_NAME: process.env.SYSTEM_NAME, + // @ts-ignore FS_SITE: process.env.FS_SITE, // @ts-ignore BASE_PATH: process.env.BASE_PATH, diff --git a/controller/package.json b/controller/package.json index 8de8c4f9..edbca2e9 100644 --- a/controller/package.json +++ b/controller/package.json @@ -1,6 +1,6 @@ { "name": "@fs/ppaas-controller", - "version": "3.0.0", + "version": "3.0.1", "description": "Controller Service for running pewpew tests", "private": true, "scripts": { @@ -61,7 +61,7 @@ "js-yaml": "^4.1.0", "next": "~13.5.3", "next-cookies": "^2.0.3", - "openid-client": "~5.5.0", + "openid-client": "~5.6.0", "rc-progress": "^3.4.2", "react": "^18.2.0", "react-accessible-accordion": "^5.0.0", diff --git a/controller/pages/api/util/clientutil.ts b/controller/pages/api/util/clientutil.ts index a2472565..8df4a3ed 100644 --- a/controller/pages/api/util/clientutil.ts +++ b/controller/pages/api/util/clientutil.ts @@ -13,7 +13,6 @@ export const CNAME_DOMAIN: string = publicRuntimeConfig.CNAME_DOMAIN || ".pewpew export const ROUTING_DOMAIN: string = publicRuntimeConfig.ROUTING_DOMAIN || ".pewpew.org"; export const TEST_LOCALHOST: boolean = publicRuntimeConfig.TEST_LOCALHOST === "true"; export const LOCALHOST_DOMAIN: string = "localhost"; -export const APPLICATION_NAME: string | undefined = publicRuntimeConfig.APPLICATION_NAME; export function getBasePath (): string { return publicRuntimeConfig.BASE_PATH || ""; diff --git a/controller/pages/api/util/pewpew.ts b/controller/pages/api/util/pewpew.ts index c3dc824f..35e8e5be 100644 --- a/controller/pages/api/util/pewpew.ts +++ b/controller/pages/api/util/pewpew.ts @@ -125,7 +125,7 @@ export async function postPewPew (parsedForm: ParsedForm, authPermissions: AuthP } const { stdout, stderr } = await execFile(`${pewpewVersionBinary.filepath}`, ["--version"]); log(`${pewpewVersionBinary.filepath} output`, LogLevel.DEBUG, { stdout, stderr }); - const match = stdout.match(/pewpew (\d+\.\d+\.\d+[^\s]*)/); + const match = stdout.match(/pewpew (\d+\.\d+\.\d+[^\s]*)/); // Need to allow for -preview1, etc. log(`${pewpewVersionBinary.originalFilename} version match`, LogLevel.DEBUG, { match }); if (!match || match.length < 2) { return { json: { message: "Could not determine version" }, status: 400 }; diff --git a/controller/pages/api/util/testmanager.ts b/controller/pages/api/util/testmanager.ts index 4e5caba0..50fcca09 100644 --- a/controller/pages/api/util/testmanager.ts +++ b/controller/pages/api/util/testmanager.ts @@ -52,6 +52,7 @@ import { formatError, isYamlFile, latestPewPewVersion } from "./clientutil"; import { createS3Filename as createS3MessageFilename } from "@fs/ppaas-common/dist/src/ppaass3message"; import { createS3Filename as createS3StatusFilename } from "@fs/ppaas-common/dist/src/ppaasteststatus"; import fs from "fs/promises"; +import semver from "semver"; logger.config.LogFileName = "ppaas-controller"; @@ -65,6 +66,7 @@ const DEFAULT_MAX_SEARCH_RESULTS: number = parseInt(process.env.DEFAULT_MAX_SEAR const MAX_SEARCH_RESULTS: number = parseInt(process.env.MAX_SEARCH_RESULTS || "0", 10) || 10000; const ONE_MINUTE: number = 60000; const FIFTEEN_MINUTES: number = 15 * ONE_MINUTE; +const LEGACY_PEWPEW_VERSION = "<0.6.0-preview"; // Export for testing export enum CacheLocation { @@ -433,6 +435,16 @@ export async function downloadPriorTestId ( }; } +// Export for testing +export function getValidateLegacyOnly (version: string | undefined): boolean | undefined { + // undefined or "latest" parse as anything (reutrn undefined) + if (!version || version === latestPewPewVersion) { + return undefined; + } + // This needs to create the validateLegacyOnly, so anything less than 0.6.0 + return semver.satisfies(version, LEGACY_PEWPEW_VERSION, { includePrerelease: true }); +} + // Export for testing export interface ValidateYamlfileResult { testRunTimeMn: number | undefined; @@ -445,7 +457,8 @@ export async function validateYamlfile ( environmentVariables: EnvironmentVariables, additionalFileNames: string[], bypassParser: boolean | undefined, - authPermissions: AuthPermissions + authPermissions: AuthPermissions, + validateLegacyOnly?: boolean ): Promise { let testRunTimeMn: number | undefined; let bucketSizeMs: number | undefined; @@ -466,7 +479,8 @@ export async function validateYamlfile ( for (const splunkPath of logger.PEWPEW_SPLUNK_INJECTED_VARIABLES) { dummyEnvironmentVariables[splunkPath] = dummySplunkPath; } - yamlParser = await YamlParser.parseYamlFile(yamlFile.filepath, dummyEnvironmentVariables); + // Pass pewpew version legacy/scripting + yamlParser = await YamlParser.parseYamlFile(yamlFile.filepath, dummyEnvironmentVariables, validateLegacyOnly); } catch(error) { return { json: { message: `yamlFile: ${yamlFile.originalFilename || yamlFile.filepath} failed to parse`, error: formatError(error) }, status: 400 }; } @@ -1206,7 +1220,9 @@ export abstract class TestManager { // Trace level since it might have passwords log("environmentVariables", LogLevel.TRACE, environmentVariablesFile); - const validateResult: ErrorResponse | ValidateYamlfileResult = await validateYamlfile(yamlFile, PpaasEncryptEnvironmentFile.getEnvironmentVariables(environmentVariablesFile), additionalFileNames, bypassParser, authPermissions); + // Pass pewpew version legacy/scripting + const validateLegacyOnly = getValidateLegacyOnly(version); + const validateResult: ErrorResponse | ValidateYamlfileResult = await validateYamlfile(yamlFile, PpaasEncryptEnvironmentFile.getEnvironmentVariables(environmentVariablesFile), additionalFileNames, bypassParser, authPermissions, validateLegacyOnly); // eslint-disable-next-line no-prototype-builtins if (validateResult.hasOwnProperty("json")) { return validateResult as ErrorResponse; diff --git a/controller/pages/login.tsx b/controller/pages/login.tsx index ddd24546..9fa11801 100644 --- a/controller/pages/login.tsx +++ b/controller/pages/login.tsx @@ -39,9 +39,6 @@ const LoginButton = styled.button` height: 50px; text-align: center; `; -const Alight = styled.a` - color: lightblue; -`; // What this returns or calls from the parents export interface LoginProps { @@ -50,8 +47,8 @@ export interface LoginProps { errorLoading: string | undefined; } -const NOT_AUTHORIZED_MESSAGE_AUTHENTICATION: JSX.Element = <>

Please go to https://tools.fsdpt.org/portal/userManagement/requestAccess and request 'Performance Test - User' permission if you need to be able to run tests.

DO NOT request 'Non Prod' Permissions. Those are for internal authentication testing only.; -const ACCESS_DENIED_AUTHENTICATION_MESSAGE: JSX.Element = <>

Please go to https://tools.fsdpt.org/portal/userManagement/requestAccess and request either the 'Performance Test - User' (run tests) or 'Performance Test - Read Only' (view results) permission.

DO NOT request 'Non Prod' Permissions. Those are for internal authentication testing only.; +const NOT_AUTHORIZED_MESSAGE_AUTHENTICATION: JSX.Element = <>

Please request 'Pewpew - User' permission if you need to be able to run tests.

DO NOT request 'Non Prod' Permissions. Those are for internal authentication testing only.; +const ACCESS_DENIED_AUTHENTICATION_MESSAGE: JSX.Element = <>

Please request either the 'Pewpew Test - User' (run tests) or 'Pewpew - Read Only' (view results) permission.

DO NOT request 'Non Prod' Permissions. Those are for internal authentication testing only.; const Login = ({ token, redirectUrl, errorLoading }: LoginProps): JSX.Element => { log("redirectUrl: " + redirectUrl, LogLevel.DEBUG); diff --git a/controller/test/pewpew.spec.ts b/controller/test/pewpew.spec.ts index 38a1d8a2..fdeefac0 100644 --- a/controller/test/pewpew.spec.ts +++ b/controller/test/pewpew.spec.ts @@ -38,27 +38,28 @@ import semver from "semver"; logger.config.LogFileName = "ppaas-controller"; const UNIT_TEST_FOLDER = process.env.UNIT_TEST_FOLDER || "test"; -const PEWPEW_FILEPATH = path.join(UNIT_TEST_FOLDER, "pewpew.zip"); +const PEWPEW_LEGACY_FILEPATH = path.join(UNIT_TEST_FOLDER, "pewpew.zip"); +const PEWPEW_SCRIPTING_FILEPATH = path.join(UNIT_TEST_FOLDER, "scripting/pewpew.zip"); const authAdmin: AuthPermissions = { authPermission: AuthPermission.Admin, token: "admin1" }; -const pewpewZipFile: File = createFormidableFile( - path.basename(PEWPEW_FILEPATH), - PEWPEW_FILEPATH, +const legacyPewpewZipFile: File = createFormidableFile( + path.basename(PEWPEW_LEGACY_FILEPATH), + PEWPEW_LEGACY_FILEPATH, "unittest", 1, null ); const invalidFiles = { - additionalFiles: [pewpewZipFile] as any as File + additionalFiles: [legacyPewpewZipFile] as any as File }; const pewpewS3Folder = PEWPEW_BINARY_FOLDER; const pewpewFilename = PEWPEW_EXECUTABLE_NAME; -const versions = ["0.5.10", "0.5.11", "0.5.12-preview1", "0.5.12-preview2", "latest"]; +const versions = ["0.5.11", "0.5.12", "0.5.13-preview1", "0.5.13-preview2", "0.6.0-preview1", "0.6.0-preview2", "latest"]; const s3Object: S3Object = { LastModified: new Date(), Size: 1, @@ -78,26 +79,48 @@ class TestSchedulerIntegration extends TestScheduler { } describe("PewPew Util", () => { - let files: Files = {}; + let filesLegacyPewpew: Files = {}; + let filesScriptingPewpew: Files = {}; let mixedFiles: Files = {}; before(async () => { mockS3(); mockUploadObject(); mockGetObjectTagging(new Map([["tagName", "tagValue"]])); - const filename: string = pewpewZipFile.originalFilename!; + try { - const unzippedFiles: File[] = await unzipFile(pewpewZipFile); + const filename: string = legacyPewpewZipFile.originalFilename!; + const unzippedFiles: File[] = await unzipFile(legacyPewpewZipFile); log("unzipped " + filename, LogLevel.DEBUG, unzippedFiles); - files = { + filesLegacyPewpew = { additionalFiles: unzippedFiles as any as File }; - log("new files " + filename, LogLevel.DEBUG, files); + log("legacy files " + filename, LogLevel.DEBUG, filesLegacyPewpew); mixedFiles = { - additionalFiles: [...unzippedFiles, pewpewZipFile] as any as File + additionalFiles: [...unzippedFiles, legacyPewpewZipFile] as any as File + }; + } catch (error) { + log("Error unzipping " + legacyPewpewZipFile.originalFilename, LogLevel.ERROR, error); + throw error; + } + + const scriptingPewpewZipFile: File = createFormidableFile( + path.basename(PEWPEW_SCRIPTING_FILEPATH), + PEWPEW_SCRIPTING_FILEPATH, + "unittest", + 1, + null + ); + try { + const filename: string = scriptingPewpewZipFile.originalFilename!; + const unzippedFiles: File[] = await unzipFile(scriptingPewpewZipFile); + log("unzipped " + filename, LogLevel.DEBUG, unzippedFiles); + filesScriptingPewpew = { + additionalFiles: unzippedFiles as any as File }; + log("scripting files " + filename, LogLevel.DEBUG, filesScriptingPewpew); } catch (error) { - log("Error unzipping " + filename, LogLevel.ERROR, error); + log("Error unzipping " + scriptingPewpewZipFile.originalFilename, LogLevel.ERROR, error); throw error; } }); @@ -127,10 +150,11 @@ describe("PewPew Util", () => { }); describe("postPewPew", () => { - it("postPewPew should respond 200 OK", (done: Mocha.Done) => { + + it("postPewPew legacy should respond 200 OK", (done: Mocha.Done) => { const parsedForm: ParsedForm = { fields: {}, - files + files: filesLegacyPewpew }; log("postPewPew parsedForm", LogLevel.DEBUG, parsedForm); postPewPew(parsedForm, authAdmin).then((res: ErrorResponse) => { @@ -142,7 +166,7 @@ describe("PewPew Util", () => { expect(body.message).to.not.equal(undefined); expect(body.message).to.include("PewPew uploaded, version"); expect(body.message).to.not.include("as latest"); - const match: RegExpMatchArray | null = body.message.match(/PewPew uploaded, version: (\d+\.\d+\.\d+)/); + const match: RegExpMatchArray | null = body.message.match(/PewPew uploaded, version: (\d+\.\d+\.\d+(-[a-zA-Z0-9]+)?)/); log(`pewpew match: ${match}`, LogLevel.DEBUG, match); expect(match, "pewpew match").to.not.equal(null); expect(match!.length, "pewpew match.length").to.be.greaterThan(1); @@ -158,7 +182,7 @@ describe("PewPew Util", () => { fields: { latest: "true" }, - files + files: filesLegacyPewpew }; log("postPewPew parsedForm", LogLevel.DEBUG, parsedForm); postPewPew(parsedForm, authAdmin).then((res: ErrorResponse) => { @@ -177,6 +201,32 @@ describe("PewPew Util", () => { }); }); + it("postPewPew scripting should respond 200 OK", (done: Mocha.Done) => { + const parsedForm: ParsedForm = { + fields: {}, + files: filesScriptingPewpew + }; + log("postPewPew parsedForm", LogLevel.DEBUG, parsedForm); + postPewPew(parsedForm, authAdmin).then((res: ErrorResponse) => { + log("postPewPew res", LogLevel.DEBUG, res); + expect(res.status, JSON.stringify(res.json)).to.equal(200); + const body: TestManagerError = res.json; + log("body: " + JSON.stringify(body), LogLevel.DEBUG, body); + expect(body).to.not.equal(undefined); + expect(body.message).to.not.equal(undefined); + expect(body.message).to.include("PewPew uploaded, version"); + expect(body.message).to.not.include("as latest"); + const match: RegExpMatchArray | null = body.message.match(/PewPew uploaded, version: (\d+\.\d+\.\d+(-[a-zA-Z0-9]+)?)/); + log(`pewpew match: ${match}`, LogLevel.DEBUG, match); + expect(match, "pewpew match").to.not.equal(null); + expect(match!.length, "pewpew match.length").to.be.greaterThan(1); + done(); + }).catch((error) => { + log("postPewPew error", LogLevel.ERROR, error); + done(error); + }); + }); + it("postPewPew no files should respond 400 Bad Request", (done: Mocha.Done) => { const parsedForm: ParsedForm = { fields: {}, diff --git a/controller/test/pewpew_scripting.zip b/controller/test/scripting/pewpew.zip similarity index 100% rename from controller/test/pewpew_scripting.zip rename to controller/test/scripting/pewpew.zip diff --git a/controller/test/scriptingnopeakload.yaml b/controller/test/scriptingnopeakload.yaml index 1dc37894..38babdc0 100644 --- a/controller/test/scriptingnopeakload.yaml +++ b/controller/test/scriptingnopeakload.yaml @@ -28,7 +28,7 @@ endpoints: query: select: response.body where: response.status == 200 - send: if_not_full + send: block - method: GET url: http://127.0.0.1:8080/healthcheck headers: diff --git a/controller/test/testmanager.spec.ts b/controller/test/testmanager.spec.ts index b44cddba..dc8d3a5b 100644 --- a/controller/test/testmanager.spec.ts +++ b/controller/test/testmanager.spec.ts @@ -17,6 +17,7 @@ import { getRecentTests, getRequestedTests, getRunningTests, + getValidateLegacyOnly, removeOldest, validateYamlfile } from "../pages/api/util/testmanager"; @@ -33,9 +34,11 @@ import { logger } from "@fs/ppaas-common"; import type { File, FileJSON } from "formidable"; +import { Test as MochaTest } from "mocha"; import { PpaasEncryptS3File } from "../pages/api/util/ppaasencrypts3file"; import { TestSchedulerIntegration } from "./testscheduler.spec"; import { expect } from "chai"; +import { latestPewPewVersion } from "../pages/api/util/clientutil"; import path from "path"; logger.config.LogFileName = "ppaas-controller"; @@ -44,6 +47,9 @@ const localDirectory: string = path.resolve(process.env.UNIT_TEST_FOLDER || "tes const BASIC_YAML_FILE: string = "basic.yaml"; const BASIC_YAML_WITH_ENV = "basicwithenv.yaml"; const BASIC_YAML_WITH_FILES = "basicwithfiles.yaml"; +const SCRIPTING_YAML_FILE: string = "scripting.yaml"; +const SCRIPTING_YAML_WITH_ENV = "scriptingwithenv.yaml"; +const SCRIPTING_YAML_WITH_FILES = "scriptingwithfiles.yaml"; const BASIC_TXT_FILE: string = "text.txt"; const BASIC_TXT_FILE2: string = "text2.txt"; const environmentVariables: EnvironmentVariables = { @@ -310,24 +316,117 @@ describe("TestManager", () => { }).catch((error) => done(error)); }); + const validateLegacyOnlySuite: Mocha.Suite = describe("getValidateLegacyOnly", () => { + before (() => { + const validateLegacyOnlyArray: [string, boolean][] = [ + ["0.4.0", true], + ["0.5.0", true], + ["0.5.12", true], + ["0.5.13-preview1", true], + ["0.5.14-alpha", true], + ["0.5.999", true], + ["0.6.0-preview", false], + ["0.6.0-preview1", false], + ["0.6.0-scripting", false], + ["0.6.0-scripting2", false], + ["0.6.0", false], + ["0.6.1", false], + ["0.7.0", false], + ["1.0.0", false] + ]; + for (const [version, expected] of validateLegacyOnlyArray) { + validateLegacyOnlySuite.addTest(new MochaTest(version + " should return " + expected, (done: Mocha.Done) => { + try { + expect(getValidateLegacyOnly(version)).to.equal(expected); + done(); + } catch (error) { + done(error); + } + })); + } + }); + + it("should return undefined for undefined", (done: Mocha.Done) => { + try { + expect(getValidateLegacyOnly(undefined)).to.equal(undefined); + done(); + } catch (error) { + done(error); + } + }); + + it("should return undefined for empty string", (done: Mocha.Done) => { + try { + expect(getValidateLegacyOnly("")).to.equal(undefined); + done(); + } catch (error) { + done(error); + } + }); + + it("should return undefined for latest", (done: Mocha.Done) => { + try { + expect(getValidateLegacyOnly(latestPewPewVersion)).to.equal(undefined); + done(); + } catch (error) { + done(error); + } + }); + }); + describe("validateYamlfile", () => { let basicYamlFile: File; let basicYamlFileWithEnv: File; let basicYamlFileWithFiles: File; + let scriptingYamlFile: File; + let scriptingYamlFileWithEnv: File; + let scriptingYamlFileWithFiles: File; before(async () => { try { basicYamlFile = await convertPPaaSFileToFile(new PpaasS3File({ filename: BASIC_YAML_FILE, s3Folder, localDirectory })); basicYamlFileWithEnv = await convertPPaaSFileToFile(new PpaasS3File({ filename: BASIC_YAML_WITH_ENV, s3Folder, localDirectory })); basicYamlFileWithFiles = await convertPPaaSFileToFile(new PpaasS3File({ filename: BASIC_YAML_WITH_FILES, s3Folder, localDirectory })); + scriptingYamlFile = await convertPPaaSFileToFile(new PpaasS3File({ filename: SCRIPTING_YAML_FILE, s3Folder, localDirectory })); + scriptingYamlFileWithEnv = await convertPPaaSFileToFile(new PpaasS3File({ filename: SCRIPTING_YAML_WITH_ENV, s3Folder, localDirectory })); + scriptingYamlFileWithFiles = await convertPPaaSFileToFile(new PpaasS3File({ filename: SCRIPTING_YAML_WITH_FILES, s3Folder, localDirectory })); } catch (error) { log("Could not run the validateYamlfile before()", LogLevel.ERROR, error); throw error; } }); + it("should validate basic parsed as any", (done: Mocha.Done) => { + validateYamlfile(basicYamlFile, {}, [], false, authUser1, undefined) + .then((response: ErrorResponse | ValidateYamlfileResult) => { + log("should validate basic parsed as any", LogLevel.DEBUG, response); + expect(response, "response").to.not.equal(undefined); + expect(response.hasOwnProperty("json"), "has json").to.equal(false); + expect(response.hasOwnProperty("testRunTimeMn"), "has testRunTimeMn").to.equal(true); + const yamlResult: ValidateYamlfileResult = response as ValidateYamlfileResult; + expect(yamlResult.bucketSizeMs, "bucketSizeMs").to.equal(60000); + expect(yamlResult.testRunTimeMn, "testRunTimeMn").to.equal(2); + done(); + }).catch((error) => done(error)); + }); + + it("should validate scripting parsed as any", (done: Mocha.Done) => { + validateYamlfile(scriptingYamlFile, {}, [], false, authUser1, undefined) + .then((response: ErrorResponse | ValidateYamlfileResult) => { + log("should validate scripting parsed as any", LogLevel.DEBUG, response); + expect(response, "response").to.not.equal(undefined); + expect(response.hasOwnProperty("json"), "has json").to.equal(false); + expect(response.hasOwnProperty("testRunTimeMn"), "has testRunTimeMn").to.equal(true); + const yamlResult: ValidateYamlfileResult = response as ValidateYamlfileResult; + expect(yamlResult.bucketSizeMs, "bucketSizeMs").to.equal(60000); + expect(yamlResult.testRunTimeMn, "testRunTimeMn").to.equal(2); + done(); + }).catch((error) => done(error)); + }); + + describe("legacy", () => { it("should validate basic", (done: Mocha.Done) => { - validateYamlfile(basicYamlFile, {}, [], false, authUser1) + validateYamlfile(basicYamlFile, {}, [], false, authUser1, true) .then((response: ErrorResponse | ValidateYamlfileResult) => { log("should validate basic", LogLevel.DEBUG, response); expect(response, "response").to.not.equal(undefined); @@ -340,8 +439,26 @@ describe("TestManager", () => { }).catch((error) => done(error)); }); + it("should fail basic parsed as scripting", (done: Mocha.Done) => { + validateYamlfile(basicYamlFile, {}, [], false, authUser1, false) + .then((response: ErrorResponse | ValidateYamlfileResult) => { + log("should fail basic parsed as scripting", LogLevel.DEBUG, response); + expect(response, "response").to.not.equal(undefined); + expect(response.hasOwnProperty("json"), "has json").to.equal(true); + expect(response.hasOwnProperty("testRunTimeMn"), "has testRunTimeMn").to.equal(false); + const errorResponse: ErrorResponse = response as ErrorResponse; + expect(errorResponse.status, "status").to.equal(400); + expect(errorResponse.json, "json").to.not.equal(undefined); + expect(errorResponse.json.message, "json.message").to.not.equal(undefined); + expect(errorResponse.json.message, "json.message").to.include("failed to parse"); + expect(errorResponse.json.error).to.not.equal(undefined); + expect(errorResponse.json.error).to.include("YamlParse"); + done(); + }).catch((error) => done(error)); + }); + it("should fail basic without env", (done: Mocha.Done) => { - validateYamlfile(basicYamlFileWithEnv, {}, [], false, authUser1) + validateYamlfile(basicYamlFileWithEnv, {}, [], false, authUser1, true) .then((response: ErrorResponse | ValidateYamlfileResult) => { log("should fail basic without env", LogLevel.DEBUG, response); expect(response, "response").to.not.equal(undefined); @@ -359,7 +476,7 @@ describe("TestManager", () => { }); it("should validate basic with env", (done: Mocha.Done) => { - validateYamlfile(basicYamlFileWithEnv, environmentVariables, [], false, authUser1) + validateYamlfile(basicYamlFileWithEnv, environmentVariables, [], false, authUser1, true) .then((response: ErrorResponse | ValidateYamlfileResult) => { log("should validate basic with env", LogLevel.DEBUG, response); expect(response, "response").to.not.equal(undefined); @@ -373,7 +490,7 @@ describe("TestManager", () => { }); it("should fail basic without files", (done: Mocha.Done) => { - validateYamlfile(basicYamlFileWithFiles, {}, [BASIC_TXT_FILE], false, authUser1) + validateYamlfile(basicYamlFileWithFiles, {}, [BASIC_TXT_FILE], false, authUser1, true) .then((response: ErrorResponse | ValidateYamlfileResult) => { log("should fail basic without files", LogLevel.DEBUG, response); expect(response, "response").to.not.equal(undefined); @@ -389,7 +506,7 @@ describe("TestManager", () => { }); it("should validate basic with files", (done: Mocha.Done) => { - validateYamlfile(basicYamlFileWithFiles, {}, [BASIC_TXT_FILE, BASIC_TXT_FILE2], false, authUser1) + validateYamlfile(basicYamlFileWithFiles, {}, [BASIC_TXT_FILE, BASIC_TXT_FILE2], false, authUser1, true) .then((response: ErrorResponse | ValidateYamlfileResult) => { expect(response, "response").to.not.equal(undefined); expect(response.hasOwnProperty("json"), "has json").to.equal(false); @@ -404,7 +521,7 @@ describe("TestManager", () => { }); it("user should fail bypass", (done: Mocha.Done) => { - validateYamlfile(basicYamlFile, {}, [], true, authUser1) + validateYamlfile(basicYamlFile, {}, [], true, authUser1, true) .then((response: ErrorResponse | ValidateYamlfileResult) => { expect(response, "response").to.not.equal(undefined); expect(response.hasOwnProperty("json"), "has json").to.equal(true); @@ -419,7 +536,7 @@ describe("TestManager", () => { }); it("admin should pass bypass", (done: Mocha.Done) => { - validateYamlfile(basicYamlFile, {}, [], true, authAdmin1) + validateYamlfile(basicYamlFile, {}, [], true, authAdmin1, true) .then((response: ErrorResponse | ValidateYamlfileResult) => { expect(response, "response").to.not.equal(undefined); expect(response.hasOwnProperty("json"), "has json").to.equal(false); @@ -432,7 +549,7 @@ describe("TestManager", () => { }); it("bypassParser shouldn't need variables", (done: Mocha.Done) => { - validateYamlfile(basicYamlFileWithEnv, {}, [], true, authAdmin1) + validateYamlfile(basicYamlFileWithEnv, {}, [], true, authAdmin1, true) .then((response: ErrorResponse | ValidateYamlfileResult) => { expect(response, "response").to.not.equal(undefined); expect(response.hasOwnProperty("json"), "has json").to.equal(false); @@ -445,7 +562,7 @@ describe("TestManager", () => { }); it("bypassParser shouldn't need files", (done: Mocha.Done) => { - validateYamlfile(basicYamlFileWithFiles, {}, [], true, authAdmin1) + validateYamlfile(basicYamlFileWithFiles, {}, [], true, authAdmin1, true) .then((response: ErrorResponse | ValidateYamlfileResult) => { expect(response, "response").to.not.equal(undefined); expect(response.hasOwnProperty("json"), "has json").to.equal(false); @@ -456,6 +573,158 @@ describe("TestManager", () => { done(); }).catch((error) => done(error)); }); + }); + + describe("scripting", () => { + it("should validate scripting", (done: Mocha.Done) => { + validateYamlfile(scriptingYamlFile, {}, [], false, authUser1, false) + .then((response: ErrorResponse | ValidateYamlfileResult) => { + log("should validate scripting", LogLevel.DEBUG, response); + expect(response, "response").to.not.equal(undefined); + expect(response.hasOwnProperty("json"), "has json").to.equal(false); + expect(response.hasOwnProperty("testRunTimeMn"), "has testRunTimeMn").to.equal(true); + const yamlResult: ValidateYamlfileResult = response as ValidateYamlfileResult; + expect(yamlResult.bucketSizeMs, "bucketSizeMs").to.equal(60000); + expect(yamlResult.testRunTimeMn, "testRunTimeMn").to.equal(2); + done(); + }).catch((error) => done(error)); + }); + + it("should fail scripting parsed as legacy", (done: Mocha.Done) => { + validateYamlfile(scriptingYamlFile, {}, [], false, authUser1, true) + .then((response: ErrorResponse | ValidateYamlfileResult) => { + log("should fail scripting parsed as legacy", LogLevel.DEBUG, response); + expect(response, "response").to.not.equal(undefined); + expect(response.hasOwnProperty("json"), "has json").to.equal(true); + expect(response.hasOwnProperty("testRunTimeMn"), "has testRunTimeMn").to.equal(false); + const errorResponse: ErrorResponse = response as ErrorResponse; + expect(errorResponse.status, "status").to.equal(400); + expect(errorResponse.json, "json").to.not.equal(undefined); + expect(errorResponse.json.message, "json.message").to.not.equal(undefined); + expect(errorResponse.json.message, "json.message").to.include("failed to parse"); + expect(errorResponse.json.error).to.not.equal(undefined); + expect(errorResponse.json.error).to.include("UnrecognizedKey"); + done(); + }).catch((error) => done(error)); + }); + + it("should fail scripting without env", (done: Mocha.Done) => { + validateYamlfile(scriptingYamlFileWithEnv, {}, [], false, authUser1, false) + .then((response: ErrorResponse | ValidateYamlfileResult) => { + log("should fail scripting without env", LogLevel.DEBUG, response); + expect(response, "response").to.not.equal(undefined); + expect(response.hasOwnProperty("json"), "has json").to.equal(true); + expect(response.hasOwnProperty("testRunTimeMn"), "has testRunTimeMn").to.equal(false); + const errorResponse: ErrorResponse = response as ErrorResponse; + expect(errorResponse.status, "status").to.equal(400); + expect(errorResponse.json, "json").to.not.equal(undefined); + expect(errorResponse.json.message, "json.message").to.not.equal(undefined); + expect(errorResponse.json.message, "json.message").to.include("failed to parse"); + expect(errorResponse.json.error).to.not.equal(undefined); + expect(errorResponse.json.error).to.include("SERVICE_URL_AGENT"); + done(); + }).catch((error) => done(error)); + }); + + it("should validate scripting with env", (done: Mocha.Done) => { + validateYamlfile(scriptingYamlFileWithEnv, environmentVariables, [], false, authUser1, false) + .then((response: ErrorResponse | ValidateYamlfileResult) => { + log("should validate scripting with env", LogLevel.DEBUG, response); + expect(response, "response").to.not.equal(undefined); + expect(response.hasOwnProperty("json"), "has json").to.equal(false); + expect(response.hasOwnProperty("testRunTimeMn"), "has testRunTimeMn").to.equal(true); + const yamlResult: ValidateYamlfileResult = response as ValidateYamlfileResult; + expect(yamlResult.bucketSizeMs, "bucketSizeMs").to.equal(60000); + expect(yamlResult.testRunTimeMn, "testRunTimeMn").to.equal(2); + done(); + }).catch((error) => done(error)); + }); + + it("should fail scripting without files", (done: Mocha.Done) => { + validateYamlfile(scriptingYamlFileWithFiles, {}, [BASIC_TXT_FILE], false, authUser1, false) + .then((response: ErrorResponse | ValidateYamlfileResult) => { + log("should fail scripting without files", LogLevel.DEBUG, response); + expect(response, "response").to.not.equal(undefined); + expect(response.hasOwnProperty("json"), "has json").to.equal(true); + expect(response.hasOwnProperty("testRunTimeMn"), "has testRunTimeMn").to.equal(false); + const errorResponse: ErrorResponse = response as ErrorResponse; + expect(errorResponse.status, "status").to.equal(400); + expect(errorResponse.json, "json").to.not.equal(undefined); + expect(errorResponse.json.message, "json.message").to.not.equal(undefined); + expect(errorResponse.json.message, "json.message").to.include(BASIC_TXT_FILE2); + done(); + }).catch((error) => done(error)); + }); + + it("should validate scripting with files", (done: Mocha.Done) => { + validateYamlfile(scriptingYamlFileWithFiles, {}, [BASIC_TXT_FILE, BASIC_TXT_FILE2], false, authUser1, false) + .then((response: ErrorResponse | ValidateYamlfileResult) => { + expect(response, "response").to.not.equal(undefined); + expect(response.hasOwnProperty("json"), "has json").to.equal(false); + expect(response.hasOwnProperty("testRunTimeMn"), "has testRunTimeMn").to.equal(true); + const yamlResult: ValidateYamlfileResult = response as ValidateYamlfileResult; + expect(yamlResult.bucketSizeMs, "bucketSizeMs").to.not.equal(undefined); + expect(yamlResult.testRunTimeMn, "testRunTimeMn").to.not.equal(undefined); + expect(yamlResult.bucketSizeMs, "bucketSizeMs").to.equal(60000); + expect(yamlResult.testRunTimeMn, "testRunTimeMn").to.equal(2); + done(); + }).catch((error) => done(error)); + }); + + it("user should fail bypass", (done: Mocha.Done) => { + validateYamlfile(scriptingYamlFile, {}, [], true, authUser1, false) + .then((response: ErrorResponse | ValidateYamlfileResult) => { + expect(response, "response").to.not.equal(undefined); + expect(response.hasOwnProperty("json"), "has json").to.equal(true); + expect(response.hasOwnProperty("testRunTimeMn"), "has testRunTimeMn").to.equal(false); + const errorResponse: ErrorResponse = response as ErrorResponse; + expect(errorResponse.status, "status").to.equal(403); + expect(errorResponse.json, "json").to.not.equal(undefined); + expect(errorResponse.json.message, "json.message").to.not.equal(undefined); + expect(errorResponse.json.message, "json.message").to.include("bypass the config parser"); + done(); + }).catch((error) => done(error)); + }); + + it("admin should pass bypass", (done: Mocha.Done) => { + validateYamlfile(scriptingYamlFile, {}, [], true, authAdmin1, false) + .then((response: ErrorResponse | ValidateYamlfileResult) => { + expect(response, "response").to.not.equal(undefined); + expect(response.hasOwnProperty("json"), "has json").to.equal(false); + expect(response.hasOwnProperty("testRunTimeMn"), "has testRunTimeMn").to.equal(true); + const yamlResult: ValidateYamlfileResult = response as ValidateYamlfileResult; + expect(yamlResult.bucketSizeMs, "bucketSizeMs").to.equal(undefined); + expect(yamlResult.testRunTimeMn, "testRunTimeMn").to.equal(undefined); + done(); + }).catch((error) => done(error)); + }); + + it("bypassParser shouldn't need variables", (done: Mocha.Done) => { + validateYamlfile(scriptingYamlFileWithEnv, {}, [], true, authAdmin1, false) + .then((response: ErrorResponse | ValidateYamlfileResult) => { + expect(response, "response").to.not.equal(undefined); + expect(response.hasOwnProperty("json"), "has json").to.equal(false); + expect(response.hasOwnProperty("testRunTimeMn"), "has testRunTimeMn").to.equal(true); + const yamlResult: ValidateYamlfileResult = response as ValidateYamlfileResult; + expect(yamlResult.bucketSizeMs, "bucketSizeMs").to.equal(undefined); + expect(yamlResult.testRunTimeMn, "testRunTimeMn").to.equal(undefined); + done(); + }).catch((error) => done(error)); + }); + + it("bypassParser shouldn't need files", (done: Mocha.Done) => { + validateYamlfile(scriptingYamlFileWithFiles, {}, [], true, authAdmin1, false) + .then((response: ErrorResponse | ValidateYamlfileResult) => { + expect(response, "response").to.not.equal(undefined); + expect(response.hasOwnProperty("json"), "has json").to.equal(false); + expect(response.hasOwnProperty("testRunTimeMn"), "has testRunTimeMn").to.equal(true); + const yamlResult: ValidateYamlfileResult = response as ValidateYamlfileResult; + expect(yamlResult.bucketSizeMs, "bucketSizeMs").to.equal(undefined); + expect(yamlResult.testRunTimeMn, "testRunTimeMn").to.equal(undefined); + done(); + }).catch((error) => done(error)); + }); + }); }); describe("getAllTest", () => { diff --git a/guide/results-viewer-react/package-lock.json b/guide/results-viewer-react/package-lock.json index f51cba27..d17dad69 100644 --- a/guide/results-viewer-react/package-lock.json +++ b/guide/results-viewer-react/package-lock.json @@ -2544,9 +2544,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.0.tgz", - "integrity": "sha512-zJmuCWj2VLBt4c25CfBIbMZLGLyhkvs7LznyVX5HfpzeocThgIj5XQK4L+g3U36mMcx8bPMhGyPpwCATamC4jQ==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", + "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -2650,9 +2650,9 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.4.tgz", - "integrity": "sha512-qprfWkn82Iw821mcKofJ5Pk9wgioHicxcQMxx+5zt5GSKoqdWvgG5AxVmpmUUjzTLPVSH5auBrhI93Deayn/DA==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz", + "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==", "dev": true }, "node_modules/@fs/config-gen": { @@ -4405,9 +4405,9 @@ } }, "node_modules/@storybook/builder-webpack5/node_modules/@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true }, "node_modules/@storybook/builder-webpack5/node_modules/lru-cache": { @@ -4741,9 +4741,9 @@ } }, "node_modules/@storybook/core-common/node_modules/@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true }, "node_modules/@storybook/core-common/node_modules/ansi-styles": { @@ -4866,9 +4866,9 @@ } }, "node_modules/@storybook/core-server/node_modules/@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true }, "node_modules/@storybook/core-server/node_modules/ansi-styles": { @@ -4974,9 +4974,9 @@ } }, "node_modules/@storybook/core-webpack/node_modules/@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true }, "node_modules/@storybook/csf": { @@ -5215,9 +5215,9 @@ } }, "node_modules/@storybook/preset-react-webpack/node_modules/@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true }, "node_modules/@storybook/preset-react-webpack/node_modules/lru-cache": { @@ -5402,15 +5402,15 @@ } }, "node_modules/@storybook/react-webpack5/node_modules/@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true }, "node_modules/@storybook/react/node_modules/@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true }, "node_modules/@storybook/router": { @@ -5519,13 +5519,13 @@ } }, "node_modules/@storybook/testing-library": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@storybook/testing-library/-/testing-library-0.2.1.tgz", - "integrity": "sha512-AdbfLCm1C2nEFrhA3ScdicfW6Fjcorehr6RlGwECMiWwaXisnP971Wd4psqtWxlAqQo4tYBZ0f6rJ3J78JLtsg==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@storybook/testing-library/-/testing-library-0.2.2.tgz", + "integrity": "sha512-L8sXFJUHmrlyU2BsWWZGuAjv39Jl1uAqUHdxmN42JY15M4+XCMjGlArdCCjDe1wpTSW6USYISA9axjZojgtvnw==", "dev": true, "dependencies": { "@testing-library/dom": "^9.0.0", - "@testing-library/user-event": "~14.4.0", + "@testing-library/user-event": "^14.4.0", "ts-dedent": "^2.2.0" } }, @@ -5566,9 +5566,9 @@ } }, "node_modules/@swc/core": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.90.tgz", - "integrity": "sha512-wptBxP4PldOnhmyDVj8qUcn++GRqyw1qc9wOTGtPNHz8cpuTfdfIgYGlhI4La0UYqecuaaIfLfokyuNePOMHPg==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.91.tgz", + "integrity": "sha512-r950d0fdlZ8qbSDyvApn3HyCojiZE8xpgJzQvypeMi32dalYwugdJKWyLB55JIGMRGJ8+lmVvY4MPGkSR3kXgA==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -5583,16 +5583,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.3.90", - "@swc/core-darwin-x64": "1.3.90", - "@swc/core-linux-arm-gnueabihf": "1.3.90", - "@swc/core-linux-arm64-gnu": "1.3.90", - "@swc/core-linux-arm64-musl": "1.3.90", - "@swc/core-linux-x64-gnu": "1.3.90", - "@swc/core-linux-x64-musl": "1.3.90", - "@swc/core-win32-arm64-msvc": "1.3.90", - "@swc/core-win32-ia32-msvc": "1.3.90", - "@swc/core-win32-x64-msvc": "1.3.90" + "@swc/core-darwin-arm64": "1.3.91", + "@swc/core-darwin-x64": "1.3.91", + "@swc/core-linux-arm-gnueabihf": "1.3.91", + "@swc/core-linux-arm64-gnu": "1.3.91", + "@swc/core-linux-arm64-musl": "1.3.91", + "@swc/core-linux-x64-gnu": "1.3.91", + "@swc/core-linux-x64-musl": "1.3.91", + "@swc/core-win32-arm64-msvc": "1.3.91", + "@swc/core-win32-ia32-msvc": "1.3.91", + "@swc/core-win32-x64-msvc": "1.3.91" }, "peerDependencies": { "@swc/helpers": "^0.5.0" @@ -5604,9 +5604,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.90.tgz", - "integrity": "sha512-he0w74HvcoufE6CZrB/U/VGVbc7021IQvYrn1geMACnq/OqMBqjdczNtdNfJAy87LZ4AOUjHDKEIjsZZu7o8nQ==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.91.tgz", + "integrity": "sha512-7kHGiQ1he5khcEeJuHDmLZPM3rRL/ith5OTmV6bOPsoHi46kLeixORW+ts1opC3tC9vu6xbk16xgX0QAJchc1w==", "cpu": [ "arm64" ], @@ -5620,9 +5620,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.90.tgz", - "integrity": "sha512-hKNM0Ix0qMlAamPe0HUfaAhQVbZEL5uK6Iw8v9ew0FtVB4v7EifQ9n41wh+yCj0CjcHBPEBbQU0P6mNTxJu/RQ==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.91.tgz", + "integrity": "sha512-8SpU18FbFpZDVzsHsAwdI1thF/picQGxq9UFxa8W+T9SDnbsqwFJv/6RqKJeJoDV6qFdl2OLjuO0OL7xrp0qnQ==", "cpu": [ "x64" ], @@ -5636,9 +5636,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.90.tgz", - "integrity": "sha512-HumvtrqTWE8rlFuKt7If0ZL7145H/jVc4AeziVjcd+/ajpqub7IyfrLCYd5PmKMtfeSVDMsxjG0BJ0HLRxrTJA==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.91.tgz", + "integrity": "sha512-fOq4Cy8UbwX1yf0WB0d8hWZaIKCnPtPGguRqdXGLfwvhjZ9SIErT6PnmGTGRbQCNCIkOZWHKyTU0r8t2dN3haQ==", "cpu": [ "arm" ], @@ -5652,9 +5652,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.90.tgz", - "integrity": "sha512-tA7DqCS7YCwngwXZQeqQhhMm8BbydpaABw8Z/EDQ7KPK1iZ1rNjZw+aWvSpmNmEGmH1RmQ9QDS9mGRDp0faAeg==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.91.tgz", + "integrity": "sha512-fki4ioRP/Esy4vdp8T34RCV+V9dqkRmOt763pf74pdiyFV2dPLXa5lnw/XvR1RTfPGknrYgjEQLCfZlReTryRw==", "cpu": [ "arm64" ], @@ -5668,9 +5668,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.90.tgz", - "integrity": "sha512-p2Vtid5BZA36fJkNUwk5HP+HJlKgTru+Ghna7pRe45ghKkkRIUk3fhkgudEvfKfhT+3AvP+GTVQ+T9k0gc9S8w==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.91.tgz", + "integrity": "sha512-XrG+DUUqNtfVLcJ20imby7fpBwQNG5VsEQBzQndSonPyUOa2YkTbBb60YDondfQGDABopuHH8gHN8o2H2/VCnQ==", "cpu": [ "arm64" ], @@ -5684,9 +5684,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.90.tgz", - "integrity": "sha512-J6pDtWaulYGXuANERuvv4CqmUbZOQrRZBCRQGZQJ6a86RWpesZqckBelnYx48wYmkgvMkF95Y3xbI3WTfoSHzw==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.91.tgz", + "integrity": "sha512-d11bYhX+YPBr/Frcjc6eVn3C0LuS/9U1Li9EmQ+6s9EpYtYRl2ygSlC8eueLbaiazBnCVYFnc8bU4o0kc5B9sw==", "cpu": [ "x64" ], @@ -5700,9 +5700,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.90.tgz", - "integrity": "sha512-3Gh6EA3+0K+l3MqnRON7h5bZ32xLmfcVM6QiHHJ9dBttq7YOEeEoMOCdIPMaQxJmK1VfLgZCsPYRd66MhvUSkw==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.91.tgz", + "integrity": "sha512-2SRp5Dke2P4jCQePkDx9trkkTstnRpZJVw5r3jvYdk0zeO6iC4+ZPvvoWXJLigqQv/fZnIiSUfJ6ssOoaEqTzQ==", "cpu": [ "x64" ], @@ -5716,9 +5716,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.90.tgz", - "integrity": "sha512-BNaw/iJloDyaNOFV23Sr53ULlnbmzSoerTJ10v0TjSZOEIpsS0Rw6xOK1iI0voDJnRXeZeWRSxEC9DhefNtN/g==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.91.tgz", + "integrity": "sha512-l9qKXikOxj42UIjbeZpz9xtBmr736jOMqInNP8mVF2/U+ws5sI8zJjcOFFtfis4ru7vWCXhB1wtltdlJYO2vGA==", "cpu": [ "arm64" ], @@ -5732,9 +5732,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.90.tgz", - "integrity": "sha512-SiyTethWAheE/JbxXCukAAciU//PLcmVZ2ME92MRuLMLmOhrwksjbaa7ukj9WEF3LWrherhSqTXnpj3VC1l/qw==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.91.tgz", + "integrity": "sha512-+s+52O0QVPmzOgjEe/rcb0AK6q/J7EHKwAyJCu/FaYO9df5ovE0HJjSKP6HAF0dGPO5hkENrXuNGujofUH9vtQ==", "cpu": [ "ia32" ], @@ -5748,9 +5748,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.90.tgz", - "integrity": "sha512-OpWAW5ljKcPJ3SQ0pUuKqYfwXv7ssIhVgrH9XP9ONtdgXKWZRL9hqJQkcL55FARw/gDjKanoCM47wsTNQL+ZZA==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.91.tgz", + "integrity": "sha512-7u9HDQhjUC3Gv43EFW84dZtduWCSa4MgltK+Sp9zEGti6WXqDPu/ESjvDsQEVYTBEMEvZs/xVAXPgLVHorV5nQ==", "cpu": [ "x64" ], @@ -5847,9 +5847,9 @@ } }, "node_modules/@testing-library/user-event": { - "version": "14.4.3", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.4.3.tgz", - "integrity": "sha512-kCUc5MEwaEMakkO5x7aoD+DLi02ehmEM2QCGWvNqAS1dV/fAvORWEjnjsEIvml59M7Y5kCkWN6fCCyPOe8OL6Q==", + "version": "14.5.1", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.1.tgz", + "integrity": "sha512-UCcUKrUYGj7ClomOo2SpNVvx4/fkd/2BbIHDCle8A0ax+P3bU7yJwDBDrS6ZwdTMARWTGODX1hEsCcO+7beJjg==", "dev": true, "engines": { "node": ">=12", @@ -6161,9 +6161,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.7.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.2.tgz", - "integrity": "sha512-RcdC3hOBOauLP+r/kRt27NrByYtDjsXyAuSbR87O6xpsvi763WI+5fbSIvYJrXnt9w4RuxhV6eAXfIs7aaf/FQ==", + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.2.tgz", + "integrity": "sha512-Vvycsc9FQdwhxE3y3DzeIxuEJbWGDsnrxvMADzTDF/lcdR9/K+AQIeAghTQsHtotg/q0j3WEOYS/jQgSdWue3w==", "dev": true }, "node_modules/@types/node-fetch": { @@ -6195,9 +6195,9 @@ "dev": true }, "node_modules/@types/prop-types": { - "version": "15.7.7", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.7.tgz", - "integrity": "sha512-FbtmBWCcSa2J4zL781Zf1p5YUBXQomPEcep9QZCfRfQgTxz3pJWiDFLebohZ9fFntX5ibzOkSsrJ0TEew8cAog==", + "version": "15.7.8", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.8.tgz", + "integrity": "sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ==", "dev": true }, "node_modules/@types/qs": { @@ -6213,9 +6213,9 @@ "dev": true }, "node_modules/@types/react": { - "version": "18.2.23", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.23.tgz", - "integrity": "sha512-qHLW6n1q2+7KyBEYnrZpcsAmU/iiCh9WGCKgXvMxx89+TYdJWRjZohVIo9XTcoLhfX3+/hP0Pbulu3bCZQ9PSA==", + "version": "18.2.24", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.24.tgz", + "integrity": "sha512-Ee0Jt4sbJxMu1iDcetZEIKQr99J1Zfb6D4F3qfUWoR1JpInkY1Wdg4WwCyBjL257D0+jGqSl1twBjV8iCaC0Aw==", "dev": true, "dependencies": { "@types/prop-types": "*", @@ -6345,16 +6345,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.3.tgz", - "integrity": "sha512-vntq452UHNltxsaaN+L9WyuMch8bMd9CqJ3zhzTPXXidwbf5mqqKCVXEuvRZUqLJSTLeWE65lQwyXsRGnXkCTA==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.4.tgz", + "integrity": "sha512-DAbgDXwtX+pDkAHwiGhqP3zWUGpW49B7eqmgpPtg+BKJXwdct79ut9+ifqOFPJGClGKSHXn2PTBatCnldJRUoA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/type-utils": "6.7.3", - "@typescript-eslint/utils": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", + "@typescript-eslint/scope-manager": "6.7.4", + "@typescript-eslint/type-utils": "6.7.4", + "@typescript-eslint/utils": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -6413,15 +6413,15 @@ "dev": true }, "node_modules/@typescript-eslint/parser": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.3.tgz", - "integrity": "sha512-TlutE+iep2o7R8Lf+yoer3zU6/0EAUc8QIBB3GYBc1KGz4c4TRm83xwXUZVPlZ6YCLss4r77jbu6j3sendJoiQ==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.4.tgz", + "integrity": "sha512-I5zVZFY+cw4IMZUeNCU7Sh2PO5O57F7Lr0uyhgCJmhN/BuTlnc55KxPonR4+EM3GBdfiCyGZye6DgMjtubQkmA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/typescript-estree": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", + "@typescript-eslint/scope-manager": "6.7.4", + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/typescript-estree": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4", "debug": "^4.3.4" }, "engines": { @@ -6441,13 +6441,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.3.tgz", - "integrity": "sha512-wOlo0QnEou9cHO2TdkJmzF7DFGvAKEnB82PuPNHpT8ZKKaZu6Bm63ugOTn9fXNJtvuDPanBc78lGUGGytJoVzQ==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.4.tgz", + "integrity": "sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3" + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -6458,13 +6458,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.3.tgz", - "integrity": "sha512-Fc68K0aTDrKIBvLnKTZ5Pf3MXK495YErrbHb1R6aTpfK5OdSFj0rVN7ib6Tx6ePrZ2gsjLqr0s98NG7l96KSQw==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.4.tgz", + "integrity": "sha512-n+g3zi1QzpcAdHFP9KQF+rEFxMb2KxtnJGID3teA/nxKHOVi3ylKovaqEzGBbVY2pBttU6z85gp0D00ufLzViQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.7.3", - "@typescript-eslint/utils": "6.7.3", + "@typescript-eslint/typescript-estree": "6.7.4", + "@typescript-eslint/utils": "6.7.4", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -6485,9 +6485,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.3.tgz", - "integrity": "sha512-4g+de6roB2NFcfkZb439tigpAMnvEIg3rIjWQ+EM7IBaYt/CdJt6em9BJ4h4UpdgaBWdmx2iWsafHTrqmgIPNw==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", + "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -6498,13 +6498,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.3.tgz", - "integrity": "sha512-YLQ3tJoS4VxLFYHTw21oe1/vIZPRqAO91z6Uv0Ss2BKm/Ag7/RVQBcXTGcXhgJMdA4U+HrKuY5gWlJlvoaKZ5g==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.4.tgz", + "integrity": "sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -6558,17 +6558,17 @@ "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.3.tgz", - "integrity": "sha512-vzLkVder21GpWRrmSR9JxGZ5+ibIUSudXlW52qeKpzUEQhRSmyZiVDDj3crAth7+5tmN1ulvgKaCU2f/bPRCzg==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.4.tgz", + "integrity": "sha512-PRQAs+HUn85Qdk+khAxsVV+oULy3VkbH3hQ8hxLRJXWBEd7iI+GbQxH5SEUSH7kbEoTp6oT1bOwyga24ELALTA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/typescript-estree": "6.7.3", + "@typescript-eslint/scope-manager": "6.7.4", + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/typescript-estree": "6.7.4", "semver": "^7.5.4" }, "engines": { @@ -6616,12 +6616,12 @@ "dev": true }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.3.tgz", - "integrity": "sha512-HEVXkU9IB+nk9o63CeICMHxFWbHWr3E1mpilIQBe9+7L/lH97rleFLVtYsfnWB+JVMaiFnEaxvknvmIzX+CqVg==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", + "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/types": "6.7.4", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -7866,9 +7866,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001541", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001541.tgz", - "integrity": "sha512-bLOsqxDgTqUBkzxbNlSBt8annkDpQB9NdzdTbO2ooJ+eC/IQcvDspDc058g84ejCelF7vHUx57KIOjEecOHXaw==", + "version": "1.0.30001543", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001543.tgz", + "integrity": "sha512-qxdO8KPWPQ+Zk6bvNpPeQIOH47qZSYdFZd6dXQzb2KzhnSXju4Kd7H1PkSJx6NICSMgo/IhRZRhhfPTHYpJUCA==", "funding": [ { "type": "opencollective", @@ -8415,11 +8415,11 @@ "dev": true }, "node_modules/core-js-compat": { - "version": "3.32.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.32.2.tgz", - "integrity": "sha512-+GjlguTDINOijtVRUxrQOv3kfu9rl+qPNdX2LTbJ/ZyVTuxK+ksVSAGX1nHstu4hrv1En/uPTtWgq2gI5wt4AQ==", + "version": "3.33.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.0.tgz", + "integrity": "sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw==", "dependencies": { - "browserslist": "^4.21.10" + "browserslist": "^4.22.1" }, "funding": { "type": "opencollective", @@ -8427,9 +8427,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.32.2", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.32.2.tgz", - "integrity": "sha512-Y2rxThOuNywTjnX/PgA5vWM6CZ9QB9sz9oGeCixV8MqXZO70z/5SHzf9EeBrEBK0PN36DnEBBu9O/aGWzKuMZQ==", + "version": "3.33.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.33.0.tgz", + "integrity": "sha512-FKSIDtJnds/YFIEaZ4HszRX7hkxGpNKM7FC9aJ9WLJbSd3lD4vOltFuVIBLR8asSx9frkTSqL0dw90SKQxgKrg==", "dev": true, "hasInstallScript": true, "funding": { @@ -9105,9 +9105,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.537", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.537.tgz", - "integrity": "sha512-W1+g9qs9hviII0HAwOdehGYkr+zt7KKdmCcJcjH0mYg6oL8+ioT3Skjmt7BLoAQqXhjf40AXd+HlR4oAWMlXjA==" + "version": "1.4.540", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.540.tgz", + "integrity": "sha512-aoCqgU6r9+o9/S7wkcSbmPRFi7OWZWiXS9rtjEd+Ouyu/Xyw5RSq2XN8s5Qp8IaFOLiRrhQCphCIjAxgG3eCAg==" }, "node_modules/emoji-regex": { "version": "9.2.2", @@ -10402,7 +10402,8 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "node_modules/functions-have-names": { "version": "1.2.3", @@ -10690,12 +10691,9 @@ } }, "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", "engines": { "node": ">= 0.4.0" } @@ -15773,9 +15771,9 @@ } }, "node_modules/terser": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.20.0.tgz", - "integrity": "sha512-e56ETryaQDyebBwJIWYB2TT6f2EZ0fL0sW/JRXNMN26zZdKi2u/E/5my5lG6jNxym6qsrVXfFRmOdV42zlAgLQ==", + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.21.0.tgz", + "integrity": "sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -18963,9 +18961,9 @@ } }, "@eslint-community/regexpp": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.0.tgz", - "integrity": "sha512-zJmuCWj2VLBt4c25CfBIbMZLGLyhkvs7LznyVX5HfpzeocThgIj5XQK4L+g3U36mMcx8bPMhGyPpwCATamC4jQ==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", + "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", "dev": true }, "@eslint/eslintrc": { @@ -19043,9 +19041,9 @@ } }, "@floating-ui/utils": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.4.tgz", - "integrity": "sha512-qprfWkn82Iw821mcKofJ5Pk9wgioHicxcQMxx+5zt5GSKoqdWvgG5AxVmpmUUjzTLPVSH5auBrhI93Deayn/DA==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz", + "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==", "dev": true }, "@fs/config-gen": { @@ -20139,9 +20137,9 @@ }, "dependencies": { "@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true }, "lru-cache": { @@ -20400,9 +20398,9 @@ }, "dependencies": { "@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true }, "ansi-styles": { @@ -20501,9 +20499,9 @@ }, "dependencies": { "@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true }, "ansi-styles": { @@ -20580,9 +20578,9 @@ }, "dependencies": { "@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true } } @@ -20760,9 +20758,9 @@ }, "dependencies": { "@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true }, "lru-cache": { @@ -20849,9 +20847,9 @@ }, "dependencies": { "@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true } } @@ -20891,9 +20889,9 @@ }, "dependencies": { "@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true } } @@ -20972,13 +20970,13 @@ } }, "@storybook/testing-library": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@storybook/testing-library/-/testing-library-0.2.1.tgz", - "integrity": "sha512-AdbfLCm1C2nEFrhA3ScdicfW6Fjcorehr6RlGwECMiWwaXisnP971Wd4psqtWxlAqQo4tYBZ0f6rJ3J78JLtsg==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@storybook/testing-library/-/testing-library-0.2.2.tgz", + "integrity": "sha512-L8sXFJUHmrlyU2BsWWZGuAjv39Jl1uAqUHdxmN42JY15M4+XCMjGlArdCCjDe1wpTSW6USYISA9axjZojgtvnw==", "dev": true, "requires": { "@testing-library/dom": "^9.0.0", - "@testing-library/user-event": "~14.4.0", + "@testing-library/user-event": "^14.4.0", "ts-dedent": "^2.2.0" } }, @@ -21007,92 +21005,92 @@ } }, "@swc/core": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.90.tgz", - "integrity": "sha512-wptBxP4PldOnhmyDVj8qUcn++GRqyw1qc9wOTGtPNHz8cpuTfdfIgYGlhI4La0UYqecuaaIfLfokyuNePOMHPg==", - "dev": true, - "requires": { - "@swc/core-darwin-arm64": "1.3.90", - "@swc/core-darwin-x64": "1.3.90", - "@swc/core-linux-arm-gnueabihf": "1.3.90", - "@swc/core-linux-arm64-gnu": "1.3.90", - "@swc/core-linux-arm64-musl": "1.3.90", - "@swc/core-linux-x64-gnu": "1.3.90", - "@swc/core-linux-x64-musl": "1.3.90", - "@swc/core-win32-arm64-msvc": "1.3.90", - "@swc/core-win32-ia32-msvc": "1.3.90", - "@swc/core-win32-x64-msvc": "1.3.90", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.91.tgz", + "integrity": "sha512-r950d0fdlZ8qbSDyvApn3HyCojiZE8xpgJzQvypeMi32dalYwugdJKWyLB55JIGMRGJ8+lmVvY4MPGkSR3kXgA==", + "dev": true, + "requires": { + "@swc/core-darwin-arm64": "1.3.91", + "@swc/core-darwin-x64": "1.3.91", + "@swc/core-linux-arm-gnueabihf": "1.3.91", + "@swc/core-linux-arm64-gnu": "1.3.91", + "@swc/core-linux-arm64-musl": "1.3.91", + "@swc/core-linux-x64-gnu": "1.3.91", + "@swc/core-linux-x64-musl": "1.3.91", + "@swc/core-win32-arm64-msvc": "1.3.91", + "@swc/core-win32-ia32-msvc": "1.3.91", + "@swc/core-win32-x64-msvc": "1.3.91", "@swc/counter": "^0.1.1", "@swc/types": "^0.1.5" } }, "@swc/core-darwin-arm64": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.90.tgz", - "integrity": "sha512-he0w74HvcoufE6CZrB/U/VGVbc7021IQvYrn1geMACnq/OqMBqjdczNtdNfJAy87LZ4AOUjHDKEIjsZZu7o8nQ==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.91.tgz", + "integrity": "sha512-7kHGiQ1he5khcEeJuHDmLZPM3rRL/ith5OTmV6bOPsoHi46kLeixORW+ts1opC3tC9vu6xbk16xgX0QAJchc1w==", "dev": true, "optional": true }, "@swc/core-darwin-x64": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.90.tgz", - "integrity": "sha512-hKNM0Ix0qMlAamPe0HUfaAhQVbZEL5uK6Iw8v9ew0FtVB4v7EifQ9n41wh+yCj0CjcHBPEBbQU0P6mNTxJu/RQ==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.91.tgz", + "integrity": "sha512-8SpU18FbFpZDVzsHsAwdI1thF/picQGxq9UFxa8W+T9SDnbsqwFJv/6RqKJeJoDV6qFdl2OLjuO0OL7xrp0qnQ==", "dev": true, "optional": true }, "@swc/core-linux-arm-gnueabihf": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.90.tgz", - "integrity": "sha512-HumvtrqTWE8rlFuKt7If0ZL7145H/jVc4AeziVjcd+/ajpqub7IyfrLCYd5PmKMtfeSVDMsxjG0BJ0HLRxrTJA==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.91.tgz", + "integrity": "sha512-fOq4Cy8UbwX1yf0WB0d8hWZaIKCnPtPGguRqdXGLfwvhjZ9SIErT6PnmGTGRbQCNCIkOZWHKyTU0r8t2dN3haQ==", "dev": true, "optional": true }, "@swc/core-linux-arm64-gnu": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.90.tgz", - "integrity": "sha512-tA7DqCS7YCwngwXZQeqQhhMm8BbydpaABw8Z/EDQ7KPK1iZ1rNjZw+aWvSpmNmEGmH1RmQ9QDS9mGRDp0faAeg==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.91.tgz", + "integrity": "sha512-fki4ioRP/Esy4vdp8T34RCV+V9dqkRmOt763pf74pdiyFV2dPLXa5lnw/XvR1RTfPGknrYgjEQLCfZlReTryRw==", "dev": true, "optional": true }, "@swc/core-linux-arm64-musl": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.90.tgz", - "integrity": "sha512-p2Vtid5BZA36fJkNUwk5HP+HJlKgTru+Ghna7pRe45ghKkkRIUk3fhkgudEvfKfhT+3AvP+GTVQ+T9k0gc9S8w==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.91.tgz", + "integrity": "sha512-XrG+DUUqNtfVLcJ20imby7fpBwQNG5VsEQBzQndSonPyUOa2YkTbBb60YDondfQGDABopuHH8gHN8o2H2/VCnQ==", "dev": true, "optional": true }, "@swc/core-linux-x64-gnu": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.90.tgz", - "integrity": "sha512-J6pDtWaulYGXuANERuvv4CqmUbZOQrRZBCRQGZQJ6a86RWpesZqckBelnYx48wYmkgvMkF95Y3xbI3WTfoSHzw==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.91.tgz", + "integrity": "sha512-d11bYhX+YPBr/Frcjc6eVn3C0LuS/9U1Li9EmQ+6s9EpYtYRl2ygSlC8eueLbaiazBnCVYFnc8bU4o0kc5B9sw==", "dev": true, "optional": true }, "@swc/core-linux-x64-musl": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.90.tgz", - "integrity": "sha512-3Gh6EA3+0K+l3MqnRON7h5bZ32xLmfcVM6QiHHJ9dBttq7YOEeEoMOCdIPMaQxJmK1VfLgZCsPYRd66MhvUSkw==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.91.tgz", + "integrity": "sha512-2SRp5Dke2P4jCQePkDx9trkkTstnRpZJVw5r3jvYdk0zeO6iC4+ZPvvoWXJLigqQv/fZnIiSUfJ6ssOoaEqTzQ==", "dev": true, "optional": true }, "@swc/core-win32-arm64-msvc": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.90.tgz", - "integrity": "sha512-BNaw/iJloDyaNOFV23Sr53ULlnbmzSoerTJ10v0TjSZOEIpsS0Rw6xOK1iI0voDJnRXeZeWRSxEC9DhefNtN/g==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.91.tgz", + "integrity": "sha512-l9qKXikOxj42UIjbeZpz9xtBmr736jOMqInNP8mVF2/U+ws5sI8zJjcOFFtfis4ru7vWCXhB1wtltdlJYO2vGA==", "dev": true, "optional": true }, "@swc/core-win32-ia32-msvc": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.90.tgz", - "integrity": "sha512-SiyTethWAheE/JbxXCukAAciU//PLcmVZ2ME92MRuLMLmOhrwksjbaa7ukj9WEF3LWrherhSqTXnpj3VC1l/qw==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.91.tgz", + "integrity": "sha512-+s+52O0QVPmzOgjEe/rcb0AK6q/J7EHKwAyJCu/FaYO9df5ovE0HJjSKP6HAF0dGPO5hkENrXuNGujofUH9vtQ==", "dev": true, "optional": true }, "@swc/core-win32-x64-msvc": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.90.tgz", - "integrity": "sha512-OpWAW5ljKcPJ3SQ0pUuKqYfwXv7ssIhVgrH9XP9ONtdgXKWZRL9hqJQkcL55FARw/gDjKanoCM47wsTNQL+ZZA==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.91.tgz", + "integrity": "sha512-7u9HDQhjUC3Gv43EFW84dZtduWCSa4MgltK+Sp9zEGti6WXqDPu/ESjvDsQEVYTBEMEvZs/xVAXPgLVHorV5nQ==", "dev": true, "optional": true }, @@ -21161,9 +21159,9 @@ } }, "@testing-library/user-event": { - "version": "14.4.3", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.4.3.tgz", - "integrity": "sha512-kCUc5MEwaEMakkO5x7aoD+DLi02ehmEM2QCGWvNqAS1dV/fAvORWEjnjsEIvml59M7Y5kCkWN6fCCyPOe8OL6Q==", + "version": "14.5.1", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.1.tgz", + "integrity": "sha512-UCcUKrUYGj7ClomOo2SpNVvx4/fkd/2BbIHDCle8A0ax+P3bU7yJwDBDrS6ZwdTMARWTGODX1hEsCcO+7beJjg==", "dev": true, "requires": {} }, @@ -21469,9 +21467,9 @@ "dev": true }, "@types/node": { - "version": "20.7.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.2.tgz", - "integrity": "sha512-RcdC3hOBOauLP+r/kRt27NrByYtDjsXyAuSbR87O6xpsvi763WI+5fbSIvYJrXnt9w4RuxhV6eAXfIs7aaf/FQ==", + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.2.tgz", + "integrity": "sha512-Vvycsc9FQdwhxE3y3DzeIxuEJbWGDsnrxvMADzTDF/lcdR9/K+AQIeAghTQsHtotg/q0j3WEOYS/jQgSdWue3w==", "dev": true }, "@types/node-fetch": { @@ -21503,9 +21501,9 @@ "dev": true }, "@types/prop-types": { - "version": "15.7.7", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.7.tgz", - "integrity": "sha512-FbtmBWCcSa2J4zL781Zf1p5YUBXQomPEcep9QZCfRfQgTxz3pJWiDFLebohZ9fFntX5ibzOkSsrJ0TEew8cAog==", + "version": "15.7.8", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.8.tgz", + "integrity": "sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ==", "dev": true }, "@types/qs": { @@ -21521,9 +21519,9 @@ "dev": true }, "@types/react": { - "version": "18.2.23", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.23.tgz", - "integrity": "sha512-qHLW6n1q2+7KyBEYnrZpcsAmU/iiCh9WGCKgXvMxx89+TYdJWRjZohVIo9XTcoLhfX3+/hP0Pbulu3bCZQ9PSA==", + "version": "18.2.24", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.24.tgz", + "integrity": "sha512-Ee0Jt4sbJxMu1iDcetZEIKQr99J1Zfb6D4F3qfUWoR1JpInkY1Wdg4WwCyBjL257D0+jGqSl1twBjV8iCaC0Aw==", "dev": true, "requires": { "@types/prop-types": "*", @@ -21653,16 +21651,16 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.3.tgz", - "integrity": "sha512-vntq452UHNltxsaaN+L9WyuMch8bMd9CqJ3zhzTPXXidwbf5mqqKCVXEuvRZUqLJSTLeWE65lQwyXsRGnXkCTA==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.4.tgz", + "integrity": "sha512-DAbgDXwtX+pDkAHwiGhqP3zWUGpW49B7eqmgpPtg+BKJXwdct79ut9+ifqOFPJGClGKSHXn2PTBatCnldJRUoA==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/type-utils": "6.7.3", - "@typescript-eslint/utils": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", + "@typescript-eslint/scope-manager": "6.7.4", + "@typescript-eslint/type-utils": "6.7.4", + "@typescript-eslint/utils": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -21698,54 +21696,54 @@ } }, "@typescript-eslint/parser": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.3.tgz", - "integrity": "sha512-TlutE+iep2o7R8Lf+yoer3zU6/0EAUc8QIBB3GYBc1KGz4c4TRm83xwXUZVPlZ6YCLss4r77jbu6j3sendJoiQ==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.4.tgz", + "integrity": "sha512-I5zVZFY+cw4IMZUeNCU7Sh2PO5O57F7Lr0uyhgCJmhN/BuTlnc55KxPonR4+EM3GBdfiCyGZye6DgMjtubQkmA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/typescript-estree": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", + "@typescript-eslint/scope-manager": "6.7.4", + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/typescript-estree": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.3.tgz", - "integrity": "sha512-wOlo0QnEou9cHO2TdkJmzF7DFGvAKEnB82PuPNHpT8ZKKaZu6Bm63ugOTn9fXNJtvuDPanBc78lGUGGytJoVzQ==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.4.tgz", + "integrity": "sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==", "dev": true, "requires": { - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3" + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4" } }, "@typescript-eslint/type-utils": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.3.tgz", - "integrity": "sha512-Fc68K0aTDrKIBvLnKTZ5Pf3MXK495YErrbHb1R6aTpfK5OdSFj0rVN7ib6Tx6ePrZ2gsjLqr0s98NG7l96KSQw==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.4.tgz", + "integrity": "sha512-n+g3zi1QzpcAdHFP9KQF+rEFxMb2KxtnJGID3teA/nxKHOVi3ylKovaqEzGBbVY2pBttU6z85gp0D00ufLzViQ==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.7.3", - "@typescript-eslint/utils": "6.7.3", + "@typescript-eslint/typescript-estree": "6.7.4", + "@typescript-eslint/utils": "6.7.4", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/types": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.3.tgz", - "integrity": "sha512-4g+de6roB2NFcfkZb439tigpAMnvEIg3rIjWQ+EM7IBaYt/CdJt6em9BJ4h4UpdgaBWdmx2iWsafHTrqmgIPNw==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", + "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.3.tgz", - "integrity": "sha512-YLQ3tJoS4VxLFYHTw21oe1/vIZPRqAO91z6Uv0Ss2BKm/Ag7/RVQBcXTGcXhgJMdA4U+HrKuY5gWlJlvoaKZ5g==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.4.tgz", + "integrity": "sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==", "dev": true, "requires": { - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -21780,17 +21778,17 @@ } }, "@typescript-eslint/utils": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.3.tgz", - "integrity": "sha512-vzLkVder21GpWRrmSR9JxGZ5+ibIUSudXlW52qeKpzUEQhRSmyZiVDDj3crAth7+5tmN1ulvgKaCU2f/bPRCzg==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.4.tgz", + "integrity": "sha512-PRQAs+HUn85Qdk+khAxsVV+oULy3VkbH3hQ8hxLRJXWBEd7iI+GbQxH5SEUSH7kbEoTp6oT1bOwyga24ELALTA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/typescript-estree": "6.7.3", + "@typescript-eslint/scope-manager": "6.7.4", + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/typescript-estree": "6.7.4", "semver": "^7.5.4" }, "dependencies": { @@ -21821,12 +21819,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.3.tgz", - "integrity": "sha512-HEVXkU9IB+nk9o63CeICMHxFWbHWr3E1mpilIQBe9+7L/lH97rleFLVtYsfnWB+JVMaiFnEaxvknvmIzX+CqVg==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", + "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", "dev": true, "requires": { - "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/types": "6.7.4", "eslint-visitor-keys": "^3.4.1" } }, @@ -22785,9 +22783,9 @@ "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==" }, "caniuse-lite": { - "version": "1.0.30001541", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001541.tgz", - "integrity": "sha512-bLOsqxDgTqUBkzxbNlSBt8annkDpQB9NdzdTbO2ooJ+eC/IQcvDspDc058g84ejCelF7vHUx57KIOjEecOHXaw==" + "version": "1.0.30001543", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001543.tgz", + "integrity": "sha512-qxdO8KPWPQ+Zk6bvNpPeQIOH47qZSYdFZd6dXQzb2KzhnSXju4Kd7H1PkSJx6NICSMgo/IhRZRhhfPTHYpJUCA==" }, "case-sensitive-paths-webpack-plugin": { "version": "2.4.0", @@ -23210,17 +23208,17 @@ "dev": true }, "core-js-compat": { - "version": "3.32.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.32.2.tgz", - "integrity": "sha512-+GjlguTDINOijtVRUxrQOv3kfu9rl+qPNdX2LTbJ/ZyVTuxK+ksVSAGX1nHstu4hrv1En/uPTtWgq2gI5wt4AQ==", + "version": "3.33.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.0.tgz", + "integrity": "sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw==", "requires": { - "browserslist": "^4.21.10" + "browserslist": "^4.22.1" } }, "core-js-pure": { - "version": "3.32.2", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.32.2.tgz", - "integrity": "sha512-Y2rxThOuNywTjnX/PgA5vWM6CZ9QB9sz9oGeCixV8MqXZO70z/5SHzf9EeBrEBK0PN36DnEBBu9O/aGWzKuMZQ==", + "version": "3.33.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.33.0.tgz", + "integrity": "sha512-FKSIDtJnds/YFIEaZ4HszRX7hkxGpNKM7FC9aJ9WLJbSd3lD4vOltFuVIBLR8asSx9frkTSqL0dw90SKQxgKrg==", "dev": true }, "core-util-is": { @@ -23733,9 +23731,9 @@ } }, "electron-to-chromium": { - "version": "1.4.537", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.537.tgz", - "integrity": "sha512-W1+g9qs9hviII0HAwOdehGYkr+zt7KKdmCcJcjH0mYg6oL8+ioT3Skjmt7BLoAQqXhjf40AXd+HlR4oAWMlXjA==" + "version": "1.4.540", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.540.tgz", + "integrity": "sha512-aoCqgU6r9+o9/S7wkcSbmPRFi7OWZWiXS9rtjEd+Ouyu/Xyw5RSq2XN8s5Qp8IaFOLiRrhQCphCIjAxgG3eCAg==" }, "emoji-regex": { "version": "9.2.2", @@ -24744,7 +24742,8 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "functions-have-names": { "version": "1.2.3", @@ -24956,12 +24955,9 @@ } }, "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==" }, "has-bigints": { "version": "1.0.2", @@ -28701,9 +28697,9 @@ } }, "terser": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.20.0.tgz", - "integrity": "sha512-e56ETryaQDyebBwJIWYB2TT6f2EZ0fL0sW/JRXNMN26zZdKi2u/E/5my5lG6jNxym6qsrVXfFRmOdV42zlAgLQ==", + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.21.0.tgz", + "integrity": "sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==", "dev": true, "requires": { "@jridgewell/source-map": "^0.3.3", diff --git a/lib/config-wasm/tests/test.js b/lib/config-wasm/tests/test.js index 714e817d..44b7896b 100644 --- a/lib/config-wasm/tests/test.js +++ b/lib/config-wasm/tests/test.js @@ -112,6 +112,17 @@ const suite = describe("config-wasm", () => { } }); + it(integrationYaml + " should fail on parse legacy", (done) => { + try { + varMap.set("PORT", "8081"); + config = new Config(integrationFile, varMap, undefined, true); + done(new Error(integrationYaml + " should require variables")); + } catch (error) { + expect(`${error}`).to.include("UnrecognizedKey"); + done(); + } + }); + it(onDemandYaml + " should require variables", (done) => { try { config = new Config(onDemandFile, varMap); @@ -146,6 +157,30 @@ const suite = describe("config-wasm", () => { } }); + it(integrationYaml + " should pass with variables on parse new", (done) => { + try { + varMap.set("PORT", "8081"); + config = new Config(integrationFile, varMap, undefined, false); + expect(config).to.not.equal(undefined); + config.checkOk(); + expect(config.getBucketSize(), "getBucketSize").to.not.equal(undefined); + expect(config.getBucketSize().toString(), "getBucketSize").to.equal("60"); + expect(config.getDuration(), "getDuration").to.not.equal(undefined); + expect(config.getDuration().toString(), "getDuration").to.equal("5"); + expect(config.getInputFiles(), "getInputFiles").to.not.equal(undefined); + expect(config.getInputFiles().length, "getInputFiles.length").to.equal(1); + expect(config.getInputFiles()[0], "getInputFiles[0]").to.equal("integration.data"); + expect(config.getLoggerFiles(), "getLoggerFiles").to.not.equal(undefined); + expect(config.getLoggerFiles().length, "getLoggerFiles.length").to.equal(2); + expect(config.getLoggerFiles()[0], "getLoggerFiles[0]").to.equal("stderr"); + expect(config.getLoggerFiles()[1], "getLoggerFiles[1]").to.include("test-"); + done(); + } catch (error) { + console.error("test error", error); + done(error); + } + }); + it(onDemandYaml + " should pass with variables", (done) => { try { varMap.set("PORT", "8081"); @@ -178,6 +213,17 @@ const suite = describe("config-wasm", () => { } }); + it(integrationFileLegacy + " legacy should fail on parse new", (done) => { + try { + varMap.set("PORT", "8081"); + config = new Config(integrationFileLegacy, varMap, undefined, false); + done(new Error(integrationFileLegacy + " should require variables")); + } catch (error) { + expect(`${error}`).to.include("YamlParse"); + done(); + } + }); + it(onDemandYaml + " should require variables", (done) => { try { config = new Config(onDemandFileLegacy, varMap); @@ -212,6 +258,30 @@ const suite = describe("config-wasm", () => { } }); + it(integrationYaml + " legacy should pass with variables on parse legacy", (done) => { + try { + varMap.set("PORT", "8081"); + config = new Config(integrationFileLegacy, varMap, undefined, true); + expect(config).to.not.equal(undefined); + config.checkOk(); + expect(config.getBucketSize(), "getBucketSize").to.not.equal(undefined); + expect(config.getBucketSize().toString(), "getBucketSize").to.equal("60"); + expect(config.getDuration(), "getDuration").to.not.equal(undefined); + expect(config.getDuration().toString(), "getDuration").to.equal("5"); + expect(config.getInputFiles(), "getInputFiles").to.not.equal(undefined); + expect(config.getInputFiles().length, "getInputFiles.length").to.equal(1); + expect(config.getInputFiles()[0], "getInputFiles[0]").to.equal("integration.data"); + expect(config.getLoggerFiles(), "getLoggerFiles").to.not.equal(undefined); + expect(config.getLoggerFiles().length, "getLoggerFiles.length").to.equal(2); + expect(config.getLoggerFiles()[0], "getLoggerFiles[0]").to.equal("stderr"); + expect(config.getLoggerFiles()[1], "getLoggerFiles[1]").to.include("test-"); + done(); + } catch (error) { + console.error("test error", error); + done(error); + } + }); + it(onDemandYaml + " legacy should pass with variables", (done) => { try { varMap.set("PORT", "8081"); diff --git a/package-lock.json b/package-lock.json index dc79ec32..c4e85c78 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@fs/monorepo", - "version": "3.0.0", + "version": "3.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@fs/monorepo", - "version": "3.0.0", + "version": "3.0.1", "workspaces": [ "./lib/config-wasm/pkg", "./common", @@ -44,7 +44,7 @@ }, "agent": { "name": "@fs/ppaas-agent", - "version": "3.0.0", + "version": "3.0.1", "dependencies": { "@fs/config-wasm": "*", "@fs/ppaas-common": "*", @@ -53,7 +53,8 @@ "dotenv-flow": "^3.2.0", "expiry-map": "^2.0.0", "express": "^4.18.2", - "rimraf": "^5.0.0" + "rimraf": "^5.0.0", + "semver": "^7.5.2" }, "devDependencies": { "@aws-sdk/client-s3": "^3.363.0", @@ -64,6 +65,7 @@ "@types/express": "^4.17.17", "@types/mocha": "^10.0.0", "@types/node": "^20.0.0", + "@types/semver": "^7.5.0", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", "axios": "~1.5.0", @@ -79,7 +81,7 @@ }, "common": { "name": "@fs/ppaas-common", - "version": "3.0.0", + "version": "3.0.1", "dependencies": { "@aws-sdk/client-ec2": "^3.363.0", "@aws-sdk/client-s3": "^3.363.0", @@ -116,7 +118,7 @@ }, "controller": { "name": "@fs/ppaas-controller", - "version": "3.0.0", + "version": "3.0.1", "dependencies": { "@aws-sdk/client-s3": "^3.363.0", "@aws-sdk/client-secrets-manager": "^3.363.0", @@ -142,7 +144,7 @@ "js-yaml": "^4.1.0", "next": "~13.5.3", "next-cookies": "^2.0.3", - "openid-client": "~5.5.0", + "openid-client": "~5.6.0", "rc-progress": "^3.4.2", "react": "^18.2.0", "react-accessible-accordion": "^5.0.0", @@ -208,6 +210,7 @@ } }, "controller/lib/hdr-histogram-wasm": { + "name": "@fs/hdr-histogram-wasm", "version": "0.6.0-scripting", "license": "Apache 2.0" }, @@ -375,18 +378,18 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@aws-sdk/client-ec2": { - "version": "3.422.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-ec2/-/client-ec2-3.422.0.tgz", - "integrity": "sha512-3SJSyuJIPBkKKA/aLuqcHG9dABRaqbvBXNWrqxUYyYdacr+eHB+KLMi0MuKjMZm2/42pK1V1T5xbyxsTOO1XBA==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-ec2/-/client-ec2-3.423.0.tgz", + "integrity": "sha512-FH6axw/YNzOtKxuPWr2v3LAvzZMtyDwhWtuYlLFmjqCe5kBhM+7+tMa4HKaoW40B7rp5iE5FqkiCn0PweNx9GQ==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.421.0", - "@aws-sdk/credential-provider-node": "3.421.0", + "@aws-sdk/client-sts": "3.423.0", + "@aws-sdk/credential-provider-node": "3.423.0", "@aws-sdk/middleware-host-header": "3.418.0", "@aws-sdk/middleware-logger": "3.418.0", "@aws-sdk/middleware-recursion-detection": "3.418.0", - "@aws-sdk/middleware-sdk-ec2": "3.418.0", + "@aws-sdk/middleware-sdk-ec2": "3.423.0", "@aws-sdk/middleware-signing": "3.418.0", "@aws-sdk/middleware-user-agent": "3.418.0", "@aws-sdk/region-config-resolver": "3.418.0", @@ -426,15 +429,15 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.421.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.421.0.tgz", - "integrity": "sha512-vUXTY4toeHDf5EY2kOn04Ww9vTW2IVGy4+cymFp1cz5QT7g9KKj4Okj5DMdPld2y7wjgc+J/viTWEf26By49vw==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.423.0.tgz", + "integrity": "sha512-Sn/6fotTDGp+uUfPU0JrKszHT/cYwZonly6Ahi4R/uxASLQnOEAF7MwVSjms+/LGu72Qs0Tt7B7RKW76GI4OIA==", "dependencies": { "@aws-crypto/sha1-browser": "3.0.0", "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.421.0", - "@aws-sdk/credential-provider-node": "3.421.0", + "@aws-sdk/client-sts": "3.423.0", + "@aws-sdk/credential-provider-node": "3.423.0", "@aws-sdk/middleware-bucket-endpoint": "3.418.0", "@aws-sdk/middleware-expect-continue": "3.418.0", "@aws-sdk/middleware-flexible-checksums": "3.418.0", @@ -491,14 +494,14 @@ } }, "node_modules/@aws-sdk/client-secrets-manager": { - "version": "3.421.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.421.0.tgz", - "integrity": "sha512-uwoSstFm+A60f2/CuIDHqTJdYm4hPMNCzkI3J/pKoD4A6suLIoJ9lEKGV3fdeL456vir4RTwiJG6Llzo+zI+nA==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.423.0.tgz", + "integrity": "sha512-w4Qrlx65wx1UO40Bi6u5d+mEKCqLqU1PTFcZ8F9UPl0I7yjHhRxY+Pw88WUlRnWBRVkYznUPtoh/4xG0lKW9oA==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.421.0", - "@aws-sdk/credential-provider-node": "3.421.0", + "@aws-sdk/client-sts": "3.423.0", + "@aws-sdk/credential-provider-node": "3.423.0", "@aws-sdk/middleware-host-header": "3.418.0", "@aws-sdk/middleware-logger": "3.418.0", "@aws-sdk/middleware-recursion-detection": "3.418.0", @@ -539,14 +542,14 @@ } }, "node_modules/@aws-sdk/client-sqs": { - "version": "3.421.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.421.0.tgz", - "integrity": "sha512-Ir5bNvYiMneqEn+jzlYoLTVymSXf8gB0QiM9xkef8/IamYF9WQIS6rVxcCTi/DaHjCBSsUeAyYvt+SvqwiFOHg==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.423.0.tgz", + "integrity": "sha512-U4xA93ds3Is98e5i2LawoM1HIaxwBS0lXIFazGJqYt/wdpA/NZVsRKr8HXaCteqgjkXJrPFkHi8HOHhDXy93YA==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.421.0", - "@aws-sdk/credential-provider-node": "3.421.0", + "@aws-sdk/client-sts": "3.423.0", + "@aws-sdk/credential-provider-node": "3.423.0", "@aws-sdk/middleware-host-header": "3.418.0", "@aws-sdk/middleware-logger": "3.418.0", "@aws-sdk/middleware-recursion-detection": "3.418.0", @@ -589,9 +592,9 @@ } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.421.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.421.0.tgz", - "integrity": "sha512-40CmW7K2/FZEn3CbOjbpRYeVjKu6aJQlpRHcAgEJGNoVEAnRA3YNH4H0BN2iWWITfYg3B7sIjMm5VE9fCIK1Ng==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.423.0.tgz", + "integrity": "sha512-znIufHkwhCIePgaYciIs3x/+BpzR57CZzbCKHR9+oOvGyufEPPpUT5bFLvbwTgfiVkTjuk6sG/ES3U5Bc+xtrA==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", @@ -633,13 +636,13 @@ } }, "node_modules/@aws-sdk/client-sts": { - "version": "3.421.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.421.0.tgz", - "integrity": "sha512-/92NOZMcdkBcvGrINk5B/l+6DGcVzYE4Ab3ME4vcY9y//u2gd0yNn5YYRSzzjVBLvhDP3u6CbTfLX2Bm4qihPw==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.423.0.tgz", + "integrity": "sha512-EcpkKu02QZbRX6dQE0u7a8RgWrn/5riz1qAlKd7rM8FZJpr/D6GGX8ZzWxjgp7pRUgfNvinTmIudDnyQY3v9Mg==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/credential-provider-node": "3.421.0", + "@aws-sdk/credential-provider-node": "3.423.0", "@aws-sdk/middleware-host-header": "3.418.0", "@aws-sdk/middleware-logger": "3.418.0", "@aws-sdk/middleware-recursion-detection": "3.418.0", @@ -695,13 +698,13 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.421.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.421.0.tgz", - "integrity": "sha512-J5yH/gkpAk6FMeH5F9u5Nr6oG+97tj1kkn5q49g3XMbtWw7GiynadxdtoRBCeIg1C7o2LOQx4B1AnhNhIw1z/g==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.423.0.tgz", + "integrity": "sha512-7CsFWz8g7dQmblp57XzzxMirO4ClowGZIOwAheBkmk6q1XHbllcHFnbh2kdPyQQ0+JmjDg6waztIc7dY7Ycfvw==", "dependencies": { "@aws-sdk/credential-provider-env": "3.418.0", "@aws-sdk/credential-provider-process": "3.418.0", - "@aws-sdk/credential-provider-sso": "3.421.0", + "@aws-sdk/credential-provider-sso": "3.423.0", "@aws-sdk/credential-provider-web-identity": "3.418.0", "@aws-sdk/types": "3.418.0", "@smithy/credential-provider-imds": "^2.0.0", @@ -715,14 +718,14 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.421.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.421.0.tgz", - "integrity": "sha512-g1dvdvfDj0u8B/gOsHR3o1arP4O4QE/dFm2IJBYr/eUdKISMUgbQULWtg4zdtAf0Oz4xN0723i7fpXAF1gTnRA==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.423.0.tgz", + "integrity": "sha512-lygbGJJUnDpgo8OEqdoYd51BKkyBVQ1Catiua/m0aHvL+SCmVrHiYPQPawWYGxpH8X3DXdXa0nd0LkEaevrHRg==", "dependencies": { "@aws-sdk/credential-provider-env": "3.418.0", - "@aws-sdk/credential-provider-ini": "3.421.0", + "@aws-sdk/credential-provider-ini": "3.423.0", "@aws-sdk/credential-provider-process": "3.418.0", - "@aws-sdk/credential-provider-sso": "3.421.0", + "@aws-sdk/credential-provider-sso": "3.423.0", "@aws-sdk/credential-provider-web-identity": "3.418.0", "@aws-sdk/types": "3.418.0", "@smithy/credential-provider-imds": "^2.0.0", @@ -751,11 +754,11 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.421.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.421.0.tgz", - "integrity": "sha512-f8T3L5rhImL6T6RTSvbOxaWw9k2fDOT2DZbNjcPz9ITWmwXj2NNbdHGWuRi3dv2HoY/nW2IJdNxnhdhbn6Fc1A==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.423.0.tgz", + "integrity": "sha512-zAH68IjRMmW22USbsCVQ5Q6AHqhmWABwLbZAMocSGMasddTGv/nkA/nUiVCJ/B4LI3P81FoPQVrG5JxNmkNH0w==", "dependencies": { - "@aws-sdk/client-sso": "3.421.0", + "@aws-sdk/client-sso": "3.423.0", "@aws-sdk/token-providers": "3.418.0", "@aws-sdk/types": "3.418.0", "@smithy/property-provider": "^2.0.0", @@ -782,9 +785,9 @@ } }, "node_modules/@aws-sdk/lib-storage": { - "version": "3.421.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.421.0.tgz", - "integrity": "sha512-m3zgZhTUfCp2vFWJA4azHgqaFB/OaWgdumYxPHr0JKbjBkGRFyQ90dmRtzVhROOIwI+GxKYxMi1HXhDU6FwsdQ==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.423.0.tgz", + "integrity": "sha512-EyE1d/99BxUdfHs144u7h5gkb/GccApHT2uq1QwaLHqee5rw8+oZoAbhrwQ5kyysH2v3GSdcBEeTwonNJo1jSw==", "dependencies": { "@smithy/abort-controller": "^2.0.1", "@smithy/middleware-endpoint": "^2.0.9", @@ -905,9 +908,9 @@ } }, "node_modules/@aws-sdk/middleware-sdk-ec2": { - "version": "3.418.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-ec2/-/middleware-sdk-ec2-3.418.0.tgz", - "integrity": "sha512-+nxKSQW4Yd4y6SUrI4AbKLj7IrSvzYctTAMPXwx9YUkjZMnIonX+qpsZ9k++2GKlPCjcF4DAC0NrVqZeWtjiiA==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-ec2/-/middleware-sdk-ec2-3.423.0.tgz", + "integrity": "sha512-dfhe4aFQK0dbx3XX87rDIB0fmh52U0YMb0niSgZN2i4x91Q7YGpGQZAhj8gdcyML2KsKZMv/9m6PrCEIzCqqHQ==", "dependencies": { "@aws-sdk/types": "3.418.0", "@aws-sdk/util-format-url": "3.418.0", @@ -1028,9 +1031,9 @@ } }, "node_modules/@aws-sdk/s3-request-presigner": { - "version": "3.421.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.421.0.tgz", - "integrity": "sha512-qQB6DRV81SZ4Q9JQL8/X4QH1aTyefeKIkmc3KH5QtP5PZJAKOoU4kqIXTFrUFCPan3CjWQw565ZR0usgR6RynQ==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.423.0.tgz", + "integrity": "sha512-VwC5WjcFKdmPpQXYn6vKi+9iJtP6a0sY9UJu0fy6yXKK4pm9yk9ZFflq46PWT/Z6JNAR+dvi+hzAZLbvXWpSvA==", "dependencies": { "@aws-sdk/signature-v4-multi-region": "3.418.0", "@aws-sdk/types": "3.418.0", @@ -3925,9 +3928,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.0.tgz", - "integrity": "sha512-zJmuCWj2VLBt4c25CfBIbMZLGLyhkvs7LznyVX5HfpzeocThgIj5XQK4L+g3U36mMcx8bPMhGyPpwCATamC4jQ==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", + "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -4004,9 +4007,9 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.4.tgz", - "integrity": "sha512-qprfWkn82Iw821mcKofJ5Pk9wgioHicxcQMxx+5zt5GSKoqdWvgG5AxVmpmUUjzTLPVSH5auBrhI93Deayn/DA==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz", + "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==", "dev": true }, "node_modules/@fs/config-wasm": { @@ -4380,14 +4383,14 @@ } }, "node_modules/@next/env": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/env/-/env-13.5.3.tgz", - "integrity": "sha512-X4te86vsbjsB7iO4usY9jLPtZ827Mbx+WcwNBGUOIuswuTAKQtzsuoxc/6KLxCMvogKG795MhrR1LDhYgDvasg==" + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/env/-/env-13.5.4.tgz", + "integrity": "sha512-LGegJkMvRNw90WWphGJ3RMHMVplYcOfRWf2Be3td3sUa+1AaxmsYyANsA+znrGCBjXJNi4XAQlSoEfUxs/4kIQ==" }, "node_modules/@next/eslint-plugin-next": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.5.3.tgz", - "integrity": "sha512-lbZOoEjzSuTtpk9UgV9rOmxYw+PsSfNR+00mZcInqooiDMZ1u+RqT1YQYLsEZPW1kumZoQe5+exkCBtZ2xn0uw==", + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.5.4.tgz", + "integrity": "sha512-vI94U+D7RNgX6XypSyjeFrOzxGlZyxOplU0dVE5norIfZGn/LDjJYPHdvdsR5vN1eRtl6PDAsOHmycFEOljK5A==", "dev": true, "dependencies": { "glob": "7.1.7" @@ -4414,9 +4417,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.5.3.tgz", - "integrity": "sha512-6hiYNJxJmyYvvKGrVThzo4nTcqvqUTA/JvKim7Auaj33NexDqSNwN5YrrQu+QhZJCIpv2tULSHt+lf+rUflLSw==", + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.5.4.tgz", + "integrity": "sha512-Df8SHuXgF1p+aonBMcDPEsaahNo2TCwuie7VXED4FVyECvdXfRT9unapm54NssV9tF3OQFKBFOdlje4T43VO0w==", "cpu": [ "arm64" ], @@ -4429,9 +4432,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.5.3.tgz", - "integrity": "sha512-UpBKxu2ob9scbpJyEq/xPgpdrgBgN3aLYlxyGqlYX5/KnwpJpFuIHU2lx8upQQ7L+MEmz+fA1XSgesoK92ppwQ==", + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.5.4.tgz", + "integrity": "sha512-siPuUwO45PnNRMeZnSa8n/Lye5ZX93IJom9wQRB5DEOdFrw0JjOMu1GINB8jAEdwa7Vdyn1oJ2xGNaQpdQQ9Pw==", "cpu": [ "x64" ], @@ -4444,9 +4447,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.5.3.tgz", - "integrity": "sha512-5AzM7Yx1Ky+oLY6pHs7tjONTF22JirDPd5Jw/3/NazJ73uGB05NqhGhB4SbeCchg7SlVYVBeRMrMSZwJwq/xoA==", + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.5.4.tgz", + "integrity": "sha512-l/k/fvRP/zmB2jkFMfefmFkyZbDkYW0mRM/LB+tH5u9pB98WsHXC0WvDHlGCYp3CH/jlkJPL7gN8nkTQVrQ/2w==", "cpu": [ "arm64" ], @@ -4459,9 +4462,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.5.3.tgz", - "integrity": "sha512-A/C1shbyUhj7wRtokmn73eBksjTM7fFQoY2v/0rTM5wehpkjQRLOXI8WJsag2uLhnZ4ii5OzR1rFPwoD9cvOgA==", + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.5.4.tgz", + "integrity": "sha512-YYGb7SlLkI+XqfQa8VPErljb7k9nUnhhRrVaOdfJNCaQnHBcvbT7cx/UjDQLdleJcfyg1Hkn5YSSIeVfjgmkTg==", "cpu": [ "arm64" ], @@ -4474,9 +4477,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.5.3.tgz", - "integrity": "sha512-FubPuw/Boz8tKkk+5eOuDHOpk36F80rbgxlx4+xty/U71e3wZZxVYHfZXmf0IRToBn1Crb8WvLM9OYj/Ur815g==", + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.5.4.tgz", + "integrity": "sha512-uE61vyUSClnCH18YHjA8tE1prr/PBFlBFhxBZis4XBRJoR+txAky5d7gGNUIbQ8sZZ7LVkSVgm/5Fc7mwXmRAg==", "cpu": [ "x64" ], @@ -4489,9 +4492,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.5.3.tgz", - "integrity": "sha512-DPw8nFuM1uEpbX47tM3wiXIR0Qa+atSzs9Q3peY1urkhofx44o7E1svnq+a5Q0r8lAcssLrwiM+OyJJgV/oj7g==", + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.5.4.tgz", + "integrity": "sha512-qVEKFYML/GvJSy9CfYqAdUexA6M5AklYcQCW+8JECmkQHGoPxCf04iMh7CPR7wkHyWWK+XLt4Ja7hhsPJtSnhg==", "cpu": [ "x64" ], @@ -4504,9 +4507,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.5.3.tgz", - "integrity": "sha512-zBPSP8cHL51Gub/YV8UUePW7AVGukp2D8JU93IHbVDu2qmhFAn9LWXiOOLKplZQKxnIPUkJTQAJDCWBWU4UWUA==", + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.5.4.tgz", + "integrity": "sha512-mDSQfqxAlfpeZOLPxLymZkX0hYF3juN57W6vFHTvwKlnHfmh12Pt7hPIRLYIShk8uYRsKPtMTth/EzpwRI+u8w==", "cpu": [ "arm64" ], @@ -4519,9 +4522,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.5.3.tgz", - "integrity": "sha512-ONcL/lYyGUj4W37D4I2I450SZtSenmFAvapkJQNIJhrPMhzDU/AdfLkW98NvH1D2+7FXwe7yclf3+B7v28uzBQ==", + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.5.4.tgz", + "integrity": "sha512-aoqAT2XIekIWoriwzOmGFAvTtVY5O7JjV21giozBTP5c6uZhpvTWRbmHXbmsjZqY4HnEZQRXWkSAppsIBweKqw==", "cpu": [ "ia32" ], @@ -4534,9 +4537,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.5.3.tgz", - "integrity": "sha512-2Vz2tYWaLqJvLcWbbTlJ5k9AN6JD7a5CN2pAeIzpbecK8ZF/yobA39cXtv6e+Z8c5UJuVOmaTldEAIxvsIux/Q==", + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.5.4.tgz", + "integrity": "sha512-cyRvlAxwlddlqeB9xtPSfNSCRy8BOa4wtMo0IuI9P7Y0XT2qpDrpFKRyZ7kUngZis59mPVla5k8X1oOJ8RxDYg==", "cpu": [ "x64" ], @@ -5344,9 +5347,9 @@ } }, "node_modules/@rushstack/eslint-patch": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.5.0.tgz", - "integrity": "sha512-EF3948ckf3f5uPgYbQ6GhyA56Dmv8yg0+ir+BroRjwdxyZJsekhZzawOecC2rOTPCz173t7ZcR1HHZu0dZgOCw==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.5.1.tgz", + "integrity": "sha512-6i/8UoL0P5y4leBIGzvkZdS85RDMG9y1ihZzmTZQ5LdHUYmZ7pKFoj8X0236s3lusPs1Fa5HTQUpwI+UfTcmeA==", "dev": true }, "node_modules/@sinonjs/commons": { @@ -5515,9 +5518,9 @@ } }, "node_modules/@smithy/fetch-http-handler": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.2.0.tgz", - "integrity": "sha512-P2808PM0CsEkXj3rnQAi3QyqRbAAi8iuePYUB5GveJ+dVd1WMv03NM+CYCI14IGXt1j/r7jHGvMJHO+Gv+kdMQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.2.1.tgz", + "integrity": "sha512-bXyM8PBAIKxVV++2ZSNBEposTDjFQ31XWOdHED+2hWMNvJHUoQqFbECg/uhcVOa6vHie2/UnzIZfXBSTpDBnEw==", "dependencies": { "@smithy/protocol-http": "^3.0.6", "@smithy/querystring-builder": "^2.0.10", @@ -5784,13 +5787,13 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.1.8.tgz", - "integrity": "sha512-Puuc4wuhdTSs8wstkNJ/JtpaFwIh0qDE27zawfRVzzjpXprpT+4wROqO2+NVoZ+6GKv7kz7QgZx6AI5325bSeQ==", + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.1.9.tgz", + "integrity": "sha512-HTicQSn/lOcXKJT+DKJ4YMu51S6PzbWsO8Z6Pwueo30mSoFKXg5P0BDkg2VCDqCVR0mtddM/F6hKhjW6YAV/yg==", "dependencies": { "@smithy/middleware-stack": "^2.0.4", "@smithy/types": "^2.3.4", - "@smithy/util-stream": "^2.0.13", + "@smithy/util-stream": "^2.0.14", "tslib": "^2.5.0" }, "engines": { @@ -5873,12 +5876,12 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.0.12.tgz", - "integrity": "sha512-BCsFPdNThMS2312/Zj3/TtFsXfO2BwkbDNsoWbdtZ0cAv9cE6vqGKllYXmq2Gj6u+Vv8V3wUgBUicNol6s/7Sg==", + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.0.13.tgz", + "integrity": "sha512-UmmOdUzaQjqdsl1EjbpEaQxM0VDFqTj6zDuI26/hXN7L/a1k1koTwkYpogHMvunDX3fjrQusg5gv1Td4UsGyog==", "dependencies": { "@smithy/property-provider": "^2.0.11", - "@smithy/smithy-client": "^2.1.8", + "@smithy/smithy-client": "^2.1.9", "@smithy/types": "^2.3.4", "bowser": "^2.11.0", "tslib": "^2.5.0" @@ -5888,15 +5891,15 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.0.14.tgz", - "integrity": "sha512-EtomtYsWDkBGs0fLeF+7N2df+zIqGix+O4llWqQD+97rbo2hk+GBWeZzBkujKrzFeXNUbPkFqfvZPLdoq4S4XQ==", + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.0.15.tgz", + "integrity": "sha512-g6J7MHAibVPMTlXyH3mL+Iet4lMJKFVhsOhJmn+IKG81uy9m42CkRSDlwdQSJAcprLQBIaOPdFxNXQvrg2w1Uw==", "dependencies": { "@smithy/config-resolver": "^2.0.11", "@smithy/credential-provider-imds": "^2.0.13", "@smithy/node-config-provider": "^2.0.13", "@smithy/property-provider": "^2.0.11", - "@smithy/smithy-client": "^2.1.8", + "@smithy/smithy-client": "^2.1.9", "@smithy/types": "^2.3.4", "tslib": "^2.5.0" }, @@ -5941,11 +5944,11 @@ } }, "node_modules/@smithy/util-stream": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.0.13.tgz", - "integrity": "sha512-aeua6pN0WMdQtZNRRJ8J+mop57fezLMsApYbk5Q3q11pyHwZypVPuKoelr7K9PMJZcuYk90dQyUsUAd7hTCeRg==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.0.14.tgz", + "integrity": "sha512-XjvlDYe+9DieXhLf7p+EgkXwFtl34kHZcWfHnc5KaILbhyVfDLWuqKTFx6WwCFqb01iFIig8trGwExRIqqkBYg==", "dependencies": { - "@smithy/fetch-http-handler": "^2.2.0", + "@smithy/fetch-http-handler": "^2.2.1", "@smithy/node-http-handler": "^2.1.6", "@smithy/types": "^2.3.4", "@smithy/util-base64": "^2.0.0", @@ -6703,9 +6706,9 @@ } }, "node_modules/@storybook/builder-webpack5/node_modules/@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true }, "node_modules/@storybook/channels": { @@ -7273,9 +7276,9 @@ } }, "node_modules/@storybook/core-common/node_modules/@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true }, "node_modules/@storybook/core-common/node_modules/brace-expansion": { @@ -7478,9 +7481,9 @@ } }, "node_modules/@storybook/core-server/node_modules/@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true }, "node_modules/@storybook/core-webpack": { @@ -7501,9 +7504,9 @@ } }, "node_modules/@storybook/core-webpack/node_modules/@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true }, "node_modules/@storybook/csf": { @@ -7694,9 +7697,9 @@ } }, "node_modules/@storybook/nextjs/node_modules/@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true }, "node_modules/@storybook/node-logger": { @@ -7754,9 +7757,9 @@ } }, "node_modules/@storybook/preset-react-webpack/node_modules/@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true }, "node_modules/@storybook/preview": { @@ -7875,9 +7878,9 @@ } }, "node_modules/@storybook/react/node_modules/@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==", + "version": "16.18.57", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.57.tgz", + "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true }, "node_modules/@storybook/react/node_modules/acorn": { @@ -7994,9 +7997,9 @@ } }, "node_modules/@swc/core": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.90.tgz", - "integrity": "sha512-wptBxP4PldOnhmyDVj8qUcn++GRqyw1qc9wOTGtPNHz8cpuTfdfIgYGlhI4La0UYqecuaaIfLfokyuNePOMHPg==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.91.tgz", + "integrity": "sha512-r950d0fdlZ8qbSDyvApn3HyCojiZE8xpgJzQvypeMi32dalYwugdJKWyLB55JIGMRGJ8+lmVvY4MPGkSR3kXgA==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -8011,16 +8014,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.3.90", - "@swc/core-darwin-x64": "1.3.90", - "@swc/core-linux-arm-gnueabihf": "1.3.90", - "@swc/core-linux-arm64-gnu": "1.3.90", - "@swc/core-linux-arm64-musl": "1.3.90", - "@swc/core-linux-x64-gnu": "1.3.90", - "@swc/core-linux-x64-musl": "1.3.90", - "@swc/core-win32-arm64-msvc": "1.3.90", - "@swc/core-win32-ia32-msvc": "1.3.90", - "@swc/core-win32-x64-msvc": "1.3.90" + "@swc/core-darwin-arm64": "1.3.91", + "@swc/core-darwin-x64": "1.3.91", + "@swc/core-linux-arm-gnueabihf": "1.3.91", + "@swc/core-linux-arm64-gnu": "1.3.91", + "@swc/core-linux-arm64-musl": "1.3.91", + "@swc/core-linux-x64-gnu": "1.3.91", + "@swc/core-linux-x64-musl": "1.3.91", + "@swc/core-win32-arm64-msvc": "1.3.91", + "@swc/core-win32-ia32-msvc": "1.3.91", + "@swc/core-win32-x64-msvc": "1.3.91" }, "peerDependencies": { "@swc/helpers": "^0.5.0" @@ -8032,9 +8035,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.90.tgz", - "integrity": "sha512-he0w74HvcoufE6CZrB/U/VGVbc7021IQvYrn1geMACnq/OqMBqjdczNtdNfJAy87LZ4AOUjHDKEIjsZZu7o8nQ==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.91.tgz", + "integrity": "sha512-7kHGiQ1he5khcEeJuHDmLZPM3rRL/ith5OTmV6bOPsoHi46kLeixORW+ts1opC3tC9vu6xbk16xgX0QAJchc1w==", "cpu": [ "arm64" ], @@ -8048,9 +8051,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.90.tgz", - "integrity": "sha512-hKNM0Ix0qMlAamPe0HUfaAhQVbZEL5uK6Iw8v9ew0FtVB4v7EifQ9n41wh+yCj0CjcHBPEBbQU0P6mNTxJu/RQ==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.91.tgz", + "integrity": "sha512-8SpU18FbFpZDVzsHsAwdI1thF/picQGxq9UFxa8W+T9SDnbsqwFJv/6RqKJeJoDV6qFdl2OLjuO0OL7xrp0qnQ==", "cpu": [ "x64" ], @@ -8064,9 +8067,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.90.tgz", - "integrity": "sha512-HumvtrqTWE8rlFuKt7If0ZL7145H/jVc4AeziVjcd+/ajpqub7IyfrLCYd5PmKMtfeSVDMsxjG0BJ0HLRxrTJA==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.91.tgz", + "integrity": "sha512-fOq4Cy8UbwX1yf0WB0d8hWZaIKCnPtPGguRqdXGLfwvhjZ9SIErT6PnmGTGRbQCNCIkOZWHKyTU0r8t2dN3haQ==", "cpu": [ "arm" ], @@ -8080,9 +8083,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.90.tgz", - "integrity": "sha512-tA7DqCS7YCwngwXZQeqQhhMm8BbydpaABw8Z/EDQ7KPK1iZ1rNjZw+aWvSpmNmEGmH1RmQ9QDS9mGRDp0faAeg==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.91.tgz", + "integrity": "sha512-fki4ioRP/Esy4vdp8T34RCV+V9dqkRmOt763pf74pdiyFV2dPLXa5lnw/XvR1RTfPGknrYgjEQLCfZlReTryRw==", "cpu": [ "arm64" ], @@ -8096,9 +8099,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.90.tgz", - "integrity": "sha512-p2Vtid5BZA36fJkNUwk5HP+HJlKgTru+Ghna7pRe45ghKkkRIUk3fhkgudEvfKfhT+3AvP+GTVQ+T9k0gc9S8w==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.91.tgz", + "integrity": "sha512-XrG+DUUqNtfVLcJ20imby7fpBwQNG5VsEQBzQndSonPyUOa2YkTbBb60YDondfQGDABopuHH8gHN8o2H2/VCnQ==", "cpu": [ "arm64" ], @@ -8112,9 +8115,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.90.tgz", - "integrity": "sha512-J6pDtWaulYGXuANERuvv4CqmUbZOQrRZBCRQGZQJ6a86RWpesZqckBelnYx48wYmkgvMkF95Y3xbI3WTfoSHzw==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.91.tgz", + "integrity": "sha512-d11bYhX+YPBr/Frcjc6eVn3C0LuS/9U1Li9EmQ+6s9EpYtYRl2ygSlC8eueLbaiazBnCVYFnc8bU4o0kc5B9sw==", "cpu": [ "x64" ], @@ -8128,9 +8131,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.90.tgz", - "integrity": "sha512-3Gh6EA3+0K+l3MqnRON7h5bZ32xLmfcVM6QiHHJ9dBttq7YOEeEoMOCdIPMaQxJmK1VfLgZCsPYRd66MhvUSkw==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.91.tgz", + "integrity": "sha512-2SRp5Dke2P4jCQePkDx9trkkTstnRpZJVw5r3jvYdk0zeO6iC4+ZPvvoWXJLigqQv/fZnIiSUfJ6ssOoaEqTzQ==", "cpu": [ "x64" ], @@ -8144,9 +8147,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.90.tgz", - "integrity": "sha512-BNaw/iJloDyaNOFV23Sr53ULlnbmzSoerTJ10v0TjSZOEIpsS0Rw6xOK1iI0voDJnRXeZeWRSxEC9DhefNtN/g==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.91.tgz", + "integrity": "sha512-l9qKXikOxj42UIjbeZpz9xtBmr736jOMqInNP8mVF2/U+ws5sI8zJjcOFFtfis4ru7vWCXhB1wtltdlJYO2vGA==", "cpu": [ "arm64" ], @@ -8160,9 +8163,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.90.tgz", - "integrity": "sha512-SiyTethWAheE/JbxXCukAAciU//PLcmVZ2ME92MRuLMLmOhrwksjbaa7ukj9WEF3LWrherhSqTXnpj3VC1l/qw==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.91.tgz", + "integrity": "sha512-+s+52O0QVPmzOgjEe/rcb0AK6q/J7EHKwAyJCu/FaYO9df5ovE0HJjSKP6HAF0dGPO5hkENrXuNGujofUH9vtQ==", "cpu": [ "ia32" ], @@ -8176,9 +8179,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.3.90", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.90.tgz", - "integrity": "sha512-OpWAW5ljKcPJ3SQ0pUuKqYfwXv7ssIhVgrH9XP9ONtdgXKWZRL9hqJQkcL55FARw/gDjKanoCM47wsTNQL+ZZA==", + "version": "1.3.91", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.91.tgz", + "integrity": "sha512-7u9HDQhjUC3Gv43EFW84dZtduWCSa4MgltK+Sp9zEGti6WXqDPu/ESjvDsQEVYTBEMEvZs/xVAXPgLVHorV5nQ==", "cpu": [ "x64" ], @@ -8520,9 +8523,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.7.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.2.tgz", - "integrity": "sha512-RcdC3hOBOauLP+r/kRt27NrByYtDjsXyAuSbR87O6xpsvi763WI+5fbSIvYJrXnt9w4RuxhV6eAXfIs7aaf/FQ==", + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.2.tgz", + "integrity": "sha512-Vvycsc9FQdwhxE3y3DzeIxuEJbWGDsnrxvMADzTDF/lcdR9/K+AQIeAghTQsHtotg/q0j3WEOYS/jQgSdWue3w==", "dev": true }, "node_modules/@types/node-fetch": { @@ -8554,9 +8557,9 @@ "dev": true }, "node_modules/@types/prop-types": { - "version": "15.7.7", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.7.tgz", - "integrity": "sha512-FbtmBWCcSa2J4zL781Zf1p5YUBXQomPEcep9QZCfRfQgTxz3pJWiDFLebohZ9fFntX5ibzOkSsrJ0TEew8cAog==", + "version": "15.7.8", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.8.tgz", + "integrity": "sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ==", "dev": true }, "node_modules/@types/qs": { @@ -8572,9 +8575,9 @@ "dev": true }, "node_modules/@types/react": { - "version": "18.2.23", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.23.tgz", - "integrity": "sha512-qHLW6n1q2+7KyBEYnrZpcsAmU/iiCh9WGCKgXvMxx89+TYdJWRjZohVIo9XTcoLhfX3+/hP0Pbulu3bCZQ9PSA==", + "version": "18.2.24", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.24.tgz", + "integrity": "sha512-Ee0Jt4sbJxMu1iDcetZEIKQr99J1Zfb6D4F3qfUWoR1JpInkY1Wdg4WwCyBjL257D0+jGqSl1twBjV8iCaC0Aw==", "dev": true, "dependencies": { "@types/prop-types": "*", @@ -8646,9 +8649,9 @@ } }, "node_modules/@types/sinon": { - "version": "10.0.17", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.17.tgz", - "integrity": "sha512-+6ILpcixQ0Ma3dHMTLv4rSycbDXkDljgKL+E0nI2RUxxhYTFyPSjt6RVMxh7jUshvyVcBvicb0Ktj+lAJcjgeA==", + "version": "10.0.18", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.18.tgz", + "integrity": "sha512-OpQC9ug8BcnNxue2WF5aTruMaDRFn6NyfaE4DmAKOlQMn54b7CnCvDFV3wj5fk/HbSSTYmOYs2bTb5ShANjyQg==", "dev": true, "dependencies": { "@types/sinonjs__fake-timers": "*" @@ -8675,16 +8678,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.3.tgz", - "integrity": "sha512-vntq452UHNltxsaaN+L9WyuMch8bMd9CqJ3zhzTPXXidwbf5mqqKCVXEuvRZUqLJSTLeWE65lQwyXsRGnXkCTA==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.4.tgz", + "integrity": "sha512-DAbgDXwtX+pDkAHwiGhqP3zWUGpW49B7eqmgpPtg+BKJXwdct79ut9+ifqOFPJGClGKSHXn2PTBatCnldJRUoA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/type-utils": "6.7.3", - "@typescript-eslint/utils": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", + "@typescript-eslint/scope-manager": "6.7.4", + "@typescript-eslint/type-utils": "6.7.4", + "@typescript-eslint/utils": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -8710,15 +8713,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.3.tgz", - "integrity": "sha512-TlutE+iep2o7R8Lf+yoer3zU6/0EAUc8QIBB3GYBc1KGz4c4TRm83xwXUZVPlZ6YCLss4r77jbu6j3sendJoiQ==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.4.tgz", + "integrity": "sha512-I5zVZFY+cw4IMZUeNCU7Sh2PO5O57F7Lr0uyhgCJmhN/BuTlnc55KxPonR4+EM3GBdfiCyGZye6DgMjtubQkmA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/typescript-estree": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", + "@typescript-eslint/scope-manager": "6.7.4", + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/typescript-estree": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4", "debug": "^4.3.4" }, "engines": { @@ -8738,13 +8741,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.3.tgz", - "integrity": "sha512-wOlo0QnEou9cHO2TdkJmzF7DFGvAKEnB82PuPNHpT8ZKKaZu6Bm63ugOTn9fXNJtvuDPanBc78lGUGGytJoVzQ==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.4.tgz", + "integrity": "sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3" + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -8755,13 +8758,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.3.tgz", - "integrity": "sha512-Fc68K0aTDrKIBvLnKTZ5Pf3MXK495YErrbHb1R6aTpfK5OdSFj0rVN7ib6Tx6ePrZ2gsjLqr0s98NG7l96KSQw==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.4.tgz", + "integrity": "sha512-n+g3zi1QzpcAdHFP9KQF+rEFxMb2KxtnJGID3teA/nxKHOVi3ylKovaqEzGBbVY2pBttU6z85gp0D00ufLzViQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.7.3", - "@typescript-eslint/utils": "6.7.3", + "@typescript-eslint/typescript-estree": "6.7.4", + "@typescript-eslint/utils": "6.7.4", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -8782,9 +8785,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.3.tgz", - "integrity": "sha512-4g+de6roB2NFcfkZb439tigpAMnvEIg3rIjWQ+EM7IBaYt/CdJt6em9BJ4h4UpdgaBWdmx2iWsafHTrqmgIPNw==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", + "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -8795,13 +8798,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.3.tgz", - "integrity": "sha512-YLQ3tJoS4VxLFYHTw21oe1/vIZPRqAO91z6Uv0Ss2BKm/Ag7/RVQBcXTGcXhgJMdA4U+HrKuY5gWlJlvoaKZ5g==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.4.tgz", + "integrity": "sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -8822,17 +8825,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.3.tgz", - "integrity": "sha512-vzLkVder21GpWRrmSR9JxGZ5+ibIUSudXlW52qeKpzUEQhRSmyZiVDDj3crAth7+5tmN1ulvgKaCU2f/bPRCzg==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.4.tgz", + "integrity": "sha512-PRQAs+HUn85Qdk+khAxsVV+oULy3VkbH3hQ8hxLRJXWBEd7iI+GbQxH5SEUSH7kbEoTp6oT1bOwyga24ELALTA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/typescript-estree": "6.7.3", + "@typescript-eslint/scope-manager": "6.7.4", + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/typescript-estree": "6.7.4", "semver": "^7.5.4" }, "engines": { @@ -8847,12 +8850,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.3.tgz", - "integrity": "sha512-HEVXkU9IB+nk9o63CeICMHxFWbHWr3E1mpilIQBe9+7L/lH97rleFLVtYsfnWB+JVMaiFnEaxvknvmIzX+CqVg==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", + "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/types": "6.7.4", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -10408,9 +10411,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001541", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001541.tgz", - "integrity": "sha512-bLOsqxDgTqUBkzxbNlSBt8annkDpQB9NdzdTbO2ooJ+eC/IQcvDspDc058g84ejCelF7vHUx57KIOjEecOHXaw==", + "version": "1.0.30001543", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001543.tgz", + "integrity": "sha512-qxdO8KPWPQ+Zk6bvNpPeQIOH47qZSYdFZd6dXQzb2KzhnSXju4Kd7H1PkSJx6NICSMgo/IhRZRhhfPTHYpJUCA==", "funding": [ { "type": "opencollective", @@ -10905,11 +10908,11 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/core-js-compat": { - "version": "3.32.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.32.2.tgz", - "integrity": "sha512-+GjlguTDINOijtVRUxrQOv3kfu9rl+qPNdX2LTbJ/ZyVTuxK+ksVSAGX1nHstu4hrv1En/uPTtWgq2gI5wt4AQ==", + "version": "3.33.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.0.tgz", + "integrity": "sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw==", "dependencies": { - "browserslist": "^4.21.10" + "browserslist": "^4.22.1" }, "funding": { "type": "opencollective", @@ -10917,9 +10920,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.32.2", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.32.2.tgz", - "integrity": "sha512-Y2rxThOuNywTjnX/PgA5vWM6CZ9QB9sz9oGeCixV8MqXZO70z/5SHzf9EeBrEBK0PN36DnEBBu9O/aGWzKuMZQ==", + "version": "3.33.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.33.0.tgz", + "integrity": "sha512-FKSIDtJnds/YFIEaZ4HszRX7hkxGpNKM7FC9aJ9WLJbSd3lD4vOltFuVIBLR8asSx9frkTSqL0dw90SKQxgKrg==", "dev": true, "hasInstallScript": true, "funding": { @@ -11828,9 +11831,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.537", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.537.tgz", - "integrity": "sha512-W1+g9qs9hviII0HAwOdehGYkr+zt7KKdmCcJcjH0mYg6oL8+ioT3Skjmt7BLoAQqXhjf40AXd+HlR4oAWMlXjA==" + "version": "1.4.540", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.540.tgz", + "integrity": "sha512-aoCqgU6r9+o9/S7wkcSbmPRFi7OWZWiXS9rtjEd+Ouyu/Xyw5RSq2XN8s5Qp8IaFOLiRrhQCphCIjAxgG3eCAg==" }, "node_modules/elliptic": { "version": "6.5.4", @@ -12253,12 +12256,12 @@ } }, "node_modules/eslint-config-next": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.5.3.tgz", - "integrity": "sha512-VN2qbCpq2DMWgs7SVF8KTmc8bVaWz3s4nmcFqRLs7PNBt5AXejOhJuZ4zg2sCEHOvz5RvqdwLeI++NSCV6qHVg==", + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.5.4.tgz", + "integrity": "sha512-FzQGIj4UEszRX7fcRSJK6L1LrDiVZvDFW320VVntVKh3BSU8Fb9kpaoxQx0cdFgf3MQXdeSbrCXJ/5Z/NndDkQ==", "dev": true, "dependencies": { - "@next/eslint-plugin-next": "13.5.3", + "@next/eslint-plugin-next": "13.5.4", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", @@ -13725,12 +13728,9 @@ } }, "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", "engines": { "node": ">= 0.4.0" } @@ -14143,9 +14143,9 @@ } }, "node_modules/immer": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.2.tgz", - "integrity": "sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.3.tgz", + "integrity": "sha512-pwupu3eWfouuaowscykeckFmVTpqbzW+rXFCX8rQLkZzM9ftBmU/++Ra+o+L27mz03zJTlyV4UUr+fdKNffo4A==", "dev": true, "funding": { "type": "opencollective", @@ -14980,9 +14980,9 @@ } }, "node_modules/jose": { - "version": "4.14.6", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.14.6.tgz", - "integrity": "sha512-EqJPEUlZD0/CSUMubKtMaYUOtWe91tZXTWMJZoKSbLk+KtdhNdcvppH8lA9XwVu2V4Ailvsj0GBZJ2ZwDjfesQ==", + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.1.tgz", + "integrity": "sha512-CinpaEMmwb/59YG0N6SC3DY1imdTU5iNl08HPWR7NdyxACPeFuQbqjaocEjCDGq04KbnxSqQu702vL3ZTvKe5w==", "funding": { "url": "https://github.com/sponsors/panva" } @@ -15926,18 +15926,17 @@ "dev": true }, "node_modules/next": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/next/-/next-13.5.3.tgz", - "integrity": "sha512-4Nt4HRLYDW/yRpJ/QR2t1v63UOMS55A38dnWv3UDOWGezuY0ZyFO1ABNbD7mulVzs9qVhgy2+ppjdsANpKP1mg==", + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/next/-/next-13.5.4.tgz", + "integrity": "sha512-+93un5S779gho8y9ASQhb/bTkQF17FNQOtXLKAj3lsNgltEcF0C5PMLLncDmH+8X1EnJH1kbqAERa29nRXqhjA==", "dependencies": { - "@next/env": "13.5.3", + "@next/env": "13.5.4", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", - "postcss": "8.4.14", + "postcss": "8.4.31", "styled-jsx": "5.1.1", - "watchpack": "2.4.0", - "zod": "3.21.4" + "watchpack": "2.4.0" }, "bin": { "next": "dist/bin/next" @@ -15946,15 +15945,15 @@ "node": ">=16.14.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "13.5.3", - "@next/swc-darwin-x64": "13.5.3", - "@next/swc-linux-arm64-gnu": "13.5.3", - "@next/swc-linux-arm64-musl": "13.5.3", - "@next/swc-linux-x64-gnu": "13.5.3", - "@next/swc-linux-x64-musl": "13.5.3", - "@next/swc-win32-arm64-msvc": "13.5.3", - "@next/swc-win32-ia32-msvc": "13.5.3", - "@next/swc-win32-x64-msvc": "13.5.3" + "@next/swc-darwin-arm64": "13.5.4", + "@next/swc-darwin-x64": "13.5.4", + "@next/swc-linux-arm64-gnu": "13.5.4", + "@next/swc-linux-arm64-musl": "13.5.4", + "@next/swc-linux-x64-gnu": "13.5.4", + "@next/swc-linux-x64-musl": "13.5.4", + "@next/swc-win32-arm64-msvc": "13.5.4", + "@next/swc-win32-ia32-msvc": "13.5.4", + "@next/swc-win32-x64-msvc": "13.5.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -15979,46 +15978,6 @@ "universal-cookie": "^4.0.2" } }, - "node_modules/next/node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/next/node_modules/postcss": { - "version": "8.4.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", - "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - } - ], - "dependencies": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, "node_modules/nise": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", @@ -16761,11 +16720,11 @@ } }, "node_modules/openid-client": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.5.0.tgz", - "integrity": "sha512-Y7Xl8BgsrkzWLHkVDYuroM67hi96xITyEDSkmWaGUiNX6CkcXC3XyQGdv5aWZ6dukVKBFVQCADi9gCavOmU14w==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.6.0.tgz", + "integrity": "sha512-uFTkN/iqgKvSnmpVAS/T6SNThukRMBcmymTQ71Ngus1F60tdtKVap7zCrleocY+fogPtpmoxi5Q1YdrgYuTlkA==", "dependencies": { - "jose": "^4.14.4", + "jose": "^4.15.1", "lru-cache": "^6.0.0", "object-hash": "^2.2.0", "oidc-token-hash": "^5.0.3" @@ -18362,9 +18321,9 @@ } }, "node_modules/read-pkg/node_modules/type-fest": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.3.2.tgz", - "integrity": "sha512-VpwuOgnTsQUUWi0id8Hl4/xiQ+OoaeJGe8dnFjzubJYe/lOc2/d1Qx/d3FqWR0FlpOG/cvukAXfB12A49Y4iiA==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.3.3.tgz", + "integrity": "sha512-bxhiFii6BBv6UiSDq7uKTMyADT9unXEl3ydGefndVLxFeB44LRbT4K7OJGDYSyDrKnklCC1Pre68qT2wbUl2Aw==", "dev": true, "engines": { "node": ">=16" @@ -19895,9 +19854,9 @@ } }, "node_modules/terser": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.20.0.tgz", - "integrity": "sha512-e56ETryaQDyebBwJIWYB2TT6f2EZ0fL0sW/JRXNMN26zZdKi2u/E/5my5lG6jNxym6qsrVXfFRmOdV42zlAgLQ==", + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.21.0.tgz", + "integrity": "sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -21230,14 +21189,6 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/zod": { - "version": "3.21.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz", - "integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } } } } diff --git a/package.json b/package.json index 0ee1d67d..665bec46 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@fs/monorepo", - "version": "3.0.0", + "version": "3.0.1", "description": "Service for running pewpew tests", "private": true, "workspaces": [