diff --git a/.changeset/cute-queens-hunt.md b/.changeset/cute-queens-hunt.md new file mode 100644 index 00000000..92672ee1 --- /dev/null +++ b/.changeset/cute-queens-hunt.md @@ -0,0 +1,5 @@ +--- +"@perfect-abstractions/compose-cli": patch +--- + +add project build + auto detect project framework diff --git a/.gitignore b/.gitignore index 863e596b..aea54b49 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,5 @@ docgen-summary.json .agents .cursor .opencode + +soljson-latest.js diff --git a/cli/.npmignore b/cli/.npmignore index 01aa1a8f..bdca98d3 100644 --- a/cli/.npmignore +++ b/cli/.npmignore @@ -6,3 +6,5 @@ test/ tsconfig.json eslint.config.js *.log + +soljson-latest.json diff --git a/cli/eslint.config.js b/cli/eslint.config.js index 485869a6..7acf00c6 100644 --- a/cli/eslint.config.js +++ b/cli/eslint.config.js @@ -3,7 +3,7 @@ const tseslint = require("typescript-eslint"); module.exports = [ { - ignores: ["node_modules/**", "dist/**", "src/templates/**"], + ignores: ["node_modules/**", "dist/**", "src/templates/**", "soljson-latest.js"], }, js.configs.recommended, { diff --git a/cli/src/adapters/foundryAdapter.ts b/cli/src/adapters/foundryAdapter.ts index 184ecb1f..2e606897 100644 --- a/cli/src/adapters/foundryAdapter.ts +++ b/cli/src/adapters/foundryAdapter.ts @@ -50,6 +50,14 @@ const adapter: IFrameworkAdapter = { return path.join(projectRoot, "test"); }, + getArtifactDir(projectRoot: string): string { + return path.join(projectRoot, "out"); + }, + + async compile(projectRoot: string): Promise { + await runCommand("forge", ["build"], { cwd: projectRoot }); + }, + async resolveSoliditySourcePath(ctx: ComposeContext, sourcePath: string): Promise { return resolveCatalogSourceForRead(sourcePath); }, diff --git a/cli/src/adapters/hardhatAdapter.ts b/cli/src/adapters/hardhatAdapter.ts index bab706bd..4dc49a28 100644 --- a/cli/src/adapters/hardhatAdapter.ts +++ b/cli/src/adapters/hardhatAdapter.ts @@ -22,6 +22,14 @@ const adapter: IFrameworkAdapter = { return path.join(projectRoot, "test"); }, + getArtifactDir(projectRoot: string): string { + return path.join(projectRoot, "artifacts"); + }, + + async compile(projectRoot: string): Promise { + await runCommand("npx", ["hardhat", "compile"], { cwd: projectRoot }); + }, + async resolveSoliditySourcePath(ctx: ComposeContext, sourcePath: string): Promise { return resolveCatalogSourceForRead(sourcePath); }, diff --git a/cli/src/adapters/interface/IFrameworkAdapter.ts b/cli/src/adapters/interface/IFrameworkAdapter.ts index f6b44a04..2a4c49bd 100644 --- a/cli/src/adapters/interface/IFrameworkAdapter.ts +++ b/cli/src/adapters/interface/IFrameworkAdapter.ts @@ -18,6 +18,12 @@ export interface IFrameworkAdapter { /** Resolve the framework's test root inside the generated project. */ getTestRoot(projectRoot: string): string; + /** Resolve the framework's artifact output directory inside the generated project. */ + getArtifactDir(projectRoot: string): string; + + /** Compile the project using the framework's build tool. */ + compile(projectRoot: string): Promise; + /** * Resolve a catalog Solidity path to a readable local file. * diff --git a/cli/src/comander.ts b/cli/src/comander.ts index 8c448436..c536b45b 100644 --- a/cli/src/comander.ts +++ b/cli/src/comander.ts @@ -44,6 +44,10 @@ export function buildProgram(): Command { .command("catalog") .description("List all available bases in the Compose Catalog") + program + .command("build") + .description("Compile the project if artifacts are stale or missing") + return program; } diff --git a/cli/src/modules/compile/module.ts b/cli/src/modules/compile/module.ts new file mode 100644 index 00000000..6f6d7017 --- /dev/null +++ b/cli/src/modules/compile/module.ts @@ -0,0 +1,37 @@ +import fs from "node:fs"; +import { IFrameworkAdapter } from "../../adapters/interface/IFrameworkAdapter"; +import { getNewestSourceMtime, getOldestArtifactMtime } from "./utils"; + +export const CompileModule = { + areArtifactsStale(projectRoot: string, adapter: IFrameworkAdapter): boolean { + const artifactDir = adapter.getArtifactDir(projectRoot); + + if (!fs.existsSync(artifactDir)) { + return true; + } + + const sourceDir = adapter.getContractSourceRoot(projectRoot); + const newestSource = getNewestSourceMtime(sourceDir); + + if (newestSource === null) { + return false; + } + + const oldestArtifact = getOldestArtifactMtime(artifactDir); + + if (oldestArtifact === null) { + return true; + } + + return newestSource > oldestArtifact; + }, + + async compileIfNeeded(projectRoot: string, adapter: IFrameworkAdapter): Promise { + if (!this.areArtifactsStale(projectRoot, adapter)) { + console.log("No file change") + return; + } + + await adapter.compile(projectRoot); + } +} diff --git a/cli/src/modules/compile/utils.ts b/cli/src/modules/compile/utils.ts new file mode 100644 index 00000000..a1b7d5e3 --- /dev/null +++ b/cli/src/modules/compile/utils.ts @@ -0,0 +1,46 @@ +import fs from "node:fs"; +import path from "node:path"; + +export function getNewestSourceMtime(sourceDir: string): number | null { + if (!fs.existsSync(sourceDir)) return null; + + let newest = 0; + const entries = fs.readdirSync(sourceDir, { recursive: true }); + + for (const entry of entries) { + const fullPath = path.join(sourceDir, String(entry)); + if (!fullPath.endsWith(".sol")) continue; + + try { + const stat = fs.statSync(fullPath); + if (stat.isFile() && stat.mtimeMs > newest) { + newest = stat.mtimeMs; + } + } catch { + // skip inaccessible files + } + } + + return newest > 0 ? newest : null; +} + +export function getOldestArtifactMtime(artifactDir: string): number | null { + if (!fs.existsSync(artifactDir)) return null; + + let oldest = Infinity; + const entries = fs.readdirSync(artifactDir, { recursive: true }); + + for (const entry of entries) { + const fullPath = path.join(artifactDir, String(entry)); + try { + const stat = fs.statSync(fullPath); + if (stat.isFile() && stat.mtimeMs < oldest) { + oldest = stat.mtimeMs; + } + } catch { + // skip inaccessible files + } + } + + return oldest < Infinity ? oldest : null; +} diff --git a/cli/src/modules/framework/module.ts b/cli/src/modules/framework/module.ts new file mode 100644 index 00000000..70d5530c --- /dev/null +++ b/cli/src/modules/framework/module.ts @@ -0,0 +1,25 @@ +import fs from "node:fs"; +import path from "node:path"; + +export type Framework = "foundry" | "hardhat"; + +const HARDHAT_CONFIG_FILES = [ + "hardhat.config.js", + "hardhat.config.ts", + "hardhat.config.cjs", + "hardhat.config.mjs", +]; + +export const FrameworkModule = { + detect(projectRoot: string): Framework | null { + if (fs.existsSync(path.join(projectRoot, "foundry.toml"))) { + return "foundry"; + } + + if (HARDHAT_CONFIG_FILES.some((f) => fs.existsSync(path.join(projectRoot, f)))) { + return "hardhat"; + } + + return null; + } +} diff --git a/cli/src/modules/pipelineBuilder/module.ts b/cli/src/modules/pipelineBuilder/module.ts index f98d4cc2..606282d9 100644 --- a/cli/src/modules/pipelineBuilder/module.ts +++ b/cli/src/modules/pipelineBuilder/module.ts @@ -2,6 +2,7 @@ import { ComposeContext } from "../../context/types"; import { InitPipeline } from "../../pipelines/initPipeline"; import { InfoPipeline } from "../../pipelines/infoPipeline"; import { CatalogPipeline } from "../../pipelines/catalogPipeline"; +import { BuildPipeline } from "../../pipelines/buildPipeline"; /** * Pipeline builder module that routes CLI commands to their corresponding pipelines. @@ -51,6 +52,13 @@ export const PipelineBuilderModule = { error: null, }; return CatalogPipeline.execute(ctx); + case "build": + ctx.state.commandSelected = { + success: true, + result: { command: ctx.param.command }, + error: null, + }; + return BuildPipeline.execute(ctx); default: ctx.state.commandRouting = { success: false, diff --git a/cli/src/pipelines/buildPipeline.ts b/cli/src/pipelines/buildPipeline.ts new file mode 100644 index 00000000..dd55a9de --- /dev/null +++ b/cli/src/pipelines/buildPipeline.ts @@ -0,0 +1,34 @@ +import { ComposeContext } from "../context/types"; +import { CompileModule } from "../modules/compile/module"; +import { FrameworkModule } from "../modules/framework/module"; +import { DependencyKey } from "../resolver/dependencyKey"; +import { DependencyResolver } from "../resolver/dependencyResolver"; +import { IFrameworkAdapter } from "../adapters/interface/IFrameworkAdapter"; + +export const BuildPipeline = { + async execute(ctx: ComposeContext): Promise { + const projectRoot = String(ctx.param.projectRoot ?? process.cwd()); + + const framework = FrameworkModule.detect(projectRoot); + + if (!framework) { + throw new Error( + `No supported framework detected in ${projectRoot}. ` + + `Expected foundry.toml or hardhat.config.*`, + ); + } + + const deps = await DependencyResolver.resolve([ + { key: framework as DependencyKey }, + ]); + + const adapter = deps[framework as DependencyKey] as IFrameworkAdapter | undefined; + if (!adapter) { + throw new Error(`${framework} adapter was not resolved.`); + } + + await CompileModule.compileIfNeeded(projectRoot, adapter); + + return ctx; + }, +}; diff --git a/cli/src/utils/exec.ts b/cli/src/utils/exec.ts index ab4ed5ac..1855f3d7 100644 --- a/cli/src/utils/exec.ts +++ b/cli/src/utils/exec.ts @@ -51,6 +51,39 @@ export function runCommand(command: string, args: string[], options?: { cwd?: st * @param binaryName - Name of the binary to find (e.g., "node", "forge"). * @throws {Error} If the binary is not found in PATH. */ +export function runCommandCapture( + command: string, + args: string[], + options?: { cwd?: string }, +): Promise { + return new Promise((resolve, reject) => { + const resolvedCommand = resolveCommand(command); + const useShell = process.platform === "win32" && (command === "npm" || command === "npx"); + const child = spawn(resolvedCommand, args, { + stdio: ["inherit", "pipe", "pipe"], + shell: useShell, + ...options, + }); + + let stderr = ""; + child.stderr?.on("data", (chunk: Buffer) => { + stderr += chunk.toString(); + }); + + child.on("error", reject); + child.on("exit", (code) => { + if (code === 0) { + resolve(); + return; + } + if (stderr) { + process.stderr.write(stderr); + } + reject(new Error(`Compilation failed: ${command} ${args.join(" ")} (exit ${code})`)); + }); + }); +} + export async function isBinaryInPath(binaryName: string): Promise { const pathEnv = process.env.PATH || ""; const separator = process.platform === "win32" ? ";" : ":"; diff --git a/package-lock.json b/package-lock.json index dcd3706f..5f5c4a4b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ }, "cli": { "name": "@perfect-abstractions/compose-cli", - "version": "0.1.2", + "version": "0.1.3", "license": "MIT", "dependencies": { "@inquirer/checkbox": "5.2.1", @@ -355,7 +355,6 @@ "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.55.1.tgz", "integrity": "sha512-GAqHl9zERhC3bbBfubwUu07G3UXO06gORvOcsiTBZB3et0s3auNUbHlYdYNp4VKa3sUZqH5AcD3OKzU/KDGXjQ==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.55.1", "@algolia/requester-browser-xhr": "5.55.1", @@ -500,7 +499,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.7", @@ -2562,7 +2560,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -2585,7 +2582,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" } @@ -2695,7 +2691,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -3117,7 +3112,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -3983,7 +3977,6 @@ "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.10.1.tgz", "integrity": "sha512-3pf2fXXw0eVk8WnC3T4LIigRDupcpvngpKo9Vy7mYyBhuddc0klDUuZAIfzMoK6z05pdlk6EFC/vBSX43+1O5w==", "license": "MIT", - "peer": true, "dependencies": { "@docusaurus/babel": "3.10.1", "@docusaurus/bundler": "3.10.1", @@ -4316,7 +4309,6 @@ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.10.1.tgz", "integrity": "sha512-2jRVrtzjf8LClGTHQlwlwuD3wQXRx3WEoF7XUarJ8Ou+0onV+SLtejsyfY9JLpfUh9hPhXM4pbBGkyAY4Bi3HQ==", "license": "MIT", - "peer": true, "dependencies": { "@docusaurus/core": "3.10.1", "@docusaurus/logger": "3.10.1", @@ -6131,7 +6123,6 @@ "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", "license": "MIT", - "peer": true, "dependencies": { "@types/mdx": "^2.0.0" }, @@ -6977,7 +6968,6 @@ "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", @@ -7082,7 +7072,6 @@ "integrity": "sha512-1CuKjFkPxIgGdeHVuNbkxmBxkcbdc08u0aiI43pFq6yY1tTVKmXT9hFEooyyKs/sJ3xf1GPHyEwTtk9Xl8dvQw==", "hasInstallScript": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.27" @@ -8026,7 +8015,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.18.0" } @@ -8054,7 +8042,6 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -8235,7 +8222,6 @@ "integrity": "sha512-KA0OshtlcCCXmbfqyZkM5pV3/WNraJf7DkJRLpyrmwPtud57H5BDX7C3k0LPSPxpprfRL+cJDGabF10mvNCoCw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.64.0", "@typescript-eslint/types": "8.64.0", @@ -8710,7 +8696,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -8778,7 +8763,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -8824,7 +8808,6 @@ "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.55.1.tgz", "integrity": "sha512-FyaFnnsbVPtevQwqSj/SdxE3jAsSsY0BEH8IVLf9rXxEBdAhAmT6VKCVSMWoaPIHVN1Eufh/1w8q6k8URpIkWw==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/abtesting": "1.21.1", "@algolia/client-abtesting": "5.55.1", @@ -9447,7 +9430,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.10.38", "caniuse-lite": "^1.0.30001799", @@ -10667,7 +10649,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -10991,15 +10972,13 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cytoscape": { "version": "3.34.0", "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.34.0.tgz", "integrity": "sha512-62rNSrioXw93uliKFBwjukeQyeWwH2PqDrTac31r2P6464u3AUvTk0xS4LVvT251g7IgkFunrI48ZEZGjywSOg==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10" } @@ -11421,7 +11400,6 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", - "peer": true, "engines": { "node": ">=12" } @@ -12232,7 +12210,6 @@ "integrity": "sha512-GVTD7s1vdIl6UYvAfriOPeY1Df8LIZjfofLvHwde+erDHGGuHyuM6xoxRxmHiebhYuD2p1vN4wWh0XzPARSGDQ==", "dev": true, "license": "MIT", - "peer": true, "workspaces": [ "packages/*" ], @@ -13070,7 +13047,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -14803,7 +14779,6 @@ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "license": "MIT", - "peer": true, "bin": { "jiti": "bin/jiti.js" } @@ -18319,7 +18294,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -19199,7 +19173,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", @@ -20103,7 +20076,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -21040,7 +21012,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -21050,7 +21021,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -21106,7 +21076,6 @@ "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", "license": "MIT", - "peer": true, "dependencies": { "@types/react": "*" }, @@ -21135,7 +21104,6 @@ "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.12.13", "history": "^4.9.0", @@ -23168,7 +23136,6 @@ "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -23287,8 +23254,7 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD", - "peer": true + "license": "0BSD" }, "node_modules/tsyringe": { "version": "4.10.0", @@ -23394,7 +23360,6 @@ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "devOptional": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -23771,7 +23736,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -24033,7 +23997,6 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.108.4.tgz", "integrity": "sha512-yur8LyJoeiWh47dErD+Ok7vlbmDsJ3UbbRPAoxbGJ54WpE2y5yVo5G/inUzujnYgw3tPmBRdn+G7PoxXaYC33w==", "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "^1.0.8", "@types/json-schema": "^7.0.15", @@ -24497,7 +24460,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.11.tgz", "integrity": "sha512-zS54Oen9bITtp7kp2XM3AydrCIq1D+HwJOuH+c+e4LfpL/lotP5osijd+UoMnxwAam1GN8R4KtLAyIrIcBNpiA==", "license": "MIT", - "peer": true, "engines": { "node": ">=8.3.0" },