diff --git a/e2e/gradle/.gitattributes b/.gitattributes similarity index 100% rename from e2e/gradle/.gitattributes rename to .gitattributes diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 431ee92031..6147ff77a8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,6 +65,12 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 21 + - name: Check Documentation run: pnpm nx documentation timeout-minutes: 20 diff --git a/.gitignore b/.gitignore index 43b39b1cf3..afff128d8d 100644 --- a/.gitignore +++ b/.gitignore @@ -67,5 +67,8 @@ target vite.config.*.timestamp* +storybook-static -storybook-static \ No newline at end of file +# Ignore Gradle project-specific cache directory +.gradle +.kotlin diff --git a/.nx/workflows/agents.yaml b/.nx/workflows/agents.yaml index 9d5abe7b71..95c493579a 100644 --- a/.nx/workflows/agents.yaml +++ b/.nx/workflows/agents.yaml @@ -64,6 +64,13 @@ launch-templates: - name: Load Cargo Env script: echo "PATH=$HOME/.cargo/bin:$PATH" >> $NX_CLOUD_ENV + - name: Setup Java 21 + script: | + sudo apt update + sudo apt install -y openjdk-21-jdk + sudo update-alternatives --set java /usr/lib/jvm/java-21-openjdk-amd64/bin/java + java -version + linux-extra-large: resource-class: 'docker_linux_amd64/extra_large' image: 'ubuntu22.04-node20.11-v10' @@ -128,3 +135,10 @@ launch-templates: - name: Load Cargo Env script: echo "PATH=$HOME/.cargo/bin:$PATH" >> $NX_CLOUD_ENV + + - name: Setup Java 21 + script: | + sudo apt update + sudo apt install -y openjdk-21-jdk + sudo update-alternatives --set java /usr/lib/jvm/java-21-openjdk-amd64/bin/java + java -version diff --git a/.prettierignore b/.prettierignore index ddb7730ed7..0f3bb1a9f9 100644 --- a/.prettierignore +++ b/.prettierignore @@ -13,6 +13,7 @@ packages/express/src/schematics/**/files/**/*.json packages/nest/src/schematics/**/files/**/*.json packages/react/src/schematics/**/files/**/*.json packages/jest/src/schematics/**/files/**/*.json +packages/gradle/project-graph/build/**/*.* packages/nx/src/plugins/js/lock-file/__fixtures__/**/*.* packages/**/schematics/**/files/**/*.html packages/**/generators/**/files/**/*.html diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000000..dbb3f11d9a --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,6 @@ +plugins { + id("dev.nx.gradle.project-graph") version("0.0.2") + id("com.ncorti.ktfmt.gradle") version("+") +} + +group = "dev.nx" \ No newline at end of file diff --git a/docs/generated/manifests/nx-api.json b/docs/generated/manifests/nx-api.json index b168167bae..ea3355e8b9 100644 --- a/docs/generated/manifests/nx-api.json +++ b/docs/generated/manifests/nx-api.json @@ -2325,6 +2325,16 @@ } }, "migrations": { + "/nx-api/gradle/migrations/change-plugin-to-v1": { + "description": "Change @nx/gradle plugin to version 1", + "file": "generated/packages/gradle/migrations/change-plugin-to-v1.json", + "hidden": false, + "name": "change-plugin-to-v1", + "version": "21.0.0-beta.5", + "originalFilePath": "/packages/gradle", + "path": "/nx-api/gradle/migrations/change-plugin-to-v1", + "type": "migration" + }, "/nx-api/gradle/migrations/add-include-subprojects-tasks": { "description": "Add includeSubprojectsTasks to build.gradle file", "file": "generated/packages/gradle/migrations/add-include-subprojects-tasks.json", diff --git a/docs/generated/packages-metadata.json b/docs/generated/packages-metadata.json index 2dcfbde7cd..c6743548cd 100644 --- a/docs/generated/packages-metadata.json +++ b/docs/generated/packages-metadata.json @@ -2309,6 +2309,16 @@ } ], "migrations": [ + { + "description": "Change @nx/gradle plugin to version 1", + "file": "generated/packages/gradle/migrations/change-plugin-to-v1.json", + "hidden": false, + "name": "change-plugin-to-v1", + "version": "21.0.0-beta.5", + "originalFilePath": "/packages/gradle", + "path": "gradle/migrations/change-plugin-to-v1", + "type": "migration" + }, { "description": "Add includeSubprojectsTasks to build.gradle file", "file": "generated/packages/gradle/migrations/add-include-subprojects-tasks.json", diff --git a/docs/generated/packages/gradle/migrations/add-include-subprojects-tasks.json b/docs/generated/packages/gradle/migrations/add-include-subprojects-tasks.json index b9aef994f0..b9acf7cfe7 100644 --- a/docs/generated/packages/gradle/migrations/add-include-subprojects-tasks.json +++ b/docs/generated/packages/gradle/migrations/add-include-subprojects-tasks.json @@ -10,5 +10,5 @@ "path": "/packages/gradle", "schema": null, "type": "migration", - "examplesFile": "#### Add includeSubprojectsTasks to build.gradle File\n\nAdd includeSubprojectsTasks to build.gradle file\n\n#### Sample Code Changes\n\nUpdate import paths for `withModuleFederation` and `withModuleFederationForSSR`.\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"nx.json\" %}\n{\n \"plugins\": [\"@nx/gradle\"]\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% highlightLines=[5] fileName=\"nx.json\" %}\n{\n \"plugins\": [\n {\n \"options\": {\n \"includeSubprojectsTasks\": true\n },\n \"plugin\": \"@nx/gradle\"\n }\n ]\n}\n```\n\n{% /tab %}\n{% /tabs %}\n" + "examplesFile": "#### Add includeSubprojectsTasks to @nx/gradle Plugin Options\n\nAdd includeSubprojectsTasks to @nx/gradle plugin options in nx.json file\n\n#### Sample Code Changes\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"nx.json\" %}\n{\n \"plugins\": [\"@nx/gradle\"]\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% highlightLines=[5] fileName=\"nx.json\" %}\n{\n \"plugins\": [\n {\n \"options\": {\n \"includeSubprojectsTasks\": true\n },\n \"plugin\": \"@nx/gradle\"\n }\n ]\n}\n```\n\n{% /tab %}\n{% /tabs %}\n" } diff --git a/docs/generated/packages/gradle/migrations/change-plugin-to-v1.json b/docs/generated/packages/gradle/migrations/change-plugin-to-v1.json new file mode 100644 index 0000000000..c2fa18b222 --- /dev/null +++ b/docs/generated/packages/gradle/migrations/change-plugin-to-v1.json @@ -0,0 +1,14 @@ +{ + "name": "change-plugin-to-v1", + "version": "21.0.0-beta.5", + "cli": "nx", + "description": "Change @nx/gradle plugin to version 1", + "factory": "./src/migrations/21-0-0/change-plugin-to-v1", + "implementation": "/packages/gradle/src/migrations/21-0-0/change-plugin-to-v1.ts", + "aliases": [], + "hidden": false, + "path": "/packages/gradle", + "schema": null, + "type": "migration", + "examplesFile": "#### Change @nx/gradle plugin to @nx/gradle/plugin-v1\n\nChange @nx/gradle plugin to version 1 in nx.json\n\n#### Sample Code Changes\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"nx.json\" %}\n{\n \"plugins\": [\"@nx/gradle\"]\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% highlightLines=[5] fileName=\"nx.json\" %}\n{\n \"plugins\": [\"@nx/gradle/plugin-v1\"]\n}\n```\n\n{% /tab %}\n{% /tabs %}\n" +} diff --git a/docs/shared/tutorials/gradle.md b/docs/shared/tutorials/gradle.md index db6c275aef..a94e0619f8 100644 --- a/docs/shared/tutorials/gradle.md +++ b/docs/shared/tutorials/gradle.md @@ -375,10 +375,10 @@ jobs: # Uncomment this line to enable task distribution # - run: npx nx-cloud start-ci-run --distribute-on="3 linux-medium-jvm" --stop-agents-after="build" - - name: Set up JDK 17 for x64 + - name: Set up JDK 21 for x64 uses: actions/setup-java@v4 with: - java-version: '17' + java-version: '21' distribution: 'temurin' architecture: x64 diff --git a/e2e/gradle/gradle/libs.versions.toml b/e2e/gradle/gradle/libs.versions.toml deleted file mode 100644 index 4ac3234a6a..0000000000 --- a/e2e/gradle/gradle/libs.versions.toml +++ /dev/null @@ -1,2 +0,0 @@ -# This file was generated by the Gradle 'init' task. -# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format diff --git a/e2e/gradle/gradle/wrapper/gradle-wrapper.jar b/e2e/gradle/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index e6441136f3..0000000000 Binary files a/e2e/gradle/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/e2e/gradle/src/gradle-import.test.ts b/e2e/gradle/src/gradle-import.test.ts index 67cbe04d78..198ed19e62 100644 --- a/e2e/gradle/src/gradle-import.test.ts +++ b/e2e/gradle/src/gradle-import.test.ts @@ -17,10 +17,9 @@ import { createGradleProject } from './utils/create-gradle-project'; import { createFileSync } from 'fs-extra'; describe('Nx Import Gradle', () => { - let proj: string; const tempImportE2ERoot = join(e2eCwd, 'nx-import'); beforeAll(() => { - proj = newProject({ + newProject({ packages: ['@nx/js'], }); @@ -66,30 +65,7 @@ describe('Nx Import Gradle', () => { 'gradleProjectKotlin', 'kotlin-' ); - // Add project.json files to the gradle project to avoid duplicate project names - createFileSync(join(tempGraldeProjectPath, 'project.json')); - writeFileSync( - join(tempGraldeProjectPath, 'project.json'), - `{"name": "${tempGradleProjectName}"}` - ); - - execSync(`git init`, { - cwd: tempGraldeProjectPath, - }); - execSync(`git add .`, { - cwd: tempGraldeProjectPath, - }); - execSync(`git commit -am "initial commit"`, { - cwd: tempGraldeProjectPath, - }); - - try { - execSync(`git checkout -b main`, { - cwd: tempGraldeProjectPath, - }); - } catch { - // This fails if git is already configured to have `main` branch, but that's OK - } + setupGradleProjectGit(tempGraldeProjectPath, tempGradleProjectName); const remote = tempGraldeProjectPath; const ref = 'main'; @@ -140,30 +116,7 @@ describe('Nx Import Gradle', () => { 'gradleProjectGroovy', 'groovy-' ); - // Add project.json files to the gradle project to avoid duplicate project names - createFileSync(join(tempGraldeProjectPath, 'project.json')); - writeFileSync( - join(tempGraldeProjectPath, 'project.json'), - `{"name": "${tempGradleProjectName}"}` - ); - - execSync(`git init`, { - cwd: tempGraldeProjectPath, - }); - execSync(`git add .`, { - cwd: tempGraldeProjectPath, - }); - execSync(`git commit -am "initial commit"`, { - cwd: tempGraldeProjectPath, - }); - - try { - execSync(`git checkout -b main`, { - cwd: tempGraldeProjectPath, - }); - } catch { - // This fails if git is already configured to have `main` branch, but that's OK - } + setupGradleProjectGit(tempGraldeProjectPath, tempGradleProjectName); const remote = tempGraldeProjectPath; const ref = 'main'; @@ -199,3 +152,40 @@ describe('Nx Import Gradle', () => { runCommand(`git commit -am 'import groovy project'`); }); }); + +function setupGradleProjectGit( + tempGraldeProjectPath: string, + tempGradleProjectName: string +) { + // Add project.json files to the gradle project to avoid duplicate project names + createFileSync(join(tempGraldeProjectPath, 'project.json')); + writeFileSync( + join(tempGraldeProjectPath, 'project.json'), + `{"name": "${tempGradleProjectName}"}` + ); + + execSync(`./gradlew --stop`, { + cwd: tempGraldeProjectPath, + }); + execSync(`./gradlew clean`, { + cwd: tempGraldeProjectPath, + }); + + execSync(`git init`, { + cwd: tempGraldeProjectPath, + }); + execSync(`git add .`, { + cwd: tempGraldeProjectPath, + }); + execSync(`git commit -am "initial commit"`, { + cwd: tempGraldeProjectPath, + }); + + try { + execSync(`git checkout -b main`, { + cwd: tempGraldeProjectPath, + }); + } catch { + // This fails if git is already configured to have `main` branch, but that's OK + } +} diff --git a/e2e/gradle/src/gradle-plugin-v1.test.ts b/e2e/gradle/src/gradle-plugin-v1.test.ts new file mode 100644 index 0000000000..e17a34074e --- /dev/null +++ b/e2e/gradle/src/gradle-plugin-v1.test.ts @@ -0,0 +1,177 @@ +import { + checkFilesExist, + cleanupProject, + createFile, + fileExists, + newProject, + readFile, + runCLI, + uniq, + updateFile, + updateJson, +} from '@nx/e2e/utils'; +import { basename, dirname, join } from 'path'; + +import { createGradleProject } from './utils/create-gradle-project'; + +describe('Gradle Plugin V1', () => { + describe.each([{ type: 'kotlin' }, { type: 'groovy' }])( + '$type', + ({ type }: { type: 'kotlin' | 'groovy' }) => { + let gradleProjectName = uniq('my-gradle-project'); + beforeAll(() => { + newProject(); + createGradleProject(gradleProjectName, type); + runCLI(`add @nx/gradle`); + updateJson('nx.json', (json) => { + json.plugins.find((p) => p.plugin === '@nx/gradle').plugin = + '@nx/gradle/plugin-v1'; + return json; + }); + addProjectReportToBuildGradle( + `settings.gradle${type === 'kotlin' ? '.kts' : ''}` + ); + }); + afterAll(() => cleanupProject()); + + it('should build', () => { + const projects = runCLI(`show projects`); + expect(projects).toContain('app'); + expect(projects).toContain('list'); + expect(projects).toContain('utilities'); + expect(projects).toContain(gradleProjectName); + + const buildOutput = runCLI('build app', { verbose: true }); + expect(buildOutput).toContain('nx run list:build'); + expect(buildOutput).toContain(':list:classes'); + expect(buildOutput).toContain('nx run utilities:build'); + expect(buildOutput).toContain(':utilities:classes'); + + checkFilesExist( + `app/build/libs/app.jar`, + `list/build/libs/list.jar`, + `utilities/build/libs/utilities.jar` + ); + }); + + it('should track dependencies for new app', () => { + if (type === 'groovy') { + createFile( + `app2/build.gradle`, + `plugins { + id 'buildlogic.groovy-application-conventions' +} + +dependencies { + implementation project(':app') +}` + ); + } else { + createFile( + `app2/build.gradle.kts`, + `plugins { + id("buildlogic.kotlin-application-conventions") +} + +dependencies { + implementation(project(":app")) +}` + ); + updateFile(`app/build.gradle.kts`, (content) => { + content += `\r\ntasks.register("task1"){ + println("REGISTER TASK1: This is executed during the configuration phase") + }`; + return content; + }); + } + updateFile( + `settings.gradle${type === 'kotlin' ? '.kts' : ''}`, + (content) => { + content += `\r\ninclude("app2")`; + return content; + } + ); + + let buildOutput = runCLI('build app2', { verbose: true }); + // app2 depends on app + expect(buildOutput).toContain('nx run app:build'); + expect(buildOutput).toContain(':app:classes'); + expect(buildOutput).toContain('nx run list:build'); + expect(buildOutput).toContain(':list:classes'); + expect(buildOutput).toContain('nx run utilities:build'); + expect(buildOutput).toContain(':utilities:classes'); + + checkFilesExist( + `app2/build/libs/app2.jar`, + `app/build/libs/app.jar`, + `list/build/libs/list.jar`, + `utilities/build/libs/utilities.jar` + ); + }); + + it('should run atomized test target', () => { + updateJson('nx.json', (json) => { + json.plugins.find((p) => p.plugin === '@nx/gradle/plugin-v1').options[ + 'ciTargetName' + ] = 'test-ci'; + return json; + }); + + expect(() => { + runCLI('run app:test-ci--MessageUtilsTest', { verbose: true }); + runCLI('run list:test-ci--LinkedListTest', { verbose: true }); + }).not.toThrow(); + }); + } + ); +}); + +function addProjectReportToBuildGradle(settingsGradleFile: string) { + const filename = basename(settingsGradleFile); + let gradleFilePath = 'build.gradle'; + if (filename.endsWith('.kts')) { + gradleFilePath = 'build.gradle.kts'; + } + gradleFilePath = join(dirname(settingsGradleFile), gradleFilePath); + let buildGradleContent = ''; + if (!fileExists(gradleFilePath)) { + createFile(gradleFilePath, buildGradleContent); // create a build.gradle file near settings.gradle file if it does not exist + } else { + buildGradleContent = readFile(gradleFilePath).toString(); + } + + buildGradleContent += `\n\rallprojects { + apply { + plugin("project-report") + } +}`; + + if (gradleFilePath.endsWith('.kts')) { + buildGradleContent += `\n\rtasks.register("projectReportAll") { + // All project reports of subprojects + allprojects.forEach { + dependsOn(it.tasks.get("projectReport")) + } + + // All projectReportAll of included builds + gradle.includedBuilds.forEach { + dependsOn(it.task(":projectReportAll")) + } +}`; + } else { + buildGradleContent += `\n\rtasks.register("projectReportAll") { + // All project reports of subprojects + allprojects.forEach { + dependsOn(it.tasks.getAt("projectReport")) + } + + // All projectReportAll of included builds + gradle.includedBuilds.forEach { + dependsOn(it.task(":projectReportAll")) + } + }`; + } + if (buildGradleContent) { + updateFile(gradleFilePath, buildGradleContent); + } +} diff --git a/e2e/gradle/src/gradle.test.ts b/e2e/gradle/src/gradle.test.ts index 856f77b43c..44814f3779 100644 --- a/e2e/gradle/src/gradle.test.ts +++ b/e2e/gradle/src/gradle.test.ts @@ -6,6 +6,7 @@ import { runCLI, uniq, updateFile, + updateJson, } from '@nx/e2e/utils'; import { createGradleProject } from './utils/create-gradle-project'; @@ -30,9 +31,9 @@ describe('Gradle', () => { expect(projects).toContain(gradleProjectName); const buildOutput = runCLI('build app', { verbose: true }); - expect(buildOutput).toContain('nx run list:build'); + expect(buildOutput).toContain('nx run list:'); expect(buildOutput).toContain(':list:classes'); - expect(buildOutput).toContain('nx run utilities:build'); + expect(buildOutput).toContain('nx run utilities:'); expect(buildOutput).toContain(':utilities:classes'); checkFilesExist( @@ -82,8 +83,28 @@ dependencies { let buildOutput = runCLI('build app2', { verbose: true }); // app2 depends on app - expect(buildOutput).toContain('nx run app:build'); + expect(buildOutput).toContain('nx run app:'); expect(buildOutput).toContain(':app:classes'); + expect(buildOutput).toContain('nx run list:'); + expect(buildOutput).toContain(':list:classes'); + expect(buildOutput).toContain('nx run utilities:'); + expect(buildOutput).toContain(':utilities:classes'); + + checkFilesExist(`app2/build/libs/app2.jar`); + }); + + it('should run atomized test target', () => { + updateJson('nx.json', (json) => { + json.plugins.find((p) => p.plugin === '@nx/gradle').options[ + 'ciTargetName' + ] = 'test-ci'; + return json; + }); + + expect(() => { + runCLI('run app:test-ci--MessageUtilsTest', { verbose: true }); + runCLI('run list:test-ci--LinkedListTest', { verbose: true }); + }).not.toThrow(); }); } ); diff --git a/e2e/gradle/src/utils/create-gradle-project.ts b/e2e/gradle/src/utils/create-gradle-project.ts index 1e4755082e..85292a04a1 100644 --- a/e2e/gradle/src/utils/create-gradle-project.ts +++ b/e2e/gradle/src/utils/create-gradle-project.ts @@ -5,6 +5,7 @@ import { tmpProjPath, } from '@nx/e2e/utils'; import { execSync } from 'child_process'; +import { readFileSync } from 'fs'; import { createFileSync, writeFileSync } from 'fs-extra'; import { join, resolve } from 'path'; @@ -15,14 +16,10 @@ export function createGradleProject( packageName: string = 'gradleProject', addProjectJsonNamePrefix: string = '' ) { - e2eConsoleLogger( - `Using java version: ${execSync('java -version')} ${execSync( - 'echo $JAVA_HOME' - )}` - ); + e2eConsoleLogger(`Using java version: ${execSync('java -version')}`); const gradleCommand = isWindows() - ? resolve(`${__dirname}/../../gradlew.bat`) - : resolve(`${__dirname}/../../gradlew`); + ? resolve(`${__dirname}/../../../../gradlew.bat`) + : resolve(`${__dirname}/../../../../gradlew`); e2eConsoleLogger( 'Using gradle version: ' + execSync(`${gradleCommand} --version`, { @@ -36,13 +33,26 @@ export function createGradleProject( ); e2eConsoleLogger( runCommand( - `${gradleCommand} init --type ${type}-application --dsl ${type} --project-name ${projectName} --package ${packageName} --no-incubating --split-project`, + `${gradleCommand} init --type ${type}-application --dsl ${type} --project-name ${projectName} --package ${packageName} --no-incubating --split-project --overwrite`, { cwd, } ) ); + try { + e2eConsoleLogger( + runCommand(`${gradleCommand} --stop`, { + cwd, + }) + ); + e2eConsoleLogger( + runCommand(`${gradleCommand} clean`, { + cwd, + }) + ); + } catch (e) {} + if (addProjectJsonNamePrefix) { createFileSync(join(cwd, 'app/project.json')); writeFileSync( @@ -60,4 +70,35 @@ export function createGradleProject( `{"name": "${addProjectJsonNamePrefix}utilities"}` ); } + + addLocalPluginManagement( + join(cwd, `settings.gradle${type === 'kotlin' ? '.kts' : ''}`) + ); + addLocalPluginManagement( + join(cwd, `buildSrc/settings.gradle${type === 'kotlin' ? '.kts' : ''}`) + ); + + e2eConsoleLogger( + execSync( + `${gradleCommand} :project-graph:publishToMavenLocal -x :project-graph:signNxProjectGraphPluginPluginMarkerMavenPublication -x :project-graph:signPluginMavenPublication -x :project-graph:publishNxProjectGraphPluginPluginMarkerMavenPublicationToMavenLocal -x :project-graph:publishPluginMavenPublicationToMavenLocal`, + { + cwd: `${__dirname}/../../../..`, + } + ).toString() + ); +} + +function addLocalPluginManagement(filePath: string) { + let content = readFileSync(filePath).toString(); + content = + `pluginManagement { + repositories { + mavenLocal() + gradlePluginPortal() + mavenCentral() + // Add other repositories if needed + } +} +` + content; + writeFileSync(filePath, content); } diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000000..494717139a --- /dev/null +++ b/gradle.properties @@ -0,0 +1,8 @@ +# This file was generated by the Gradle 'init' task. +# https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties + +org.gradle.parallel=true +org.gradle.caching=true +# disable the configuration cache for this project https://docs.gradle.org/current/userguide/configuration_cache.html#config_cache:requirements:disallowed_types +# nxProjectGraph is not supported by the configuration cache +org.gradle.configuration-cache=false \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000000..3b788e62d4 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,11 @@ +# This file was generated by the Gradle 'init' task. +# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format + +[plugins] +jvm = { id = "org.jetbrains.kotlin.jvm", version = "1.9.20" } + +[versions] +kotlin-gradle-plugin = "2.0.21" + +[libraries] +kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin-gradle-plugin" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..9bbc975c74 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/e2e/gradle/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties similarity index 74% rename from e2e/gradle/gradle/wrapper/gradle-wrapper.properties rename to gradle/wrapper/gradle-wrapper.properties index a0777a32ce..37f853b1c8 100644 --- a/e2e/gradle/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip -validateDistributionUrl=false +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/e2e/gradle/gradlew b/gradlew similarity index 95% rename from e2e/gradle/gradlew rename to gradlew index 1aa94a4269..faf93008b7 100755 --- a/e2e/gradle/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -203,7 +205,7 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. diff --git a/e2e/gradle/gradlew.bat b/gradlew.bat similarity index 91% rename from e2e/gradle/gradlew.bat rename to gradlew.bat index 93e3f59f13..9d21a21834 100644 --- a/e2e/gradle/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -43,11 +45,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/package.json b/package.json index 732174f9ad..598f3e49e3 100644 --- a/package.json +++ b/package.json @@ -369,6 +369,7 @@ "core-js": "3.36.1", "enquirer": "~2.3.6", "fast-glob": "3.3.3", + "form-data": "^4.0.2", "framer-motion": "^11.3.0", "front-matter": "^4.0.2", "glob": "7.1.4", diff --git a/packages/gradle/.eslintrc.json b/packages/gradle/.eslintrc.json index 52b3d2c335..b6e9ee1523 100644 --- a/packages/gradle/.eslintrc.json +++ b/packages/gradle/.eslintrc.json @@ -27,7 +27,12 @@ } }, { - "files": ["./package.json"], + "files": [ + "./package.json", + "./generators.json", + "./executors.json", + "./migrations.json" + ], "parser": "jsonc-eslint-parser", "rules": { "@nx/nx-plugin-checks": "error" diff --git a/packages/gradle/executors.json b/packages/gradle/executors.json new file mode 100644 index 0000000000..3a64718e93 --- /dev/null +++ b/packages/gradle/executors.json @@ -0,0 +1,3 @@ +{ + "executors": {} +} diff --git a/packages/gradle/migrations.json b/packages/gradle/migrations.json index 1dc2c58227..5088bd5347 100644 --- a/packages/gradle/migrations.json +++ b/packages/gradle/migrations.json @@ -17,6 +17,12 @@ "cli": "nx", "description": "Add includeSubprojectsTasks to build.gradle file", "factory": "./src/migrations/20-2-0/add-include-subprojects-tasks" + }, + "change-plugin-to-v1": { + "version": "21.0.0-beta.5", + "cli": "nx", + "description": "Change @nx/gradle plugin to version 1", + "factory": "./src/migrations/21-0-0/change-plugin-to-v1" } }, "packageJsonUpdates": {} diff --git a/packages/gradle/package.json b/packages/gradle/package.json index 14f5ebf31c..3ea30bcc01 100644 --- a/packages/gradle/package.json +++ b/packages/gradle/package.json @@ -26,6 +26,7 @@ "generators": "./generators.json", "exports": { ".": "./index.js", + "./plugin-v1": "./plugin-v1.js", "./package.json": "./package.json", "./migrations.json": "./migrations.json", "./generators.json": "./generators.json" @@ -38,5 +39,6 @@ }, "publishConfig": { "access": "public" - } + }, + "executors": "./executors.json" } diff --git a/packages/gradle/plugin-v1.spec.ts b/packages/gradle/plugin-v1.spec.ts new file mode 100644 index 0000000000..c82b9123ea --- /dev/null +++ b/packages/gradle/plugin-v1.spec.ts @@ -0,0 +1,131 @@ +import { CreateNodesContext } from '@nx/devkit'; +import { TempFs } from '@nx/devkit/internal-testing-utils'; +import { createNodesV2 } from './plugin-v1'; +import { type GradleReport } from './src/plugin-v1/utils/get-gradle-report'; + +let gradleReport: GradleReport; +jest.mock('./src/plugin-v1/utils/get-gradle-report', () => { + return { + GRADLE_BUILD_FILES: new Set(['build.gradle', 'build.gradle.kts']), + populateGradleReport: jest.fn().mockImplementation(() => void 0), + getCurrentGradleReport: jest.fn().mockImplementation(() => gradleReport), + }; +}); + +describe('@nx/gradle/plugin-v1', () => { + let createNodesFunction = createNodesV2[1]; + let context: CreateNodesContext; + let tempFs: TempFs; + + beforeEach(async () => { + tempFs = new TempFs('gradle-plugin'); + gradleReport = { + gradleFileToGradleProjectMap: new Map([ + ['proj/build.gradle', 'proj'], + ]), + gradleProjectToDepsMap: new Map>(), + gradleFileToOutputDirsMap: new Map>([ + ['proj/build.gradle', new Map([['build', 'build']])], + ]), + gradleProjectToTasksMap: new Map>([ + ['proj', new Set(['test'])], + ]), + gradleProjectToTasksTypeMap: new Map>([ + ['proj', new Map([['test', 'Verification']])], + ]), + gradleProjectToProjectName: new Map([['proj', 'proj']]), + gradleProjectNameToProjectRootMap: new Map([ + ['proj', 'proj'], + ]), + gradleProjectToChildProjects: new Map(), + }; + context = { + nxJsonConfiguration: { + namedInputs: { + default: ['{projectRoot}/**/*'], + production: ['!{projectRoot}/**/*.spec.ts'], + }, + }, + workspaceRoot: tempFs.tempDir, + configFiles: [], + }; + tempFs.createFileSync('package.json', JSON.stringify({ name: 'repo' })); + tempFs.createFileSync( + 'my-app/project.json', + JSON.stringify({ name: 'my-app' }) + ); + }); + + afterEach(() => { + jest.resetModules(); + tempFs.cleanup(); + tempFs = null; + }); + + it('should create nodes', async () => { + tempFs.createFileSync('gradlew', ''); + + const nodes = await createNodesFunction( + ['gradlew', 'proj/build.gradle'], + undefined, + context + ); + + expect(nodes).toMatchInlineSnapshot(` + [ + [ + "proj/build.gradle", + { + "projects": { + "proj": { + "metadata": { + "targetGroups": { + "Verification": [ + "test", + ], + }, + "technologies": [ + "gradle", + ], + }, + "name": "proj", + "projectType": "application", + "targets": { + "test": { + "cache": true, + "command": "./gradlew proj:test", + "dependsOn": [ + "testClasses", + ], + "inputs": [ + "default", + "^production", + ], + "metadata": { + "help": { + "command": "./gradlew help --task proj:test", + "example": { + "options": { + "args": [ + "--rerun", + ], + }, + }, + }, + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": ".", + }, + }, + }, + }, + }, + }, + ], + ] + `); + }); +}); diff --git a/packages/gradle/plugin-v1.ts b/packages/gradle/plugin-v1.ts new file mode 100644 index 0000000000..35195059db --- /dev/null +++ b/packages/gradle/plugin-v1.ts @@ -0,0 +1,2 @@ +export { createDependencies } from './src/plugin-v1/dependencies'; +export { createNodes, createNodesV2 } from './src/plugin-v1/nodes'; diff --git a/packages/gradle/plugin.spec.ts b/packages/gradle/plugin.spec.ts index 4d9108e34f..5306d56eff 100644 --- a/packages/gradle/plugin.spec.ts +++ b/packages/gradle/plugin.spec.ts @@ -1,14 +1,17 @@ -import { CreateNodesContext } from '@nx/devkit'; +import { CreateNodesContext, readJsonFile } from '@nx/devkit'; import { TempFs } from '@nx/devkit/internal-testing-utils'; import { createNodesV2 } from './plugin'; -import { type GradleReport } from './src/utils/get-gradle-report'; +import { type ProjectGraphReport } from './src/plugin/utils/get-project-graph-from-gradle-plugin'; +import { join } from 'path'; -let gradleReport: GradleReport; -jest.mock('./src/utils/get-gradle-report', () => { +let gradleReport: ProjectGraphReport; +jest.mock('./src/plugin/utils/get-project-graph-from-gradle-plugin', () => { return { GRADLE_BUILD_FILES: new Set(['build.gradle', 'build.gradle.kts']), - populateGradleReport: jest.fn().mockImplementation(() => void 0), - getCurrentGradleReport: jest.fn().mockImplementation(() => gradleReport), + populateProjectGraph: jest.fn().mockImplementation(() => void 0), + getCurrentProjectGraphReport: jest + .fn() + .mockImplementation(() => gradleReport), }; }); @@ -19,26 +22,9 @@ describe('@nx/gradle/plugin', () => { beforeEach(async () => { tempFs = new TempFs('gradle-plugin'); - gradleReport = { - gradleFileToGradleProjectMap: new Map([ - ['proj/build.gradle', 'proj'], - ]), - buildFileToDepsMap: new Map>(), - gradleFileToOutputDirsMap: new Map>([ - ['proj/build.gradle', new Map([['build', 'build']])], - ]), - gradleProjectToTasksMap: new Map>([ - ['proj', new Set(['test'])], - ]), - gradleProjectToTasksTypeMap: new Map>([ - ['proj', new Map([['test', 'Verification']])], - ]), - gradleProjectToProjectName: new Map([['proj', 'proj']]), - gradleProjectNameToProjectRootMap: new Map([ - ['proj', 'proj'], - ]), - gradleProjectToChildProjects: new Map(), - }; + gradleReport = readJsonFile( + join(__dirname, 'src/plugin/utils/__mocks__/gradle_tutorial.json') + ); context = { nxJsonConfiguration: { namedInputs: { @@ -76,48 +62,33 @@ describe('@nx/gradle/plugin', () => { [ "proj/build.gradle", { + "externalNodes": {}, "projects": { "proj": { "metadata": { "targetGroups": { - "Verification": [ - "test", + "help": [ + "buildEnvironment", ], }, "technologies": [ "gradle", ], }, - "name": "proj", - "projectType": "application", + "name": "gradle-tutorial", + "root": "proj", "targets": { - "test": { + "buildEnvironment": { "cache": true, - "command": "./gradlew proj:test", - "dependsOn": [ - "testClasses", - ], - "inputs": [ - "default", - "^production", - ], + "command": "./gradlew :buildEnvironment", "metadata": { - "help": { - "command": "./gradlew help --task proj:test", - "example": { - "options": { - "args": [ - "--rerun", - ], - }, - }, - }, + "description": "Displays all buildscript dependencies declared in root project 'gradle-tutorial'.", "technologies": [ "gradle", ], }, "options": { - "cwd": ".", + "cwd": "proj", }, }, }, diff --git a/packages/gradle/plugin.ts b/packages/gradle/plugin.ts index c6345f3ebd..f1b3829f07 100644 --- a/packages/gradle/plugin.ts +++ b/packages/gradle/plugin.ts @@ -1,2 +1,2 @@ export { createDependencies } from './src/plugin/dependencies'; -export { createNodes, createNodesV2 } from './src/plugin/nodes'; +export { createNodesV2 } from './src/plugin/nodes'; diff --git a/packages/gradle/project-graph/.gitignore b/packages/gradle/project-graph/.gitignore new file mode 100644 index 0000000000..667ce03db0 --- /dev/null +++ b/packages/gradle/project-graph/.gitignore @@ -0,0 +1,3 @@ +# Ignore Gradle project-specific cache directory +bin +build \ No newline at end of file diff --git a/packages/gradle/project-graph/README.md b/packages/gradle/project-graph/README.md new file mode 100644 index 0000000000..2ffdde03fd --- /dev/null +++ b/packages/gradle/project-graph/README.md @@ -0,0 +1,56 @@ +# dev.nx.gradle.project-graph + +This gradle plugin contains + +## Installation + +Kotlin +build.gradle.kts + +``` +plugins { + id("dev.nx.gradle.project-graph") version("+") +} +``` + +Groovy +build.gradle + +``` +plugins { + id "dev.nx.gradle.project-graph" version "+" +} +``` + +## Usage + +```bash +./gradlew nxProjectGraph +``` + +In terminal, it should output something like: + +``` +> Task :nxProjectGraph +< your workspace >/build/nx/add-nx-to-gradle.json +``` + +To pass in a hash parameter: + +```bash +./gradlew nxProjectGraph -Phash=12345 +``` + +It generates a json file to be consumed by nx: + +```json +{ + "nodes": { + "app": { + "targets": {} + } + }, + "dependencies": [], + "externalNodes": {} +} +``` diff --git a/packages/gradle/project-graph/build.gradle.kts b/packages/gradle/project-graph/build.gradle.kts new file mode 100644 index 0000000000..7b81d2f463 --- /dev/null +++ b/packages/gradle/project-graph/build.gradle.kts @@ -0,0 +1,120 @@ +plugins { + `java-gradle-plugin` + `maven-publish` + signing + id("com.ncorti.ktfmt.gradle") version "+" + id("dev.nx.gradle.project-graph") version "0.0.2" + id("org.jetbrains.kotlin.jvm") version "2.1.10" + id("com.gradle.plugin-publish") version "1.2.1" +} + +group = "dev.nx.gradle" + +version = "0.0.2" + +repositories { mavenCentral() } + +dependencies { + implementation("com.google.code.gson:gson:2.10.1") + testImplementation(kotlin("test")) + testImplementation("org.mockito:mockito-core:5.8.0") + testImplementation("org.mockito.kotlin:mockito-kotlin:5.2.1") + testImplementation("org.junit.jupiter:junit-jupiter:5.10.1") +} + +java { + withSourcesJar() + withJavadocJar() +} + +gradlePlugin { + website = "https://nx.dev/" + vcsUrl = "https://github.com/nrwl/nx" + plugins { + create("nxProjectGraphPlugin") { + id = "dev.nx.gradle.project-graph" + implementationClass = "dev.nx.gradle.NxProjectGraphReportPlugin" + displayName = "The Nx Plugin for Gradle to generate Nx project graph" + description = "Generates a JSON file with nodes, dependencies, and external nodes for Nx" + tags = listOf("nx", "monorepo", "javascript", "typescript") + } + } +} + +afterEvaluate { + publishing { + publications.named("pluginMaven", MavenPublication::class) { + pom { + name.set("Nx Gradle Project Graph Plugin") + description.set( + "A plugin to generate a JSON file with nodes, dependencies, and external nodes for Nx") + url.set("https://github.com/nrwl/nx") + + licenses { license { name.set("MIT") } } + + developers { + developer { + id.set("nx") + name.set("Nx") + email.set("java-services@nrwl.io") + } + } + + scm { + connection.set("scm:git:git://github.com/nrwl/nx.git") + developerConnection.set("scm:git:ssh://github.com/nrwl/nx.git") + url.set("https://github.com/nrwl/nx") + } + } + } + + repositories { + maven { + name = "localStaging" + url = uri(layout.buildDirectory.dir("staging")) + } + } + } + publishing { + publications.named("nxProjectGraphPluginPluginMarkerMaven", MavenPublication::class) { + pom { + name.set("Nx Gradle Project Graph Plugin") + description.set( + "A plugin to generate a JSON file with nodes, dependencies, and external nodes for Nx") + url.set("https://github.com/nrwl/nx") + + licenses { license { name.set("MIT") } } + + developers { + developer { + id.set("nx") + name.set("Nx") + email.set("java-services@nrwl.io") + } + } + + scm { + connection.set("scm:git:git://github.com/nrwl/nx.git") + developerConnection.set("scm:git:ssh://github.com/nrwl/nx.git") + url.set("https://github.com/nrwl/nx") + } + + repositories { + maven { + name = "localStaging" + url = uri(layout.buildDirectory.dir("staging")) + } + } + } + } + } +} + +signing { + afterEvaluate { + sign(publishing.publications["pluginMaven"]) + sign(publishing.publications["nxProjectGraphPluginPluginMarkerMaven"]) + } +} + +tasks.test { useJUnitPlatform() } diff --git a/packages/gradle/project-graph/project.json b/packages/gradle/project-graph/project.json new file mode 100644 index 0000000000..0301757775 --- /dev/null +++ b/packages/gradle/project-graph/project.json @@ -0,0 +1,43 @@ +{ + "name": "gradle-project-graph", + "$schema": "node_modules/nx/schemas/project-schema.json", + "targets": { + "test": { + "command": "./gradlew :project-graph:test", + "options": { + "args": [] + }, + "cache": true + }, + "lint": { + "command": "./gradlew :project-graph:ktfmtCheck", + "cache": true + }, + "format": { + "command": "./gradlew :project-graph:ktfmtFormat", + "cache": true + }, + "publish-staging": { + "command": "./gradlew :project-graph:publish", + "cache": true, + "outputs": ["{projectRoot}/build/staging"] + }, + "zip-staging": { + "command": "zip -r ../deployment.zip .", + "options": { + "cwd": "{projectRoot}/build/staging" + }, + "inputs": ["{projectRoot}/build/staging"], + "outputs": ["{projectRoot}/build/deployment.zip"], + "dependsOn": ["publish-staging"] + }, + "maven": { + "command": "npx ts-node publish-maven.ts --deploymentZipPath=build/deployment.zip", + "options": { + "cwd": "{projectRoot}" + }, + "inputs": ["{projectRoot}/build/deployment.zip"], + "dependsOn": ["zip-staging"] + } + } +} diff --git a/packages/gradle/project-graph/publish-maven.ts b/packages/gradle/project-graph/publish-maven.ts new file mode 100644 index 0000000000..12d20b5866 --- /dev/null +++ b/packages/gradle/project-graph/publish-maven.ts @@ -0,0 +1,133 @@ +import axios from 'axios'; +import * as fs from 'fs'; +import * as FormData from 'form-data'; + +function parseArgs() { + const args = process.argv.slice(2); + const result: Record = {}; + args.forEach((arg) => { + const [key, value] = arg.replace(/^--/, '').split('='); + result[key] = value; + }); + return result; +} + +async function publishToMavenApi( + username: string, + password: string, + deploymentZipPath = 'deployment.zip' +) { + const token = Buffer.from(`${username}:${password}`).toString('base64'); + console.log(`📦 Publishing to Maven Central...`); + + const url = 'https://central.sonatype.com/api/v1/publisher/upload'; + const form = new FormData(); + form.append('bundle', fs.createReadStream(deploymentZipPath)); + + let uploadId: string; + try { + const response = await axios.post(url, form, { + headers: { + Authorization: `Basic ${token}`, + ...form.getHeaders(), + }, + }); + uploadId = response.data.toString().trim(); + console.log(`✅ Upload ID: ${uploadId}`); + } catch (err: any) { + console.error('🚫 Upload failed:', err.response?.data || err.message); + process.exit(1); + } + + let currentStatus = await getUploadStatus(uploadId, token); + if (['PENDING', 'VALIDATING', 'PUBLISHING'].includes(currentStatus)) { + currentStatus = await retryUntilValidatedOrPublished( + currentStatus, + uploadId, + token + ); + } + + if (!['VALIDATED', 'PUBLISHED'].includes(currentStatus)) { + console.error(`🚫 Upload failed with final status: ${currentStatus}`); + process.exit(1); + } + + console.log(`📦 Upload is ${currentStatus}, proceeding to deploy...`); + if (currentStatus === 'PUBLISHED') { + console.log('✅ Already published, skipping deployment.'); + return; + } + + const deployUrl = `https://central.sonatype.com/api/v1/publisher/deployment/${uploadId}`; + try { + const deployRes = await axios.post(deployUrl, null, { + headers: { Authorization: `Basic ${token}` }, + }); + console.log(`🚀 Deployment response: ${deployRes.data}`); + } catch (err: any) { + console.error('🚫 Deployment failed:', err.response?.data || err.message); + process.exit(1); + } +} + +async function getUploadStatus( + uploadId: string, + token: string +): Promise { + const url = `https://central.sonatype.com/api/v1/publisher/status?id=${uploadId}`; + try { + const response = await axios.post(url, null, { + headers: { Authorization: `Basic ${token}` }, + }); + const state = response.data.deploymentState; + console.log(`📡 Current deployment state: ${state}`); + return state; + } catch (err: any) { + console.error( + '🚫 Failed to get status:', + err.response?.data || err.message + ); + return 'FAILED'; + } +} + +async function retryUntilValidatedOrPublished( + currentStatus: string, + uploadId: string, + token: string, + retries = 10, + delay = 10_000 +): Promise { + for (let i = 0; i < retries; i++) { + console.log(`🔁 Checking status (attempt ${i + 1}/${retries})...`); + await sleep(delay); + currentStatus = await getUploadStatus(uploadId, token); + if (['VALIDATED', 'PUBLISHED', 'FAILED'].includes(currentStatus)) break; + } + return currentStatus; +} + +function sleep(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +// Entry +(async function main() { + let { username, password, deploymentZipPath } = parseArgs(); + + username = username || process.env.MAVEN_USERNAME; + password = password || process.env.MAVEN_PASSWORD; + + if (!username || !password) { + console.error('❌ Missing MAVEN_USERNAME or MAVEN_PASSWORD'); + process.exit(1); + } + + if (!deploymentZipPath) { + console.error('❌ Missing required --deploymentZipPath argument'); + process.exit(1); + } + + await publishToMavenApi(username, password, deploymentZipPath); +})(); diff --git a/packages/gradle/project-graph/settings.gradle.kts b/packages/gradle/project-graph/settings.gradle.kts new file mode 100644 index 0000000000..d264f3bb97 --- /dev/null +++ b/packages/gradle/project-graph/settings.gradle.kts @@ -0,0 +1,16 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * For more detailed information on multi-project builds, please refer to https://docs.gradle.org/8.5/userguide/building_swift_projects.html in the Gradle documentation. + */ + +pluginManagement { + repositories { + mavenLocal() + mavenCentral() + gradlePluginPortal() + } +} + +rootProject.name = "project-graph" diff --git a/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/NxProjectGraphReportPlugin.kt b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/NxProjectGraphReportPlugin.kt new file mode 100644 index 0000000000..0b91fa86e0 --- /dev/null +++ b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/NxProjectGraphReportPlugin.kt @@ -0,0 +1,94 @@ +package dev.nx.gradle + +import java.util.* +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.tasks.TaskProvider + +class NxProjectGraphReportPlugin : Plugin { + override fun apply(project: Project) { + project.logger.info("${Date()} Applying NxProjectGraphReportPlugin to ${project.name}") + + val nxProjectReportTask: TaskProvider = + project.tasks.register("nxProjectReport", NxProjectReportTask::class.java) { task -> + val hashProperty = + project.findProperty("hash")?.toString() + ?: run { + project.logger.warn( + "No 'hash' property was provided for $project. Using default hash value: 'default-hash'") + "default-hash" + } + + val cwdProperty = + project.findProperty("cwd")?.toString() + ?: run { + project.logger.warn( + "No 'cwd' property was provided for $project. Using default hash value: ${System.getProperty("user.dir")}") + System.getProperty("user.dir") + } + + val workspaceRootProperty = + project.findProperty("workspaceRoot")?.toString() + ?: run { + project.logger.warn( + "No 'workspaceRoot' property was provided for $project. Using default hash value: ${System.getProperty("user.dir")}") + System.getProperty("user.dir") + } + + val targetNameOverrides: Map = + project.properties + .filterKeys { it.endsWith("TargetName") } + .mapValues { it.value.toString() } + task.projectName.set(project.name) + task.projectRef.set(project) + task.hash.set(hashProperty) + task.targetNameOverrides.set(targetNameOverrides) + task.cwd.set(cwdProperty) + task.workspaceRoot.set(workspaceRootProperty) + + task.description = "Create Nx project report for ${project.name}" + task.group = "Reporting" + + task.doFirst { it.logger.info("${Date()} Running nxProjectReport for ${project.name}") } + } + + // Ensure all included builds are processed only once using lazy evaluation + project.gradle.includedBuilds.distinct().forEach { includedBuild -> + nxProjectReportTask.configure { it.dependsOn(includedBuild.task(":nxProjectReport")) } + } + + // Ensure all subprojects are processed only once using lazy evaluation + project.subprojects.distinct().forEach { subProject -> + // Add a dependency on each subproject's nxProjectReport task + nxProjectReportTask.configure { + it.dependsOn(subProject.tasks.matching { it.name == "nxProjectReport" }) + } + } + + project.tasks.register("nxProjectGraph").configure { task -> + task.dependsOn(nxProjectReportTask) + task.description = "Create Nx project graph for ${project.name}" + task.group = "Reporting" + + val outputFileProvider = nxProjectReportTask.map { it.outputFile } + + task.doFirst { it.logger.info("${Date()} Running nxProjectGraph for ${project.name}") } + + task.doLast { println(outputFileProvider.get().path) } + } + + // Ensure all included builds are processed only once using lazy evaluation + project.gradle.includedBuilds.distinct().forEach { includedBuild -> + project.tasks.named("nxProjectGraph").configure { + it.dependsOn(includedBuild.task(":nxProjectGraph")) + } + } + + // Ensure all subprojects are processed only once using lazy evaluation + project.subprojects.distinct().forEach { subProject -> + project.tasks.named("nxProjectGraph").configure { + it.dependsOn(subProject.tasks.matching { it.name == "nxProjectGraph" }) + } + } + } +} diff --git a/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/NxProjectReportTask.kt b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/NxProjectReportTask.kt new file mode 100644 index 0000000000..71cc67313f --- /dev/null +++ b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/NxProjectReportTask.kt @@ -0,0 +1,63 @@ +package dev.nx.gradle + +import com.google.gson.Gson +import dev.nx.gradle.utils.createNodeForProject +import java.io.File +import java.util.* +import javax.inject.Inject +import org.gradle.api.DefaultTask +import org.gradle.api.Project +import org.gradle.api.file.ProjectLayout +import org.gradle.api.provider.MapProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.* + +@CacheableTask +abstract class NxProjectReportTask @Inject constructor(private val projectLayout: ProjectLayout) : + DefaultTask() { + + companion object { + private val gson = Gson() + } + + @get:Input abstract val projectName: Property + + @get:Input abstract val hash: Property + + @get:Input abstract val cwd: Property + + @get:Input abstract val workspaceRoot: Property + + @get:Input abstract val targetNameOverrides: MapProperty + + // Don't compute report at configuration time, move it to execution time + @get:Internal // Prevent Gradle from caching this reference + abstract val projectRef: Property + + @get:OutputFile + val outputFile: File + get() = projectLayout.buildDirectory.file("nx/${projectName.get()}.json").get().asFile + + @TaskAction + fun action() { + logger.info("${Date()} Apply task action NxProjectReportTask for ${projectName.get()}") + logger.info("${Date()} Hash input: ${hash.get()}") + logger.info("${Date()} Target Name Overrides ${targetNameOverrides.get()}") + val project = projectRef.get() // Get project reference at execution time + val report = + createNodeForProject( + project, + targetNameOverrides.get(), + workspaceRoot.get(), + cwd.get()) // Compute report at execution time + val reportJson = gson.toJson(report) + + if (outputFile.exists() && outputFile.readText() == reportJson) { + logger.info("${Date()} No change in the node report for ${projectName.get()}") + return + } + + logger.info("${Date()} Writing node report for ${projectName.get()}") + outputFile.writeText(reportJson) + } +} diff --git a/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/Dependency.kt b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/Dependency.kt new file mode 100644 index 0000000000..87c8b8dc5f --- /dev/null +++ b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/Dependency.kt @@ -0,0 +1,6 @@ +package dev.nx.gradle.data + +import java.io.Serializable + +data class Dependency(val source: String, val target: String, var sourceFile: String) : + Serializable diff --git a/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/ExternalDepData.kt b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/ExternalDepData.kt new file mode 100644 index 0000000000..c1a2b5599b --- /dev/null +++ b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/ExternalDepData.kt @@ -0,0 +1,10 @@ +package dev.nx.gradle.data + +import java.io.Serializable +import org.gradle.api.tasks.Input + +data class ExternalDepData( + @Input val version: String?, + @Input val packageName: String, + @Input val hash: String? +) : Serializable diff --git a/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/ExternalNode.kt b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/ExternalNode.kt new file mode 100644 index 0000000000..fd326b0865 --- /dev/null +++ b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/ExternalNode.kt @@ -0,0 +1,11 @@ +package dev.nx.gradle.data + +import java.io.Serializable +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Nested + +data class ExternalNode( + @Input var type: String?, + @Input val name: String, + @Nested var data: ExternalDepData +) : Serializable diff --git a/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/GradleNodeReport.kt b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/GradleNodeReport.kt new file mode 100644 index 0000000000..7929cdebf2 --- /dev/null +++ b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/GradleNodeReport.kt @@ -0,0 +1,11 @@ +package dev.nx.gradle.data + +import java.io.Serializable +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Nested + +data class GradleNodeReport( + @Nested val nodes: Map, + @Input val dependencies: Set, + @Nested val externalNodes: Map +) : Serializable diff --git a/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/GradleTargets.kt b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/GradleTargets.kt new file mode 100644 index 0000000000..de80c6c7b5 --- /dev/null +++ b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/GradleTargets.kt @@ -0,0 +1,17 @@ +package dev.nx.gradle.data + +import java.io.Serializable + +typealias NxTarget = MutableMap + +typealias NxTargets = MutableMap + +typealias TargetGroup = MutableList + +typealias TargetGroups = MutableMap + +data class GradleTargets( + val targets: NxTargets, + val targetGroups: TargetGroups, + var externalNodes: MutableMap +) : Serializable diff --git a/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/NodeMetadata.kt b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/NodeMetadata.kt new file mode 100644 index 0000000000..4c2d4d02ce --- /dev/null +++ b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/NodeMetadata.kt @@ -0,0 +1,9 @@ +package dev.nx.gradle.data + +import java.io.Serializable + +data class NodeMetadata( + val targetGroups: TargetGroups, + val technologies: List, + val description: String? +) : Serializable diff --git a/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/ProjectNode.kt b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/ProjectNode.kt new file mode 100644 index 0000000000..fa9508ae77 --- /dev/null +++ b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/data/ProjectNode.kt @@ -0,0 +1,10 @@ +package dev.nx.gradle.data + +import java.io.Serializable +import org.gradle.api.tasks.Input + +data class ProjectNode( + @Input val targets: NxTargets, + @Input val metadata: NodeMetadata, + @Input val name: String +) : Serializable diff --git a/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/utils/CiTargetsUtils.kt b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/utils/CiTargetsUtils.kt new file mode 100644 index 0000000000..c6a9a8d00b --- /dev/null +++ b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/utils/CiTargetsUtils.kt @@ -0,0 +1,143 @@ +package dev.nx.gradle.utils + +import dev.nx.gradle.data.* +import java.io.File +import org.gradle.api.Task +import org.gradle.api.file.FileCollection + +const val testCiTargetGroup = "verification" + +/** + * Add atomized ci test targets Going to loop through each test files and create a target for each + * It is going to modify targets and targetGroups in place + */ +fun addTestCiTargets( + testFiles: FileCollection, + projectBuildPath: String, + testTask: Task, + targets: NxTargets, + targetGroups: TargetGroups, + projectRoot: String, + workspaceRoot: String, + ciTargetName: String +) { + ensureTargetGroupExists(targetGroups, testCiTargetGroup) + + val gradlewCommand = getGradlewCommand() + val ciDependsOn = mutableListOf>() + + val filteredTestFiles = testFiles.filter { isTestFile(it, workspaceRoot) } + + filteredTestFiles.forEach { testFile -> + val className = getTestClassNameIfAnnotated(testFile) ?: return@forEach + + val testCiTarget = + buildTestCiTarget( + gradlewCommand = gradlewCommand, + projectBuildPath = projectBuildPath, + testClassName = className, + testFile = testFile, + testTask = testTask, + projectRoot = projectRoot, + workspaceRoot = workspaceRoot) + + val targetName = "$ciTargetName--$className" + targets[targetName] = testCiTarget + targetGroups[testCiTargetGroup]?.add(targetName) + + ciDependsOn.add(mapOf("target" to targetName, "projects" to "self", "params" to "forward")) + } + + testTask.logger.info("$testTask ci tasks: $ciDependsOn") + + if (ciDependsOn.isNotEmpty()) { + ensureParentCiTarget( + targets = targets, + targetGroups = targetGroups, + ciTargetName = ciTargetName, + projectBuildPath = projectBuildPath, + dependsOn = ciDependsOn) + } +} + +private fun getTestClassNameIfAnnotated(file: File): String? { + if (!file.exists()) return null + + val content = file.readText() + if (!content.contains("@Test")) return null + + val classRegex = Regex("""class\s+([A-Za-z_][A-Za-z0-9_]*)""") + val match = classRegex.find(content) + return match?.groupValues?.get(1) +} + +fun ensureTargetGroupExists(targetGroups: TargetGroups, group: String) { + if (!targetGroups.containsKey(group)) { + targetGroups[group] = mutableListOf() + } +} + +private fun isTestFile(file: File, workspaceRoot: String): Boolean { + val fileName = file.name.substringBefore(".") + val regex = "^(?!abstract).*?(Test)(s)?\\d*".toRegex(RegexOption.IGNORE_CASE) + return file.path.startsWith(workspaceRoot) && regex.matches(fileName) +} + +private fun buildTestCiTarget( + gradlewCommand: String, + projectBuildPath: String, + testClassName: String, + testFile: File, + testTask: Task, + projectRoot: String, + workspaceRoot: String +): MutableMap { + val target = + mutableMapOf( + "command" to "$gradlewCommand ${projectBuildPath}:test --tests $testClassName", + "metadata" to + getMetadata("Runs Gradle test $testClassName in CI", projectBuildPath, "test"), + "cache" to true, + "inputs" to arrayOf(replaceRootInPath(testFile.path, projectRoot, workspaceRoot))) + + getDependsOnForTask(testTask, null) + ?.takeIf { it.isNotEmpty() } + ?.let { + testTask.logger.info("$testTask: processed ${it.size} dependsOn") + target["dependsOn"] = it + } + + getOutputsForTask(testTask, projectRoot, workspaceRoot) + ?.takeIf { it.isNotEmpty() } + ?.let { + testTask.logger.info("$testTask: processed ${it.size} outputs") + target["outputs"] = it + } + + return target +} + +private fun ensureParentCiTarget( + targets: NxTargets, + targetGroups: TargetGroups, + ciTargetName: String, + projectBuildPath: String, + dependsOn: List> +) { + val ciTarget = + targets.getOrPut(ciTargetName) { + mutableMapOf().apply { + put("executor", "nx:noop") + put("metadata", getMetadata("Runs Gradle Tests in CI", projectBuildPath, "test", "test")) + put("dependsOn", mutableListOf>()) + put("cache", true) + } + } + + val dependsOnList = ciTarget.getOrPut("dependsOn") { mutableListOf() } as MutableList + dependsOnList.addAll(dependsOn) + + if (targetGroups[testCiTargetGroup]?.contains(ciTargetName) != true) { + targetGroups[testCiTargetGroup]?.add(ciTargetName) + } +} diff --git a/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/utils/ProjectUtils.kt b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/utils/ProjectUtils.kt new file mode 100644 index 0000000000..5984a1ac33 --- /dev/null +++ b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/utils/ProjectUtils.kt @@ -0,0 +1,159 @@ +package dev.nx.gradle.utils + +import dev.nx.gradle.data.* +import java.util.* +import org.gradle.api.Project + +/** Loops through a project and populate dependencies and nodes for each target */ +fun createNodeForProject( + project: Project, + targetNameOverrides: Map, + workspaceRoot: String, + cwd: String +): GradleNodeReport { + val logger = project.logger + logger.info("${Date()} ${project.name} createNodeForProject: get nodes and dependencies") + + // Initialize dependencies with an empty Set to prevent null issues + val dependencies: MutableSet = + try { + getDependenciesForProject(project) + } catch (e: Exception) { + logger.info( + "${Date()} ${project.name} createNodeForProject: get dependencies error: ${e.message}") + mutableSetOf() + } + logger.info("${Date()} ${project.name} createNodeForProject: got dependencies") + + // Initialize nodes and externalNodes with empty maps to prevent null issues + var nodes: Map + var externalNodes: Map + + try { + val gradleTargets: GradleTargets = + processTargetsForProject(project, dependencies, targetNameOverrides, workspaceRoot, cwd) + val projectRoot = project.projectDir.path + val projectNode = + ProjectNode( + targets = gradleTargets.targets, + metadata = + NodeMetadata(gradleTargets.targetGroups, listOf("gradle"), project.description), + name = project.name) + nodes = mapOf(projectRoot to projectNode) + externalNodes = gradleTargets.externalNodes + logger.info( + "${Date()} ${project.name} createNodeForProject: get nodes and external nodes for $projectRoot") + } catch (e: Exception) { + logger.info("${project.name}: get nodes error: ${e.message}") + nodes = emptyMap() + externalNodes = emptyMap() + } + return GradleNodeReport(nodes, dependencies, externalNodes) +} + +/** + * Process targets for project + * + * @return targets and targetGroups + */ +fun processTargetsForProject( + project: Project, + dependencies: MutableSet, + targetNameOverrides: Map, + workspaceRoot: String, + cwd: String +): GradleTargets { + val targets: NxTargets = mutableMapOf>() + val targetGroups: TargetGroups = mutableMapOf>() + val externalNodes = mutableMapOf() + val projectRoot = project.projectDir.path + project.logger.info("Using workspace root $workspaceRoot") + + var projectBuildPath: String = + project + .buildTreePath // get the build path of project e.g. :app, :utils:number-utils, :buildSrc + if (projectBuildPath.endsWith(":")) { // root project is ":", manually remove last : + projectBuildPath = projectBuildPath.dropLast(1) + } + + val logger = project.logger + + logger.info("${Date()} ${project}: process targets") + + var gradleProject = project.buildTreePath + if (!gradleProject.endsWith(":")) { + gradleProject += ":" + } + + project.tasks.forEach { task -> + try { + logger.info("${Date()} ${project.name}: Processing $task") + val taskName = targetNameOverrides.getOrDefault(task.name + "TargetName", task.name) + // add task to target groups + val group: String? = task.group + if (!group.isNullOrBlank()) { + if (targetGroups.contains(group)) { + targetGroups[group]?.add(task.name) + } else { + targetGroups[group] = mutableListOf(task.name) + } + } + + val target = + processTask( + task, + projectBuildPath, + projectRoot, + workspaceRoot, + cwd, + externalNodes, + dependencies, + targetNameOverrides) + targets[taskName] = target + + val ciTargetName = targetNameOverrides.getOrDefault("ciTargetName", null) + ciTargetName?.let { + if (task.name.startsWith("compileTest")) { + val testTask = project.getTasksByName("test", false) + if (testTask.isNotEmpty()) { + addTestCiTargets( + task.inputs.sourceFiles, + projectBuildPath, + testTask.first(), + targets, + targetGroups, + projectRoot, + workspaceRoot, + it) + } + } + + // Add the `$ciTargetName-check` target when processing the "check" task + if (task.name == "check") { + val replacedDependencies = + (target["dependsOn"] as? List<*>)?.map { dep -> + if (dep.toString() == targetNameOverrides.getOrDefault("testTargetName", "test")) + ciTargetName + else dep.toString() + } ?: emptyList() + + // Copy the original target and override "dependsOn" + val newTarget = target.toMutableMap() + newTarget["dependsOn"] = replacedDependencies + + val ciCheckTargetName = "$ciTargetName-check" + targets[ciCheckTargetName] = newTarget + + ensureTargetGroupExists(targetGroups, testCiTargetGroup) + targetGroups[testCiTargetGroup]?.add(ciCheckTargetName) + } + } + logger.info("${Date()} ${project.name}: Processed $task") + } catch (e: Exception) { + logger.info("${task}: process task error $e") + logger.debug("Stack trace:", e) + } + } + + return GradleTargets(targets, targetGroups, externalNodes) +} diff --git a/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/utils/TaskUtils.kt b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/utils/TaskUtils.kt new file mode 100644 index 0000000000..ac49eab006 --- /dev/null +++ b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/utils/TaskUtils.kt @@ -0,0 +1,348 @@ +package dev.nx.gradle.utils + +import dev.nx.gradle.data.* +import org.gradle.api.Named +import org.gradle.api.NamedDomainObjectProvider +import org.gradle.api.Task +import org.gradle.api.tasks.TaskProvider + +/** + * Process a task and convert it into target Going to populate: + * - cache + * - inputs + * - outputs + * - command + * - metadata + * - options with cwd and args + */ +fun processTask( + task: Task, + projectBuildPath: String, + projectRoot: String, + workspaceRoot: String, + cwd: String, + externalNodes: MutableMap, + dependencies: MutableSet, + targetNameOverrides: Map +): MutableMap { + val logger = task.logger + logger.info("NxProjectReportTask: process $task for $projectRoot") + val target = mutableMapOf() + target["cache"] = true // set cache to be always true + + // process inputs + val inputs = getInputsForTask(task, projectRoot, workspaceRoot, externalNodes) + if (!inputs.isNullOrEmpty()) { + logger.info("${task}: processed ${inputs.size} inputs") + target["inputs"] = inputs + } + + // process outputs + val outputs = getOutputsForTask(task, projectRoot, workspaceRoot) + if (!outputs.isNullOrEmpty()) { + logger.info("${task}: processed ${outputs.size} outputs") + target["outputs"] = outputs + } + + // process dependsOn + val dependsOn = getDependsOnForTask(task, dependencies, targetNameOverrides) + if (!dependsOn.isNullOrEmpty()) { + logger.info("${task}: processed ${dependsOn.size} dependsOn") + target["dependsOn"] = dependsOn + } + + val gradlewCommand = getGradlewCommand() + target["command"] = "$gradlewCommand ${projectBuildPath}:${task.name}" + + val metadata = getMetadata(task.description ?: "Run ${task.name}", projectBuildPath, task.name) + target["metadata"] = metadata + + target["options"] = mapOf("cwd" to cwd) + + return target +} + +fun getGradlewCommand(): String { + val gradlewCommand: String + val operatingSystem = System.getProperty("os.name").lowercase() + gradlewCommand = + if (operatingSystem.contains("win")) { + ".\\gradlew.bat" + } else { + "./gradlew" + } + return gradlewCommand +} + +/** + * Parse task and get inputs for this task + * + * @param task task to process + * @return a list of inputs including external dependencies, null if empty or an error occurred + */ +fun getInputsForTask( + task: Task, + projectRoot: String, + workspaceRoot: String, + externalNodes: MutableMap? +): MutableList? { + return try { + val mappedInputsIncludeExternal: MutableList = mutableListOf() + val inputs = task.inputs + val externalDependencies = mutableListOf() + inputs.sourceFiles.forEach { file -> + val path: String = file.path + // replace the absolute path to contain {projectRoot} or {workspaceRoot} + val pathWithReplacedRoot = replaceRootInPath(path, projectRoot, workspaceRoot) + if (pathWithReplacedRoot != null) { // if the path is inside workspace + mappedInputsIncludeExternal.add((pathWithReplacedRoot)) + } + // if the path is outside of workspace + if (pathWithReplacedRoot == null && + externalNodes != null) { // add it to external dependencies + try { + val externalDep = getExternalDepFromInputFile(path, externalNodes, task.logger) + externalDep?.let { externalDependencies.add(it) } + } catch (e: Exception) { + task.logger.info("${task}: get external dependency error $e") + } + } + } + if (externalDependencies.isNotEmpty()) { + mappedInputsIncludeExternal.add(mutableMapOf("externalDependencies" to externalDependencies)) + } + if (mappedInputsIncludeExternal.isNotEmpty()) { + return mappedInputsIncludeExternal + } + return null + } catch (e: Exception) { + // Log the error but don't fail the build + task.logger.info("Error getting outputs for ${task.path}: ${e.message}") + task.logger.debug("Stack trace:", e) + null + } +} + +/** + * Get outputs for task + * + * @param task task to process + * @return list of outputs file, will not include if output file is outside workspace, null if empty + * or an error occurred + */ +fun getOutputsForTask(task: Task, projectRoot: String, workspaceRoot: String): List? { + return try { + val outputs = task.outputs.files + if (!outputs.isEmpty) { + return outputs.mapNotNull { file -> + val path: String = file.path + replaceRootInPath(path, projectRoot, workspaceRoot) + } + } + null + } catch (e: Exception) { + // Log the error but don't fail the build + task.logger.info("Error getting outputs for ${task.path}: ${e.message}") + task.logger.debug("Stack trace:", e) + null + } +} + +/** + * Get dependsOn for task, handling configuration timing safely. Rewrites dependency task names + * based on targetNameOverrides (e.g., test -> ci). + * + * @param task task to process + * @param dependencies optional set to collect inter-project Dependency objects + * @param targetNameOverrides optional map of overrides (e.g., test -> ci) + * @return list of dependsOn task names (possibly replaced), or null if none found or error occurred + */ +fun getDependsOnForTask( + task: Task, + dependencies: MutableSet?, + targetNameOverrides: Map = emptyMap() +): List? { + + fun mapTasksToNames(tasks: Collection): List { + return tasks.map { depTask -> + val depProject = depTask.project + val taskProject = task.project + + if (task.name != "buildDependents" && depProject != taskProject && dependencies != null) { + dependencies.add( + Dependency( + taskProject.projectDir.path, + depProject.projectDir.path, + taskProject.buildFile.path)) + } + + // Check if this task name needs to be overridden + val taskName = targetNameOverrides.getOrDefault(depTask.name + "TargetName", depTask.name) + val overriddenTaskName = + if (depProject == taskProject) { + taskName + } else { + "${depProject.name}:${taskName}" + } + + overriddenTaskName + } + } + + return try { + val dependsOnEntries = task.dependsOn + + // Prefer task.dependsOn + if (dependsOnEntries.isNotEmpty()) { + val resolvedTasks = + dependsOnEntries.flatMap { dep -> + when (dep) { + is Task -> listOf(dep) + + is TaskProvider<*>, + is NamedDomainObjectProvider<*> -> { + val providerName = (dep as Named).name + val foundTask = task.project.tasks.findByName(providerName) + if (foundTask != null) { + listOf(foundTask) + } else { + task.logger.info( + "${dep::class.simpleName} '$providerName' did not resolve to a task in project ${task.project.name}") + emptyList() + } + } + + is String -> { + val foundTask = task.project.tasks.findByPath(dep) + if (foundTask != null) { + listOf(foundTask) + } else { + task.logger.info( + "Task string '$dep' could not be resolved in project ${task.project.name}") + emptyList() + } + } + + else -> { + task.logger.info( + "Unhandled dependency type ${dep::class.java} for task ${task.path}") + emptyList() + } + } + } + + if (resolvedTasks.isNotEmpty()) { + return mapTasksToNames(resolvedTasks) + } + } + + // Fallback: taskDependencies.getDependencies(task) + val fallbackDeps = + try { + task.taskDependencies.getDependencies(null) + } catch (e: Exception) { + task.logger.info("Error calling getDependencies for ${task.path}: ${e.message}") + task.logger.debug("Stack trace:", e) + emptySet() + } + + if (fallbackDeps.isNotEmpty()) { + return mapTasksToNames(fallbackDeps) + } + + null + } catch (e: Exception) { + task.logger.info("Unexpected error getting dependencies for ${task.path}: ${e.message}") + task.logger.debug("Stack trace:", e) + null + } +} + +/** + * Get metadata for task + * + * @param description + */ +fun getMetadata( + description: String?, + projectBuildPath: String, + taskName: String, + nonAtomizedTarget: String? = null +): Map { + val gradlewCommand = getGradlewCommand() + return mapOf( + "description" to description, + "technologies" to arrayOf("gradle"), + "help" to mapOf("command" to "$gradlewCommand help --task ${projectBuildPath}:${taskName}"), + "nonAtomizedTarget" to nonAtomizedTarget) +} + +/** + * Converts a file path like: + * org.apache.commons/commons-lang3/3.13.0/b7263237aa89c1f99b327197c41d0669707a462e/commons-lang3-3.13.0.jar + * + * Into an external dependency with key: "gradle:commons-lang3-3.13.0" with value: { "type": + * "gradle", "name": "commons-lang3", "data": { "version": "3.13.0", "packageName": + * "org.apache.commons.commons-lang3", "hash": "b7263237aa89c1f99b327197c41d0669707a462e",} } + * + * @param inputFile Path to the dependency jar. + * @param externalNodes Map to populate with the resulting ExternalNode. + * @return The external dependency key (e.g., gradle:commons-lang3-3.13.0), or null if parsing + * fails. + */ +fun getExternalDepFromInputFile( + inputFile: String, + externalNodes: MutableMap, + logger: org.gradle.api.logging.Logger +): String? { + try { + val segments = inputFile.split("/") + + // Expecting at least 5 segments to safely extract group, package, version, hash, filename + if (segments.size < 5) { + logger.warn("Invalid input path: '$inputFile'. Expected at least 5 segments.") + return null + } + + val fileName = segments.last() + + // Remove any file extension (after the last dot), if present + val nameKey = fileName.substringBeforeLast(".", fileName) + + val hash = segments[segments.size - 2] + val version = segments[segments.size - 3] + val packageName = segments[segments.size - 4] + val packageGroup = segments[segments.size - 5] + + val fullPackageName = "$packageGroup.$packageName" + + val data = ExternalDepData(version, fullPackageName, hash) + val externalKey = "gradle:$nameKey" + val node = ExternalNode("gradle", externalKey, data) + + externalNodes[externalKey] = node + + return externalKey + } catch (e: Exception) { + logger.warn("Failed to parse inputFile '$inputFile': ${e.message}") + logger.debug("Stack trace:", e) + return null + } +} + +/** + * Going to replace the projectRoot with {projectRoot} and workspaceRoot with {workspaceRoot} + * + * @return mapped path if inside workspace, null if outside workspace + */ +fun replaceRootInPath(p: String, projectRoot: String, workspaceRoot: String): String? { + var path = p + if (path.startsWith(projectRoot)) { + path = path.replace(projectRoot, "{projectRoot}") + return path + } else if (path.startsWith(workspaceRoot)) { + path = path.replace(workspaceRoot, "{workspaceRoot}") + return path + } + return null +} diff --git a/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/utils/projectDependencyUtils.kt b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/utils/projectDependencyUtils.kt new file mode 100644 index 0000000000..e869d3e3b1 --- /dev/null +++ b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/utils/projectDependencyUtils.kt @@ -0,0 +1,30 @@ +package dev.nx.gradle.utils + +import dev.nx.gradle.data.Dependency +import org.gradle.api.Project + +private val dependencyCache = mutableMapOf>() + +fun getDependenciesForProject(project: Project): MutableSet { + return dependencyCache + .getOrPut(project) { buildDependenciesForProject(project) } + .toMutableSet() // Return a new mutable copy to prevent modifying the cached set +} + +private fun buildDependenciesForProject(project: Project): Set { + val dependencies = mutableSetOf() + + // Include subprojects manually + project.subprojects.forEach { childProject -> + dependencies.add( + Dependency(project.projectDir.path, childProject.projectDir.path, project.buildFile.path)) + } + + // Include included builds manually + project.gradle.includedBuilds.forEach { includedBuild -> + dependencies.add( + Dependency(project.projectDir.path, includedBuild.projectDir.path, project.buildFile.path)) + } + + return dependencies +} diff --git a/packages/gradle/project-graph/src/test/kotlin/dev/nx/gradle/utils/AddTestCiTargetsTest.kt b/packages/gradle/project-graph/src/test/kotlin/dev/nx/gradle/utils/AddTestCiTargetsTest.kt new file mode 100644 index 0000000000..58d41d8561 --- /dev/null +++ b/packages/gradle/project-graph/src/test/kotlin/dev/nx/gradle/utils/AddTestCiTargetsTest.kt @@ -0,0 +1,81 @@ +package dev.nx.gradle.utils + +import dev.nx.gradle.data.* +import java.io.File +import kotlin.test.assertEquals +import kotlin.test.assertTrue +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.testfixtures.ProjectBuilder +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +class AddTestCiTargetsTest { + + private lateinit var project: Project + private lateinit var testTask: Task + private lateinit var workspaceRoot: File + private lateinit var projectRoot: File + + @BeforeEach + fun setup() { + workspaceRoot = createTempDir("workspace") + projectRoot = File(workspaceRoot, "project-a").apply { mkdirs() } + + project = ProjectBuilder.builder().withProjectDir(projectRoot).build() + testTask = project.task("test") + } + + @Test + fun `should generate test CI targets and group correctly`() { + val testFile1 = + File(projectRoot, "src/test/kotlin/MyFirstTest.kt").apply { + parentFile.mkdirs() + writeText("@Test class MyFirstTest") + } + + val testFile2 = + File(projectRoot, "src/test/kotlin/AnotherTest.kt").apply { + parentFile.mkdirs() + writeText("@Test class AnotherTest") + } + + val testFiles = project.files(testFile1, testFile2) + + val targets = mutableMapOf>() + val targetGroups = mutableMapOf>() + val ciTargetName = "ci" + + addTestCiTargets( + testFiles = testFiles, + projectBuildPath = ":project-a", + testTask = testTask, + targets = targets, + targetGroups = targetGroups, + projectRoot = projectRoot.absolutePath, + workspaceRoot = workspaceRoot.absolutePath, + ciTargetName = ciTargetName) + + // Assert each test file created a CI target + assertTrue(targets.containsKey("ci--MyFirstTest")) + assertTrue(targets.containsKey("ci--AnotherTest")) + + // Assert test group contains individual targets and parent ci task + val group = targetGroups[testCiTargetGroup] + assertTrue(group != null) + assertTrue(group!!.contains("ci--MyFirstTest")) + assertTrue(group.contains("ci--AnotherTest")) + assertTrue(group.contains("ci")) + + // Assert parent CI task includes dependsOn + val parentCi = targets["ci"] + val dependsOn = parentCi?.get("dependsOn") as? List<*> + assertEquals(2, dependsOn!!.size) + + val firstTarget = targets["ci--MyFirstTest"]!! + assertTrue(firstTarget["command"].toString().contains("--tests MyFirstTest")) + assertEquals(true, firstTarget["cache"]) + assertTrue((firstTarget["inputs"] as Array<*>)[0].toString().contains("{projectRoot}")) + assertEquals("nx:noop", parentCi["executor"]) + } +} diff --git a/packages/gradle/project-graph/src/test/kotlin/dev/nx/gradle/utils/CreateNodeForProjectTest.kt b/packages/gradle/project-graph/src/test/kotlin/dev/nx/gradle/utils/CreateNodeForProjectTest.kt new file mode 100644 index 0000000000..49289e86b1 --- /dev/null +++ b/packages/gradle/project-graph/src/test/kotlin/dev/nx/gradle/utils/CreateNodeForProjectTest.kt @@ -0,0 +1,54 @@ +package dev.nx.gradle.utils + +import dev.nx.gradle.data.* +import kotlin.test.* +import org.gradle.testfixtures.ProjectBuilder + +class CreateNodeForProjectTest { + + @Test + fun `should return GradleNodeReport with targets and metadata`() { + // Arrange + val workspaceRoot = createTempDir("workspace").absolutePath + val projectDir = createTempDir("project") + val project = ProjectBuilder.builder().withProjectDir(projectDir).build() + + // Create a couple of dummy tasks + project.task("compileJava").apply { + group = "build" + description = "Compiles Java sources" + } + + project.task("test").apply { + group = "verification" + description = "Runs the tests" + } + + val targetNameOverrides = mapOf() + + // Act + val result = + createNodeForProject( + project = project, + targetNameOverrides = targetNameOverrides, + workspaceRoot = workspaceRoot, + cwd = "{projectRoot}") + + // Assert + val projectRoot = project.projectDir.absolutePath + assertTrue(result.nodes.containsKey(projectRoot), "Expected node for project root") + + val projectNode = result.nodes[projectRoot] + assertNotNull(projectNode, "ProjectNode should not be null") + + // Check target metadata + assertEquals(project.name, projectNode.name) + assertNotNull(projectNode.targets["compileJava"], "Expected compileJava target") + assertNotNull(projectNode.targets["test"], "Expected test target") + assertEquals("build", projectNode.metadata.targetGroups.keys.firstOrNull()) + + // Dependencies and external nodes should default to empty + assertTrue(result.dependencies.isEmpty(), "Expected no dependencies") + assertTrue(result.externalNodes.isEmpty(), "Expected no external nodes") + } +} diff --git a/packages/gradle/project-graph/src/test/kotlin/dev/nx/gradle/utils/ProcessTaskUtilsTest.kt b/packages/gradle/project-graph/src/test/kotlin/dev/nx/gradle/utils/ProcessTaskUtilsTest.kt new file mode 100644 index 0000000000..994a92234e --- /dev/null +++ b/packages/gradle/project-graph/src/test/kotlin/dev/nx/gradle/utils/ProcessTaskUtilsTest.kt @@ -0,0 +1,96 @@ +package dev.nx.gradle.utils + +import dev.nx.gradle.data.Dependency +import dev.nx.gradle.data.ExternalNode +import org.gradle.testfixtures.ProjectBuilder +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import org.mockito.kotlin.* + +class ProcessTaskUtilsTest { + + @Test + fun `test replaceRootInPath`() { + val path = "/home/user/workspace/project/src/main/java" + val projectRoot = "/home/user/workspace/project" + val workspaceRoot = "/home/user/workspace" + + assertEquals("{projectRoot}/src/main/java", replaceRootInPath(path, projectRoot, workspaceRoot)) + assertEquals( + "{workspaceRoot}/project/src/main/java", + replaceRootInPath(path, "/other/path", workspaceRoot)) + assertNull(replaceRootInPath("/external/other", projectRoot, workspaceRoot)) + } + + @Test + fun `test getGradlewCommand`() { + val command = getGradlewCommand() + assertTrue(command.contains("gradlew")) + } + + @Test + fun `test getMetadata`() { + val metadata = getMetadata("Compile Java", ":project", "compileJava") + assertEquals("Compile Java", metadata["description"]) + assertEquals("gradle", (metadata["technologies"] as Array<*>)[0]) + } + + @Test + fun `test getExternalDepFromInputFile valid path`() { + val externalNodes = mutableMapOf() + val path = "org/apache/commons/commons-lang3/3.13.0/hash/commons-lang3-3.13.0.jar" + + val key = getExternalDepFromInputFile(path, externalNodes, mock()) + + assertEquals("gradle:commons-lang3-3.13.0", key) + assertTrue(externalNodes.containsKey("gradle:commons-lang3-3.13.0")) + } + + @Test + fun `test getExternalDepFromInputFile invalid path`() { + val externalNodes = mutableMapOf() + val key = getExternalDepFromInputFile("invalid/path.jar", externalNodes, mock()) + + assertNull(key) + assertTrue(externalNodes.isEmpty()) + } + + @Test + fun `test getDependsOnForTask with direct dependsOn`() { + val project = ProjectBuilder.builder().build() + val taskA = project.tasks.register("taskA").get() + val taskB = project.tasks.register("taskB").get() + + taskA.dependsOn(taskB) + + val dependencies = mutableSetOf() + val dependsOn = getDependsOnForTask(taskA, dependencies) + + assertNotNull(dependsOn) + assertTrue(dependsOn!!.contains("taskB")) + } + + @Test + fun `test processTask basic properties`() { + val project = ProjectBuilder.builder().build() + val task = project.tasks.register("compileJava").get() + task.group = "build" + task.description = "Compiles Java source files" + + val result = + processTask( + task, + projectBuildPath = ":project", + projectRoot = project.projectDir.path, + workspaceRoot = project.rootDir.path, + cwd = ".", + externalNodes = mutableMapOf(), + dependencies = mutableSetOf(), + targetNameOverrides = emptyMap()) + + assertEquals(true, result["cache"]) + assertTrue((result["command"] as String).contains("gradlew")) + assertNotNull(result["metadata"]) + assertNotNull(result["options"]) + } +} diff --git a/packages/gradle/src/generators/ci-workflow/__snapshots__/generator.spec.ts.snap b/packages/gradle/src/generators/ci-workflow/__snapshots__/generator.spec.ts.snap index cf486e7f42..732167fefb 100644 --- a/packages/gradle/src/generators/ci-workflow/__snapshots__/generator.spec.ts.snap +++ b/packages/gradle/src/generators/ci-workflow/__snapshots__/generator.spec.ts.snap @@ -13,7 +13,7 @@ jobs: _JAVA_OPTIONS: '-Xmx3g' GRADLE_OPTS: '-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=2' docker: - - image: cimg/openjdk:17.0-node + - image: cimg/openjdk:21.0-node steps: - checkout @@ -66,15 +66,15 @@ jobs: # Uncomment this line to enable task distribution # - run: npx nx-cloud start-ci-run --distribute-on="3 linux-medium-jvm" --stop-agents-after="build" - - name: Set up JDK 17 for x64 + - name: Set up JDK 21 for x64 uses: actions/setup-java@v4 with: - java-version: '17' + java-version: '21' distribution: 'temurin' architecture: x64 - name: Setup Gradle - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@v4 - uses: nrwl/nx-set-shas@v4 @@ -96,7 +96,7 @@ jobs: _JAVA_OPTIONS: '-Xmx3g' GRADLE_OPTS: '-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=2' docker: - - image: cimg/openjdk:17.0-node + - image: cimg/openjdk:21.0-node steps: - checkout @@ -149,15 +149,15 @@ jobs: # Connect your workspace by running "nx connect" and uncomment this line to enable task distribution # - run: npx nx-cloud start-ci-run --distribute-on="3 linux-medium-jvm" --stop-agents-after="build" - - name: Set up JDK 17 for x64 + - name: Set up JDK 21 for x64 uses: actions/setup-java@v4 with: - java-version: '17' + java-version: '21' distribution: 'temurin' architecture: x64 - name: Setup Gradle - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@v4 - uses: nrwl/nx-set-shas@v4 diff --git a/packages/gradle/src/generators/ci-workflow/files/circleci/.circleci/config.yml.template b/packages/gradle/src/generators/ci-workflow/files/circleci/.circleci/config.yml.template index 39828ee160..c7a6ba4cca 100644 --- a/packages/gradle/src/generators/ci-workflow/files/circleci/.circleci/config.yml.template +++ b/packages/gradle/src/generators/ci-workflow/files/circleci/.circleci/config.yml.template @@ -10,7 +10,7 @@ jobs: _JAVA_OPTIONS: "-Xmx3g" GRADLE_OPTS: "-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=2" docker: - - image: cimg/openjdk:17.0-node + - image: cimg/openjdk:21.0-node steps: - checkout diff --git a/packages/gradle/src/generators/ci-workflow/files/github/.github/workflows/__workflowFileName__.yml.template b/packages/gradle/src/generators/ci-workflow/files/github/.github/workflows/__workflowFileName__.yml.template index 3f7227ec8a..2a384492c6 100644 --- a/packages/gradle/src/generators/ci-workflow/files/github/.github/workflows/__workflowFileName__.yml.template +++ b/packages/gradle/src/generators/ci-workflow/files/github/.github/workflows/__workflowFileName__.yml.template @@ -25,15 +25,15 @@ jobs: <% if (connectedToCloud) { %># Uncomment this line to enable task distribution<% } else { %># Connect your workspace by running "nx connect" and uncomment this line to enable task distribution<% } %> # - run: <%= packageManagerPrefix %> nx-cloud start-ci-run --distribute-on="3 linux-medium-jvm" --stop-agents-after="build" - - name: Set up JDK 17 for x64 + - name: Set up JDK 21 for x64 uses: actions/setup-java@v4 with: - java-version: '17' + java-version: '21' distribution: 'temurin' architecture: x64 - name: Setup Gradle - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@v4 - uses: nrwl/nx-set-shas@v4 diff --git a/packages/gradle/src/generators/init/init.spec.ts b/packages/gradle/src/generators/init/init.spec.ts index 881688c79f..42a1e09bf6 100644 --- a/packages/gradle/src/generators/init/init.spec.ts +++ b/packages/gradle/src/generators/init/init.spec.ts @@ -24,7 +24,6 @@ describe('@nx/gradle:init', () => { "options": { "buildTargetName": "build", "classesTargetName": "classes", - "includeSubprojectsTasks": false, "testTargetName": "test", }, "plugin": "@nx/gradle", @@ -49,7 +48,6 @@ describe('@nx/gradle:init', () => { "options": { "buildTargetName": "build", "classesTargetName": "classes", - "includeSubprojectsTasks": false, "testTargetName": "test", }, "plugin": "@nx/gradle", diff --git a/packages/gradle/src/generators/init/init.ts b/packages/gradle/src/generators/init/init.ts index 2a7f9028ec..55950788aa 100644 --- a/packages/gradle/src/generators/init/init.ts +++ b/packages/gradle/src/generators/init/init.ts @@ -9,7 +9,11 @@ import { Tree, updateNxJson, } from '@nx/devkit'; -import { nxVersion } from '../../utils/versions'; +import { + gradleProjectGraphPluginName, + gradleProjectGraphVersion, + nxVersion, +} from '../../utils/versions'; import { InitGeneratorSchema } from './schema'; import { hasGradlePlugin } from '../../utils/has-gradle-plugin'; import { dirname, join, basename } from 'path'; @@ -52,7 +56,6 @@ function addPlugin(tree: Tree) { testTargetName: 'test', classesTargetName: 'classes', buildTargetName: 'build', - includeSubprojectsTasks: false, }, }); updateNxJson(tree, nxJson); @@ -67,16 +70,18 @@ export async function addBuildGradleFileNextToSettingsGradle(tree: Tree) { '**/settings.gradle?(.kts)', ]); settingsGradleFiles.forEach((settingsGradleFile) => { - addProjectReportToBuildGradle(settingsGradleFile, tree); + addNxProjectGraphPluginToBuildGradle(settingsGradleFile, tree); }); } /** * - creates a build.gradle file next to the settings.gradle file if it does not exist. - * - adds the project-report plugin to the build.gradle file if it does not exist. - * - adds a task to generate project reports for all subprojects and included builds. + * - adds the NxProjectGraphPlugin plugin to the build.gradle file if it does not exist. */ -function addProjectReportToBuildGradle(settingsGradleFile: string, tree: Tree) { +function addNxProjectGraphPluginToBuildGradle( + settingsGradleFile: string, + tree: Tree +) { const filename = basename(settingsGradleFile); let gradleFilePath = 'build.gradle'; if (filename.endsWith('.kts')) { @@ -90,53 +95,49 @@ function addProjectReportToBuildGradle(settingsGradleFile: string, tree: Tree) { buildGradleContent = tree.read(gradleFilePath).toString(); } - if (buildGradleContent.includes('allprojects')) { - if (!buildGradleContent.includes('"project-report"')) { - logger.warn(`Please add the project-report plugin to your ${gradleFilePath}: -allprojects { - apply { - plugin("project-report") - } -}`); + const nxProjectGraphReportPlugin = filename.endsWith('.kts') + ? `id("${gradleProjectGraphPluginName}") version("${gradleProjectGraphVersion}")` + : `id "${gradleProjectGraphPluginName}" version "${gradleProjectGraphVersion}"`; + if (buildGradleContent.includes('plugins {')) { + if (!buildGradleContent.includes(gradleProjectGraphPluginName)) { + buildGradleContent = buildGradleContent.replace( + 'plugins {', + `plugins { + ${nxProjectGraphReportPlugin}` + ); } } else { - buildGradleContent += `\n\rallprojects { + buildGradleContent = `plugins { + ${nxProjectGraphReportPlugin} +}\n\r${buildGradleContent}`; + } + + const applyNxProjectGraphReportPlugin = `plugin("${gradleProjectGraphPluginName}")`; + if (buildGradleContent.includes('allprojects {')) { + if ( + !buildGradleContent.includes( + `plugin("${gradleProjectGraphPluginName}")` + ) && + !buildGradleContent.includes(`plugin('${gradleProjectGraphPluginName}')`) + ) { + logger.warn( + `Please add the ${gradleProjectGraphPluginName} plugin to your ${gradleFilePath}: +allprojects { apply { - plugin("project-report") + ${applyNxProjectGraphReportPlugin} } -}`; +}` + ); + } + } else { + buildGradleContent = `${buildGradleContent}\n\rallprojects { + apply { + ${applyNxProjectGraphReportPlugin} + } + }`; } - if (!buildGradleContent.includes(`tasks.register("projectReportAll")`)) { - if (gradleFilePath.endsWith('.kts')) { - buildGradleContent += `\n\rtasks.register("projectReportAll") { - // All project reports of subprojects - allprojects.forEach { - dependsOn(it.tasks.get("projectReport")) - } - - // All projectReportAll of included builds - gradle.includedBuilds.forEach { - dependsOn(it.task(":projectReportAll")) - } -}`; - } else { - buildGradleContent += `\n\rtasks.register("projectReportAll") { - // All project reports of subprojects - allprojects.forEach { - dependsOn(it.tasks.getAt("projectReport")) - } - - // All projectReportAll of included builds - gradle.includedBuilds.forEach { - dependsOn(it.task(":projectReportAll")) - } - }`; - } - } - if (buildGradleContent) { - tree.write(gradleFilePath, buildGradleContent); - } + tree.write(gradleFilePath, buildGradleContent); } export function updateNxJsonConfiguration(tree: Tree) { diff --git a/packages/gradle/src/migrations/19-4-0/add-project-report-all.ts b/packages/gradle/src/migrations/19-4-0/add-project-report-all.ts index 0d9824e95e..d022419548 100644 --- a/packages/gradle/src/migrations/19-4-0/add-project-report-all.ts +++ b/packages/gradle/src/migrations/19-4-0/add-project-report-all.ts @@ -1,5 +1,5 @@ -import { Tree } from '@nx/devkit'; -import { addBuildGradleFileNextToSettingsGradle } from '../../generators/init/init'; +import { globAsync, logger, Tree } from '@nx/devkit'; +import { basename, dirname, join } from 'node:path'; /** * This migration adds task `projectReportAll` to build.gradle files @@ -7,3 +7,83 @@ import { addBuildGradleFileNextToSettingsGradle } from '../../generators/init/in export default async function update(tree: Tree) { await addBuildGradleFileNextToSettingsGradle(tree); } + +/** + * This function creates and populate build.gradle file next to the settings.gradle file. + */ +export async function addBuildGradleFileNextToSettingsGradle(tree: Tree) { + const settingsGradleFiles = await globAsync(tree, [ + '**/settings.gradle?(.kts)', + ]); + settingsGradleFiles.forEach((settingsGradleFile) => { + addProjectReportToBuildGradle(settingsGradleFile, tree); + }); +} + +/** + * - creates a build.gradle file next to the settings.gradle file if it does not exist. + * - adds the project-report plugin to the build.gradle file if it does not exist. + * - adds a task to generate project reports for all subprojects and included builds. + */ +function addProjectReportToBuildGradle(settingsGradleFile: string, tree: Tree) { + const filename = basename(settingsGradleFile); + let gradleFilePath = 'build.gradle'; + if (filename.endsWith('.kts')) { + gradleFilePath = 'build.gradle.kts'; + } + gradleFilePath = join(dirname(settingsGradleFile), gradleFilePath); + let buildGradleContent = ''; + if (!tree.exists(gradleFilePath)) { + tree.write(gradleFilePath, buildGradleContent); // create a build.gradle file near settings.gradle file if it does not exist + } else { + buildGradleContent = tree.read(gradleFilePath).toString(); + } + + if (buildGradleContent.includes('allprojects')) { + if (!buildGradleContent.includes('"project-report"')) { + logger.warn(`Please add the project-report plugin to your ${gradleFilePath}: +allprojects { + apply { + plugin("project-report") + } +}`); + } + } else { + buildGradleContent += `\n\rallprojects { + apply { + plugin("project-report") + } +}`; + } + + if (!buildGradleContent.includes(`tasks.register("projectReportAll")`)) { + if (gradleFilePath.endsWith('.kts')) { + buildGradleContent += `\n\rtasks.register("projectReportAll") { + // All project reports of subprojects + allprojects.forEach { + dependsOn(it.tasks.get("projectReport")) + } + + // All projectReportAll of included builds + gradle.includedBuilds.forEach { + dependsOn(it.task(":projectReportAll")) + } +}`; + } else { + buildGradleContent += `\n\rtasks.register("projectReportAll") { + // All project reports of subprojects + allprojects.forEach { + dependsOn(it.tasks.getAt("projectReport")) + } + + // All projectReportAll of included builds + gradle.includedBuilds.forEach { + dependsOn(it.task(":projectReportAll")) + } + }`; + } + } + if (buildGradleContent) { + tree.write(gradleFilePath, buildGradleContent); + } +} diff --git a/packages/gradle/src/migrations/20-2-0/add-include-subprojects-tasks.md b/packages/gradle/src/migrations/20-2-0/add-include-subprojects-tasks.md index b6ddf6d0e5..fc3742986d 100644 --- a/packages/gradle/src/migrations/20-2-0/add-include-subprojects-tasks.md +++ b/packages/gradle/src/migrations/20-2-0/add-include-subprojects-tasks.md @@ -1,11 +1,9 @@ -#### Add includeSubprojectsTasks to build.gradle File +#### Add includeSubprojectsTasks to @nx/gradle Plugin Options -Add includeSubprojectsTasks to build.gradle file +Add includeSubprojectsTasks to @nx/gradle plugin options in nx.json file #### Sample Code Changes -Update import paths for `withModuleFederation` and `withModuleFederationForSSR`. - {% tabs %} {% tab label="Before" %} diff --git a/packages/gradle/src/migrations/20-2-0/add-include-subprojects-tasks.ts b/packages/gradle/src/migrations/20-2-0/add-include-subprojects-tasks.ts index b81506bbdf..216edef9bb 100644 --- a/packages/gradle/src/migrations/20-2-0/add-include-subprojects-tasks.ts +++ b/packages/gradle/src/migrations/20-2-0/add-include-subprojects-tasks.ts @@ -1,6 +1,6 @@ import { Tree, readNxJson, updateNxJson } from '@nx/devkit'; import { hasGradlePlugin } from '../../utils/has-gradle-plugin'; -import { GradlePluginOptions } from '../../plugin/nodes'; +import { GradlePluginOptions } from '../../plugin-v1/nodes'; // This function add options includeSubprojectsTasks as true in nx.json for gradle plugin export default function update(tree: Tree) { diff --git a/packages/gradle/src/migrations/21-0-0/change-plugin-to-v1.md b/packages/gradle/src/migrations/21-0-0/change-plugin-to-v1.md new file mode 100644 index 0000000000..99023a0c2f --- /dev/null +++ b/packages/gradle/src/migrations/21-0-0/change-plugin-to-v1.md @@ -0,0 +1,26 @@ +#### Change @nx/gradle plugin to @nx/gradle/plugin-v1 + +Change @nx/gradle plugin to version 1 in nx.json + +#### Sample Code Changes + +{% tabs %} +{% tab label="Before" %} + +```json {% fileName="nx.json" %} +{ + "plugins": ["@nx/gradle"] +} +``` + +{% /tab %} +{% tab label="After" %} + +```json {% highlightLines=[5] fileName="nx.json" %} +{ + "plugins": ["@nx/gradle/plugin-v1"] +} +``` + +{% /tab %} +{% /tabs %} diff --git a/packages/gradle/src/migrations/21-0-0/change-plugin-to-v1.spec.ts b/packages/gradle/src/migrations/21-0-0/change-plugin-to-v1.spec.ts new file mode 100644 index 0000000000..ebb455143d --- /dev/null +++ b/packages/gradle/src/migrations/21-0-0/change-plugin-to-v1.spec.ts @@ -0,0 +1,57 @@ +import { Tree, readNxJson } from '@nx/devkit'; +import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; +import update from './change-plugin-to-v1'; + +describe('ChangePluginToV1', () => { + let tree: Tree; + + beforeAll(() => { + tree = createTreeWithEmptyWorkspace(); + }); + + it('should not add @nx/gradle plugin if it does not exist', async () => { + tree.write('nx.json', JSON.stringify({ namedInputs: {} })); + update(tree); + expect(readNxJson(tree)).toMatchInlineSnapshot(` + { + "namedInputs": {}, + } + `); + }); + + it('should change @nx/gradle to @nx/gradle/plugin-v1 plugin', async () => { + tree.write('nx.json', JSON.stringify({ plugins: ['@nx/gradle'] })); + update(tree); + expect(readNxJson(tree)).toMatchInlineSnapshot(` + { + "plugins": [ + "@nx/gradle/plugin-v1", + ], + } + `); + }); + + it('should add change to @nx/gradle plugin with options', async () => { + tree.write( + 'nx.json', + JSON.stringify({ + plugins: [ + { plugin: '@nx/gradle', options: { testTargetName: 'test' } }, + ], + }) + ); + update(tree); + expect(readNxJson(tree)).toMatchInlineSnapshot(` + { + "plugins": [ + { + "options": { + "testTargetName": "test", + }, + "plugin": "@nx/gradle/plugin-v1", + }, + ], + } + `); + }); +}); diff --git a/packages/gradle/src/migrations/21-0-0/change-plugin-to-v1.ts b/packages/gradle/src/migrations/21-0-0/change-plugin-to-v1.ts new file mode 100644 index 0000000000..3bb8745229 --- /dev/null +++ b/packages/gradle/src/migrations/21-0-0/change-plugin-to-v1.ts @@ -0,0 +1,25 @@ +import { Tree, readNxJson, updateNxJson } from '@nx/devkit'; +import { hasGradlePlugin } from '../../utils/has-gradle-plugin'; + +/* This function changes the plugin to v1 + * Replace @nx/gradle with @nx/gradle/plugin-v1 + */ +export default function update(tree: Tree) { + const nxJson = readNxJson(tree); + if (!nxJson) { + return; + } + if (!hasGradlePlugin(tree)) { + return; + } + let gradlePluginIndex = nxJson.plugins.findIndex((p) => + typeof p === 'string' ? p === '@nx/gradle' : p.plugin === '@nx/gradle' + ); + let gradlePlugin = nxJson.plugins[gradlePluginIndex]; + if (typeof gradlePlugin === 'string') { + nxJson.plugins[gradlePluginIndex] = '@nx/gradle/plugin-v1'; + } else { + gradlePlugin.plugin = '@nx/gradle/plugin-v1'; + } + updateNxJson(tree, nxJson); +} diff --git a/packages/gradle/src/plugin-v1/dependencies.ts b/packages/gradle/src/plugin-v1/dependencies.ts new file mode 100644 index 0000000000..8a72bbce17 --- /dev/null +++ b/packages/gradle/src/plugin-v1/dependencies.ts @@ -0,0 +1,96 @@ +import { + CreateDependencies, + CreateDependenciesContext, + DependencyType, + FileMap, + RawProjectGraphDependency, + validateDependency, +} from '@nx/devkit'; +import { basename, dirname } from 'node:path'; + +import { getCurrentGradleReport } from './utils/get-gradle-report'; +import { GRADLE_BUILD_FILES } from '../utils/split-config-files'; + +export const createDependencies: CreateDependencies = async ( + _, + context: CreateDependenciesContext +) => { + const gradleFiles: string[] = findGradleFiles(context.filesToProcess); + if (gradleFiles.length === 0) { + return []; + } + + const gradleDependenciesStart = performance.mark('gradleDependencies:start'); + const { + gradleFileToGradleProjectMap, + gradleProjectNameToProjectRootMap, + gradleProjectToDepsMap, + gradleProjectToChildProjects, + } = getCurrentGradleReport(); + const dependencies: Set = new Set(); + + for (const gradleFile of gradleFiles) { + const gradleProject = gradleFileToGradleProjectMap.get(gradleFile); + const projectName = Object.values(context.projects).find( + (project) => project.root === dirname(gradleFile) + )?.name; + const dependedProjects: Set = + gradleProjectToDepsMap.get(gradleProject); + + if (projectName && dependedProjects?.size) { + dependedProjects?.forEach((dependedProject) => { + const targetProjectRoot = gradleProjectNameToProjectRootMap.get( + dependedProject + ) as string; + const targetProjectName = Object.values(context.projects).find( + (project) => project.root === targetProjectRoot + )?.name; + if (targetProjectName) { + const dependency: RawProjectGraphDependency = { + source: projectName as string, + target: targetProjectName as string, + type: DependencyType.static, + sourceFile: gradleFile, + }; + validateDependency(dependency, context); + dependencies.add(dependency); + } + }); + } + gradleProjectToChildProjects.get(gradleProject)?.forEach((childProject) => { + if (childProject) { + const dependency: RawProjectGraphDependency = { + source: projectName as string, + target: childProject, + type: DependencyType.static, + sourceFile: gradleFile, + }; + validateDependency(dependency, context); + dependencies.add(dependency); + } + }); + } + + const gradleDependenciesEnd = performance.mark('gradleDependencies:end'); + performance.measure( + 'gradleDependencies', + gradleDependenciesStart.name, + gradleDependenciesEnd.name + ); + + return Array.from(dependencies); +}; + +function findGradleFiles(fileMap: FileMap): string[] { + const gradleFiles: string[] = []; + + for (const [_, files] of Object.entries(fileMap.projectFileMap)) { + for (const file of files) { + if (GRADLE_BUILD_FILES.has(basename(file.file))) { + gradleFiles.push(file.file); + } + } + } + + return gradleFiles; +} diff --git a/packages/gradle/src/plugin-v1/nodes.spec.ts b/packages/gradle/src/plugin-v1/nodes.spec.ts new file mode 100644 index 0000000000..ec17dc59aa --- /dev/null +++ b/packages/gradle/src/plugin-v1/nodes.spec.ts @@ -0,0 +1,587 @@ +import { CreateNodesContext } from '@nx/devkit'; + +import { TempFs } from 'nx/src/internal-testing-utils/temp-fs'; +import { type GradleReport } from './utils/get-gradle-report'; + +let gradleReport: GradleReport; +jest.mock('./utils/get-gradle-report', () => { + return { + GRADLE_BUILD_FILES: new Set(['build.gradle', 'build.gradle.kts']), + populateGradleReport: jest.fn().mockImplementation(() => void 0), + getCurrentGradleReport: jest.fn().mockImplementation(() => gradleReport), + }; +}); + +import { createNodesV2 } from './nodes'; + +describe('@nx/gradle/plugin-v1/nodes', () => { + let createNodesFunction = createNodesV2[1]; + let context: CreateNodesContext; + let tempFs: TempFs; + let cwd: string; + + beforeEach(async () => { + tempFs = new TempFs('test'); + gradleReport = { + gradleFileToGradleProjectMap: new Map([ + ['proj/build.gradle', 'proj'], + ]), + gradleProjectToDepsMap: new Map>(), + gradleFileToOutputDirsMap: new Map>([ + ['proj/build.gradle', new Map([['build', 'build']])], + ]), + gradleProjectToTasksMap: new Map>([ + ['proj', new Set(['test'])], + ]), + gradleProjectToTasksTypeMap: new Map>([ + [ + 'proj', + new Map([ + ['test', 'Verification'], + ['build', 'Build'], + ]), + ], + ]), + gradleProjectToProjectName: new Map([['proj', 'proj']]), + gradleProjectNameToProjectRootMap: new Map([ + ['proj', 'proj'], + ]), + gradleProjectToChildProjects: new Map(), + }; + cwd = process.cwd(); + process.chdir(tempFs.tempDir); + context = { + nxJsonConfiguration: { + namedInputs: { + default: ['{projectRoot}/**/*'], + production: ['!{projectRoot}/**/*.spec.ts'], + }, + }, + workspaceRoot: tempFs.tempDir, + configFiles: [], + }; + + await tempFs.createFiles({ + 'proj/build.gradle': ``, + gradlew: '', + }); + }); + + afterEach(() => { + jest.resetModules(); + process.chdir(cwd); + }); + + it('should create nodes based on gradle', async () => { + const results = await createNodesFunction( + ['proj/build.gradle'], + { + buildTargetName: 'build', + }, + context + ); + + expect(results).toMatchInlineSnapshot(` + [ + [ + "proj/build.gradle", + { + "projects": { + "proj": { + "metadata": { + "targetGroups": { + "Verification": [ + "test", + ], + }, + "technologies": [ + "gradle", + ], + }, + "name": "proj", + "projectType": "application", + "targets": { + "test": { + "cache": true, + "command": "./gradlew proj:test", + "dependsOn": [ + "testClasses", + ], + "inputs": [ + "default", + "^production", + ], + "metadata": { + "help": { + "command": "./gradlew help --task proj:test", + "example": { + "options": { + "args": [ + "--rerun", + ], + }, + }, + }, + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": ".", + }, + }, + }, + }, + }, + }, + ], + ] + `); + }); + + it('should create nodes include subprojects tasks', async () => { + const results = await createNodesFunction( + ['proj/build.gradle'], + { + buildTargetName: 'build', + includeSubprojectsTasks: true, + }, + context + ); + + expect(results).toMatchInlineSnapshot(` + [ + [ + "proj/build.gradle", + { + "projects": { + "proj": { + "metadata": { + "targetGroups": { + "Build": [ + "build", + ], + "Verification": [ + "test", + ], + }, + "technologies": [ + "gradle", + ], + }, + "name": "proj", + "projectType": "application", + "targets": { + "build": { + "cache": true, + "command": "./gradlew proj:build", + "dependsOn": [ + "^build", + "classes", + "test", + ], + "inputs": [ + "production", + "^production", + ], + "metadata": { + "help": { + "command": "./gradlew help --task proj:build", + "example": { + "options": { + "args": [ + "--rerun", + ], + }, + }, + }, + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": ".", + }, + "outputs": [ + "build", + ], + }, + "test": { + "cache": true, + "command": "./gradlew proj:test", + "dependsOn": [ + "testClasses", + ], + "inputs": [ + "default", + "^production", + ], + "metadata": { + "help": { + "command": "./gradlew help --task proj:test", + "example": { + "options": { + "args": [ + "--rerun", + ], + }, + }, + }, + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": ".", + }, + }, + }, + }, + }, + }, + ], + ] + `); + }); + + it('should create nodes based on gradle for nested project root', async () => { + gradleReport = { + gradleFileToGradleProjectMap: new Map([ + ['nested/nested/proj/build.gradle', 'proj'], + ]), + gradleProjectToDepsMap: new Map>(), + gradleFileToOutputDirsMap: new Map>([ + ['nested/nested/proj/build.gradle', new Map([['build', 'build']])], + ]), + gradleProjectToTasksMap: new Map>([ + ['proj', new Set(['test'])], + ]), + gradleProjectToTasksTypeMap: new Map>([ + ['proj', new Map([['test', 'Verification']])], + ]), + gradleProjectToProjectName: new Map([['proj', 'proj']]), + gradleProjectNameToProjectRootMap: new Map([ + ['proj', 'proj'], + ]), + gradleProjectToChildProjects: new Map(), + }; + await tempFs.createFiles({ + 'nested/nested/proj/build.gradle': ``, + }); + + const results = await createNodesFunction( + ['nested/nested/proj/build.gradle'], + { + buildTargetName: 'build', + }, + context + ); + + expect(results).toMatchInlineSnapshot(` + [ + [ + "nested/nested/proj/build.gradle", + { + "projects": { + "nested/nested/proj": { + "metadata": { + "targetGroups": { + "Verification": [ + "test", + ], + }, + "technologies": [ + "gradle", + ], + }, + "name": "proj", + "projectType": "application", + "targets": { + "test": { + "cache": true, + "command": "./gradlew proj:test", + "dependsOn": [ + "testClasses", + ], + "inputs": [ + "default", + "^production", + ], + "metadata": { + "help": { + "command": "./gradlew help --task proj:test", + "example": { + "options": { + "args": [ + "--rerun", + ], + }, + }, + }, + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": ".", + }, + }, + }, + }, + }, + }, + ], + ] + `); + }); + + describe('with atomized tests targets', () => { + beforeEach(async () => { + gradleReport = { + gradleFileToGradleProjectMap: new Map([ + ['nested/nested/proj/build.gradle', 'proj'], + ]), + gradleProjectToDepsMap: new Map>(), + gradleFileToOutputDirsMap: new Map>([ + ['nested/nested/proj/build.gradle', new Map([['build', 'build']])], + ]), + gradleProjectToTasksMap: new Map>([ + ['proj', new Set(['test'])], + ]), + gradleProjectToTasksTypeMap: new Map>([ + ['proj', new Map([['test', 'Test']])], + ]), + gradleProjectToProjectName: new Map([['proj', 'proj']]), + gradleProjectNameToProjectRootMap: new Map([ + ['proj', 'proj'], + ]), + gradleProjectToChildProjects: new Map(), + }; + await tempFs.createFiles({ + 'nested/nested/proj/build.gradle': ``, + }); + await tempFs.createFiles({ + 'proj/src/test/java/test/rootTest.java': ``, + }); + await tempFs.createFiles({ + 'nested/nested/proj/src/test/java/test/aTest.java': ``, + }); + await tempFs.createFiles({ + 'nested/nested/proj/src/test/java/test/bTest.java': ``, + }); + await tempFs.createFiles({ + 'nested/nested/proj/src/test/java/test/cTests.java': ``, + }); + }); + + it('should create nodes with atomized tests targets based on gradle for nested project root', async () => { + const results = await createNodesFunction( + [ + 'nested/nested/proj/build.gradle', + 'proj/src/test/java/test/rootTest.java', + 'nested/nested/proj/src/test/java/test/aTest.java', + 'nested/nested/proj/src/test/java/test/bTest.java', + 'nested/nested/proj/src/test/java/test/cTests.java', + ], + { + buildTargetName: 'build', + ciTargetName: 'test-ci', + }, + context + ); + + expect(results).toMatchInlineSnapshot(` + [ + [ + "nested/nested/proj/build.gradle", + { + "projects": { + "nested/nested/proj": { + "metadata": { + "targetGroups": { + "Test": [ + "test-ci--aTest", + "test-ci--bTest", + "test-ci--cTests", + "test-ci", + "test", + ], + }, + "technologies": [ + "gradle", + ], + }, + "name": "proj", + "projectType": "application", + "targets": { + "test": { + "cache": false, + "command": "./gradlew proj:test", + "dependsOn": [ + "testClasses", + ], + "inputs": [ + "default", + "^production", + ], + "metadata": { + "help": { + "command": "./gradlew help --task proj:test", + "example": { + "options": { + "args": [ + "--rerun", + ], + }, + }, + }, + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": ".", + }, + }, + "test-ci": { + "cache": true, + "dependsOn": [ + { + "params": "forward", + "projects": "self", + "target": "test-ci--aTest", + }, + { + "params": "forward", + "projects": "self", + "target": "test-ci--bTest", + }, + { + "params": "forward", + "projects": "self", + "target": "test-ci--cTests", + }, + ], + "executor": "nx:noop", + "inputs": [ + "default", + "^production", + ], + "metadata": { + "description": "Runs Gradle Tests in CI", + "help": { + "command": "./gradlew help --task proj:test", + "example": { + "options": { + "args": [ + "--rerun", + ], + }, + }, + }, + "nonAtomizedTarget": "test", + "technologies": [ + "gradle", + ], + }, + }, + "test-ci--aTest": { + "cache": true, + "command": "./gradlew proj:test --tests aTest", + "dependsOn": [ + "testClasses", + ], + "inputs": [ + "default", + "^production", + ], + "metadata": { + "description": "Runs Gradle test nested/nested/proj/src/test/java/test/aTest.java in CI", + "help": { + "command": "./gradlew help --task proj:test", + "example": { + "options": { + "args": [ + "--rerun", + ], + }, + }, + }, + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": ".", + }, + }, + "test-ci--bTest": { + "cache": true, + "command": "./gradlew proj:test --tests bTest", + "dependsOn": [ + "testClasses", + ], + "inputs": [ + "default", + "^production", + ], + "metadata": { + "description": "Runs Gradle test nested/nested/proj/src/test/java/test/bTest.java in CI", + "help": { + "command": "./gradlew help --task proj:test", + "example": { + "options": { + "args": [ + "--rerun", + ], + }, + }, + }, + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": ".", + }, + }, + "test-ci--cTests": { + "cache": true, + "command": "./gradlew proj:test --tests cTests", + "dependsOn": [ + "testClasses", + ], + "inputs": [ + "default", + "^production", + ], + "metadata": { + "description": "Runs Gradle test nested/nested/proj/src/test/java/test/cTests.java in CI", + "help": { + "command": "./gradlew help --task proj:test", + "example": { + "options": { + "args": [ + "--rerun", + ], + }, + }, + }, + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": ".", + }, + }, + }, + }, + }, + }, + ], + ] + `); + }); + }); +}); diff --git a/packages/gradle/src/plugin-v1/nodes.ts b/packages/gradle/src/plugin-v1/nodes.ts new file mode 100644 index 0000000000..145e29d807 --- /dev/null +++ b/packages/gradle/src/plugin-v1/nodes.ts @@ -0,0 +1,435 @@ +import { + CreateNodes, + CreateNodesV2, + CreateNodesContext, + ProjectConfiguration, + TargetConfiguration, + createNodesFromFiles, + readJsonFile, + writeJsonFile, + CreateNodesFunction, + logger, +} from '@nx/devkit'; +import { calculateHashForCreateNodes } from '@nx/devkit/src/utils/calculate-hash-for-create-nodes'; +import { existsSync } from 'node:fs'; +import { basename, dirname, join } from 'node:path'; +import { workspaceDataDirectory } from 'nx/src/utils/cache-directory'; +import { findProjectForPath } from 'nx/src/devkit-internals'; + +import { + populateGradleReport, + getCurrentGradleReport, + GradleReport, +} from './utils/get-gradle-report'; +import { hashObject } from 'nx/src/hasher/file-hasher'; +import { + gradleConfigAndTestGlob, + gradleConfigGlob, + splitConfigFiles, +} from '../utils/split-config-files'; +import { getGradleExecFile, findGradlewFile } from '../utils/exec-gradle'; + +const cacheableTaskType = new Set(['Build', 'Verification']); +const dependsOnMap = { + build: ['^build', 'classes', 'test'], + testClasses: ['classes'], + test: ['testClasses'], + classes: ['^classes'], +}; + +interface GradleTask { + type: string; + name: string; +} + +export interface GradlePluginOptions { + includeSubprojectsTasks?: boolean; // default is false, show all gradle tasks in the project + ciTargetName?: string; + testTargetName?: string; + classesTargetName?: string; + buildTargetName?: string; + [taskTargetName: string]: string | undefined | boolean; +} + +function normalizeOptions(options: GradlePluginOptions): GradlePluginOptions { + options ??= {}; + options.testTargetName ??= 'test'; + options.classesTargetName ??= 'classes'; + options.buildTargetName ??= 'build'; + return options; +} + +type GradleTargets = Record>; + +function readTargetsCache(cachePath: string): GradleTargets { + return existsSync(cachePath) ? readJsonFile(cachePath) : {}; +} + +export function writeTargetsToCache(cachePath: string, results: GradleTargets) { + writeJsonFile(cachePath, results); +} + +export const createNodesV2: CreateNodesV2 = [ + gradleConfigAndTestGlob, + async (files, options, context) => { + const { buildFiles, projectRoots, gradlewFiles, testFiles } = + splitConfigFiles(files); + const optionsHash = hashObject(options); + const cachePath = join( + workspaceDataDirectory, + `gradle-${optionsHash}.hash` + ); + const targetsCache = readTargetsCache(cachePath); + + await populateGradleReport( + context.workspaceRoot, + gradlewFiles.map((f) => join(context.workspaceRoot, f)) + ); + const gradleReport = getCurrentGradleReport(); + const gradleProjectRootToTestFilesMap = getGradleProjectRootToTestFilesMap( + testFiles, + projectRoots + ); + + try { + return createNodesFromFiles( + makeCreateNodesForGradleConfigFile( + gradleReport, + targetsCache, + gradleProjectRootToTestFilesMap + ), + buildFiles, + options, + context + ); + } finally { + writeTargetsToCache(cachePath, targetsCache); + } + }, +]; + +export const makeCreateNodesForGradleConfigFile = + ( + gradleReport: GradleReport, + targetsCache: GradleTargets = {}, + gradleProjectRootToTestFilesMap: Record = {} + ): CreateNodesFunction => + async ( + gradleFilePath, + options: GradlePluginOptions | undefined, + context: CreateNodesContext + ) => { + const projectRoot = dirname(gradleFilePath); + options = normalizeOptions(options); + + const hash = await calculateHashForCreateNodes( + projectRoot, + options ?? {}, + context + ); + targetsCache[hash] ??= await createGradleProject( + gradleReport, + gradleFilePath, + options, + context, + gradleProjectRootToTestFilesMap[projectRoot] + ); + const project = targetsCache[hash]; + if (!project) { + return {}; + } + return { + projects: { + [projectRoot]: project, + }, + }; + }; + +/** + @deprecated This is replaced with {@link createNodesV2}. Update your plugin to export its own `createNodesV2` function that wraps this one instead. + This function will change to the v2 function in Nx 20. + */ +export const createNodes: CreateNodes = [ + gradleConfigGlob, + async (buildFile, options, context) => { + logger.warn( + '`createNodes` is deprecated. Update your plugin to utilize createNodesV2 instead. In Nx 20, this will change to the createNodesV2 API.' + ); + const { gradlewFiles } = splitConfigFiles(context.configFiles); + await populateGradleReport(context.workspaceRoot, gradlewFiles); + const gradleReport = getCurrentGradleReport(); + const internalCreateNodes = + makeCreateNodesForGradleConfigFile(gradleReport); + return await internalCreateNodes(buildFile, options, context); + }, +]; + +async function createGradleProject( + gradleReport: GradleReport, + gradleFilePath: string, + options: GradlePluginOptions | undefined, + context: CreateNodesContext, + testFiles = [] +) { + try { + const { + gradleProjectToTasksTypeMap, + gradleProjectToTasksMap, + gradleFileToOutputDirsMap, + gradleFileToGradleProjectMap, + gradleProjectToProjectName, + } = gradleReport; + + const gradleProject = gradleFileToGradleProjectMap.get( + gradleFilePath + ) as string; + const projectName = gradleProjectToProjectName.get(gradleProject); + if (!projectName) { + return; + } + + const tasksTypeMap: Map = gradleProjectToTasksTypeMap.get( + gradleProject + ) as Map; + const tasksSet = gradleProjectToTasksMap.get(gradleProject) as Set; + let tasks: GradleTask[] = []; + tasksSet.forEach((taskName) => { + tasks.push({ + type: tasksTypeMap?.get(taskName) as string, + name: taskName, + }); + }); + if (options.includeSubprojectsTasks) { + tasksTypeMap.forEach((taskType, taskName) => { + if (!tasksSet.has(taskName)) { + tasks.push({ + type: taskType, + name: taskName, + }); + } + }); + } + + const outputDirs = gradleFileToOutputDirsMap.get(gradleFilePath) as Map< + string, + string + >; + + const { targets, targetGroups } = await createGradleTargets( + tasks, + options, + context, + outputDirs, + gradleProject, + gradleFilePath, + testFiles + ); + const project: Partial = { + name: projectName, + projectType: 'application', + targets, + metadata: { + targetGroups, + technologies: ['gradle'], + }, + }; + + return project; + } catch (e) { + console.error(e); + return undefined; + } +} + +async function createGradleTargets( + tasks: GradleTask[], + options: GradlePluginOptions | undefined, + context: CreateNodesContext, + outputDirs: Map, + gradleProject: string, + gradleBuildFilePath: string, + testFiles: string[] = [] +): Promise<{ + targetGroups: Record; + targets: Record; +}> { + const inputsMap = createInputsMap(context); + const gradlewFileDirectory = dirname( + findGradlewFile(gradleBuildFilePath, context.workspaceRoot) + ); + + const targets: Record = {}; + const targetGroups: Record = {}; + for (const task of tasks) { + const targetName = options?.[`${task.name}TargetName`] ?? task.name; + + let outputs = [outputDirs.get(task.name)].filter(Boolean); + if (task.name === 'test') { + outputs = [ + outputDirs.get('testReport'), + outputDirs.get('testResults'), + ].filter(Boolean); + getTestCiTargets( + testFiles, + gradleProject, + targetName as string, + options.ciTargetName, + inputsMap['test'], + outputs, + task.type, + targets, + targetGroups, + gradlewFileDirectory + ); + } + + const taskCommandToRun = `${gradleProject ? gradleProject + ':' : ''}${ + task.name + }`; + + targets[targetName as string] = { + command: `${getGradleExecFile()} ${taskCommandToRun}`, + options: { + cwd: gradlewFileDirectory, + }, + cache: cacheableTaskType.has(task.type), + inputs: inputsMap[task.name], + dependsOn: dependsOnMap[task.name], + metadata: { + technologies: ['gradle'], + help: { + command: `${getGradleExecFile()} help --task ${taskCommandToRun}`, + example: { + options: { + args: ['--rerun'], + }, + }, + }, + }, + ...(outputs && outputs.length ? { outputs } : {}), + }; + + if (task.type) { + if (!targetGroups[task.type]) { + targetGroups[task.type] = []; + } + targetGroups[task.type].push(targetName as string); + } + } + return { targetGroups, targets }; +} + +function createInputsMap( + context: CreateNodesContext +): Record { + const namedInputs = context.nxJsonConfiguration.namedInputs; + return { + build: namedInputs?.production + ? ['production', '^production'] + : ['default', '^default'], + test: ['default', namedInputs?.production ? '^production' : '^default'], + classes: namedInputs?.production + ? ['production', '^production'] + : ['default', '^default'], + }; +} + +function getTestCiTargets( + testFiles: string[], + gradleProject: string, + testTargetName: string, + ciTargetName: string, + inputs: TargetConfiguration['inputs'], + outputs: string[], + targetGroupName: string, + targets: Record, + targetGroups: Record, + gradlewFileDirectory: string +): void { + if (!testFiles || testFiles.length === 0 || !ciTargetName) { + return; + } + const taskCommandToRun = `${gradleProject ? gradleProject + ':' : ''}test`; + + if (!targetGroups[targetGroupName]) { + targetGroups[targetGroupName] = []; + } + + const dependsOn: TargetConfiguration['dependsOn'] = []; + testFiles.forEach((testFile) => { + const testName = basename(testFile).split('.')[0]; + const targetName = ciTargetName + '--' + testName; + + targets[targetName] = { + command: `${getGradleExecFile()} ${taskCommandToRun} --tests ${testName}`, + options: { + cwd: gradlewFileDirectory, + }, + cache: true, + inputs, + dependsOn: dependsOnMap['test'], + metadata: { + technologies: ['gradle'], + description: `Runs Gradle test ${testFile} in CI`, + help: { + command: `${getGradleExecFile()} help --task ${taskCommandToRun}`, + example: { + options: { + args: ['--rerun'], + }, + }, + }, + }, + ...(outputs && outputs.length > 0 ? { outputs } : {}), + }; + targetGroups[targetGroupName].push(targetName); + dependsOn.push({ + target: targetName, + projects: 'self', + params: 'forward', + }); + }); + + targets[ciTargetName] = { + executor: 'nx:noop', + cache: true, + inputs, + dependsOn: dependsOn, + ...(outputs && outputs.length > 0 ? { outputs } : {}), + metadata: { + technologies: ['gradle'], + description: 'Runs Gradle Tests in CI', + nonAtomizedTarget: testTargetName, + help: { + command: `${getGradleExecFile()} help --task ${taskCommandToRun}`, + example: { + options: { + args: ['--rerun'], + }, + }, + }, + }, + }; + targetGroups[targetGroupName].push(ciTargetName); +} + +function getGradleProjectRootToTestFilesMap( + testFiles: string[], + projectRoots: string[] +): Record | undefined { + if (testFiles.length === 0 || projectRoots.length === 0) { + return; + } + const roots = new Map(projectRoots.map((root) => [root, root])); + const testFilesToGradleProjectMap: Record = {}; + testFiles.forEach((testFile) => { + const projectRoot = findProjectForPath(testFile, roots); + if (projectRoot) { + if (!testFilesToGradleProjectMap[projectRoot]) { + testFilesToGradleProjectMap[projectRoot] = []; + } + testFilesToGradleProjectMap[projectRoot].push(testFile); + } + }); + return testFilesToGradleProjectMap; +} diff --git a/packages/gradle/src/utils/__mocks__/gradle-composite-dependencies.txt b/packages/gradle/src/plugin-v1/utils/__mocks__/gradle-composite-dependencies.txt similarity index 100% rename from packages/gradle/src/utils/__mocks__/gradle-composite-dependencies.txt rename to packages/gradle/src/plugin-v1/utils/__mocks__/gradle-composite-dependencies.txt diff --git a/packages/gradle/src/utils/__mocks__/gradle-custom-dependencies.txt b/packages/gradle/src/plugin-v1/utils/__mocks__/gradle-custom-dependencies.txt similarity index 100% rename from packages/gradle/src/utils/__mocks__/gradle-custom-dependencies.txt rename to packages/gradle/src/plugin-v1/utils/__mocks__/gradle-custom-dependencies.txt diff --git a/packages/gradle/src/utils/__mocks__/gradle-dependencies.txt b/packages/gradle/src/plugin-v1/utils/__mocks__/gradle-dependencies.txt similarity index 100% rename from packages/gradle/src/utils/__mocks__/gradle-dependencies.txt rename to packages/gradle/src/plugin-v1/utils/__mocks__/gradle-dependencies.txt diff --git a/packages/gradle/src/utils/__mocks__/gradle-project-report-println.txt b/packages/gradle/src/plugin-v1/utils/__mocks__/gradle-project-report-println.txt similarity index 57% rename from packages/gradle/src/utils/__mocks__/gradle-project-report-println.txt rename to packages/gradle/src/plugin-v1/utils/__mocks__/gradle-project-report-println.txt index 25aea1d09d..3f0854d474 100644 --- a/packages/gradle/src/utils/__mocks__/gradle-project-report-println.txt +++ b/packages/gradle/src/plugin-v1/utils/__mocks__/gradle-project-report-println.txt @@ -1,8 +1,5 @@ > Task :dependencyReport -See the report at: file:///tmp/build/reports/project/dependencies.txt - -> Task :htmlDependencyReport -See the report at: file:///tmp/build/reports/project/dependencies/index.html +See the report at: file://__dirname__/__mocks__/gradle-dependencies.txt > Task :propertyReport See the report at: file:///tmp/build/reports/project/properties.txt @@ -11,10 +8,7 @@ See the report at: file:///tmp/build/reports/project/properties.txt See the report at: file:///tmp/build/reports/project/tasks.txt > Task :app:dependencyReport -See the report at: file:///tmp/app/build/reports/project/dependencies.txt - -> Task :app:htmlDependencyReport -See the report at: file:///tmp/app/build/reports/project/dependencies/index.html +See the report at: file://__dirname__/__mocks__/gradle-dependencies.txt > Task :app:propertyReport See the report at: file:///tmp/app/build/reports/project/properties.txt @@ -25,10 +19,7 @@ NAMED TASK1: This is executed during the configuration phase See the report at: file:///tmp/app/build/reports/project/tasks.txt > Task :list:dependencyReport -See the report at: file:///tmp/list/build/reports/project/dependencies.txt - -> Task :list:htmlDependencyReport -See the report at: file:///tmp/list/build/reports/project/dependencies/index.html +See the report at: file://__dirname__/__mocks__/gradle-dependencies.txt > Task :list:propertyReport See the report at: file:///tmp/list/build/reports/project/properties.txt @@ -37,10 +28,7 @@ See the report at: file:///tmp/list/build/reports/project/properties.txt See the report at: file:///tmp/list/build/reports/project/tasks.txt > Task :utilities:dependencyReport -See the report at: file:///tmp/utilities/build/reports/project/dependencies.txt - -> Task :utilities:htmlDependencyReport -See the report at: file:///tmp/utilities/build/reports/project/dependencies/index.html +See the report at: file://__dirname__/__mocks__/gradle-dependencies.txt > Task :utilities:propertyReport See the report at: file:///tmp/utilities/build/reports/project/properties.txt diff --git a/packages/gradle/src/utils/__mocks__/gradle-project-report.txt b/packages/gradle/src/plugin-v1/utils/__mocks__/gradle-project-report.txt similarity index 67% rename from packages/gradle/src/utils/__mocks__/gradle-project-report.txt rename to packages/gradle/src/plugin-v1/utils/__mocks__/gradle-project-report.txt index 9d961171cf..27632b2b6c 100644 --- a/packages/gradle/src/utils/__mocks__/gradle-project-report.txt +++ b/packages/gradle/src/plugin-v1/utils/__mocks__/gradle-project-report.txt @@ -1,5 +1,5 @@ > Task :dependencyReport -See the report at: file:///tmp/build/reports/project/dependencies.txt +See the report at: file://__dirname__/__mocks__/gradle-dependencies.txt > Task :htmlDependencyReport See the report at: file:///tmp/build/reports/project/dependencies/index.html @@ -11,10 +11,7 @@ See the report at: file:///tmp/build/reports/project/properties.txt See the report at: file:///tmp/build/reports/project/tasks.txt > Task :app:dependencyReport -See the report at: file:///tmp/app/build/reports/project/dependencies.txt - -> Task :app:htmlDependencyReport -See the report at: file:///tmp/app/build/reports/project/dependencies/index.html +See the report at: file://__dirname__/__mocks__/gradle-dependencies.txt > Task :app:propertyReport See the report at: file:///tmp/app/build/reports/project/properties.txt @@ -23,7 +20,7 @@ See the report at: file:///tmp/app/build/reports/project/properties.txt See the report at: file:///tmp/app/build/reports/project/tasks.txt > Task :list:dependencyReport -See the report at: file:///tmp/list/build/reports/project/dependencies.txt +See the report at: file://__dirname__/__mocks__/gradle-dependencies.txt > Task :list:htmlDependencyReport See the report at: file:///tmp/list/build/reports/project/dependencies/index.html @@ -35,10 +32,7 @@ See the report at: file:///tmp/list/build/reports/project/properties.txt See the report at: file:///tmp/list/build/reports/project/tasks.txt > Task :utilities:dependencyReport -See the report at: file:///tmp/utilities/build/reports/project/dependencies.txt - -> Task :utilities:htmlDependencyReport -See the report at: file:///tmp/utilities/build/reports/project/dependencies/index.html +See the report at: file://__dirname__/__mocks__/gradle-dependencies.txt > Task :utilities:propertyReport See the report at: file:///tmp/utilities/build/reports/project/properties.txt diff --git a/packages/gradle/src/utils/__mocks__/gradle-properties-report-child-projects.txt b/packages/gradle/src/plugin-v1/utils/__mocks__/gradle-properties-report-child-projects.txt similarity index 100% rename from packages/gradle/src/utils/__mocks__/gradle-properties-report-child-projects.txt rename to packages/gradle/src/plugin-v1/utils/__mocks__/gradle-properties-report-child-projects.txt diff --git a/packages/gradle/src/utils/__mocks__/gradle-properties-report-no-child-projects.txt b/packages/gradle/src/plugin-v1/utils/__mocks__/gradle-properties-report-no-child-projects.txt similarity index 100% rename from packages/gradle/src/utils/__mocks__/gradle-properties-report-no-child-projects.txt rename to packages/gradle/src/plugin-v1/utils/__mocks__/gradle-properties-report-no-child-projects.txt diff --git a/packages/gradle/src/utils/get-gradle-report.spec.ts b/packages/gradle/src/plugin-v1/utils/get-gradle-report.spec.ts similarity index 65% rename from packages/gradle/src/utils/get-gradle-report.spec.ts rename to packages/gradle/src/plugin-v1/utils/get-gradle-report.spec.ts index 80af85c937..cba5c9bdaa 100644 --- a/packages/gradle/src/utils/get-gradle-report.spec.ts +++ b/packages/gradle/src/plugin-v1/utils/get-gradle-report.spec.ts @@ -1,31 +1,103 @@ import { readFileSync } from 'fs'; +import { fileSync } from 'tmp'; import { join } from 'path'; import { processGradleDependencies, processProjectReports, + writeGradleReportToCache, } from './get-gradle-report'; describe('processProjectReports', () => { + const tmpFile = fileSync(); + it('should process project reports', () => { const projectReportLines = readFileSync( join(__dirname, '__mocks__/gradle-project-report.txt'), 'utf-8' - ).split('\n'); + ) + .replaceAll('__dirname__', __dirname) + .split('\n'); const report = processProjectReports(projectReportLines); expect( Object.keys(Object.fromEntries(report.gradleProjectToTasksTypeMap)) ).toEqual(['', ':app', ':list', ':utilities']); + + writeGradleReportToCache(tmpFile.name, report); + expect(readFileSync(tmpFile.name).toString()).toMatchInlineSnapshot(` + "{ + "gradleFileToGradleProjectMap": {}, + "gradleProjectToDepsMap": { + "": [ + ":utilities" + ], + ":app": [ + ":utilities" + ], + ":list": [ + ":utilities" + ], + ":utilities": [ + ":utilities" + ] + }, + "gradleFileToOutputDirsMap": {}, + "gradleProjectToTasksTypeMap": { + "": {}, + ":app": {}, + ":list": {}, + ":utilities": {} + }, + "gradleProjectToTasksMap": {}, + "gradleProjectToProjectName": {}, + "gradleProjectNameToProjectRootMap": {}, + "gradleProjectToChildProjects": {} + }" + `); }); it('should process project reports with println', () => { const projectReportLines = readFileSync( join(__dirname, '__mocks__/gradle-project-report-println.txt'), 'utf-8' - ).split('\n'); + ) + .replaceAll('__dirname__', __dirname) + .split('\n'); const report = processProjectReports(projectReportLines); expect( Object.keys(Object.fromEntries(report.gradleProjectToTasksTypeMap)) ).toEqual(['', ':app', ':list', ':utilities']); + + writeGradleReportToCache(tmpFile.name, report); + expect(readFileSync(tmpFile.name).toString()).toMatchInlineSnapshot(` + "{ + "gradleFileToGradleProjectMap": {}, + "gradleProjectToDepsMap": { + "": [ + ":utilities" + ], + ":app": [ + ":utilities" + ], + ":list": [ + ":utilities" + ], + ":utilities": [ + ":utilities" + ] + }, + "gradleFileToOutputDirsMap": {}, + "gradleProjectToTasksTypeMap": { + "": {}, + ":app": {}, + ":list": {}, + ":utilities": {} + }, + "gradleProjectToTasksMap": {}, + "gradleProjectToProjectName": {}, + "gradleProjectNameToProjectRootMap": {}, + "gradleProjectToChildProjects": {} + }" + `); }); it('should process properties report with child projects', () => { diff --git a/packages/gradle/src/utils/get-gradle-report.ts b/packages/gradle/src/plugin-v1/utils/get-gradle-report.ts similarity index 93% rename from packages/gradle/src/utils/get-gradle-report.ts rename to packages/gradle/src/plugin-v1/utils/get-gradle-report.ts index d518cd47b7..0d7bcaae7f 100644 --- a/packages/gradle/src/utils/get-gradle-report.ts +++ b/packages/gradle/src/plugin-v1/utils/get-gradle-report.ts @@ -11,18 +11,15 @@ import { import { hashWithWorkspaceContext } from 'nx/src/utils/workspace-context'; import { dirname } from 'path'; -import { gradleConfigAndTestGlob } from './split-config-files'; -import { - getProjectReportLines, - fileSeparator, - newLineSeparator, -} from './get-project-report-lines'; +import { gradleConfigAndTestGlob } from '../../utils/split-config-files'; +import { getProjectReportLines } from './get-project-report-lines'; import { workspaceDataDirectory } from 'nx/src/utils/cache-directory'; +import { fileSeparator, newLineSeparator } from '../../utils/exec-gradle'; export interface GradleReport { gradleFileToGradleProjectMap: Map; - buildFileToDepsMap: Map>; gradleFileToOutputDirsMap: Map>; + gradleProjectToDepsMap: Map>; gradleProjectToTasksTypeMap: Map>; gradleProjectToTasksMap: Map>; gradleProjectToProjectName: Map; @@ -33,7 +30,7 @@ export interface GradleReport { export interface GradleReportJSON { hash: string; gradleFileToGradleProjectMap: Record; - buildFileToDepsMap: Record>; + gradleProjectToDepsMap: Record>; gradleFileToOutputDirsMap: Record>; gradleProjectToTasksTypeMap: Record>; gradleProjectToTasksMap: Record>; @@ -56,8 +53,10 @@ function readGradleReportCache( gradleFileToGradleProjectMap: new Map( Object.entries(gradleReportJson['gradleFileToGradleProjectMap']) ), - buildFileToDepsMap: new Map( - Object.entries(gradleReportJson['buildFileToDepsMap']) + gradleProjectToDepsMap: new Map( + Object.entries(gradleReportJson['gradleProjectToDepsMap']).map( + ([key, value]) => [key, new Set(value)] + ) ), gradleFileToOutputDirsMap: new Map( Object.entries(gradleReportJson['gradleFileToOutputDirsMap']).map( @@ -96,7 +95,12 @@ export function writeGradleReportToCache( gradleFileToGradleProjectMap: Object.fromEntries( results.gradleFileToGradleProjectMap ), - buildFileToDepsMap: Object.fromEntries(results.buildFileToDepsMap), + gradleProjectToDepsMap: Object.fromEntries( + Array.from(results.gradleProjectToDepsMap).map(([key, value]) => [ + key, + Array.from(value), + ]) + ), gradleFileToOutputDirsMap: Object.fromEntries( Array.from(results.gradleFileToOutputDirsMap).map(([key, value]) => [ key, @@ -215,7 +219,7 @@ export function processProjectReports( * Map of Gradle File path to Gradle Project Name */ const gradleFileToGradleProjectMap = new Map(); - const dependenciesMap = new Map(); + const gradleProjectToDepsMap = new Map>(); /** * Map of Gradle Build File to tasks type map */ @@ -223,10 +227,6 @@ export function processProjectReports( const gradleProjectToTasksMap = new Map>(); const gradleProjectToProjectName = new Map(); const gradleProjectNameToProjectRootMap = new Map(); - /** - * Map of buildFile to dependencies report path - */ - const buildFileToDepsMap = new Map>(); /** * Map fo possible output files of each gradle file * e.g. {build.gradle.kts: { projectReportDir: '' testReportDir: '' }} @@ -253,7 +253,10 @@ export function processProjectReports( index++; } const [_, file] = projectReportLines[index].split(fileSeparator); - dependenciesMap.set(gradleProject, file); + gradleProjectToDepsMap.set( + gradleProject, + processGradleDependencies(file) + ); } if (line.endsWith('propertyReport')) { const gradleProject = line.substring( @@ -320,13 +323,6 @@ export function processProjectReports( relative(workspaceRoot, absBuildFilePath) ); const buildDir = relative(workspaceRoot, absBuildDirPath); - const depsFile = dependenciesMap.get(gradleProject); - if (depsFile) { - buildFileToDepsMap.set( - buildFile, - processGradleDependencies(depsFile) - ); - } outputDirMap.set('build', `{workspaceRoot}/${buildDir}`); outputDirMap.set( @@ -389,9 +385,9 @@ export function processProjectReports( return { gradleFileToGradleProjectMap, - buildFileToDepsMap, gradleFileToOutputDirsMap, gradleProjectToTasksTypeMap, + gradleProjectToDepsMap, gradleProjectToTasksMap, gradleProjectToProjectName, gradleProjectNameToProjectRootMap, diff --git a/packages/gradle/src/utils/get-project-report-lines.ts b/packages/gradle/src/plugin-v1/utils/get-project-report-lines.ts similarity index 87% rename from packages/gradle/src/utils/get-project-report-lines.ts rename to packages/gradle/src/plugin-v1/utils/get-project-report-lines.ts index 3c5ae4606b..78d434c589 100644 --- a/packages/gradle/src/utils/get-project-report-lines.ts +++ b/packages/gradle/src/plugin-v1/utils/get-project-report-lines.ts @@ -1,16 +1,7 @@ import { AggregateCreateNodesError, logger, output } from '@nx/devkit'; -import { execGradleAsync } from './exec-gradle'; +import { execGradleAsync, newLineSeparator } from '../../utils/exec-gradle'; import { existsSync } from 'fs'; import { dirname, join } from 'path'; -import { execSync } from 'child_process'; - -export const fileSeparator = process.platform.startsWith('win') - ? 'file:///' - : 'file://'; - -export const newLineSeparator = process.platform.startsWith('win') - ? '\r\n' - : '\n'; /** * This function executes the gradle projectReportAll task and returns the output as an array of lines. @@ -21,8 +12,6 @@ export async function getProjectReportLines( gradlewFile: string ): Promise { let projectReportBuffer: Buffer; - - // Attempt to run projectReport or projectReportAll task, regardless of build.gradle or build.gradle.kts location try { projectReportBuffer = await execGradleAsync(gradlewFile, [ 'projectReportAll', diff --git a/packages/gradle/src/plugin/__snapshots__/nodes.spec.ts.snap b/packages/gradle/src/plugin/__snapshots__/nodes.spec.ts.snap new file mode 100644 index 0000000000..620e9490da --- /dev/null +++ b/packages/gradle/src/plugin/__snapshots__/nodes.spec.ts.snap @@ -0,0 +1,849 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`@nx/gradle/plugin/nodes should create nodes based on gradle 1`] = ` +[ + [ + "proj/build.gradle", + { + "externalNodes": {}, + "projects": { + "proj": { + "metadata": { + "targetGroups": { + "help": [ + "buildEnvironment", + ], + }, + "technologies": [ + "gradle", + ], + }, + "name": "gradle-tutorial", + "root": "proj", + "targets": { + "buildEnvironment": { + "cache": true, + "command": "./gradlew :buildEnvironment", + "metadata": { + "description": "Displays all buildscript dependencies declared in root project 'gradle-tutorial'.", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + }, + }, + }, + }, + }, + ], +] +`; + +exports[`@nx/gradle/plugin/nodes should create nodes based on gradle for nested project root 1`] = ` +[ + [ + "nested/nested/proj/build.gradle", + { + "externalNodes": {}, + "projects": { + "nested/nested/proj": { + "metadata": { + "targetGroups": { + "help": [ + "buildEnvironment", + ], + }, + "technologies": [ + "gradle", + ], + }, + "name": "my-composite", + "root": "nested/nested/proj", + "targets": { + "buildEnvironment": { + "cache": true, + "command": "./gradlew :buildEnvironment", + "metadata": { + "description": "Displays all buildscript dependencies declared in root project 'my-composite'.", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "nested/nested/proj", + }, + }, + }, + }, + }, + }, + ], +] +`; + +exports[`@nx/gradle/plugin/nodes should create nodes with atomized tests targets based on gradle if ciTargetName is specified 1`] = ` +[ + [ + "proj/application/build.gradle", + { + "externalNodes": {}, + "projects": { + "proj/application": { + "metadata": { + "targetGroups": { + "verification": [ + "ci", + ], + }, + "technologies": [ + "gradle", + ], + }, + "name": "application", + "root": "proj/application", + "targets": { + "ci": { + "cache": true, + "dependsOn": [ + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest10", + }, + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest7", + }, + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest6", + }, + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest3", + }, + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest2", + }, + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest9", + }, + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest", + }, + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest5", + }, + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest4", + }, + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest8", + }, + ], + "executor": "nx:noop", + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest10.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest7.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest6.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest3.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest2.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest9.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest5.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest4.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest8.java", + ], + "metadata": { + "description": "Runs Gradle Tests in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest10": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest10", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest10.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest10.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest2": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest2", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest2.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest2.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest3": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest3", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest3.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest3.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest4": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest4", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest4.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest4.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest5": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest5", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest5.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest5.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest6": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest6", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest6.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest6.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest7": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest7", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest7.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest7.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest8": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest8", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest8.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest8.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest9": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest9", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest9.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest9.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + }, + }, + }, + }, + ], +] +`; + +exports[`@nx/gradle/plugin/nodes should not create nodes with atomized tests targets based on gradle if ciTargetName is not specified 1`] = ` +[ + [ + "proj/application/build.gradle", + { + "externalNodes": {}, + "projects": { + "proj/application": { + "metadata": { + "targetGroups": { + "verification": [ + "ci", + ], + }, + "technologies": [ + "gradle", + ], + }, + "name": "application", + "root": "proj/application", + "targets": { + "ci": { + "cache": true, + "dependsOn": [ + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest10", + }, + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest7", + }, + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest6", + }, + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest3", + }, + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest2", + }, + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest9", + }, + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest", + }, + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest5", + }, + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest4", + }, + { + "params": "forward", + "projects": "self", + "target": "ci--DemoApplicationTest8", + }, + ], + "executor": "nx:noop", + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest10.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest7.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest6.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest3.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest2.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest9.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest5.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest4.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest8.java", + ], + "metadata": { + "description": "Runs Gradle Tests in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest10": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest10", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest10.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest10.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest2": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest2", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest2.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest2.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest3": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest3", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest3.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest3.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest4": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest4", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest4.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest4.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest5": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest5", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest5.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest5.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest6": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest6", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest6.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest6.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest7": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest7", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest7.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest7.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest8": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest8", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest8.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest8.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + "ci--DemoApplicationTest9": { + "cache": true, + "command": "./gradlew :application:test --tests DemoApplicationTest9", + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar", + ], + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest9.java", + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest9.java in CI", + "technologies": [ + "gradle", + ], + }, + "options": { + "cwd": "proj", + }, + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin", + ], + }, + }, + }, + }, + }, + ], +] +`; diff --git a/packages/gradle/src/plugin/dependencies.ts b/packages/gradle/src/plugin/dependencies.ts index 24d5003b2c..65b2e21673 100644 --- a/packages/gradle/src/plugin/dependencies.ts +++ b/packages/gradle/src/plugin/dependencies.ts @@ -2,94 +2,71 @@ import { CreateDependencies, CreateDependenciesContext, DependencyType, - FileMap, - RawProjectGraphDependency, + logger, + normalizePath, + StaticDependency, validateDependency, + workspaceRoot, } from '@nx/devkit'; -import { basename, dirname } from 'node:path'; +import { relative } from 'node:path'; -import { getCurrentGradleReport } from '../utils/get-gradle-report'; -import { GRADLE_BUILD_FILES } from '../utils/split-config-files'; +import { + getCurrentProjectGraphReport, + populateProjectGraph, +} from './utils/get-project-graph-from-gradle-plugin'; +import { GradlePluginOptions } from './utils/gradle-plugin-options'; +import { GRALDEW_FILES, splitConfigFiles } from '../utils/split-config-files'; +import { globWithWorkspaceContext } from 'nx/src/utils/workspace-context'; -export const createDependencies: CreateDependencies = async ( - _, +export const createDependencies: CreateDependencies< + GradlePluginOptions +> = async ( + options: GradlePluginOptions, context: CreateDependenciesContext ) => { - const gradleFiles: string[] = findGradleFiles(context.filesToProcess); - if (gradleFiles.length === 0) { - return []; - } - - const gradleDependenciesStart = performance.mark('gradleDependencies:start'); - const { - gradleFileToGradleProjectMap, - gradleProjectNameToProjectRootMap, - buildFileToDepsMap, - gradleProjectToChildProjects, - } = getCurrentGradleReport(); - const dependencies: Set = new Set(); - - for (const gradleFile of gradleFiles) { - const gradleProject = gradleFileToGradleProjectMap.get(gradleFile); - const projectName = Object.values(context.projects).find( - (project) => project.root === dirname(gradleFile) - )?.name; - const dependedProjects: Set = buildFileToDepsMap.get(gradleFile); - - if (projectName && dependedProjects?.size) { - dependedProjects?.forEach((dependedProject) => { - const targetProjectRoot = gradleProjectNameToProjectRootMap.get( - dependedProject - ) as string; - const targetProjectName = Object.values(context.projects).find( - (project) => project.root === targetProjectRoot - )?.name; - if (targetProjectName) { - const dependency: RawProjectGraphDependency = { - source: projectName as string, - target: targetProjectName as string, - type: DependencyType.static, - sourceFile: gradleFile, - }; - validateDependency(dependency, context); - dependencies.add(dependency); - } - }); - } - gradleProjectToChildProjects.get(gradleProject)?.forEach((childProject) => { - if (childProject) { - const dependency: RawProjectGraphDependency = { - source: projectName as string, - target: childProject, - type: DependencyType.static, - sourceFile: gradleFile, - }; - validateDependency(dependency, context); - dependencies.add(dependency); - } - }); - } - - const gradleDependenciesEnd = performance.mark('gradleDependencies:end'); - performance.measure( - 'gradleDependencies', - gradleDependenciesStart.name, - gradleDependenciesEnd.name + const files = await globWithWorkspaceContext( + workspaceRoot, + Array.from(GRALDEW_FILES) ); + const { gradlewFiles } = splitConfigFiles(files); + await populateProjectGraph(context.workspaceRoot, gradlewFiles, options); + const { dependencies: dependenciesFromReport } = + getCurrentProjectGraphReport(); - return Array.from(dependencies); -}; - -function findGradleFiles(fileMap: FileMap): string[] { - const gradleFiles: string[] = []; - - for (const [_, files] of Object.entries(fileMap.projectFileMap)) { - for (const file of files) { - if (GRADLE_BUILD_FILES.has(basename(file.file))) { - gradleFiles.push(file.file); + const dependencies: Array = []; + dependenciesFromReport.forEach((dependencyFromPlugin: StaticDependency) => { + try { + const source = + relative(workspaceRoot, dependencyFromPlugin.source) || '.'; + const sourceProjectName = + Object.values(context.projects).find( + (project) => source === project.root + )?.name ?? dependencyFromPlugin.source; + const target = + relative(workspaceRoot, dependencyFromPlugin.target) || '.'; + const targetProjectName = + Object.values(context.projects).find( + (project) => target === project.root + )?.name ?? dependencyFromPlugin.target; + if (!sourceProjectName || !targetProjectName) { + return; } + const dependency: StaticDependency = { + source: sourceProjectName, + target: targetProjectName, + type: DependencyType.static, + sourceFile: normalizePath( + relative(workspaceRoot, dependencyFromPlugin.sourceFile) + ), + }; + validateDependency(dependency, context); + dependencies.push(dependency); + } catch { + logger.warn( + `Unable to parse dependency from gradle plugin: ${dependencyFromPlugin.source} -> ${dependencyFromPlugin.target}` + ); } - } + }); - return gradleFiles; -} + return dependencies; +}; diff --git a/packages/gradle/src/plugin/nodes.spec.ts b/packages/gradle/src/plugin/nodes.spec.ts index c6dd65f87f..31bee1d8cb 100644 --- a/packages/gradle/src/plugin/nodes.spec.ts +++ b/packages/gradle/src/plugin/nodes.spec.ts @@ -1,20 +1,22 @@ -import { CreateNodesContext } from '@nx/devkit'; - +import { CreateNodesContext, readJsonFile } from '@nx/devkit'; +import { join } from 'path'; import { TempFs } from 'nx/src/internal-testing-utils/temp-fs'; -import { type GradleReport } from '../utils/get-gradle-report'; +import { type ProjectGraphReport } from './utils/get-project-graph-from-gradle-plugin'; -let gradleReport: GradleReport; -jest.mock('../utils/get-gradle-report', () => { +let gradleReport: ProjectGraphReport; +jest.mock('./utils/get-project-graph-from-gradle-plugin', () => { return { GRADLE_BUILD_FILES: new Set(['build.gradle', 'build.gradle.kts']), - populateGradleReport: jest.fn().mockImplementation(() => void 0), - getCurrentGradleReport: jest.fn().mockImplementation(() => gradleReport), + populateProjectGraph: jest.fn().mockImplementation(() => void 0), + getCurrentProjectGraphReport: jest + .fn() + .mockImplementation(() => gradleReport), }; }); import { createNodesV2 } from './nodes'; -describe('@nx/gradle/plugin', () => { +describe('@nx/gradle/plugin/nodes', () => { let createNodesFunction = createNodesV2[1]; let context: CreateNodesContext; let tempFs: TempFs; @@ -22,32 +24,9 @@ describe('@nx/gradle/plugin', () => { beforeEach(async () => { tempFs = new TempFs('test'); - gradleReport = { - gradleFileToGradleProjectMap: new Map([ - ['proj/build.gradle', 'proj'], - ]), - buildFileToDepsMap: new Map>(), - gradleFileToOutputDirsMap: new Map>([ - ['proj/build.gradle', new Map([['build', 'build']])], - ]), - gradleProjectToTasksMap: new Map>([ - ['proj', new Set(['test'])], - ]), - gradleProjectToTasksTypeMap: new Map>([ - [ - 'proj', - new Map([ - ['test', 'Verification'], - ['build', 'Build'], - ]), - ], - ]), - gradleProjectToProjectName: new Map([['proj', 'proj']]), - gradleProjectNameToProjectRootMap: new Map([ - ['proj', 'proj'], - ]), - gradleProjectToChildProjects: new Map(), - }; + gradleReport = readJsonFile( + join(__dirname, 'utils/__mocks__/gradle_tutorial.json') + ); cwd = process.cwd(); process.chdir(tempFs.tempDir); context = { @@ -81,190 +60,13 @@ describe('@nx/gradle/plugin', () => { context ); - expect(results).toMatchInlineSnapshot(` - [ - [ - "proj/build.gradle", - { - "projects": { - "proj": { - "metadata": { - "targetGroups": { - "Verification": [ - "test", - ], - }, - "technologies": [ - "gradle", - ], - }, - "name": "proj", - "projectType": "application", - "targets": { - "test": { - "cache": true, - "command": "./gradlew proj:test", - "dependsOn": [ - "testClasses", - ], - "inputs": [ - "default", - "^production", - ], - "metadata": { - "help": { - "command": "./gradlew help --task proj:test", - "example": { - "options": { - "args": [ - "--rerun", - ], - }, - }, - }, - "technologies": [ - "gradle", - ], - }, - "options": { - "cwd": ".", - }, - }, - }, - }, - }, - }, - ], - ] - `); - }); - - it('should create nodes include subprojects tasks', async () => { - const results = await createNodesFunction( - ['proj/build.gradle'], - { - buildTargetName: 'build', - includeSubprojectsTasks: true, - }, - context - ); - - expect(results).toMatchInlineSnapshot(` - [ - [ - "proj/build.gradle", - { - "projects": { - "proj": { - "metadata": { - "targetGroups": { - "Build": [ - "build", - ], - "Verification": [ - "test", - ], - }, - "technologies": [ - "gradle", - ], - }, - "name": "proj", - "projectType": "application", - "targets": { - "build": { - "cache": true, - "command": "./gradlew proj:build", - "dependsOn": [ - "^build", - "classes", - "test", - ], - "inputs": [ - "production", - "^production", - ], - "metadata": { - "help": { - "command": "./gradlew help --task proj:build", - "example": { - "options": { - "args": [ - "--rerun", - ], - }, - }, - }, - "technologies": [ - "gradle", - ], - }, - "options": { - "cwd": ".", - }, - "outputs": [ - "build", - ], - }, - "test": { - "cache": true, - "command": "./gradlew proj:test", - "dependsOn": [ - "testClasses", - ], - "inputs": [ - "default", - "^production", - ], - "metadata": { - "help": { - "command": "./gradlew help --task proj:test", - "example": { - "options": { - "args": [ - "--rerun", - ], - }, - }, - }, - "technologies": [ - "gradle", - ], - }, - "options": { - "cwd": ".", - }, - }, - }, - }, - }, - }, - ], - ] - `); + expect(results).toMatchSnapshot(); }); it('should create nodes based on gradle for nested project root', async () => { - gradleReport = { - gradleFileToGradleProjectMap: new Map([ - ['nested/nested/proj/build.gradle', 'proj'], - ]), - buildFileToDepsMap: new Map>(), - gradleFileToOutputDirsMap: new Map>([ - ['nested/nested/proj/build.gradle', new Map([['build', 'build']])], - ]), - gradleProjectToTasksMap: new Map>([ - ['proj', new Set(['test'])], - ]), - gradleProjectToTasksTypeMap: new Map>([ - ['proj', new Map([['test', 'Verification']])], - ]), - gradleProjectToProjectName: new Map([['proj', 'proj']]), - gradleProjectNameToProjectRootMap: new Map([ - ['proj', 'proj'], - ]), - gradleProjectToChildProjects: new Map(), - }; + gradleReport = readJsonFile( + join(__dirname, '/utils/__mocks__/gradle_composite.json') + ); await tempFs.createFiles({ 'nested/nested/proj/build.gradle': ``, }); @@ -277,311 +79,30 @@ describe('@nx/gradle/plugin', () => { context ); - expect(results).toMatchInlineSnapshot(` - [ - [ - "nested/nested/proj/build.gradle", - { - "projects": { - "nested/nested/proj": { - "metadata": { - "targetGroups": { - "Verification": [ - "test", - ], - }, - "technologies": [ - "gradle", - ], - }, - "name": "proj", - "projectType": "application", - "targets": { - "test": { - "cache": true, - "command": "./gradlew proj:test", - "dependsOn": [ - "testClasses", - ], - "inputs": [ - "default", - "^production", - ], - "metadata": { - "help": { - "command": "./gradlew help --task proj:test", - "example": { - "options": { - "args": [ - "--rerun", - ], - }, - }, - }, - "technologies": [ - "gradle", - ], - }, - "options": { - "cwd": ".", - }, - }, - }, - }, - }, - }, - ], - ] - `); + expect(results).toMatchSnapshot(); }); - describe('with atomized tests targets', () => { - beforeEach(async () => { - gradleReport = { - gradleFileToGradleProjectMap: new Map([ - ['nested/nested/proj/build.gradle', 'proj'], - ]), - buildFileToDepsMap: new Map>(), - gradleFileToOutputDirsMap: new Map>([ - ['nested/nested/proj/build.gradle', new Map([['build', 'build']])], - ]), - gradleProjectToTasksMap: new Map>([ - ['proj', new Set(['test'])], - ]), - gradleProjectToTasksTypeMap: new Map>([ - ['proj', new Map([['test', 'Test']])], - ]), - gradleProjectToProjectName: new Map([['proj', 'proj']]), - gradleProjectNameToProjectRootMap: new Map([ - ['proj', 'proj'], - ]), - gradleProjectToChildProjects: new Map(), - }; - await tempFs.createFiles({ - 'nested/nested/proj/build.gradle': ``, - }); - await tempFs.createFiles({ - 'proj/src/test/java/test/rootTest.java': ``, - }); - await tempFs.createFiles({ - 'nested/nested/proj/src/test/java/test/aTest.java': ``, - }); - await tempFs.createFiles({ - 'nested/nested/proj/src/test/java/test/bTest.java': ``, - }); - await tempFs.createFiles({ - 'nested/nested/proj/src/test/java/test/cTests.java': ``, - }); - }); + it('should create nodes with atomized tests targets based on gradle if ciTargetName is specified', async () => { + const results = await createNodesFunction( + ['proj/application/build.gradle'], + { + buildTargetName: 'build', + ciTargetName: 'test-ci', + }, + context + ); - it('should create nodes with atomized tests targets based on gradle for nested project root', async () => { - const results = await createNodesFunction( - [ - 'nested/nested/proj/build.gradle', - 'proj/src/test/java/test/rootTest.java', - 'nested/nested/proj/src/test/java/test/aTest.java', - 'nested/nested/proj/src/test/java/test/bTest.java', - 'nested/nested/proj/src/test/java/test/cTests.java', - ], - { - buildTargetName: 'build', - ciTargetName: 'test-ci', - }, - context - ); + expect(results).toMatchSnapshot(); + }); - expect(results).toMatchInlineSnapshot(` - [ - [ - "nested/nested/proj/build.gradle", - { - "projects": { - "nested/nested/proj": { - "metadata": { - "targetGroups": { - "Test": [ - "test-ci--aTest", - "test-ci--bTest", - "test-ci--cTests", - "test-ci", - "test", - ], - }, - "technologies": [ - "gradle", - ], - }, - "name": "proj", - "projectType": "application", - "targets": { - "test": { - "cache": false, - "command": "./gradlew proj:test", - "dependsOn": [ - "testClasses", - ], - "inputs": [ - "default", - "^production", - ], - "metadata": { - "help": { - "command": "./gradlew help --task proj:test", - "example": { - "options": { - "args": [ - "--rerun", - ], - }, - }, - }, - "technologies": [ - "gradle", - ], - }, - "options": { - "cwd": ".", - }, - }, - "test-ci": { - "cache": true, - "dependsOn": [ - { - "params": "forward", - "projects": "self", - "target": "test-ci--aTest", - }, - { - "params": "forward", - "projects": "self", - "target": "test-ci--bTest", - }, - { - "params": "forward", - "projects": "self", - "target": "test-ci--cTests", - }, - ], - "executor": "nx:noop", - "inputs": [ - "default", - "^production", - ], - "metadata": { - "description": "Runs Gradle Tests in CI", - "help": { - "command": "./gradlew help --task proj:test", - "example": { - "options": { - "args": [ - "--rerun", - ], - }, - }, - }, - "nonAtomizedTarget": "test", - "technologies": [ - "gradle", - ], - }, - }, - "test-ci--aTest": { - "cache": true, - "command": "./gradlew proj:test --tests aTest", - "dependsOn": [ - "testClasses", - ], - "inputs": [ - "default", - "^production", - ], - "metadata": { - "description": "Runs Gradle test nested/nested/proj/src/test/java/test/aTest.java in CI", - "help": { - "command": "./gradlew help --task proj:test", - "example": { - "options": { - "args": [ - "--rerun", - ], - }, - }, - }, - "technologies": [ - "gradle", - ], - }, - "options": { - "cwd": ".", - }, - }, - "test-ci--bTest": { - "cache": true, - "command": "./gradlew proj:test --tests bTest", - "dependsOn": [ - "testClasses", - ], - "inputs": [ - "default", - "^production", - ], - "metadata": { - "description": "Runs Gradle test nested/nested/proj/src/test/java/test/bTest.java in CI", - "help": { - "command": "./gradlew help --task proj:test", - "example": { - "options": { - "args": [ - "--rerun", - ], - }, - }, - }, - "technologies": [ - "gradle", - ], - }, - "options": { - "cwd": ".", - }, - }, - "test-ci--cTests": { - "cache": true, - "command": "./gradlew proj:test --tests cTests", - "dependsOn": [ - "testClasses", - ], - "inputs": [ - "default", - "^production", - ], - "metadata": { - "description": "Runs Gradle test nested/nested/proj/src/test/java/test/cTests.java in CI", - "help": { - "command": "./gradlew help --task proj:test", - "example": { - "options": { - "args": [ - "--rerun", - ], - }, - }, - }, - "technologies": [ - "gradle", - ], - }, - "options": { - "cwd": ".", - }, - }, - }, - }, - }, - }, - ], - ] - `); - }); + it('should not create nodes with atomized tests targets based on gradle if ciTargetName is not specified', async () => { + const results = await createNodesFunction( + ['proj/application/build.gradle'], + { + buildTargetName: 'build', + }, + context + ); + expect(results).toMatchSnapshot(); }); }); diff --git a/packages/gradle/src/plugin/nodes.ts b/packages/gradle/src/plugin/nodes.ts index 6c61721dd4..e5f58519ae 100644 --- a/packages/gradle/src/plugin/nodes.ts +++ b/packages/gradle/src/plugin/nodes.ts @@ -1,67 +1,36 @@ import { - CreateNodes, CreateNodesV2, CreateNodesContext, ProjectConfiguration, - TargetConfiguration, createNodesFromFiles, readJsonFile, writeJsonFile, CreateNodesFunction, - logger, + workspaceRoot, + ProjectGraphExternalNode, } from '@nx/devkit'; import { calculateHashForCreateNodes } from '@nx/devkit/src/utils/calculate-hash-for-create-nodes'; import { existsSync } from 'node:fs'; -import { basename, dirname, join } from 'node:path'; +import { dirname, join } from 'node:path'; import { workspaceDataDirectory } from 'nx/src/utils/cache-directory'; -import { findProjectForPath } from 'nx/src/devkit-internals'; -import { - populateGradleReport, - getCurrentGradleReport, - GradleReport, -} from '../utils/get-gradle-report'; import { hashObject } from 'nx/src/hasher/file-hasher'; import { gradleConfigAndTestGlob, - gradleConfigGlob, splitConfigFiles, } from '../utils/split-config-files'; -import { getGradleExecFile, findGraldewFile } from '../utils/exec-gradle'; - -const cacheableTaskType = new Set(['Build', 'Verification']); -const dependsOnMap = { - build: ['^build', 'classes', 'test'], - testClasses: ['classes'], - test: ['testClasses'], - classes: ['^classes'], -}; - -interface GradleTask { - type: string; - name: string; -} - -export interface GradlePluginOptions { - includeSubprojectsTasks?: boolean; // default is false, show all gradle tasks in the project - ciTargetName?: string; - testTargetName?: string; - classesTargetName?: string; - buildTargetName?: string; - [taskTargetName: string]: string | undefined | boolean; -} - -function normalizeOptions(options: GradlePluginOptions): GradlePluginOptions { - options ??= {}; - options.testTargetName ??= 'test'; - options.classesTargetName ??= 'classes'; - options.buildTargetName ??= 'build'; - return options; -} +import { + getCurrentProjectGraphReport, + populateProjectGraph, +} from './utils/get-project-graph-from-gradle-plugin'; +import { + GradlePluginOptions, + normalizeOptions, +} from './utils/gradle-plugin-options'; type GradleTargets = Record>; -function readTargetsCache(cachePath: string): GradleTargets { +function readProjectsCache(cachePath: string): GradleTargets { return existsSync(cachePath) ? readJsonFile(cachePath) : {}; } @@ -72,47 +41,39 @@ export function writeTargetsToCache(cachePath: string, results: GradleTargets) { export const createNodesV2: CreateNodesV2 = [ gradleConfigAndTestGlob, async (files, options, context) => { - const { buildFiles, projectRoots, gradlewFiles, testFiles } = - splitConfigFiles(files); + const { buildFiles, gradlewFiles } = splitConfigFiles(files); const optionsHash = hashObject(options); const cachePath = join( workspaceDataDirectory, `gradle-${optionsHash}.hash` ); - const targetsCache = readTargetsCache(cachePath); + const projectsCache = readProjectsCache(cachePath); - await populateGradleReport( + await populateProjectGraph( context.workspaceRoot, - gradlewFiles.map((f) => join(context.workspaceRoot, f)) - ); - const gradleReport = getCurrentGradleReport(); - const gradleProjectRootToTestFilesMap = getGradleProjectRootToTestFilesMap( - testFiles, - projectRoots + gradlewFiles.map((f) => join(context.workspaceRoot, f)), + options ); + const { nodes, externalNodes } = getCurrentProjectGraphReport(); try { return createNodesFromFiles( - makeCreateNodesForGradleConfigFile( - gradleReport, - targetsCache, - gradleProjectRootToTestFilesMap - ), + makeCreateNodesForGradleConfigFile(nodes, projectsCache, externalNodes), buildFiles, options, context ); } finally { - writeTargetsToCache(cachePath, targetsCache); + writeTargetsToCache(cachePath, projectsCache); } }, ]; export const makeCreateNodesForGradleConfigFile = ( - gradleReport: GradleReport, - targetsCache: GradleTargets = {}, - gradleProjectRootToTestFilesMap: Record = {} + projects: Record>, + projectsCache: GradleTargets = {}, + externalNodes: Record = {} ): CreateNodesFunction => async ( gradleFilePath, @@ -127,309 +88,18 @@ export const makeCreateNodesForGradleConfigFile = options ?? {}, context ); - targetsCache[hash] ??= await createGradleProject( - gradleReport, - gradleFilePath, - options, - context, - gradleProjectRootToTestFilesMap[projectRoot] - ); - const project = targetsCache[hash]; + projectsCache[hash] ??= + projects[projectRoot] ?? projects[join(workspaceRoot, projectRoot)]; + const project = projectsCache[hash]; if (!project) { return {}; } + project.root = projectRoot; + return { projects: { [projectRoot]: project, }, + externalNodes: externalNodes, }; }; - -/** - @deprecated This is replaced with {@link createNodesV2}. Update your plugin to export its own `createNodesV2` function that wraps this one instead. - This function will change to the v2 function in Nx 20. - */ -export const createNodes: CreateNodes = [ - gradleConfigGlob, - async (buildFile, options, context) => { - logger.warn( - '`createNodes` is deprecated. Update your plugin to utilize createNodesV2 instead. In Nx 20, this will change to the createNodesV2 API.' - ); - const { gradlewFiles } = splitConfigFiles(context.configFiles); - await populateGradleReport(context.workspaceRoot, gradlewFiles); - const gradleReport = getCurrentGradleReport(); - const internalCreateNodes = - makeCreateNodesForGradleConfigFile(gradleReport); - return await internalCreateNodes(buildFile, options, context); - }, -]; - -async function createGradleProject( - gradleReport: GradleReport, - gradleFilePath: string, - options: GradlePluginOptions | undefined, - context: CreateNodesContext, - testFiles = [] -) { - try { - const { - gradleProjectToTasksTypeMap, - gradleProjectToTasksMap, - gradleFileToOutputDirsMap, - gradleFileToGradleProjectMap, - gradleProjectToProjectName, - } = gradleReport; - - const gradleProject = gradleFileToGradleProjectMap.get( - gradleFilePath - ) as string; - const projectName = gradleProjectToProjectName.get(gradleProject); - if (!projectName) { - return; - } - - const tasksTypeMap: Map = gradleProjectToTasksTypeMap.get( - gradleProject - ) as Map; - const tasksSet = gradleProjectToTasksMap.get(gradleProject) as Set; - let tasks: GradleTask[] = []; - tasksSet.forEach((taskName) => { - tasks.push({ - type: tasksTypeMap?.get(taskName) as string, - name: taskName, - }); - }); - if (options.includeSubprojectsTasks) { - tasksTypeMap.forEach((taskType, taskName) => { - if (!tasksSet.has(taskName)) { - tasks.push({ - type: taskType, - name: taskName, - }); - } - }); - } - - const outputDirs = gradleFileToOutputDirsMap.get(gradleFilePath) as Map< - string, - string - >; - - const { targets, targetGroups } = await createGradleTargets( - tasks, - options, - context, - outputDirs, - gradleProject, - gradleFilePath, - testFiles - ); - const project: Partial = { - name: projectName, - projectType: 'application', - targets, - metadata: { - targetGroups, - technologies: ['gradle'], - }, - }; - - return project; - } catch (e) { - console.error(e); - return undefined; - } -} - -async function createGradleTargets( - tasks: GradleTask[], - options: GradlePluginOptions | undefined, - context: CreateNodesContext, - outputDirs: Map, - gradleProject: string, - gradleBuildFilePath: string, - testFiles: string[] = [] -): Promise<{ - targetGroups: Record; - targets: Record; -}> { - const inputsMap = createInputsMap(context); - const gradlewFileDirectory = dirname( - findGraldewFile(gradleBuildFilePath, context.workspaceRoot) - ); - - const targets: Record = {}; - const targetGroups: Record = {}; - for (const task of tasks) { - const targetName = options?.[`${task.name}TargetName`] ?? task.name; - - let outputs = [outputDirs.get(task.name)].filter(Boolean); - if (task.name === 'test') { - outputs = [ - outputDirs.get('testReport'), - outputDirs.get('testResults'), - ].filter(Boolean); - getTestCiTargets( - testFiles, - gradleProject, - targetName as string, - options.ciTargetName, - inputsMap['test'], - outputs, - task.type, - targets, - targetGroups, - gradlewFileDirectory - ); - } - - const taskCommandToRun = `${gradleProject ? gradleProject + ':' : ''}${ - task.name - }`; - - targets[targetName as string] = { - command: `${getGradleExecFile()} ${taskCommandToRun}`, - options: { - cwd: gradlewFileDirectory, - }, - cache: cacheableTaskType.has(task.type), - inputs: inputsMap[task.name], - dependsOn: dependsOnMap[task.name], - metadata: { - technologies: ['gradle'], - help: { - command: `${getGradleExecFile()} help --task ${taskCommandToRun}`, - example: { - options: { - args: ['--rerun'], - }, - }, - }, - }, - ...(outputs && outputs.length ? { outputs } : {}), - }; - - if (task.type) { - if (!targetGroups[task.type]) { - targetGroups[task.type] = []; - } - targetGroups[task.type].push(targetName as string); - } - } - return { targetGroups, targets }; -} - -function createInputsMap( - context: CreateNodesContext -): Record { - const namedInputs = context.nxJsonConfiguration.namedInputs; - return { - build: namedInputs?.production - ? ['production', '^production'] - : ['default', '^default'], - test: ['default', namedInputs?.production ? '^production' : '^default'], - classes: namedInputs?.production - ? ['production', '^production'] - : ['default', '^default'], - }; -} - -function getTestCiTargets( - testFiles: string[], - gradleProject: string, - testTargetName: string, - ciTargetName: string, - inputs: TargetConfiguration['inputs'], - outputs: string[], - targetGroupName: string, - targets: Record, - targetGroups: Record, - gradlewFileDirectory: string -): void { - if (!testFiles || testFiles.length === 0 || !ciTargetName) { - return; - } - const taskCommandToRun = `${gradleProject ? gradleProject + ':' : ''}test`; - - if (!targetGroups[targetGroupName]) { - targetGroups[targetGroupName] = []; - } - - const dependsOn: TargetConfiguration['dependsOn'] = []; - testFiles.forEach((testFile) => { - const testName = basename(testFile).split('.')[0]; - const targetName = ciTargetName + '--' + testName; - - targets[targetName] = { - command: `${getGradleExecFile()} ${taskCommandToRun} --tests ${testName}`, - options: { - cwd: gradlewFileDirectory, - }, - cache: true, - inputs, - dependsOn: dependsOnMap['test'], - metadata: { - technologies: ['gradle'], - description: `Runs Gradle test ${testFile} in CI`, - help: { - command: `${getGradleExecFile()} help --task ${taskCommandToRun}`, - example: { - options: { - args: ['--rerun'], - }, - }, - }, - }, - ...(outputs && outputs.length > 0 ? { outputs } : {}), - }; - targetGroups[targetGroupName].push(targetName); - dependsOn.push({ - target: targetName, - projects: 'self', - params: 'forward', - }); - }); - - targets[ciTargetName] = { - executor: 'nx:noop', - cache: true, - inputs, - dependsOn: dependsOn, - ...(outputs && outputs.length > 0 ? { outputs } : {}), - metadata: { - technologies: ['gradle'], - description: 'Runs Gradle Tests in CI', - nonAtomizedTarget: testTargetName, - help: { - command: `${getGradleExecFile()} help --task ${taskCommandToRun}`, - example: { - options: { - args: ['--rerun'], - }, - }, - }, - }, - }; - targetGroups[targetGroupName].push(ciTargetName); -} - -function getGradleProjectRootToTestFilesMap( - testFiles: string[], - projectRoots: string[] -): Record | undefined { - if (testFiles.length === 0 || projectRoots.length === 0) { - return; - } - const roots = new Map(projectRoots.map((root) => [root, root])); - const testFilesToGradleProjectMap: Record = {}; - testFiles.forEach((testFile) => { - const projectRoot = findProjectForPath(testFile, roots); - if (projectRoot) { - if (!testFilesToGradleProjectMap[projectRoot]) { - testFilesToGradleProjectMap[projectRoot] = []; - } - testFilesToGradleProjectMap[projectRoot].push(testFile); - } - }); - return testFilesToGradleProjectMap; -} diff --git a/packages/gradle/src/plugin/utils/__mocks__/gradle_composite.json b/packages/gradle/src/plugin/utils/__mocks__/gradle_composite.json new file mode 100644 index 0000000000..eeb6326286 --- /dev/null +++ b/packages/gradle/src/plugin/utils/__mocks__/gradle_composite.json @@ -0,0 +1,38 @@ +{ + "nodes": { + "nested/nested/proj": { + "targets": { + "buildEnvironment": { + "cache": true, + "metadata": { + "description": "Displays all buildscript dependencies declared in root project \u0027my-composite\u0027.", + "technologies": ["gradle"] + }, + "command": "./gradlew :buildEnvironment", + "options": { + "cwd": "nested/nested/proj" + } + } + }, + "metadata": { + "targetGroups": { + "help": ["buildEnvironment"] + }, + "technologies": ["gradle"] + }, + "name": "my-composite" + } + }, + "dependencies": [ + { + "source": "nested/nested/proj", + "target": "projectRoot/my-app", + "sourceFile": "projectRoot/build.gradle.kts" + }, + { + "source": "nested/nested/proj", + "target": "projectRoot/my-utils", + "sourceFile": "projectRoot/build.gradle.kts" + } + ] +} diff --git a/packages/gradle/src/plugin/utils/__mocks__/gradle_nx_list.json b/packages/gradle/src/plugin/utils/__mocks__/gradle_nx_list.json new file mode 100644 index 0000000000..bb83fd416e --- /dev/null +++ b/packages/gradle/src/plugin/utils/__mocks__/gradle_nx_list.json @@ -0,0 +1,590 @@ +{ + "targets": { + "assemble": { + "cache": true, + "parallelism": false, + "dependsOn": ["list:jar"], + "command": "./gradlew :list:assemble", + "metadata": { + "description": "Assembles the outputs of this project.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:assemble" } + }, + "options": { "cwd": "." } + }, + "build": { + "cache": true, + "parallelism": false, + "dependsOn": ["list:check", "list:assemble"], + "command": "./gradlew :list:build", + "metadata": { + "description": "Assembles and tests this project.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:build" } + }, + "options": { "cwd": "." } + }, + "buildDependents": { + "cache": true, + "parallelism": false, + "command": "./gradlew :list:buildDependents", + "metadata": { + "description": "Assembles and tests this project and all projects that depend on it.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:buildDependents" } + }, + "options": { "cwd": "." } + }, + "buildEnvironment": { + "cache": true, + "parallelism": false, + "command": "./gradlew :list:buildEnvironment", + "metadata": { + "description": "Displays all buildscript dependencies declared in project \u0027:list\u0027.", + "technologies": ["gradle"], + "help": { + "command": "./gradlew help --task :list:buildEnvironment" + } + }, + "options": { "cwd": "." } + }, + "buildNeeded": { + "cache": true, + "parallelism": false, + "dependsOn": ["list:build"], + "command": "./gradlew :list:buildNeeded", + "metadata": { + "description": "Assembles and tests this project and all projects it depends on.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:buildNeeded" } + }, + "options": { "cwd": "." } + }, + "check": { + "cache": true, + "parallelism": false, + "dependsOn": ["list:test"], + "command": "./gradlew :list:check", + "metadata": { + "description": "Runs all checks.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:check" } + }, + "options": { "cwd": "." } + }, + "classes": { + "cache": true, + "parallelism": false, + "dependsOn": ["list:compileJava", "list:processResources"], + "command": "./gradlew :list:classes", + "metadata": { + "description": "Assembles main classes.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:classes" } + }, + "options": { "cwd": "." } + }, + "clean": { + "cache": true, + "parallelism": false, + "command": "./gradlew :list:clean", + "metadata": { + "description": "Deletes the build directory.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:clean" } + }, + "options": { "cwd": "." } + }, + "compileJava": { + "cache": true, + "parallelism": false, + "inputs": [ + "{projectRoot}/src/main/java/org/example/list/LinkedList.java" + ], + "outputs": [ + "{projectRoot}/build/classes/java/main", + "{projectRoot}/build/generated/sources/annotationProcessor/java/main", + "{projectRoot}/build/generated/sources/headers/java/main", + "{projectRoot}/build/tmp/compileJava/previous-compilation-data.bin" + ], + "command": "./gradlew :list:compileJava", + "metadata": { + "description": "Compiles main Java source.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:compileJava" } + }, + "options": { "cwd": "." } + }, + "compileTestJava": { + "cache": true, + "parallelism": false, + "inputs": [ + "{projectRoot}/src/test/java/org/example/list/LinkedListTest.java", + "{projectRoot}/src/test/java/org/example/list/LinkedList2Test.java" + ], + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin" + ], + "dependsOn": ["list:classes", "list:compileJava"], + "command": "./gradlew :list:compileTestJava", + "metadata": { + "description": "Compiles test Java source.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:compileTestJava" } + }, + "options": { "cwd": "." } + }, + "ci--LinkedListTest": { + "command": "./gradlew :list:test --tests LinkedListTest", + "metadata": { + "description": "Runs Gradle test LinkedListTest in CI", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:test" } + }, + "cache": true, + "parallelism": false, + "inputs": [ + "{projectRoot}/src/test/java/org/example/list/LinkedListTest.java" + ], + "dependsOn": [ + "list:compileTestJava", + "list:testClasses", + "list:classes", + "list:compileJava" + ], + "outputs": [ + "{projectRoot}/build/test-results/test/binary", + "{projectRoot}/build/reports/tests/test", + "{projectRoot}/build/test-results/test" + ] + }, + "ci--LinkedList2Test": { + "command": "./gradlew :list:test --tests LinkedList2Test", + "metadata": { + "description": "Runs Gradle test LinkedList2Test in CI", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:test" } + }, + "cache": true, + "parallelism": false, + "inputs": [ + "{projectRoot}/src/test/java/org/example/list/LinkedList2Test.java" + ], + "dependsOn": [ + "list:compileTestJava", + "list:testClasses", + "list:classes", + "list:compileJava" + ], + "outputs": [ + "{projectRoot}/build/test-results/test/binary", + "{projectRoot}/build/reports/tests/test", + "{projectRoot}/build/test-results/test" + ] + }, + "ci": { + "executor": "nx:noop", + "metadata": { + "description": "Runs Gradle Tests in CI", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:test" } + }, + "dependsOn": [ + { + "target": "ci--LinkedListTest", + "projects": "self", + "params": "forward" + }, + { + "target": "ci--LinkedList2Test", + "projects": "self", + "params": "forward" + } + ], + "cache": true, + "parallelism": false + }, + "components": { + "cache": true, + "parallelism": false, + "command": "./gradlew :list:components", + "metadata": { + "description": "Displays the components produced by project \u0027:list\u0027. [deprecated]", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:components" } + }, + "options": { "cwd": "." } + }, + "nxProjectGraph": { + "cache": true, + "parallelism": false, + "dependsOn": ["list:nxProjectGraphLocal"], + "command": "./gradlew :list:nxProjectGraph", + "metadata": { + "description": "Print nodes report for Nx", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:nxProjectGraph" } + }, + "options": { "cwd": "." } + }, + "createNodesLocal": { + "cache": true, + "parallelism": false, + "outputs": ["{projectRoot}/build/nx/list.json"], + "command": "./gradlew :list:nxProjectGraphLocal", + "metadata": { + "description": "Create nodes and dependencies for Nx", + "technologies": ["gradle"], + "help": { + "command": "./gradlew help --task :list:nxProjectGraphLocal" + } + }, + "options": { "cwd": "." } + }, + "dependencies": { + "cache": true, + "parallelism": false, + "command": "./gradlew :list:dependencies", + "metadata": { + "description": "Displays all dependencies declared in project \u0027:list\u0027.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:dependencies" } + }, + "options": { "cwd": "." } + }, + "dependencyInsight": { + "cache": true, + "parallelism": false, + "command": "./gradlew :list:dependencyInsight", + "metadata": { + "description": "Displays the insight into a specific dependency in project \u0027:list\u0027.", + "technologies": ["gradle"], + "help": { + "command": "./gradlew help --task :list:dependencyInsight" + } + }, + "options": { "cwd": "." } + }, + "dependencyReport": { + "cache": true, + "parallelism": false, + "outputs": ["{projectRoot}/build/reports/project/dependencies.txt"], + "command": "./gradlew :list:dependencyReport", + "metadata": { + "description": "Generates a report about your library dependencies.", + "technologies": ["gradle"], + "help": { + "command": "./gradlew help --task :list:dependencyReport" + } + }, + "options": { "cwd": "." } + }, + "dependentComponents": { + "cache": true, + "parallelism": false, + "command": "./gradlew :list:dependentComponents", + "metadata": { + "description": "Displays the dependent components of components in project \u0027:list\u0027. [deprecated]", + "technologies": ["gradle"], + "help": { + "command": "./gradlew help --task :list:dependentComponents" + } + }, + "options": { "cwd": "." } + }, + "help": { + "cache": true, + "parallelism": false, + "command": "./gradlew :list:help", + "metadata": { + "description": "Displays a help message.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:help" } + }, + "options": { "cwd": "." } + }, + "htmlDependencyReport": { + "cache": true, + "parallelism": false, + "outputs": ["{projectRoot}/build/reports/project/dependencies"], + "command": "./gradlew :list:htmlDependencyReport", + "metadata": { + "description": "Generates an HTML report about your library dependencies.", + "technologies": ["gradle"], + "help": { + "command": "./gradlew help --task :list:htmlDependencyReport" + } + }, + "options": { "cwd": "." } + }, + "jar": { + "cache": true, + "parallelism": false, + "inputs": ["{projectRoot}/build/tmp/jar/MANIFEST.MF"], + "outputs": ["{projectRoot}/build/libs/list.jar"], + "dependsOn": ["list:classes", "list:compileJava"], + "command": "./gradlew :list:jar", + "metadata": { + "description": "Assembles a jar archive containing the classes of the \u0027main\u0027 feature.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:jar" } + }, + "options": { "cwd": "." } + }, + "javaToolchains": { + "cache": true, + "parallelism": false, + "command": "./gradlew :list:javaToolchains", + "metadata": { + "description": "Displays the detected java toolchains.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:javaToolchains" } + }, + "options": { "cwd": "." } + }, + "javadoc": { + "cache": true, + "parallelism": false, + "inputs": [ + "{projectRoot}/src/main/java/org/example/list/LinkedList.java" + ], + "outputs": ["{projectRoot}/build/docs/javadoc"], + "dependsOn": ["list:classes", "list:compileJava"], + "command": "./gradlew :list:javadoc", + "metadata": { + "description": "Generates Javadoc API documentation for the \u0027main\u0027 feature.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:javadoc" } + }, + "options": { "cwd": "." } + }, + "kotlinDslAccessorsReport": { + "cache": true, + "parallelism": false, + "command": "./gradlew :list:kotlinDslAccessorsReport", + "metadata": { + "description": "Prints the Kotlin code for accessing the currently available project extensions and conventions.", + "technologies": ["gradle"], + "help": { + "command": "./gradlew help --task :list:kotlinDslAccessorsReport" + } + }, + "options": { "cwd": "." } + }, + "model": { + "cache": true, + "parallelism": false, + "command": "./gradlew :list:model", + "metadata": { + "description": "Displays the configuration model of project \u0027:list\u0027. [deprecated]", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:model" } + }, + "options": { "cwd": "." } + }, + "outgoingVariants": { + "cache": true, + "parallelism": false, + "command": "./gradlew :list:outgoingVariants", + "metadata": { + "description": "Displays the outgoing variants of project \u0027:list\u0027.", + "technologies": ["gradle"], + "help": { + "command": "./gradlew help --task :list:outgoingVariants" + } + }, + "options": { "cwd": "." } + }, + "processResources": { + "cache": true, + "parallelism": false, + "outputs": ["{projectRoot}/build/resources/main"], + "command": "./gradlew :list:processResources", + "metadata": { + "description": "Processes main resources.", + "technologies": ["gradle"], + "help": { + "command": "./gradlew help --task :list:processResources" + } + }, + "options": { "cwd": "." } + }, + "processTestResources": { + "cache": true, + "parallelism": false, + "outputs": ["{projectRoot}/build/resources/test"], + "command": "./gradlew :list:processTestResources", + "metadata": { + "description": "Processes test resources.", + "technologies": ["gradle"], + "help": { + "command": "./gradlew help --task :list:processTestResources" + } + }, + "options": { "cwd": "." } + }, + "projectReport": { + "cache": true, + "parallelism": false, + "dependsOn": [ + "list:taskReport", + "list:dependencyReport", + "list:propertyReport", + "list:htmlDependencyReport" + ], + "command": "./gradlew :list:projectReport", + "metadata": { + "description": "Generates a report about your project.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:projectReport" } + }, + "options": { "cwd": "." } + }, + "projects": { + "cache": true, + "parallelism": false, + "command": "./gradlew :list:projects", + "metadata": { + "description": "Displays the sub-projects of project \u0027:list\u0027.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:projects" } + }, + "options": { "cwd": "." } + }, + "properties": { + "cache": true, + "parallelism": false, + "command": "./gradlew :list:properties", + "metadata": { + "description": "Displays the properties of project \u0027:list\u0027.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:properties" } + }, + "options": { "cwd": "." } + }, + "propertyReport": { + "cache": true, + "parallelism": false, + "outputs": ["{projectRoot}/build/reports/project/properties.txt"], + "command": "./gradlew :list:propertyReport", + "metadata": { + "description": "Generates a report about your properties.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:propertyReport" } + }, + "options": { "cwd": "." } + }, + "resolvableConfigurations": { + "cache": true, + "parallelism": false, + "command": "./gradlew :list:resolvableConfigurations", + "metadata": { + "description": "Displays the configurations that can be resolved in project \u0027:list\u0027.", + "technologies": ["gradle"], + "help": { + "command": "./gradlew help --task :list:resolvableConfigurations" + } + }, + "options": { "cwd": "." } + }, + "taskReport": { + "cache": true, + "parallelism": false, + "outputs": ["{projectRoot}/build/reports/project/tasks.txt"], + "command": "./gradlew :list:taskReport", + "metadata": { + "description": "Generates a report about your tasks.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:taskReport" } + }, + "options": { "cwd": "." } + }, + "tasks": { + "cache": true, + "parallelism": false, + "command": "./gradlew :list:tasks", + "metadata": { + "description": "Displays the tasks runnable from project \u0027:list\u0027.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:tasks" } + }, + "options": { "cwd": "." } + }, + "test": { + "cache": true, + "parallelism": false, + "outputs": [ + "{projectRoot}/build/test-results/test/binary", + "{projectRoot}/build/reports/tests/test", + "{projectRoot}/build/test-results/test" + ], + "dependsOn": [ + "list:compileTestJava", + "list:testClasses", + "list:classes", + "list:compileJava" + ], + "command": "./gradlew :list:test", + "metadata": { + "description": "Runs the test suite.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:test" } + }, + "options": { "cwd": "." } + }, + "testClasses": { + "cache": true, + "parallelism": false, + "dependsOn": ["list:processTestResources", "list:compileTestJava"], + "command": "./gradlew :list:testClasses", + "metadata": { + "description": "Assembles test classes.", + "technologies": ["gradle"], + "help": { "command": "./gradlew help --task :list:testClasses" } + }, + "options": { "cwd": "." } + } + }, + "metadata": { + "targetGroups": { + "build": [ + "assemble", + "build", + "buildDependents", + "buildNeeded", + "classes", + "clean", + "jar", + "testClasses" + ], + "help": [ + "buildEnvironment", + "dependencies", + "dependencyInsight", + "help", + "javaToolchains", + "kotlinDslAccessorsReport", + "outgoingVariants", + "projects", + "properties", + "resolvableConfigurations", + "tasks" + ], + "verification": [ + "check", + "ci--LinkedListTest", + "ci--LinkedList2Test", + "ci", + "test" + ], + "Nx Custom": ["createNodes", "createNodesLocal"], + "documentation": ["javadoc"], + "reporting": ["projectReport"] + }, + "technologies": ["gradle"] + }, + "name": "list" +} diff --git a/packages/gradle/src/plugin/utils/__mocks__/gradle_tutorial.json b/packages/gradle/src/plugin/utils/__mocks__/gradle_tutorial.json new file mode 100644 index 0000000000..3a9cdf91bd --- /dev/null +++ b/packages/gradle/src/plugin/utils/__mocks__/gradle_tutorial.json @@ -0,0 +1,344 @@ +{ + "nodes": { + "proj": { + "targets": { + "buildEnvironment": { + "cache": true, + "metadata": { + "description": "Displays all buildscript dependencies declared in root project \u0027gradle-tutorial\u0027.", + "technologies": ["gradle"] + }, + "command": "./gradlew :buildEnvironment", + "options": { "cwd": "proj" } + } + }, + "metadata": { + "targetGroups": { + "help": ["buildEnvironment"] + }, + "technologies": ["gradle"] + }, + "name": "gradle-tutorial" + }, + "proj/application": { + "targets": { + "ci--DemoApplicationTest10": { + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest10.java" + ], + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin" + ], + "cache": true, + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar" + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest10.java in CI", + "technologies": ["gradle"] + }, + "command": "./gradlew :application:test --tests DemoApplicationTest10", + "options": { "cwd": "proj" } + }, + "ci--DemoApplicationTest7": { + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest7.java" + ], + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin" + ], + "cache": true, + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar" + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest7.java in CI", + "technologies": ["gradle"] + }, + "command": "./gradlew :application:test --tests DemoApplicationTest7", + "options": { "cwd": "proj" } + }, + "ci--DemoApplicationTest6": { + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest6.java" + ], + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin" + ], + "cache": true, + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar" + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest6.java in CI", + "technologies": ["gradle"] + }, + "command": "./gradlew :application:test --tests DemoApplicationTest6", + "options": { "cwd": "proj" } + }, + "ci--DemoApplicationTest3": { + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest3.java" + ], + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin" + ], + "cache": true, + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar" + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest3.java in CI", + "technologies": ["gradle"] + }, + "command": "./gradlew :application:test --tests DemoApplicationTest3", + "options": { "cwd": "proj" } + }, + "ci--DemoApplicationTest2": { + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest2.java" + ], + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin" + ], + "cache": true, + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar" + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest2.java in CI", + "technologies": ["gradle"] + }, + "command": "./gradlew :application:test --tests DemoApplicationTest2", + "options": { "cwd": "proj" } + }, + "ci--DemoApplicationTest9": { + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest9.java" + ], + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin" + ], + "cache": true, + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar" + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest9.java in CI", + "technologies": ["gradle"] + }, + "command": "./gradlew :application:test --tests DemoApplicationTest9", + "options": { "cwd": "proj" } + }, + "ci--DemoApplicationTest": { + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest.java" + ], + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin" + ], + "cache": true, + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar" + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest.java in CI", + "technologies": ["gradle"] + }, + "command": "./gradlew :application:test --tests DemoApplicationTest", + "options": { "cwd": "proj" } + }, + "ci--DemoApplicationTest5": { + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest5.java" + ], + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin" + ], + "cache": true, + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar" + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest5.java in CI", + "technologies": ["gradle"] + }, + "command": "./gradlew :application:test --tests DemoApplicationTest5", + "options": { "cwd": "proj" } + }, + "ci--DemoApplicationTest4": { + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest4.java" + ], + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin" + ], + "cache": true, + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar" + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest4.java in CI", + "technologies": ["gradle"] + }, + "command": "./gradlew :application:test --tests DemoApplicationTest4", + "options": { "cwd": "proj" } + }, + "ci--DemoApplicationTest8": { + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest8.java" + ], + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin" + ], + "cache": true, + "dependsOn": [ + "application:classes", + "application:compileJava", + "library:jar" + ], + "metadata": { + "description": "Runs Gradle test proj/application/src/test/java/com/example/multimodule/application/DemoApplicationTest8.java in CI", + "technologies": ["gradle"] + }, + "command": "./gradlew :application:test --tests DemoApplicationTest8", + "options": { "cwd": "proj" } + }, + "ci": { + "inputs": [ + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest10.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest7.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest6.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest3.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest2.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest9.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest5.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest4.java", + "{projectRoot}/src/test/java/com/example/multimodule/application/DemoApplicationTest8.java" + ], + "outputs": [ + "{projectRoot}/build/classes/java/test", + "{projectRoot}/build/generated/sources/annotationProcessor/java/test", + "{projectRoot}/build/generated/sources/headers/java/test", + "{projectRoot}/build/tmp/compileTestJava/previous-compilation-data.bin" + ], + "cache": true, + "dependsOn": [ + { + "target": "ci--DemoApplicationTest10", + "projects": "self", + "params": "forward" + }, + { + "target": "ci--DemoApplicationTest7", + "projects": "self", + "params": "forward" + }, + { + "target": "ci--DemoApplicationTest6", + "projects": "self", + "params": "forward" + }, + { + "target": "ci--DemoApplicationTest3", + "projects": "self", + "params": "forward" + }, + { + "target": "ci--DemoApplicationTest2", + "projects": "self", + "params": "forward" + }, + { + "target": "ci--DemoApplicationTest9", + "projects": "self", + "params": "forward" + }, + { + "target": "ci--DemoApplicationTest", + "projects": "self", + "params": "forward" + }, + { + "target": "ci--DemoApplicationTest5", + "projects": "self", + "params": "forward" + }, + { + "target": "ci--DemoApplicationTest4", + "projects": "self", + "params": "forward" + }, + { + "target": "ci--DemoApplicationTest8", + "projects": "self", + "params": "forward" + } + ], + "metadata": { + "description": "Runs Gradle Tests in CI", + "technologies": ["gradle"] + }, + "options": { "cwd": "proj" }, + "executor": "nx:noop" + } + }, + "metadata": { + "targetGroups": { + "verification": ["ci"] + }, + "technologies": ["gradle"] + }, + "name": "application" + } + } +} diff --git a/packages/gradle/src/plugin/utils/get-project-graph-from-gradle-plugin.ts b/packages/gradle/src/plugin/utils/get-project-graph-from-gradle-plugin.ts new file mode 100644 index 0000000000..affe47c535 --- /dev/null +++ b/packages/gradle/src/plugin/utils/get-project-graph-from-gradle-plugin.ts @@ -0,0 +1,203 @@ +import { existsSync } from 'node:fs'; +import { join } from 'node:path'; + +import { + AggregateCreateNodesError, + hashArray, + ProjectConfiguration, + ProjectGraphExternalNode, + readJsonFile, + StaticDependency, + writeJsonFile, +} from '@nx/devkit'; + +import { hashWithWorkspaceContext } from 'nx/src/utils/workspace-context'; +import { gradleConfigAndTestGlob } from '../../utils/split-config-files'; +import { workspaceDataDirectory } from 'nx/src/utils/cache-directory'; +import { getNxProjectGraphLines } from './get-project-graph-lines'; +import { GradlePluginOptions } from './gradle-plugin-options'; +import { hashObject } from 'nx/src/devkit-internals'; + +// the output json file from the gradle plugin +export interface ProjectGraphReport { + nodes: { + [appRoot: string]: Partial; + }; + dependencies: Array; + externalNodes?: Record; +} + +export interface ProjectGraphReportCache extends ProjectGraphReport { + hash: string; +} + +function readProjectGraphReportCache( + cachePath: string, + hash: string +): ProjectGraphReport | undefined { + const projectGraphReportCache: Partial = existsSync( + cachePath + ) + ? readJsonFile(cachePath) + : undefined; + if (!projectGraphReportCache || projectGraphReportCache.hash !== hash) { + return; + } + return projectGraphReportCache as ProjectGraphReport; +} + +export function writeProjectGraphReportToCache( + cachePath: string, + results: ProjectGraphReport +) { + let projectGraphReportJson: ProjectGraphReportCache = { + hash: gradleCurrentConfigHash, + ...results, + }; + + writeJsonFile(cachePath, projectGraphReportJson); +} + +let projectGraphReportCache: ProjectGraphReport; +let gradleCurrentConfigHash: string; +let projectGraphReportCachePath: string = join( + workspaceDataDirectory, + 'gradle-nodes.hash' +); + +export function getCurrentProjectGraphReport(): ProjectGraphReport { + if (!projectGraphReportCache) { + throw new AggregateCreateNodesError( + [ + [ + null, + new Error( + `Expected cached gradle report. Please open an issue at https://github.com/nrwl/nx/issues/new/choose` + ), + ], + ], + [] + ); + } + return projectGraphReportCache; +} + +/** + * This function populates the gradle report cache. + * For each gradlew file, it runs the `nxProjectGraph` task and processes the output. + * It will throw an error if both tasks fail. + * It will accumulate the output of all gradlew files. + * @param workspaceRoot + * @param gradlewFiles absolute paths to all gradlew files in the workspace + * @returns Promise + */ +export async function populateProjectGraph( + workspaceRoot: string, + gradlewFiles: string[], + options: GradlePluginOptions +): Promise { + const gradleConfigHash = hashArray([ + await hashWithWorkspaceContext(workspaceRoot, [gradleConfigAndTestGlob]), + hashObject(options), + process.env.CI, + ]); + projectGraphReportCache ??= readProjectGraphReportCache( + projectGraphReportCachePath, + gradleConfigHash + ); + if ( + projectGraphReportCache && + (!gradleCurrentConfigHash || gradleConfigHash === gradleCurrentConfigHash) + ) { + return; + } + + const gradleProjectGraphReportStart = performance.mark( + 'gradleProjectGraphReport:start' + ); + + const projectGraphLines = await gradlewFiles.reduce( + async ( + projectGraphLines: Promise, + gradlewFile: string + ): Promise => { + const getNxProjectGraphLinesStart = performance.mark( + `${gradlewFile}GetNxProjectGraphLines:start` + ); + const allLines = await projectGraphLines; + const currentLines = await getNxProjectGraphLines( + gradlewFile, + gradleConfigHash, + options + ); + const getNxProjectGraphLinesEnd = performance.mark( + `${gradlewFile}GetNxProjectGraphLines:end` + ); + performance.measure( + `${gradlewFile}GetNxProjectGraphLines`, + getNxProjectGraphLinesStart.name, + getNxProjectGraphLinesEnd.name + ); + return [...allLines, ...currentLines]; + }, + Promise.resolve([]) + ); + + const gradleProjectGraphReportEnd = performance.mark( + 'gradleProjectGraphReport:end' + ); + performance.measure( + 'gradleProjectGraphReport', + gradleProjectGraphReportStart.name, + gradleProjectGraphReportEnd.name + ); + gradleCurrentConfigHash = gradleConfigHash; + projectGraphReportCache = processNxProjectGraph(projectGraphLines); + writeProjectGraphReportToCache( + projectGraphReportCachePath, + projectGraphReportCache + ); +} + +export function processNxProjectGraph( + projectGraphLines: string[] +): ProjectGraphReport { + let index = 0; + let projectGraphReportForAllProjects: ProjectGraphReport = { + nodes: {}, + dependencies: [], + externalNodes: {}, + }; + while (index < projectGraphLines.length) { + const line = projectGraphLines[index].trim(); + if (line.startsWith('> Task ') && line.endsWith(':nxProjectGraph')) { + while ( + index < projectGraphLines.length && + !projectGraphLines[index].includes('.json') + ) { + index++; + } + const file = projectGraphLines[index]; + const projectGraphReportJson: ProjectGraphReport = + readJsonFile(file); + projectGraphReportForAllProjects.nodes = { + ...projectGraphReportForAllProjects.nodes, + ...projectGraphReportJson.nodes, + }; + if (projectGraphReportJson.dependencies) { + projectGraphReportForAllProjects.dependencies.push( + ...projectGraphReportJson.dependencies + ); + } + if (Object.keys(projectGraphReportJson.externalNodes ?? {}).length > 0) { + projectGraphReportForAllProjects.externalNodes = { + ...projectGraphReportForAllProjects.externalNodes, + ...projectGraphReportJson.externalNodes, + }; + } + } + index++; + } + + return projectGraphReportForAllProjects; +} diff --git a/packages/gradle/src/plugin/utils/get-project-graph-lines.ts b/packages/gradle/src/plugin/utils/get-project-graph-lines.ts new file mode 100644 index 0000000000..9b0fab22f6 --- /dev/null +++ b/packages/gradle/src/plugin/utils/get-project-graph-lines.ts @@ -0,0 +1,90 @@ +import { AggregateCreateNodesError, output, workspaceRoot } from '@nx/devkit'; +import { execGradleAsync, newLineSeparator } from '../../utils/exec-gradle'; +import { GradlePluginOptions } from './gradle-plugin-options'; +import { dirname } from 'node:path'; + +export async function getNxProjectGraphLines( + gradlewFile: string, + gradleConfigHash: string, + gradlePluginOptions: GradlePluginOptions +): Promise { + if (process.env.VERCEL) { + // skip on Vercel + return []; + } + + let nxProjectGraphBuffer: Buffer; + + const gradlePluginOptionsArgs = + Object.entries(gradlePluginOptions ?? {})?.map( + ([key, value]) => `-P${key}=${value}` + ) ?? []; + + try { + nxProjectGraphBuffer = await execGradleAsync(gradlewFile, [ + 'nxProjectGraph', + `-Phash=${gradleConfigHash}`, + '--no-configuration-cache', // disable configuration cache + '--parallel', // add parallel to improve performance + '--build-cache', // enable build cache + '--warning-mode', + 'none', + ...gradlePluginOptionsArgs, + `-Pcwd=${dirname(gradlewFile)}`, + `-PworkspaceRoot=${workspaceRoot}`, + process.env.NX_VERBOSE_LOGGING ? '--info' : '', + ]); + } catch (e: Buffer | Error | any) { + if (e.toString()?.includes('ERROR: JAVA_HOME')) { + throw new AggregateCreateNodesError( + [ + [ + gradlewFile, + new Error( + `Could not find Java. Please install Java and try again: https://www.java.com/en/download/help/index_installing.html.\n\r${e.toString()}` + ), + ], + ], + [] + ); + } else if (e.toString()?.includes(`Task 'nxProjectGraph' not found`)) { + throw new AggregateCreateNodesError( + [ + [ + gradlewFile, + new Error( + `Could not run 'nxProjectGraph' task. Please run 'nx generate @nx/gradle:init' to generate the necessary tasks.\n\r${e.toString()}` + ), + ], + ], + [] + ); + } else { + throw new AggregateCreateNodesError( + [ + [ + gradlewFile, + new Error( + `Could not run 'nxProjectGraph' Gradle task. Please install Gradle and try again: https://gradle.org/install/.\r\n${e.toString()}` + ), + ], + ], + [] + ); + } + } + + const projectGraphLines = nxProjectGraphBuffer + .toString() + .split(newLineSeparator) + .filter((line) => line.trim() !== ''); + + if (process.env.NX_VERBOSE_LOGGING === 'true') { + output.log({ + title: `Successfully ran 'nxProjectGraph' task using ${gradlewFile} with hash ${gradleConfigHash}`, + bodyLines: projectGraphLines, + }); + } + + return projectGraphLines; +} diff --git a/packages/gradle/src/plugin/utils/gradle-plugin-options.ts b/packages/gradle/src/plugin/utils/gradle-plugin-options.ts new file mode 100644 index 0000000000..267f521423 --- /dev/null +++ b/packages/gradle/src/plugin/utils/gradle-plugin-options.ts @@ -0,0 +1,13 @@ +export interface GradlePluginOptions { + testTargetName?: string; + ciTargetName?: string; + [taskTargetName: string]: string | undefined | boolean; +} + +export function normalizeOptions( + options: GradlePluginOptions +): GradlePluginOptions { + options ??= {}; + options.testTargetName ??= 'test'; + return options; +} diff --git a/packages/gradle/src/utils/exec-gradle.spec.ts b/packages/gradle/src/utils/exec-gradle.spec.ts index a8b2ae1286..88e8fd54fa 100644 --- a/packages/gradle/src/utils/exec-gradle.spec.ts +++ b/packages/gradle/src/utils/exec-gradle.spec.ts @@ -1,8 +1,8 @@ import { TempFs } from 'nx/src/internal-testing-utils/temp-fs'; -import { findGraldewFile } from './exec-gradle'; +import { findGradlewFile } from './exec-gradle'; describe('exec gradle', () => { - describe('findGraldewFile', () => { + describe('findGradlewFile', () => { let tempFs: TempFs; let cwd: string; @@ -27,14 +27,14 @@ describe('exec gradle', () => { 'nested/nested/proj/src/test/java/test/aTest.java': ``, 'nested/nested/proj/src/test/java/test/bTest.java': ``, }); - let gradlewFile = findGraldewFile('proj/build.gradle', tempFs.tempDir); + let gradlewFile = findGradlewFile('proj/build.gradle', tempFs.tempDir); expect(gradlewFile).toEqual('gradlew'); - gradlewFile = findGraldewFile( + gradlewFile = findGradlewFile( 'nested/nested/proj/build.gradle', tempFs.tempDir ); expect(gradlewFile).toEqual('gradlew'); - gradlewFile = findGraldewFile( + gradlewFile = findGradlewFile( 'nested/nested/proj/settings.gradle', tempFs.tempDir ); @@ -54,16 +54,16 @@ describe('exec gradle', () => { 'nested/nested/proj/src/test/java/test/bTest.java': ``, }); - let gradlewFile = findGraldewFile('proj/build.gradle', tempFs.tempDir); + let gradlewFile = findGradlewFile('proj/build.gradle', tempFs.tempDir); expect(gradlewFile).toEqual('proj/gradlew'); - gradlewFile = findGraldewFile('proj/settings.gradle', tempFs.tempDir); + gradlewFile = findGradlewFile('proj/settings.gradle', tempFs.tempDir); expect(gradlewFile).toEqual('proj/gradlew'); - gradlewFile = findGraldewFile( + gradlewFile = findGradlewFile( 'nested/nested/proj/build.gradle', tempFs.tempDir ); expect(gradlewFile).toEqual('nested/nested/proj/gradlew'); - gradlewFile = findGraldewFile( + gradlewFile = findGradlewFile( 'nested/nested/proj/settings.gradle', tempFs.tempDir ); @@ -80,7 +80,7 @@ describe('exec gradle', () => { 'nested/nested/proj/src/test/java/test/bTest.java': ``, }); expect(() => - findGraldewFile('proj/build.gradle', tempFs.tempDir) + findGradlewFile('proj/build.gradle', tempFs.tempDir) ).toThrow(); }); }); diff --git a/packages/gradle/src/utils/exec-gradle.ts b/packages/gradle/src/utils/exec-gradle.ts index 19628bf684..543db1efd5 100644 --- a/packages/gradle/src/utils/exec-gradle.ts +++ b/packages/gradle/src/utils/exec-gradle.ts @@ -4,6 +4,14 @@ import { existsSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { LARGE_BUFFER } from 'nx/src/executors/run-commands/run-commands.impl'; +export const fileSeparator = process.platform.startsWith('win') + ? 'file:///' + : 'file://'; + +export const newLineSeparator = process.platform.startsWith('win') + ? '\r\n' + : '\n'; + /** * For gradle command, it needs to be run from the directory of the gradle binary * @returns gradle binary file name @@ -54,13 +62,13 @@ export function execGradleAsync( /** * This function recursively finds the nearest gradlew file in the workspace - * @param originalFileToSearch the original file to search for + * @param originalFileToSearch the original file to search for, relative to workspace root, file path not directory path * @param wr workspace root * @param currentSearchPath the path to start searching for gradlew file * @returns the relative path of the gradlew file to workspace root, throws an error if gradlew file is not found - * It will return gradlew.bat file on windows and gradlew file on other platforms + * It will return relative path to workspace root of gradlew.bat file on windows and gradlew file on other platforms */ -export function findGraldewFile( +export function findGradlewFile( originalFileToSearch: string, wr: string = workspaceRoot, currentSearchPath?: string @@ -92,5 +100,5 @@ export function findGraldewFile( } } - return findGraldewFile(originalFileToSearch, wr, parent); + return findGradlewFile(originalFileToSearch, wr, parent); } diff --git a/packages/gradle/src/utils/split-config-files.ts b/packages/gradle/src/utils/split-config-files.ts index 2869107e88..ab0ee9e95a 100644 --- a/packages/gradle/src/utils/split-config-files.ts +++ b/packages/gradle/src/utils/split-config-files.ts @@ -8,6 +8,8 @@ export const GRADLE_TEST_FILES = [ '**/src/test/kotlin/**/*Test.kt', '**/src/test/java/**/*Tests.java', '**/src/test/kotlin/**/*Tests.kt', + '**/src/test/groovy/**/*Test.groovy', + '**/src/test/groovy/**/*Tests.groovy', ]; export const gradleConfigGlob = combineGlobPatterns( diff --git a/packages/gradle/src/utils/versions.ts b/packages/gradle/src/utils/versions.ts index e268dc8f82..5de3983d9b 100644 --- a/packages/gradle/src/utils/versions.ts +++ b/packages/gradle/src/utils/versions.ts @@ -1 +1,4 @@ export const nxVersion = require('../../package.json').version; + +export const gradleProjectGraphPluginName = 'dev.nx.gradle.project-graph'; +export const gradleProjectGraphVersion = '0.0.2'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 74bcfd8c8c..92ef571584 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -90,6 +90,9 @@ importers: fast-glob: specifier: 3.3.3 version: 3.3.3 + form-data: + specifier: ^4.0.2 + version: 4.0.2 framer-motion: specifier: ^11.3.0 version: 11.5.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -174,7 +177,7 @@ importers: version: 0.1902.0(chokidar@3.6.0) '@angular-devkit/build-angular': specifier: 19.2.0 - version: 19.2.0(stndy3yfcthbju7r3pdqp75gku) + version: 19.2.0(fiob6yppbuzqqpw7bpjs7r5k6m) '@angular-devkit/core': specifier: 19.2.0 version: 19.2.0(chokidar@3.6.0) @@ -264,7 +267,7 @@ importers: version: 1.38.0 '@module-federation/enhanced': specifier: ^0.9.0 - version: 0.9.0(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + version: 0.9.1(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(webpack@5.98.0) '@module-federation/sdk': specifier: ^0.9.0 version: 0.9.0 @@ -279,7 +282,7 @@ importers: version: 0.2.4 '@nestjs/cli': specifier: ^10.0.2 - version: 10.4.5(@swc/cli@0.6.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(chokidar@3.6.0))(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + version: 10.4.5(@swc/cli@0.6.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(chokidar@3.6.0))(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) '@nestjs/common': specifier: ^9.0.0 version: 9.4.3(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -294,10 +297,10 @@ importers: version: 9.2.0(chokidar@3.6.0)(typescript@5.7.3) '@nestjs/swagger': specifier: ^6.0.0 - version: 6.3.0(@nestjs/common@9.4.3(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@9.4.3(@nestjs/common@9.4.3(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@9.4.3)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2) + version: 6.3.0(@nestjs/common@9.4.3(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@9.4.3)(reflect-metadata@0.2.2) '@nestjs/testing': specifier: ^9.0.0 - version: 9.4.3(@nestjs/common@9.4.3(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@9.4.3(@nestjs/common@9.4.3(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@9.4.3)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@9.4.3(@nestjs/common@9.4.3(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@9.4.3)) + version: 9.4.3(@nestjs/common@9.4.3(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@9.4.3)(@nestjs/platform-express@9.4.3) '@notionhq/client': specifier: ^2.2.15 version: 2.2.15(encoding@0.1.13) @@ -309,7 +312,7 @@ importers: version: 3.13.2(rollup@4.22.0)(webpack-sources@3.2.3) '@nx/angular': specifier: 21.0.0-beta.4 - version: 21.0.0-beta.4(m2fpeifx3zewnwiuits4v2eyjm) + version: 21.0.0-beta.4(j4dvvmbta2x4s76qau4q2xjbhy) '@nx/cypress': specifier: 21.0.0-beta.4 version: 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@zkochan/js-yaml@0.0.7)(cypress@14.3.0)(eslint@8.57.0)(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0)) @@ -336,7 +339,7 @@ importers: version: 1.3.0-beta.11 '@nx/next': specifier: 21.0.0-beta.4 - version: 21.0.0-beta.4(m6qvbv3x7azwoqxph4efgoxvje) + version: 21.0.0-beta.4(@babel/core@7.25.2)(@babel/traverse@7.26.9)(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/helpers@0.5.11)(@zkochan/js-yaml@0.0.7)(bufferutil@4.0.7)(esbuild@0.25.0)(eslint@8.57.0)(html-webpack-plugin@5.5.0(webpack@5.98.0))(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4)(webpack@5.98.0) '@nx/playwright': specifier: 21.0.0-beta.4 version: 21.0.0-beta.4(@babel/traverse@7.26.9)(@playwright/test@1.47.1)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@zkochan/js-yaml@0.0.7)(eslint@8.57.0)(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0)) @@ -351,13 +354,13 @@ importers: version: 1.3.0-beta.11 '@nx/react': specifier: 21.0.0-beta.4 - version: 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/helpers@0.5.11)(@zkochan/js-yaml@0.0.7)(bufferutil@4.0.7)(esbuild@0.25.0)(eslint@8.57.0)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + version: 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/helpers@0.5.11)(@zkochan/js-yaml@0.0.7)(bufferutil@4.0.7)(esbuild@0.25.0)(eslint@8.57.0)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4)(webpack@5.98.0) '@nx/rsbuild': specifier: 21.0.0-beta.4 version: 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0)) '@nx/rspack': specifier: 21.0.0-beta.4 - version: 21.0.0-beta.4(3rkozrjia44o7a5hsza4wqcyli) + version: 21.0.0-beta.4(2mm4hostrwli5jitdy3fuo43oa) '@nx/storybook': specifier: 21.0.0-beta.4 version: 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@zkochan/js-yaml@0.0.7)(cypress@14.3.0)(eslint@8.57.0)(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0)) @@ -369,7 +372,7 @@ importers: version: 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0)) '@nx/webpack': specifier: 21.0.0-beta.4 - version: 21.0.0-beta.4(@babel/traverse@7.26.9)(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(bufferutil@4.0.7)(esbuild@0.25.0)(html-webpack-plugin@5.5.0(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + version: 21.0.0-beta.4(@babel/traverse@7.26.9)(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(bufferutil@4.0.7)(esbuild@0.25.0)(html-webpack-plugin@5.5.0(webpack@5.98.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4) '@phenomnomnominal/tsquery': specifier: ~5.0.1 version: 5.0.1(typescript@5.7.3) @@ -378,7 +381,7 @@ importers: version: 1.47.1 '@pmmmwh/react-refresh-webpack-plugin': specifier: ^0.5.7 - version: 0.5.15(react-refresh@0.10.0)(type-fest@3.13.1)(webpack-dev-server@5.2.1(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack-hot-middleware@2.26.1)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + version: 0.5.15(react-refresh@0.10.0)(type-fest@3.13.1)(webpack-dev-server@5.2.1)(webpack-hot-middleware@2.26.1)(webpack@5.98.0) '@pnpm/lockfile-types': specifier: ^6.0.0 version: 6.0.0 @@ -417,7 +420,7 @@ importers: version: 1.2.6(@swc/helpers@0.5.11) '@rspack/dev-server': specifier: 1.0.9 - version: 1.0.9(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@types/express@4.17.21)(bufferutil@4.0.7)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + version: 1.0.9(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@types/express@4.17.21)(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0) '@rspack/plugin-minify': specifier: ^0.7.5 version: 0.7.5 @@ -444,7 +447,7 @@ importers: version: 8.4.6(@storybook/test@8.5.1(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.22.0)(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8))(typescript@5.7.3)(vite@6.2.0(@types/node@20.16.10)(jiti@1.21.6)(less@4.1.3)(sass-embedded@1.85.1)(sass@1.55.0)(stylus@0.64.0)(terser@5.39.0)(yaml@2.6.1))(webpack-sources@3.2.3) '@storybook/react-webpack5': specifier: 8.4.6 - version: 8.4.6(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@storybook/test@8.5.1(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8)))(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8))(typescript@5.7.3)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + version: 8.4.6(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@storybook/test@8.5.1(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8)))(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8))(typescript@5.7.3)(webpack-cli@5.1.4) '@storybook/test': specifier: ^8.5.1 version: 8.5.1(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8)) @@ -612,7 +615,7 @@ importers: version: 29.7.0(@babel/core@7.25.2) babel-loader: specifier: ^9.1.2 - version: 9.2.1(@babel/core@7.25.2)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + version: 9.2.1(@babel/core@7.25.2)(webpack@5.98.0) browserslist: specifier: ^4.21.4 version: 4.23.3 @@ -639,10 +642,10 @@ importers: version: 2.0.0 copy-webpack-plugin: specifier: ^10.2.4 - version: 10.2.4(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + version: 10.2.4(webpack@5.98.0) css-minimizer-webpack-plugin: specifier: ^5.0.0 - version: 5.0.1(esbuild@0.25.0)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + version: 5.0.1(esbuild@0.25.0)(webpack@5.98.0) cypress: specifier: 14.3.0 version: 14.3.0 @@ -732,7 +735,7 @@ importers: version: 5.0.2 fork-ts-checker-webpack-plugin: specifier: 7.2.13 - version: 7.2.13(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + version: 7.2.13(typescript@5.7.3)(webpack@5.98.0) fs-extra: specifier: ^11.1.0 version: 11.2.0 @@ -750,7 +753,7 @@ importers: version: 4.7.7 html-webpack-plugin: specifier: 5.5.0 - version: 5.5.0(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + version: 5.5.0(webpack@5.98.0) http-proxy-middleware: specifier: ^3.0.3 version: 3.0.3 @@ -831,10 +834,10 @@ importers: version: 4.1.3 less-loader: specifier: 11.1.0 - version: 11.1.0(less@4.1.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + version: 11.1.0(less@4.1.3)(webpack@5.98.0) license-webpack-plugin: specifier: ^4.0.2 - version: 4.0.2(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + version: 4.0.2(webpack@5.98.0) lines-and-columns: specifier: 2.0.3 version: 2.0.3 @@ -867,7 +870,7 @@ importers: version: 0.80.12 mini-css-extract-plugin: specifier: ~2.4.7 - version: 2.4.7(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + version: 2.4.7(webpack@5.98.0) minimatch: specifier: 9.0.3 version: 9.0.3 @@ -975,13 +978,13 @@ importers: version: 1.85.1 sass-loader: specifier: 16.0.5 - version: 16.0.5(@rspack/core@1.2.6(@swc/helpers@0.5.11))(sass-embedded@1.85.1)(sass@1.55.0)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + version: 16.0.5(@rspack/core@1.2.6(@swc/helpers@0.5.11))(sass-embedded@1.85.1)(sass@1.55.0)(webpack@5.98.0) semver: specifier: ^7.6.3 version: 7.6.3 source-map-loader: specifier: ^5.0.0 - version: 5.0.0(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + version: 5.0.0(webpack@5.98.0) source-map-support: specifier: 0.5.19 version: 0.5.19 @@ -993,7 +996,7 @@ importers: version: 4.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8)) style-loader: specifier: ^3.3.0 - version: 3.3.4(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + version: 3.3.4(webpack@5.98.0) tar-stream: specifier: ~2.2.0 version: 2.2.0 @@ -1002,7 +1005,7 @@ importers: version: 1.0.2 terser-webpack-plugin: specifier: ^5.3.3 - version: 5.3.10(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + version: 5.3.10(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack@5.98.0) tmp: specifier: ~0.2.1 version: 0.2.3 @@ -1014,7 +1017,7 @@ importers: version: 29.1.0(@babel/core@7.25.2)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.2))(esbuild@0.25.0)(jest@29.7.0(@types/node@20.16.10)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@types/node@20.16.10)(typescript@5.7.3)))(typescript@5.7.3) ts-loader: specifier: ^9.3.1 - version: 9.5.1(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + version: 9.5.1(typescript@5.7.3)(webpack@5.98.0) ts-node: specifier: 10.9.1 version: 10.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@types/node@20.16.10)(typescript@5.7.3) @@ -1053,10 +1056,10 @@ importers: version: 3.0.5(@types/debug@4.1.12)(@types/node@20.16.10)(jiti@1.21.6)(jsdom@20.0.3(bufferutil@4.0.7))(less@4.1.3)(sass-embedded@1.85.1)(sass@1.55.0)(stylus@0.64.0)(terser@5.39.0)(yaml@2.6.1) webpack: specifier: 5.98.0 - version: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + version: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) webpack-dev-server: specifier: 5.2.1 - version: 5.2.1(bufferutil@4.0.7)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + version: 5.2.1(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0) webpack-merge: specifier: ^5.8.0 version: 5.10.0 @@ -1065,7 +1068,7 @@ importers: version: 3.0.0 webpack-subresource-integrity: specifier: ^5.1.0 - version: 5.1.0(html-webpack-plugin@5.5.0(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + version: 5.1.0(html-webpack-plugin@5.5.0(webpack@5.98.0))(webpack@5.98.0) xstate: specifier: 4.34.0 version: 4.34.0 @@ -4672,33 +4675,15 @@ packages: '@mediapipe/tasks-vision@0.10.8': resolution: {integrity: sha512-Rp7ll8BHrKB3wXaRFKhrltwZl1CiXGdibPxuWXvqGnKTnv8fqa/nvftYNuSbf+pbJWKYCXdBtYTITdAUTGGh0Q==} - '@module-federation/bridge-react-webpack-plugin@0.9.0': - resolution: {integrity: sha512-EaUMMmNVx5IRXB8o39tPU05uWuDN38noQbUjwE2xi8Y5xTx3CFZ9tkgXX+tvzcWc+bu4RnaziaI0RtyBfHhHKw==} - '@module-federation/bridge-react-webpack-plugin@0.9.1': resolution: {integrity: sha512-znN/Qm6M0U1t3iF10gu1hSxDkk18yz78yvk+AMB34UDzpXHiC1zbpIeV2CQNV5GCeafmCICmcn9y1qh7F54KTg==} - '@module-federation/data-prefetch@0.9.0': - resolution: {integrity: sha512-KFC3lOzW/Hwvcgm/tn7075fqC/ONhA+5zPqDz090EsCQqnWQHodzx0XF88/tTvWdfc3mYK9BGYfsnpjlVGT1zA==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - '@module-federation/data-prefetch@0.9.1': resolution: {integrity: sha512-rS1AsgRvIMAWK8oMprEBF0YQ3WvsqnumjinvAZU1Dqut5DICmpQMTPEO1OrAKyjO+PQgEhmq13HggzN6ebGLrQ==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' - '@module-federation/dts-plugin@0.9.0': - resolution: {integrity: sha512-2Uu1sPRT9/uB+pG4vQGkLdpsMVM6FK7howulTdy42u6Dz0c2Ivc//od/noM0KEgWf1p54FAtWzpjkqjO5PyciA==} - peerDependencies: - typescript: ^4.9.0 || ^5.0.0 - vue-tsc: '>=1.0.24' - peerDependenciesMeta: - vue-tsc: - optional: true - '@module-federation/dts-plugin@0.9.1': resolution: {integrity: sha512-DezBrFaIKfDcEY7UhqyO1WbYocERYsR/CDN8AV6OvMnRlQ8u0rgM8qBUJwx0s+K59f+CFQFKEN4C8p7naCiHrw==} peerDependencies: @@ -4708,20 +4693,6 @@ packages: vue-tsc: optional: true - '@module-federation/enhanced@0.9.0': - resolution: {integrity: sha512-/fiIc+lZvP7pEiVWe0/0v2ueVcEumew2UNewguHFj3bxyyU5/+/5rHPRV5QIKcLzydrVLvTiS4/dB2Mqd7CVAg==} - peerDependencies: - typescript: ^4.9.0 || ^5.0.0 - vue-tsc: '>=1.0.24' - webpack: ^5.0.0 - peerDependenciesMeta: - typescript: - optional: true - vue-tsc: - optional: true - webpack: - optional: true - '@module-federation/enhanced@0.9.1': resolution: {integrity: sha512-c9siKVjcgT2gtDdOTqEr+GaP2X/PWAS0OV424ljKLstFL1lcS/BIsxWFDmxPPl5hDByAH+1q4YhC1LWY4LNDQw==} peerDependencies: @@ -4739,31 +4710,17 @@ packages: '@module-federation/error-codes@0.8.4': resolution: {integrity: sha512-55LYmrDdKb4jt+qr8qE8U3al62ZANp3FhfVaNPOaAmdTh0jHdD8M3yf5HKFlr5xVkVO4eV/F/J2NCfpbh+pEXQ==} - '@module-federation/error-codes@0.9.0': - resolution: {integrity: sha512-dNqIs5cQfE4p+WIdiZ64cTSRJ5KjGaV+epvZkGttrNjXW9XAAtE7zgpo7cMQ8GWA3wCGaKnFw7Dn48XcU5ZMNw==} - '@module-federation/error-codes@0.9.1': resolution: {integrity: sha512-q8spCvlwUzW42iX1irnlBTcwcZftRNHyGdlaoFO1z/fW4iphnBIfijzkigWQzOMhdPgzqN/up7XN+g5hjBGBtw==} - '@module-federation/inject-external-runtime-core-plugin@0.9.0': - resolution: {integrity: sha512-gDvYmcJyuXy1qzBZ6c+AndQUm50iOXmc56C2GN+F9ILAOQ/dcWFfD+OxyjXr80Pvej6qawW9CTEEWHNF4m4a+w==} - peerDependencies: - '@module-federation/runtime-tools': 0.9.0 - '@module-federation/inject-external-runtime-core-plugin@0.9.1': resolution: {integrity: sha512-BPfzu1cqDU5BhM493enVF1VfxJWmruen0ktlHrWdJJlcddhZzyFBGaLAGoGc+83fS75aEllvJTEthw4kMViMQQ==} peerDependencies: '@module-federation/runtime-tools': 0.9.1 - '@module-federation/managers@0.9.0': - resolution: {integrity: sha512-km8fVdS/r3TRLbSCV8IytKaQVuMbXbHvdZsgK4HRIWqGyBbA2q+gbXfWSC90OhdxNA9hhPEipmx+4hvuXDwaFg==} - '@module-federation/managers@0.9.1': resolution: {integrity: sha512-8hpIrvGfiODxS1qelTd7eaLRVF7jrp17RWgeH1DWoprxELANxm5IVvqUryB+7j+BhoQzamog9DL5q4MuNfGgIA==} - '@module-federation/manifest@0.9.0': - resolution: {integrity: sha512-o6+AyKdznP/Pyd6x/1staafUKNxIuXbmmpZxeL3VDvg8uR+6QM5bd/iXnBUgxaznIGQvUwvW/F1JixdgXwp7ug==} - '@module-federation/manifest@0.9.1': resolution: {integrity: sha512-+GteKBXrAUkq49i2CSyWZXM4vYa+mEVXxR9Du71R55nXXxgbzAIoZj9gxjRunj9pcE8+YpAOyfHxLEdWngxWdg==} @@ -4782,18 +4739,6 @@ packages: react-dom: optional: true - '@module-federation/rspack@0.9.0': - resolution: {integrity: sha512-Cw5/OGknuPwmkWc3jVj+T/uqtQ33cxDVMuaFIA6qGAiy/WfMyElKnOBe0n3JRaigH/A8qkyN/rNvMynYlTczLA==} - peerDependencies: - '@rspack/core': '>=0.7' - typescript: ^4.9.0 || ^5.0.0 - vue-tsc: '>=1.0.24' - peerDependenciesMeta: - typescript: - optional: true - vue-tsc: - optional: true - '@module-federation/rspack@0.9.1': resolution: {integrity: sha512-ZJqG75dWHhyTMa9I0YPJEV2XRt0MFxnDiuMOpI92esdmwWY633CBKyNh1XxcLd629YVeTv03+whr+Fz/f91JEw==} peerDependencies: @@ -4806,9 +4751,6 @@ packages: vue-tsc: optional: true - '@module-federation/runtime-core@0.6.21': - resolution: {integrity: sha512-CLQiPP3kpcPbgPkiu/A1VURI2v4geFnEdizlB1tq0c6eDZqb5aLzvp87ZCGDVSuwY7DCq6jh1k+CM2WGge/2xA==} - '@module-federation/runtime-core@0.9.1': resolution: {integrity: sha512-r61ufhKt5pjl81v7TkmhzeIoSPOaNtLynW6+aCy3KZMa3RfRevFxmygJqv4Nug1L0NhqUeWtdLejh4VIglNy5Q==} @@ -4818,9 +4760,6 @@ packages: '@module-federation/runtime-tools@0.8.4': resolution: {integrity: sha512-fjVOsItJ1u5YY6E9FnS56UDwZgqEQUrWFnouRiPtK123LUuqUI9FH4redZoKWlE1PB0ir1Z3tnqy8eFYzPO38Q==} - '@module-federation/runtime-tools@0.9.0': - resolution: {integrity: sha512-ioYVUsUfQjS7tgRBpZ6KFbz8YET2wD/2KmrO4zVaVHZ3RPyJzwVP9sLlDDdyf/Cn/1sQjNLg57FpyBADmY5M1Q==} - '@module-federation/runtime-tools@0.9.1': resolution: {integrity: sha512-JQZ//ab+lEXoU2DHAH+JtYASGzxEjXB0s4rU+6VJXc8c+oUPxH3kWIwzjdncg2mcWBmC1140DCk+K+kDfOZ5CQ==} @@ -4830,9 +4769,6 @@ packages: '@module-federation/runtime@0.8.4': resolution: {integrity: sha512-yZeZ7z2Rx4gv/0E97oLTF3V6N25vglmwXGgoeju/W2YjsFvWzVtCDI7zRRb0mJhU6+jmSM8jP1DeQGbea/AiZQ==} - '@module-federation/runtime@0.9.0': - resolution: {integrity: sha512-WByDEbJ/9fEUBOQILQRYX9CpAjCEmiU1MBSRoTg0emRKBcE9Ms5vTBN0XVuO+3gZSeyk08SfmaLtnCaeHK8ABA==} - '@module-federation/runtime@0.9.1': resolution: {integrity: sha512-jp7K06weabM5BF5sruHr/VLyalO+cilvRDy7vdEBqq88O9mjc0RserD8J+AP4WTl3ZzU7/GRqwRsiwjjN913dA==} @@ -4848,9 +4784,6 @@ packages: '@module-federation/sdk@0.9.1': resolution: {integrity: sha512-YQonPTImgnCqZjE/A+3N2g3J5ypR6kx1tbBzc9toUANKr/dw/S63qlh/zHKzWQzxjjNNVMdXRtTMp07g3kgEWg==} - '@module-federation/third-party-dts-extractor@0.9.0': - resolution: {integrity: sha512-gNMiFxSAkyy85KmdcdapKOP0RVqfuhzosdj92T9xXxR9juuILNS0TtgKbgYwNwvDs/WjOhTON5gz2lsX0kFKRg==} - '@module-federation/third-party-dts-extractor@0.9.1': resolution: {integrity: sha512-KeIByP718hHyq+Mc53enZ419pZZ1fh9Ns6+/bYLkc3iCoJr/EDBeiLzkbMwh2AS4Qk57WW0yNC82xzf7r0Zrrw==} @@ -4875,9 +4808,6 @@ packages: '@module-federation/webpack-bundler-runtime@0.8.4': resolution: {integrity: sha512-HggROJhvHPUX7uqBD/XlajGygMNM1DG0+4OAkk8MBQe4a18QzrRNzZt6XQbRTSG4OaEoyRWhQHvYD3Yps405tQ==} - '@module-federation/webpack-bundler-runtime@0.9.0': - resolution: {integrity: sha512-banXhVcgNYTqH13C6E9KrpwJ+UHaTvHfkvCRPs1y2EVvB9guPO6MnQ9Fd1DCwVMfpq3zMtJpPHobAqF5AmkCHQ==} - '@module-federation/webpack-bundler-runtime@0.9.1': resolution: {integrity: sha512-CxySX01gT8cBowKl9xZh+voiHvThMZ471icasWnlDIZb14KasZoX1eCh9wpGvwoOdIk9rIRT7h70UvW9nmop6w==} @@ -9184,12 +9114,6 @@ packages: acorn-globals@7.0.1: resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} - acorn-import-assertions@1.9.0: - resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} - deprecated: package has been renamed to acorn-import-attributes - peerDependencies: - acorn: ^8 - acorn-import-attributes@1.9.5: resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} peerDependencies: @@ -11440,10 +11364,6 @@ packages: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} - es-set-tostringtag@2.0.3: - resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} - engines: {node: '>= 0.4'} - es-set-tostringtag@2.1.0: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} @@ -11594,27 +11514,6 @@ packages: eslint-plugin-import-x: optional: true - eslint-module-utils@2.11.0: - resolution: {integrity: sha512-gbBE5Hitek/oG6MUVj6sFuzEjA/ClzNflVrLovHi/JgLdC7fiN5gLAY1WIPW1a0V5I999MnsrvVrCOGmmVqDBQ==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - eslint-module-utils@2.12.0: resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} engines: {node: '>=4'} @@ -12177,8 +12076,8 @@ packages: resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} engines: {node: '>= 14.17'} - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + form-data@4.0.2: + resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} engines: {node: '>= 6'} format@0.2.2: @@ -19956,16 +19855,6 @@ packages: webpack-virtual-modules@0.6.2: resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} - webpack@5.88.0: - resolution: {integrity: sha512-O3jDhG5e44qIBSi/P6KpcCcH7HD+nYIHVBhdWFxcLOcIGN8zGo5nqF3BjyNCxIh4p1vFdNnreZv2h2KkoAw3lw==} - engines: {node: '>=10.13.0'} - hasBin: true - peerDependencies: - webpack-cli: '*' - peerDependenciesMeta: - webpack-cli: - optional: true - webpack@5.94.0: resolution: {integrity: sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==} engines: {node: '>=10.13.0'} @@ -20444,11 +20333,11 @@ snapshots: transitivePeerDependencies: - chokidar - '@angular-devkit/build-angular@19.2.0(stndy3yfcthbju7r3pdqp75gku)': + '@angular-devkit/build-angular@19.2.0(fiob6yppbuzqqpw7bpjs7r5k6m)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.1902.0(chokidar@3.6.0) - '@angular-devkit/build-webpack': 0.1902.0(chokidar@3.6.0)(webpack-dev-server@5.2.0(bufferutil@4.0.7)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + '@angular-devkit/build-webpack': 0.1902.0(chokidar@3.6.0)(webpack-dev-server@5.2.0(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0) '@angular-devkit/core': 19.2.0(chokidar@3.6.0) '@angular/build': 19.2.0(cxjrqumqlcnastohrhciqzxvse) '@angular/compiler-cli': 19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.7.3) @@ -20462,14 +20351,14 @@ snapshots: '@babel/preset-env': 7.26.9(@babel/core@7.26.9) '@babel/runtime': 7.26.9 '@discoveryjs/json-ext': 0.6.3 - '@ngtools/webpack': 19.2.0(@angular/compiler-cli@19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.7.3))(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + '@ngtools/webpack': 19.2.0(@angular/compiler-cli@19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.7.3))(typescript@5.7.3)(webpack@5.98.0) '@vitejs/plugin-basic-ssl': 1.2.0(vite@6.2.0(@types/node@20.16.10)(jiti@1.21.6)(less@4.1.3)(sass-embedded@1.85.1)(sass@1.55.0)(stylus@0.64.0)(terser@5.39.0)(yaml@2.6.1)) ansi-colors: 4.1.3 autoprefixer: 10.4.20(postcss@8.5.2) - babel-loader: 9.2.1(@babel/core@7.26.9)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + babel-loader: 9.2.1(@babel/core@7.26.9)(webpack@5.98.0) browserslist: 4.24.4 - copy-webpack-plugin: 12.0.2(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - css-loader: 7.1.2(@rspack/core@1.2.6(@swc/helpers@0.5.11))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + copy-webpack-plugin: 12.0.2(webpack@5.98.0) + css-loader: 7.1.2(@rspack/core@1.2.6(@swc/helpers@0.5.11))(webpack@5.98.0) esbuild-wasm: 0.25.0 fast-glob: 3.3.3 http-proxy-middleware: 3.0.3 @@ -20477,32 +20366,32 @@ snapshots: jsonc-parser: 3.3.1 karma-source-map-support: 1.4.0 less: 4.2.2 - less-loader: 12.2.0(@rspack/core@1.2.6(@swc/helpers@0.5.11))(less@4.2.2)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - license-webpack-plugin: 4.0.2(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + less-loader: 12.2.0(@rspack/core@1.2.6(@swc/helpers@0.5.11))(less@4.2.2)(webpack@5.98.0) + license-webpack-plugin: 4.0.2(webpack@5.98.0) loader-utils: 3.3.1 - mini-css-extract-plugin: 2.9.2(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + mini-css-extract-plugin: 2.9.2(webpack@5.98.0) open: 10.1.0 ora: 5.4.1 picomatch: 4.0.2 piscina: 4.8.0 postcss: 8.5.2 - postcss-loader: 8.1.1(@rspack/core@1.2.6(@swc/helpers@0.5.11))(postcss@8.5.2)(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + postcss-loader: 8.1.1(@rspack/core@1.2.6(@swc/helpers@0.5.11))(postcss@8.5.2)(typescript@5.7.3)(webpack@5.98.0) resolve-url-loader: 5.0.0 rxjs: 7.8.1 sass: 1.85.0 - sass-loader: 16.0.5(@rspack/core@1.2.6(@swc/helpers@0.5.11))(sass-embedded@1.85.1)(sass@1.85.0)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + sass-loader: 16.0.5(@rspack/core@1.2.6(@swc/helpers@0.5.11))(sass-embedded@1.85.1)(sass@1.85.0)(webpack@5.98.0) semver: 7.7.1 - source-map-loader: 5.0.0(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + source-map-loader: 5.0.0(webpack@5.98.0) source-map-support: 0.5.21 terser: 5.39.0 tree-kill: 1.2.2 tslib: 2.8.1 typescript: 5.7.3 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) - webpack-dev-middleware: 7.4.2(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - webpack-dev-server: 5.2.0(bufferutil@4.0.7)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) + webpack-dev-middleware: 7.4.2(webpack@5.98.0) + webpack-dev-server: 5.2.0(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0) webpack-merge: 6.0.1 - webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.5.0(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.5.0(webpack@5.98.0))(webpack@5.98.0) optionalDependencies: '@angular/ssr': 19.2.0(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.14.10))(@angular/router@19.2.0(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.14.10))(@angular/platform-browser@18.2.5(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.14.10)))(rxjs@7.8.1)) esbuild: 0.25.0 @@ -20533,12 +20422,12 @@ snapshots: - webpack-cli - yaml - '@angular-devkit/build-webpack@0.1902.0(chokidar@3.6.0)(webpack-dev-server@5.2.0(bufferutil@4.0.7)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)))': + '@angular-devkit/build-webpack@0.1902.0(chokidar@3.6.0)(webpack-dev-server@5.2.0(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0)': dependencies: '@angular-devkit/architect': 0.1902.0(chokidar@3.6.0) rxjs: 7.8.1 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) - webpack-dev-server: 5.2.0(bufferutil@4.0.7)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) + webpack-dev-server: 5.2.0(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0) transitivePeerDependencies: - chokidar @@ -23260,7 +23149,7 @@ snapshots: combined-stream: 1.0.8 extend: 3.0.2 forever-agent: 0.6.1 - form-data: 4.0.0 + form-data: 4.0.2 http-signature: 1.4.0 is-typedarray: 1.0.0 isstream: 0.1.2 @@ -23281,7 +23170,7 @@ snapshots: combined-stream: 1.0.8 extend: 3.0.2 forever-agent: 0.6.1 - form-data: 4.0.0 + form-data: 4.0.2 http-signature: 1.4.0 is-typedarray: 1.0.0 isstream: 0.1.2 @@ -24700,26 +24589,12 @@ snapshots: '@mediapipe/tasks-vision@0.10.8': {} - '@module-federation/bridge-react-webpack-plugin@0.9.0': - dependencies: - '@module-federation/sdk': 0.9.0 - '@types/semver': 7.5.8 - semver: 7.6.3 - '@module-federation/bridge-react-webpack-plugin@0.9.1': dependencies: '@module-federation/sdk': 0.9.1 '@types/semver': 7.5.8 semver: 7.6.3 - '@module-federation/data-prefetch@0.9.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@module-federation/runtime': 0.9.0 - '@module-federation/sdk': 0.9.0 - fs-extra: 9.1.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - '@module-federation/data-prefetch@0.9.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@module-federation/runtime': 0.9.1 @@ -24728,31 +24603,6 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@module-federation/dts-plugin@0.9.0(bufferutil@4.0.7)(typescript@5.7.3)': - dependencies: - '@module-federation/error-codes': 0.9.0 - '@module-federation/managers': 0.9.0 - '@module-federation/sdk': 0.9.0 - '@module-federation/third-party-dts-extractor': 0.9.0 - adm-zip: 0.5.16 - ansi-colors: 4.1.3 - axios: 1.8.3 - chalk: 3.0.0 - fs-extra: 9.1.0 - isomorphic-ws: 5.0.0(ws@8.18.0(bufferutil@4.0.7)) - koa: 2.15.4 - lodash.clonedeepwith: 4.5.0 - log4js: 6.9.1 - node-schedule: 2.1.1 - rambda: 9.3.0 - typescript: 5.7.3 - ws: 8.18.0(bufferutil@4.0.7) - transitivePeerDependencies: - - bufferutil - - debug - - supports-color - - utf-8-validate - '@module-federation/dts-plugin@0.9.1(bufferutil@4.0.7)(typescript@5.7.3)': dependencies: '@module-federation/error-codes': 0.9.1 @@ -24778,33 +24628,7 @@ snapshots: - supports-color - utf-8-validate - '@module-federation/enhanced@0.9.0(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)))': - dependencies: - '@module-federation/bridge-react-webpack-plugin': 0.9.0 - '@module-federation/data-prefetch': 0.9.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@module-federation/dts-plugin': 0.9.0(bufferutil@4.0.7)(typescript@5.7.3) - '@module-federation/error-codes': 0.9.0 - '@module-federation/inject-external-runtime-core-plugin': 0.9.0(@module-federation/runtime-tools@0.9.0) - '@module-federation/managers': 0.9.0 - '@module-federation/manifest': 0.9.0(bufferutil@4.0.7)(typescript@5.7.3) - '@module-federation/rspack': 0.9.0(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(typescript@5.7.3) - '@module-federation/runtime-tools': 0.9.0 - '@module-federation/sdk': 0.9.0 - btoa: 1.2.1 - upath: 2.0.1 - optionalDependencies: - typescript: 5.7.3 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) - transitivePeerDependencies: - - '@rspack/core' - - bufferutil - - debug - - react - - react-dom - - supports-color - - utf-8-validate - - '@module-federation/enhanced@0.9.1(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)))': + '@module-federation/enhanced@0.9.1(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(webpack@5.98.0)': dependencies: '@module-federation/bridge-react-webpack-plugin': 0.9.1 '@module-federation/data-prefetch': 0.9.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -24820,7 +24644,7 @@ snapshots: upath: 2.0.1 optionalDependencies: typescript: 5.7.3 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) transitivePeerDependencies: - '@rspack/core' - bufferutil @@ -24832,45 +24656,18 @@ snapshots: '@module-federation/error-codes@0.8.4': {} - '@module-federation/error-codes@0.9.0': {} - '@module-federation/error-codes@0.9.1': {} - '@module-federation/inject-external-runtime-core-plugin@0.9.0(@module-federation/runtime-tools@0.9.0)': - dependencies: - '@module-federation/runtime-tools': 0.9.0 - '@module-federation/inject-external-runtime-core-plugin@0.9.1(@module-federation/runtime-tools@0.9.1)': dependencies: '@module-federation/runtime-tools': 0.9.1 - '@module-federation/managers@0.9.0': - dependencies: - '@module-federation/sdk': 0.9.0 - find-pkg: 2.0.0 - fs-extra: 9.1.0 - '@module-federation/managers@0.9.1': dependencies: '@module-federation/sdk': 0.9.1 find-pkg: 2.0.0 fs-extra: 9.1.0 - '@module-federation/manifest@0.9.0(bufferutil@4.0.7)(typescript@5.7.3)': - dependencies: - '@module-federation/dts-plugin': 0.9.0(bufferutil@4.0.7)(typescript@5.7.3) - '@module-federation/managers': 0.9.0 - '@module-federation/sdk': 0.9.0 - chalk: 3.0.0 - find-pkg: 2.0.0 - transitivePeerDependencies: - - bufferutil - - debug - - supports-color - - typescript - - utf-8-validate - - vue-tsc - '@module-federation/manifest@0.9.1(bufferutil@4.0.7)(typescript@5.7.3)': dependencies: '@module-federation/dts-plugin': 0.9.1(bufferutil@4.0.7)(typescript@5.7.3) @@ -24886,16 +24683,16 @@ snapshots: - utf-8-validate - vue-tsc - '@module-federation/node@2.6.27(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)))': + '@module-federation/node@2.6.27(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(webpack@5.98.0)': dependencies: - '@module-federation/enhanced': 0.9.1(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + '@module-federation/enhanced': 0.9.1(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(webpack@5.98.0) '@module-federation/runtime': 0.9.1 '@module-federation/sdk': 0.9.1 - '@module-federation/utilities': 3.1.45(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + '@module-federation/utilities': 3.1.45(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.98.0) btoa: 1.2.1 encoding: 0.1.13 node-fetch: 2.7.0(encoding@0.1.13) - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) optionalDependencies: next: 14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0) react: 18.3.1 @@ -24909,24 +24706,6 @@ snapshots: - utf-8-validate - vue-tsc - '@module-federation/rspack@0.9.0(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(typescript@5.7.3)': - dependencies: - '@module-federation/bridge-react-webpack-plugin': 0.9.0 - '@module-federation/dts-plugin': 0.9.0(bufferutil@4.0.7)(typescript@5.7.3) - '@module-federation/inject-external-runtime-core-plugin': 0.9.0(@module-federation/runtime-tools@0.9.0) - '@module-federation/managers': 0.9.0 - '@module-federation/manifest': 0.9.0(bufferutil@4.0.7)(typescript@5.7.3) - '@module-federation/runtime-tools': 0.9.0 - '@module-federation/sdk': 0.9.0 - '@rspack/core': 1.2.6(@swc/helpers@0.5.11) - optionalDependencies: - typescript: 5.7.3 - transitivePeerDependencies: - - bufferutil - - debug - - supports-color - - utf-8-validate - '@module-federation/rspack@0.9.1(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(typescript@5.7.3)': dependencies: '@module-federation/bridge-react-webpack-plugin': 0.9.1 @@ -24945,11 +24724,6 @@ snapshots: - supports-color - utf-8-validate - '@module-federation/runtime-core@0.6.21': - dependencies: - '@module-federation/error-codes': 0.9.0 - '@module-federation/sdk': 0.9.0 - '@module-federation/runtime-core@0.9.1': dependencies: '@module-federation/error-codes': 0.9.1 @@ -24965,11 +24739,6 @@ snapshots: '@module-federation/runtime': 0.8.4 '@module-federation/webpack-bundler-runtime': 0.8.4 - '@module-federation/runtime-tools@0.9.0': - dependencies: - '@module-federation/runtime': 0.9.0 - '@module-federation/webpack-bundler-runtime': 0.9.0 - '@module-federation/runtime-tools@0.9.1': dependencies: '@module-federation/runtime': 0.9.1 @@ -24984,12 +24753,6 @@ snapshots: '@module-federation/error-codes': 0.8.4 '@module-federation/sdk': 0.8.4 - '@module-federation/runtime@0.9.0': - dependencies: - '@module-federation/error-codes': 0.9.0 - '@module-federation/runtime-core': 0.6.21 - '@module-federation/sdk': 0.9.0 - '@module-federation/runtime@0.9.1': dependencies: '@module-federation/error-codes': 0.9.1 @@ -25008,22 +24771,16 @@ snapshots: '@module-federation/sdk@0.9.1': {} - '@module-federation/third-party-dts-extractor@0.9.0': - dependencies: - find-pkg: 2.0.0 - fs-extra: 9.1.0 - resolve: 1.22.8 - '@module-federation/third-party-dts-extractor@0.9.1': dependencies: find-pkg: 2.0.0 fs-extra: 9.1.0 resolve: 1.22.8 - '@module-federation/utilities@3.1.45(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)))': + '@module-federation/utilities@3.1.45(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.98.0)': dependencies: '@module-federation/sdk': 0.9.1 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) optionalDependencies: next: 14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0) react: 18.3.1 @@ -25039,11 +24796,6 @@ snapshots: '@module-federation/runtime': 0.8.4 '@module-federation/sdk': 0.8.4 - '@module-federation/webpack-bundler-runtime@0.9.0': - dependencies: - '@module-federation/runtime': 0.9.0 - '@module-federation/sdk': 0.9.0 - '@module-federation/webpack-bundler-runtime@0.9.1': dependencies: '@module-federation/runtime': 0.9.1 @@ -25448,7 +25200,7 @@ snapshots: '@napi-rs/wasm-tools-win32-ia32-msvc': 0.0.2 '@napi-rs/wasm-tools-win32-x64-msvc': 0.0.2 - '@nestjs/cli@10.4.5(@swc/cli@0.6.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(chokidar@3.6.0))(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))': + '@nestjs/cli@10.4.5(@swc/cli@0.6.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(chokidar@3.6.0))(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4)': dependencies: '@angular-devkit/core': 17.3.8(chokidar@3.6.0) '@angular-devkit/schematics': 17.3.8(chokidar@3.6.0) @@ -25458,7 +25210,7 @@ snapshots: chokidar: 3.6.0 cli-table3: 0.6.5 commander: 4.1.1 - fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.3.3)(webpack@5.94.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.3.3)(webpack@5.94.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4)) glob: 10.4.2 inquirer: 8.2.6 node-emoji: 1.11.0 @@ -25467,7 +25219,7 @@ snapshots: tsconfig-paths: 4.2.0 tsconfig-paths-webpack-plugin: 4.1.0 typescript: 5.3.3 - webpack: 5.94.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.94.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) webpack-node-externals: 3.0.0 optionalDependencies: '@swc/cli': 0.6.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(chokidar@3.6.0) @@ -25539,7 +25291,7 @@ snapshots: transitivePeerDependencies: - chokidar - '@nestjs/swagger@6.3.0(@nestjs/common@9.4.3(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@9.4.3(@nestjs/common@9.4.3(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@9.4.3)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)': + '@nestjs/swagger@6.3.0(@nestjs/common@9.4.3(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@9.4.3)(reflect-metadata@0.2.2)': dependencies: '@nestjs/common': 9.4.3(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 9.4.3(@nestjs/common@9.4.3(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@9.4.3)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -25550,7 +25302,7 @@ snapshots: reflect-metadata: 0.2.2 swagger-ui-dist: 4.18.2 - '@nestjs/testing@9.4.3(@nestjs/common@9.4.3(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@9.4.3(@nestjs/common@9.4.3(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@9.4.3)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@9.4.3(@nestjs/common@9.4.3(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@9.4.3))': + '@nestjs/testing@9.4.3(@nestjs/common@9.4.3(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@9.4.3)(@nestjs/platform-express@9.4.3)': dependencies: '@nestjs/common': 9.4.3(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 9.4.3(@nestjs/common@9.4.3(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@9.4.3)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -25602,11 +25354,11 @@ snapshots: '@next/swc-win32-x64-msvc@14.2.28': optional: true - '@ngtools/webpack@19.2.0(@angular/compiler-cli@19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.7.3))(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)))': + '@ngtools/webpack@19.2.0(@angular/compiler-cli@19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.7.3))(typescript@5.7.3)(webpack@5.98.0)': dependencies: '@angular/compiler-cli': 19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.7.3) typescript: 5.7.3 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) '@nodelib/fs.scandir@2.1.5': dependencies: @@ -25953,18 +25705,18 @@ snapshots: transitivePeerDependencies: - encoding - '@nx/angular@21.0.0-beta.4(m2fpeifx3zewnwiuits4v2eyjm)': + '@nx/angular@21.0.0-beta.4(j4dvvmbta2x4s76qau4q2xjbhy)': dependencies: - '@angular-devkit/build-angular': 19.2.0(stndy3yfcthbju7r3pdqp75gku) + '@angular-devkit/build-angular': 19.2.0(fiob6yppbuzqqpw7bpjs7r5k6m) '@angular-devkit/core': 19.2.0(chokidar@3.6.0) '@angular-devkit/schematics': 19.2.0(chokidar@3.6.0) '@nx/devkit': 21.0.0-beta.4(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))) '@nx/eslint': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@zkochan/js-yaml@0.0.7)(eslint@8.57.0)(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0)) '@nx/js': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0)) - '@nx/module-federation': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/helpers@0.5.11)(bufferutil@4.0.7)(esbuild@0.25.0)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) - '@nx/rspack': 21.0.0-beta.4(3rkozrjia44o7a5hsza4wqcyli) + '@nx/module-federation': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/helpers@0.5.11)(bufferutil@4.0.7)(esbuild@0.25.0)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4) + '@nx/rspack': 21.0.0-beta.4(2mm4hostrwli5jitdy3fuo43oa) '@nx/web': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0)) - '@nx/webpack': 21.0.0-beta.4(@babel/traverse@7.26.9)(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(bufferutil@4.0.7)(esbuild@0.25.0)(html-webpack-plugin@5.5.0(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + '@nx/webpack': 21.0.0-beta.4(@babel/traverse@7.26.9)(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(bufferutil@4.0.7)(esbuild@0.25.0)(html-webpack-plugin@5.5.0(webpack@5.98.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4) '@nx/workspace': 21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)) '@phenomnomnominal/tsquery': 5.0.1(typescript@5.7.3) '@schematics/angular': 19.2.0(chokidar@3.6.0) @@ -26278,10 +26030,10 @@ snapshots: transitivePeerDependencies: - debug - '@nx/module-federation@21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/helpers@0.5.11)(bufferutil@4.0.7)(esbuild@0.25.0)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))': + '@nx/module-federation@21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/helpers@0.5.11)(bufferutil@4.0.7)(esbuild@0.25.0)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4)': dependencies: - '@module-federation/enhanced': 0.9.1(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - '@module-federation/node': 2.6.27(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + '@module-federation/enhanced': 0.9.1(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(webpack@5.98.0) + '@module-federation/node': 2.6.27(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(webpack@5.98.0) '@module-federation/sdk': 0.9.1 '@nx/devkit': 21.0.0-beta.4(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))) '@nx/js': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0)) @@ -26291,7 +26043,7 @@ snapshots: http-proxy-middleware: 3.0.3 picocolors: 1.1.1 tslib: 2.8.1 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) transitivePeerDependencies: - '@babel/traverse' - '@rspack/tracing' @@ -26313,19 +26065,19 @@ snapshots: - vue-tsc - webpack-cli - '@nx/next@21.0.0-beta.4(m6qvbv3x7azwoqxph4efgoxvje)': + '@nx/next@21.0.0-beta.4(@babel/core@7.25.2)(@babel/traverse@7.26.9)(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/helpers@0.5.11)(@zkochan/js-yaml@0.0.7)(bufferutil@4.0.7)(esbuild@0.25.0)(eslint@8.57.0)(html-webpack-plugin@5.5.0(webpack@5.98.0))(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4)(webpack@5.98.0)': dependencies: '@babel/plugin-proposal-decorators': 7.24.7(@babel/core@7.25.2) '@nx/devkit': 21.0.0-beta.4(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))) '@nx/eslint': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@zkochan/js-yaml@0.0.7)(eslint@8.57.0)(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0)) '@nx/js': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0)) - '@nx/react': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/helpers@0.5.11)(@zkochan/js-yaml@0.0.7)(bufferutil@4.0.7)(esbuild@0.25.0)(eslint@8.57.0)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + '@nx/react': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/helpers@0.5.11)(@zkochan/js-yaml@0.0.7)(bufferutil@4.0.7)(esbuild@0.25.0)(eslint@8.57.0)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4)(webpack@5.98.0) '@nx/web': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0)) - '@nx/webpack': 21.0.0-beta.4(@babel/traverse@7.26.9)(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(bufferutil@4.0.7)(esbuild@0.25.0)(html-webpack-plugin@5.5.0(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + '@nx/webpack': 21.0.0-beta.4(@babel/traverse@7.26.9)(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(bufferutil@4.0.7)(esbuild@0.25.0)(html-webpack-plugin@5.5.0(webpack@5.98.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4) '@phenomnomnominal/tsquery': 5.0.1(typescript@5.7.3) '@svgr/webpack': 8.1.0(typescript@5.7.3) - copy-webpack-plugin: 10.2.4(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - file-loader: 6.2.0(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + copy-webpack-plugin: 10.2.4(webpack@5.98.0) + file-loader: 6.2.0(webpack@5.98.0) ignore: 5.3.2 next: 14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0) semver: 7.7.1 @@ -26437,17 +26189,17 @@ snapshots: transitivePeerDependencies: - debug - '@nx/react@21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/helpers@0.5.11)(@zkochan/js-yaml@0.0.7)(bufferutil@4.0.7)(esbuild@0.25.0)(eslint@8.57.0)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)))': + '@nx/react@21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/helpers@0.5.11)(@zkochan/js-yaml@0.0.7)(bufferutil@4.0.7)(esbuild@0.25.0)(eslint@8.57.0)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4)(webpack@5.98.0)': dependencies: '@nx/devkit': 21.0.0-beta.4(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))) '@nx/eslint': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@zkochan/js-yaml@0.0.7)(eslint@8.57.0)(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0)) '@nx/js': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0)) - '@nx/module-federation': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/helpers@0.5.11)(bufferutil@4.0.7)(esbuild@0.25.0)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + '@nx/module-federation': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/helpers@0.5.11)(bufferutil@4.0.7)(esbuild@0.25.0)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4) '@nx/web': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0)) '@phenomnomnominal/tsquery': 5.0.1(typescript@5.7.3) '@svgr/webpack': 8.1.0(typescript@5.7.3) express: 4.21.2 - file-loader: 6.2.0(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + file-loader: 6.2.0(webpack@5.98.0) http-proxy-middleware: 3.0.3 minimatch: 9.0.3 picocolors: 1.1.1 @@ -26495,39 +26247,39 @@ snapshots: - typescript - verdaccio - '@nx/rspack@21.0.0-beta.4(3rkozrjia44o7a5hsza4wqcyli)': + '@nx/rspack@21.0.0-beta.4(2mm4hostrwli5jitdy3fuo43oa)': dependencies: - '@module-federation/enhanced': 0.9.0(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - '@module-federation/node': 2.6.27(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + '@module-federation/enhanced': 0.9.1(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(webpack@5.98.0) + '@module-federation/node': 2.6.27(@rspack/core@1.2.6(@swc/helpers@0.5.11))(bufferutil@4.0.7)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(webpack@5.98.0) '@nx/devkit': 21.0.0-beta.4(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))) '@nx/js': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0)) - '@nx/module-federation': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/helpers@0.5.11)(bufferutil@4.0.7)(esbuild@0.25.0)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + '@nx/module-federation': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/helpers@0.5.11)(bufferutil@4.0.7)(esbuild@0.25.0)(next@14.2.28(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4) '@nx/web': 21.0.0-beta.4(@babel/traverse@7.26.9)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0)) '@phenomnomnominal/tsquery': 5.0.1(typescript@5.7.3) '@rspack/core': 1.2.6(@swc/helpers@0.5.11) - '@rspack/dev-server': 1.0.9(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@types/express@4.17.21)(bufferutil@4.0.7)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + '@rspack/dev-server': 1.0.9(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@types/express@4.17.21)(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0) '@rspack/plugin-react-refresh': 1.0.0(react-refresh@0.10.0) autoprefixer: 10.4.13(postcss@8.4.38) browserslist: 4.24.4 - css-loader: 6.11.0(@rspack/core@1.2.6(@swc/helpers@0.5.11))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + css-loader: 6.11.0(@rspack/core@1.2.6(@swc/helpers@0.5.11))(webpack@5.98.0) enquirer: 2.3.6 express: 4.21.2 http-proxy-middleware: 3.0.3 - less-loader: 11.1.0(less@4.1.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - license-webpack-plugin: 4.0.2(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + less-loader: 11.1.0(less@4.1.3)(webpack@5.98.0) + license-webpack-plugin: 4.0.2(webpack@5.98.0) loader-utils: 2.0.3 picocolors: 1.1.1 postcss: 8.4.38 postcss-import: 14.1.0(postcss@8.4.38) - postcss-loader: 8.1.1(@rspack/core@1.2.6(@swc/helpers@0.5.11))(postcss@8.4.38)(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + postcss-loader: 8.1.1(@rspack/core@1.2.6(@swc/helpers@0.5.11))(postcss@8.4.38)(typescript@5.7.3)(webpack@5.98.0) sass: 1.85.0 sass-embedded: 1.85.1 - sass-loader: 16.0.5(@rspack/core@1.2.6(@swc/helpers@0.5.11))(sass-embedded@1.85.1)(sass@1.85.0)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - source-map-loader: 5.0.0(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - style-loader: 3.3.4(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + sass-loader: 16.0.5(@rspack/core@1.2.6(@swc/helpers@0.5.11))(sass-embedded@1.85.1)(sass@1.85.0)(webpack@5.98.0) + source-map-loader: 5.0.0(webpack@5.98.0) + style-loader: 3.3.4(webpack@5.98.0) ts-checker-rspack-plugin: 1.1.1(@rspack/core@1.2.6(@swc/helpers@0.5.11))(typescript@5.7.3) tslib: 2.8.1 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) webpack-node-externals: 3.0.0 transitivePeerDependencies: - '@babel/traverse' @@ -26615,7 +26367,7 @@ snapshots: - supports-color - verdaccio - '@nx/webpack@21.0.0-beta.4(@babel/traverse@7.26.9)(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(bufferutil@4.0.7)(esbuild@0.25.0)(html-webpack-plugin@5.5.0(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))': + '@nx/webpack@21.0.0-beta.4(@babel/traverse@7.26.9)(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))(bufferutil@4.0.7)(esbuild@0.25.0)(html-webpack-plugin@5.5.0(webpack@5.98.0))(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(typescript@5.7.3)(verdaccio@6.0.5(encoding@0.1.13)(typanion@3.14.0))(webpack-cli@5.1.4)': dependencies: '@babel/core': 7.26.9 '@nx/devkit': 21.0.0-beta.4(nx@21.0.0-beta.4(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.21)(typescript@5.7.3))(@swc/core@1.5.7(@swc/helpers@0.5.11))) @@ -26623,38 +26375,38 @@ snapshots: '@phenomnomnominal/tsquery': 5.0.1(typescript@5.7.3) ajv: 8.17.1 autoprefixer: 10.4.13(postcss@8.4.38) - babel-loader: 9.2.1(@babel/core@7.26.9)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + babel-loader: 9.2.1(@babel/core@7.26.9)(webpack@5.98.0) browserslist: 4.24.4 - copy-webpack-plugin: 10.2.4(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - css-loader: 6.11.0(@rspack/core@1.2.6(@swc/helpers@0.5.11))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - css-minimizer-webpack-plugin: 5.0.1(esbuild@0.25.0)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - fork-ts-checker-webpack-plugin: 7.2.13(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + copy-webpack-plugin: 10.2.4(webpack@5.98.0) + css-loader: 6.11.0(@rspack/core@1.2.6(@swc/helpers@0.5.11))(webpack@5.98.0) + css-minimizer-webpack-plugin: 5.0.1(esbuild@0.25.0)(webpack@5.98.0) + fork-ts-checker-webpack-plugin: 7.2.13(typescript@5.7.3)(webpack@5.98.0) less: 4.1.3 - less-loader: 11.1.0(less@4.1.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - license-webpack-plugin: 4.0.2(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + less-loader: 11.1.0(less@4.1.3)(webpack@5.98.0) + license-webpack-plugin: 4.0.2(webpack@5.98.0) loader-utils: 2.0.3 - mini-css-extract-plugin: 2.4.7(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + mini-css-extract-plugin: 2.4.7(webpack@5.98.0) parse5: 4.0.0 picocolors: 1.1.1 postcss: 8.4.38 postcss-import: 14.1.0(postcss@8.4.38) - postcss-loader: 6.2.1(postcss@8.4.38)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + postcss-loader: 6.2.1(postcss@8.4.38)(webpack@5.98.0) rxjs: 7.8.1 sass: 1.85.0 sass-embedded: 1.85.1 - sass-loader: 16.0.5(@rspack/core@1.2.6(@swc/helpers@0.5.11))(sass-embedded@1.85.1)(sass@1.85.0)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - source-map-loader: 5.0.0(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - style-loader: 3.3.4(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + sass-loader: 16.0.5(@rspack/core@1.2.6(@swc/helpers@0.5.11))(sass-embedded@1.85.1)(sass@1.85.0)(webpack@5.98.0) + source-map-loader: 5.0.0(webpack@5.98.0) + style-loader: 3.3.4(webpack@5.98.0) stylus: 0.64.0 - stylus-loader: 7.1.3(stylus@0.64.0)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - terser-webpack-plugin: 5.3.11(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - ts-loader: 9.5.1(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + stylus-loader: 7.1.3(stylus@0.64.0)(webpack@5.98.0) + terser-webpack-plugin: 5.3.11(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack@5.98.0) + ts-loader: 9.5.1(typescript@5.7.3)(webpack@5.98.0) tsconfig-paths-webpack-plugin: 4.0.0 tslib: 2.8.1 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) - webpack-dev-server: 5.2.1(bufferutil@4.0.7)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) + webpack-dev-server: 5.2.1(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0) webpack-node-externals: 3.0.0 - webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.5.0(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.5.0(webpack@5.98.0))(webpack@5.98.0) transitivePeerDependencies: - '@babel/traverse' - '@parcel/css' @@ -27128,7 +26880,7 @@ snapshots: dependencies: playwright: 1.47.1 - '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.10.0)(type-fest@3.13.1)(webpack-dev-server@5.2.1(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack-hot-middleware@2.26.1)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)))': + '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.10.0)(type-fest@3.13.1)(webpack-dev-server@5.2.1)(webpack-hot-middleware@2.26.1)(webpack@5.98.0)': dependencies: ansi-html: 0.0.9 core-js-pure: 3.38.1 @@ -27138,10 +26890,10 @@ snapshots: react-refresh: 0.10.0 schema-utils: 4.2.0 source-map: 0.7.3 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) optionalDependencies: type-fest: 3.13.1 - webpack-dev-server: 5.2.1(bufferutil@4.0.7)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + webpack-dev-server: 5.2.1(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0) webpack-hot-middleware: 2.26.1 '@pnpm/lockfile-types@6.0.0': @@ -28511,7 +28263,7 @@ snapshots: optionalDependencies: '@swc/helpers': 0.5.11 - '@rspack/dev-server@1.0.9(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@types/express@4.17.21)(bufferutil@4.0.7)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)))': + '@rspack/dev-server@1.0.9(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@types/express@4.17.21)(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0)': dependencies: '@rspack/core': 1.2.6(@swc/helpers@0.5.11) chokidar: 3.6.0 @@ -28520,8 +28272,8 @@ snapshots: http-proxy-middleware: 2.0.7(@types/express@4.17.21) mime-types: 2.1.35 p-retry: 4.6.2 - webpack-dev-middleware: 7.4.2(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - webpack-dev-server: 5.0.4(bufferutil@4.0.7)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + webpack-dev-middleware: 7.4.2(webpack@5.98.0) + webpack-dev-server: 5.0.4(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0) ws: 8.18.0(bufferutil@4.0.7) transitivePeerDependencies: - '@types/express' @@ -28753,7 +28505,7 @@ snapshots: transitivePeerDependencies: - webpack-sources - '@storybook/builder-webpack5@8.4.6(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8))(typescript@5.7.3)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))': + '@storybook/builder-webpack5@8.4.6(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8))(typescript@5.7.3)(webpack-cli@5.1.4)': dependencies: '@storybook/core-webpack': 8.4.6(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8)) '@types/node': 22.5.5 @@ -28762,23 +28514,23 @@ snapshots: case-sensitive-paths-webpack-plugin: 2.4.0 cjs-module-lexer: 1.4.1 constants-browserify: 1.0.0 - css-loader: 6.11.0(@rspack/core@1.2.6(@swc/helpers@0.5.11))(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + css-loader: 6.11.0(@rspack/core@1.2.6(@swc/helpers@0.5.11))(webpack@5.98.0) es-module-lexer: 1.6.0 - fork-ts-checker-webpack-plugin: 8.0.0(typescript@5.7.3)(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - html-webpack-plugin: 5.5.0(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + fork-ts-checker-webpack-plugin: 8.0.0(typescript@5.7.3)(webpack@5.98.0) + html-webpack-plugin: 5.5.0(webpack@5.98.0) magic-string: 0.30.17 path-browserify: 1.0.1 process: 0.11.10 semver: 7.7.1 storybook: 8.4.6(bufferutil@4.0.7)(prettier@2.8.8) - style-loader: 3.3.4(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - terser-webpack-plugin: 5.3.11(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + style-loader: 3.3.4(webpack@5.98.0) + terser-webpack-plugin: 5.3.11(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack@5.98.0) ts-dedent: 2.2.0 url: 0.11.4 util: 0.12.5 util-deprecate: 1.0.2 - webpack: 5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) - webpack-dev-middleware: 6.1.3(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) + webpack-dev-middleware: 6.1.3(webpack@5.98.0) webpack-hot-middleware: 2.26.1 webpack-virtual-modules: 0.6.2 optionalDependencies: @@ -28878,11 +28630,11 @@ snapshots: dependencies: storybook: 8.4.6(bufferutil@4.0.7)(prettier@2.8.8) - '@storybook/preset-react-webpack@8.4.6(@storybook/test@8.5.1(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8)))(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8))(typescript@5.7.3)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))': + '@storybook/preset-react-webpack@8.4.6(@storybook/test@8.5.1(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8)))(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8))(typescript@5.7.3)(webpack-cli@5.1.4)': dependencies: '@storybook/core-webpack': 8.4.6(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8)) '@storybook/react': 8.4.6(@storybook/test@8.5.1(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8))(typescript@5.7.3) - '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@5.7.3)(webpack@5.98.0) '@types/node': 22.5.5 '@types/semver': 7.5.8 find-up: 5.0.0 @@ -28894,7 +28646,7 @@ snapshots: semver: 7.7.1 storybook: 8.4.6(bufferutil@4.0.7)(prettier@2.8.8) tsconfig-paths: 4.2.0 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) optionalDependencies: typescript: 5.7.3 transitivePeerDependencies: @@ -28909,7 +28661,7 @@ snapshots: dependencies: storybook: 8.4.6(bufferutil@4.0.7)(prettier@2.8.8) - '@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)))': + '@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0(typescript@5.7.3)(webpack@5.98.0)': dependencies: debug: 4.4.0(supports-color@8.1.1) endent: 2.1.0 @@ -28919,7 +28671,7 @@ snapshots: react-docgen-typescript: 2.2.2(typescript@5.7.3) tslib: 2.8.1 typescript: 5.7.3 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) transitivePeerDependencies: - supports-color @@ -28951,10 +28703,10 @@ snapshots: - typescript - webpack-sources - '@storybook/react-webpack5@8.4.6(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@storybook/test@8.5.1(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8)))(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8))(typescript@5.7.3)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))': + '@storybook/react-webpack5@8.4.6(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@storybook/test@8.5.1(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8)))(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8))(typescript@5.7.3)(webpack-cli@5.1.4)': dependencies: - '@storybook/builder-webpack5': 8.4.6(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8))(typescript@5.7.3)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) - '@storybook/preset-react-webpack': 8.4.6(@storybook/test@8.5.1(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8)))(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8))(typescript@5.7.3)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + '@storybook/builder-webpack5': 8.4.6(@rspack/core@1.2.6(@swc/helpers@0.5.11))(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8))(typescript@5.7.3)(webpack-cli@5.1.4) + '@storybook/preset-react-webpack': 8.4.6(@storybook/test@8.5.1(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8)))(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8))(typescript@5.7.3)(webpack-cli@5.1.4) '@storybook/react': 8.4.6(@storybook/test@8.5.1(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.6(bufferutil@4.0.7)(prettier@2.8.8))(typescript@5.7.3) '@types/node': 22.5.5 react: 18.3.1 @@ -29786,7 +29538,7 @@ snapshots: '@types/node-fetch@2.6.11': dependencies: '@types/node': 20.16.10 - form-data: 4.0.0 + form-data: 4.0.2 '@types/node-forge@1.3.11': dependencies: @@ -30939,22 +30691,22 @@ snapshots: '@webcontainer/api@1.5.1': {} - '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)))': + '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.98.0)': dependencies: - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0) - '@webpack-cli/info@2.0.2(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)))': + '@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.98.0)': dependencies: - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0) - '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack-dev-server@5.2.1(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)))': + '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack-dev-server@5.2.1)(webpack@5.98.0)': dependencies: - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0) optionalDependencies: - webpack-dev-server: 5.2.1(bufferutil@4.0.7)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + webpack-dev-server: 5.2.1(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0) '@xhmikosr/archive-type@7.0.0': dependencies: @@ -31100,10 +30852,6 @@ snapshots: acorn: 8.14.0 acorn-walk: 8.3.4 - acorn-import-assertions@1.9.0(acorn@8.12.1): - dependencies: - acorn: 8.12.1 - acorn-import-attributes@1.9.5(acorn@8.14.0): dependencies: acorn: 8.14.0 @@ -31437,7 +31185,7 @@ snapshots: define-properties: 1.2.1 es-abstract: 1.23.3 es-errors: 1.3.0 - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 is-array-buffer: 3.0.4 is-shared-array-buffer: 1.0.3 @@ -31636,7 +31384,7 @@ snapshots: axios@1.8.3: dependencies: follow-redirects: 1.15.9(debug@4.3.7) - form-data: 4.0.0 + form-data: 4.0.2 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug @@ -31671,19 +31419,19 @@ snapshots: transitivePeerDependencies: - supports-color - babel-loader@9.2.1(@babel/core@7.25.2)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + babel-loader@9.2.1(@babel/core@7.25.2)(webpack@5.98.0): dependencies: '@babel/core': 7.25.2 find-cache-dir: 4.0.0 schema-utils: 4.2.0 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) - babel-loader@9.2.1(@babel/core@7.26.9)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + babel-loader@9.2.1(@babel/core@7.26.9)(webpack@5.98.0): dependencies: '@babel/core': 7.26.9 find-cache-dir: 4.0.0 schema-utils: 4.2.0 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) babel-plugin-const-enum@1.2.0(@babel/core@7.26.9): dependencies: @@ -32185,14 +31933,14 @@ snapshots: es-define-property: 1.0.0 es-errors: 1.3.0 function-bind: 1.1.2 - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 set-function-length: 1.2.2 call-bind@1.0.8: dependencies: call-bind-apply-helpers: 1.0.2 es-define-property: 1.0.0 - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 set-function-length: 1.2.2 call-bound@1.0.4: @@ -32776,7 +32524,7 @@ snapshots: dependencies: toggle-selection: 1.0.6 - copy-webpack-plugin@10.2.4(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + copy-webpack-plugin@10.2.4(webpack@5.98.0): dependencies: fast-glob: 3.3.3 glob-parent: 6.0.2 @@ -32784,9 +32532,9 @@ snapshots: normalize-path: 3.0.0 schema-utils: 4.2.0 serialize-javascript: 6.0.2 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) - copy-webpack-plugin@12.0.2(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + copy-webpack-plugin@12.0.2(webpack@5.98.0): dependencies: fast-glob: 3.3.3 glob-parent: 6.0.2 @@ -32794,7 +32542,7 @@ snapshots: normalize-path: 3.0.0 schema-utils: 4.3.0 serialize-javascript: 6.0.2 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) core-js-compat@3.38.1: dependencies: @@ -32935,7 +32683,7 @@ snapshots: postcss: 8.4.38 postcss-selector-parser: 6.1.2 - css-loader@6.11.0(@rspack/core@1.2.6(@swc/helpers@0.5.11))(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + css-loader@6.11.0(@rspack/core@1.2.6(@swc/helpers@0.5.11))(webpack@5.98.0): dependencies: icss-utils: 5.1.0(postcss@8.4.38) postcss: 8.4.38 @@ -32947,9 +32695,9 @@ snapshots: semver: 7.7.1 optionalDependencies: '@rspack/core': 1.2.6(@swc/helpers@0.5.11) - webpack: 5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) - css-loader@6.11.0(@rspack/core@1.2.6(@swc/helpers@0.5.11))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + css-loader@7.1.2(@rspack/core@1.2.6(@swc/helpers@0.5.11))(webpack@5.98.0): dependencies: icss-utils: 5.1.0(postcss@8.4.38) postcss: 8.4.38 @@ -32961,23 +32709,9 @@ snapshots: semver: 7.7.1 optionalDependencies: '@rspack/core': 1.2.6(@swc/helpers@0.5.11) - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) - css-loader@7.1.2(@rspack/core@1.2.6(@swc/helpers@0.5.11))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): - dependencies: - icss-utils: 5.1.0(postcss@8.4.38) - postcss: 8.4.38 - postcss-modules-extract-imports: 3.1.0(postcss@8.4.38) - postcss-modules-local-by-default: 4.0.5(postcss@8.4.38) - postcss-modules-scope: 3.2.0(postcss@8.4.38) - postcss-modules-values: 4.0.0(postcss@8.4.38) - postcss-value-parser: 4.2.0 - semver: 7.7.1 - optionalDependencies: - '@rspack/core': 1.2.6(@swc/helpers@0.5.11) - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) - - css-minimizer-webpack-plugin@5.0.1(esbuild@0.25.0)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + css-minimizer-webpack-plugin@5.0.1(esbuild@0.25.0)(webpack@5.98.0): dependencies: '@jridgewell/trace-mapping': 0.3.25 cssnano: 6.1.2(postcss@8.4.38) @@ -32985,7 +32719,7 @@ snapshots: postcss: 8.4.38 schema-utils: 4.2.0 serialize-javascript: 6.0.2 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) optionalDependencies: esbuild: 0.25.0 @@ -33714,10 +33448,10 @@ snapshots: es-define-property: 1.0.0 es-errors: 1.3.0 es-object-atoms: 1.0.0 - es-set-tostringtag: 2.0.3 + es-set-tostringtag: 2.1.0 es-to-primitive: 1.2.1 function.prototype.name: 1.1.6 - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 get-symbol-description: 1.0.2 globalthis: 1.0.4 gopd: 1.0.1 @@ -33763,7 +33497,7 @@ snapshots: data-view-byte-offset: 1.0.1 es-define-property: 1.0.1 es-errors: 1.3.0 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 es-set-tostringtag: 2.1.0 es-to-primitive: 1.3.0 function.prototype.name: 1.1.8 @@ -33807,7 +33541,7 @@ snapshots: es-define-property@1.0.0: dependencies: - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 es-define-property@1.0.1: {} @@ -33819,7 +33553,7 @@ snapshots: define-properties: 1.2.1 es-abstract: 1.23.3 es-errors: 1.3.0 - es-set-tostringtag: 2.0.3 + es-set-tostringtag: 2.1.0 function-bind: 1.1.2 get-intrinsic: 1.2.4 globalthis: 1.0.4 @@ -33836,7 +33570,7 @@ snapshots: define-properties: 1.2.1 es-abstract: 1.23.3 es-errors: 1.3.0 - es-set-tostringtag: 2.0.3 + es-set-tostringtag: 2.1.0 function-bind: 1.1.2 get-intrinsic: 1.2.4 globalthis: 1.0.4 @@ -33854,7 +33588,7 @@ snapshots: define-properties: 1.2.1 es-abstract: 1.23.9 es-errors: 1.3.0 - es-set-tostringtag: 2.0.3 + es-set-tostringtag: 2.1.0 function-bind: 1.1.2 get-intrinsic: 1.3.0 globalthis: 1.0.4 @@ -33878,12 +33612,6 @@ snapshots: dependencies: es-errors: 1.3.0 - es-set-tostringtag@2.0.3: - dependencies: - get-intrinsic: 1.2.4 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - es-set-tostringtag@2.1.0: dependencies: es-errors: 1.3.0 @@ -34230,7 +33958,7 @@ snapshots: debug: 4.4.0(supports-color@8.1.1) enhanced-resolve: 5.17.1 eslint: 8.57.0 - eslint-module-utils: 2.11.0(@typescript-eslint/parser@8.20.0(eslint@8.57.0)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.20.0(eslint@8.57.0)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.20.0(eslint@8.57.0)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) fast-glob: 3.3.3 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 @@ -34243,18 +33971,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.11.0(@typescript-eslint/parser@8.20.0(eslint@8.57.0)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.20.0(eslint@8.57.0)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.0))(eslint@8.57.0): - dependencies: - debug: 3.2.7(supports-color@8.1.1) - optionalDependencies: - '@typescript-eslint/parser': 8.20.0(eslint@8.57.0)(typescript@5.7.3) - eslint: 8.57.0 - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.20.0(eslint@8.57.0)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.0) - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.20.0(eslint@8.57.0)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.20.0(eslint@8.57.0)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.0))(eslint@8.57.0): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.20.0(eslint@8.57.0)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0): dependencies: debug: 3.2.7(supports-color@8.1.1) optionalDependencies: @@ -34281,7 +33998,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.20.0(eslint@8.57.0)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.20.0(eslint@8.57.0)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.20.0(eslint@8.57.0)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -34847,11 +34564,11 @@ snapshots: dependencies: flat-cache: 3.2.0 - file-loader@6.2.0(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + file-loader@6.2.0(webpack@5.98.0): dependencies: loader-utils: 2.0.3 schema-utils: 3.3.0 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) file-type@16.5.4: dependencies: @@ -35000,7 +34717,7 @@ snapshots: forever-agent@0.6.1: {} - fork-ts-checker-webpack-plugin@7.2.13(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + fork-ts-checker-webpack-plugin@7.2.13(typescript@5.7.3)(webpack@5.98.0): dependencies: '@babel/code-frame': 7.24.7 chalk: 4.1.2 @@ -35015,9 +34732,9 @@ snapshots: semver: 7.6.3 tapable: 2.2.1 typescript: 5.7.3 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) - fork-ts-checker-webpack-plugin@8.0.0(typescript@5.7.3)(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + fork-ts-checker-webpack-plugin@8.0.0(typescript@5.7.3)(webpack@5.98.0): dependencies: '@babel/code-frame': 7.26.2 chalk: 4.1.2 @@ -35032,9 +34749,9 @@ snapshots: semver: 7.7.1 tapable: 2.2.1 typescript: 5.7.3 - webpack: 5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) - fork-ts-checker-webpack-plugin@9.0.2(typescript@5.3.3)(webpack@5.94.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + fork-ts-checker-webpack-plugin@9.0.2(typescript@5.3.3)(webpack@5.94.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4)): dependencies: '@babel/code-frame': 7.26.2 chalk: 4.1.2 @@ -35049,16 +34766,17 @@ snapshots: semver: 7.7.1 tapable: 2.2.1 typescript: 5.3.3 - webpack: 5.94.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.94.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) form-data-encoder@1.7.2: {} form-data-encoder@2.1.4: {} - form-data@4.0.0: + form-data@4.0.2: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 mime-types: 2.1.35 format@0.2.2: {} @@ -35236,7 +34954,7 @@ snapshots: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 get-symbol-description@1.1.0: dependencies: @@ -35442,7 +35160,7 @@ snapshots: gopd@1.0.1: dependencies: - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 gopd@1.2.0: {} @@ -35559,7 +35277,7 @@ snapshots: has-tostringtag@1.0.2: dependencies: - has-symbols: 1.0.3 + has-symbols: 1.1.0 has-unicode@2.0.1: {} @@ -35826,23 +35544,14 @@ snapshots: html-void-elements@3.0.0: {} - html-webpack-plugin@5.5.0(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + html-webpack-plugin@5.5.0(webpack@5.98.0): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 lodash: 4.17.21 pretty-error: 4.0.0 tapable: 2.2.1 - webpack: 5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) - - html-webpack-plugin@5.5.0(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): - dependencies: - '@types/html-minifier-terser': 6.1.0 - html-minifier-terser: 6.1.0 - lodash: 4.17.21 - pretty-error: 4.0.0 - tapable: 2.2.1 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) htmlparser2@6.1.0: dependencies: @@ -36230,7 +35939,7 @@ snapshots: is-array-buffer@3.0.4: dependencies: call-bind: 1.0.7 - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 is-array-buffer@3.0.5: dependencies: @@ -36478,7 +36187,7 @@ snapshots: is-symbol@1.0.4: dependencies: - has-symbols: 1.0.3 + has-symbols: 1.1.0 is-symbol@1.1.1: dependencies: @@ -36613,7 +36322,7 @@ snapshots: iterator.prototype@1.1.2: dependencies: define-properties: 1.2.1 - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 has-symbols: 1.0.3 reflect.getprototypeof: 1.0.6 set-function-name: 2.0.2 @@ -36621,7 +36330,7 @@ snapshots: iterator.prototype@1.1.3: dependencies: define-properties: 1.2.1 - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 has-symbols: 1.0.3 reflect.getprototypeof: 1.0.6 set-function-name: 2.0.2 @@ -36629,7 +36338,7 @@ snapshots: iterator.prototype@1.1.5: dependencies: define-data-property: 1.1.4 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 get-intrinsic: 1.3.0 get-proto: 1.0.1 has-symbols: 1.1.0 @@ -37025,7 +36734,7 @@ snapshots: decimal.js: 10.4.3 domexception: 4.0.0 escodegen: 2.1.0 - form-data: 4.0.0 + form-data: 4.0.2 html-encoding-sniffer: 3.0.0 http-proxy-agent: 5.0.0 https-proxy-agent: 5.0.1 @@ -37262,18 +36971,18 @@ snapshots: dependencies: readable-stream: 2.3.8 - less-loader@11.1.0(less@4.1.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + less-loader@11.1.0(less@4.1.3)(webpack@5.98.0): dependencies: klona: 2.0.6 less: 4.1.3 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) - less-loader@12.2.0(@rspack/core@1.2.6(@swc/helpers@0.5.11))(less@4.2.2)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + less-loader@12.2.0(@rspack/core@1.2.6(@swc/helpers@0.5.11))(less@4.2.2)(webpack@5.98.0): dependencies: less: 4.2.2 optionalDependencies: '@rspack/core': 1.2.6(@swc/helpers@0.5.11) - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) less@4.1.3: dependencies: @@ -37325,11 +37034,11 @@ snapshots: transitivePeerDependencies: - supports-color - license-webpack-plugin@4.0.2(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + license-webpack-plugin@4.0.2(webpack@5.98.0): dependencies: webpack-sources: 3.2.3 optionalDependencies: - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) lie@3.3.0: dependencies: @@ -38787,16 +38496,16 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.4.7(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + mini-css-extract-plugin@2.4.7(webpack@5.98.0): dependencies: schema-utils: 4.2.0 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) - mini-css-extract-plugin@2.9.2(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + mini-css-extract-plugin@2.9.2(webpack@5.98.0): dependencies: schema-utils: 4.3.0 tapable: 2.2.1 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) mini-svg-data-uri@1.4.4: {} @@ -40415,15 +40124,15 @@ snapshots: postcss: 8.4.38 ts-node: 10.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@types/node@20.16.10)(typescript@5.7.3) - postcss-loader@6.2.1(postcss@8.4.38)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + postcss-loader@6.2.1(postcss@8.4.38)(webpack@5.98.0): dependencies: cosmiconfig: 7.1.0 klona: 2.0.6 postcss: 8.4.38 semver: 7.7.1 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) - postcss-loader@8.1.1(@rspack/core@1.2.6(@swc/helpers@0.5.11))(postcss@8.4.38)(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + postcss-loader@8.1.1(@rspack/core@1.2.6(@swc/helpers@0.5.11))(postcss@8.4.38)(typescript@5.7.3)(webpack@5.98.0): dependencies: cosmiconfig: 9.0.0(typescript@5.7.3) jiti: 1.21.6 @@ -40431,11 +40140,11 @@ snapshots: semver: 7.7.1 optionalDependencies: '@rspack/core': 1.2.6(@swc/helpers@0.5.11) - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) transitivePeerDependencies: - typescript - postcss-loader@8.1.1(@rspack/core@1.2.6(@swc/helpers@0.5.11))(postcss@8.5.2)(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + postcss-loader@8.1.1(@rspack/core@1.2.6(@swc/helpers@0.5.11))(postcss@8.5.2)(typescript@5.7.3)(webpack@5.98.0): dependencies: cosmiconfig: 9.0.0(typescript@5.7.3) jiti: 1.21.6 @@ -40443,7 +40152,7 @@ snapshots: semver: 7.7.1 optionalDependencies: '@rspack/core': 1.2.6(@swc/helpers@0.5.11) - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) transitivePeerDependencies: - typescript @@ -41562,7 +41271,7 @@ snapshots: define-properties: 1.2.1 es-abstract: 1.23.3 es-errors: 1.3.0 - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 globalthis: 1.0.4 which-builtin-type: 1.1.4 @@ -42074,7 +41783,7 @@ snapshots: safe-array-concat@1.1.2: dependencies: call-bind: 1.0.7 - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 has-symbols: 1.0.3 isarray: 2.0.5 @@ -42209,23 +41918,23 @@ snapshots: dependencies: suf-log: 2.5.3 - sass-loader@16.0.5(@rspack/core@1.2.6(@swc/helpers@0.5.11))(sass-embedded@1.85.1)(sass@1.55.0)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + sass-loader@16.0.5(@rspack/core@1.2.6(@swc/helpers@0.5.11))(sass-embedded@1.85.1)(sass@1.55.0)(webpack@5.98.0): dependencies: neo-async: 2.6.2 optionalDependencies: '@rspack/core': 1.2.6(@swc/helpers@0.5.11) sass: 1.55.0 sass-embedded: 1.85.1 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) - sass-loader@16.0.5(@rspack/core@1.2.6(@swc/helpers@0.5.11))(sass-embedded@1.85.1)(sass@1.85.0)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + sass-loader@16.0.5(@rspack/core@1.2.6(@swc/helpers@0.5.11))(sass-embedded@1.85.1)(sass@1.85.0)(webpack@5.98.0): dependencies: neo-async: 2.6.2 optionalDependencies: '@rspack/core': 1.2.6(@swc/helpers@0.5.11) sass: 1.85.0 sass-embedded: 1.85.1 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) sass@1.55.0: dependencies: @@ -42406,8 +42115,8 @@ snapshots: define-data-property: 1.1.4 es-errors: 1.3.0 function-bind: 1.1.2 - get-intrinsic: 1.2.4 - gopd: 1.0.1 + get-intrinsic: 1.3.0 + gopd: 1.2.0 has-property-descriptors: 1.0.2 set-function-name@2.0.2: @@ -42520,7 +42229,7 @@ snapshots: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 object-inspect: 1.13.2 side-channel@1.1.0: @@ -42658,11 +42367,11 @@ snapshots: source-map-js@1.2.1: {} - source-map-loader@5.0.0(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + source-map-loader@5.0.0(webpack@5.98.0): dependencies: iconv-lite: 0.6.3 source-map-js: 1.2.1 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) source-map-support@0.5.13: dependencies: @@ -42947,7 +42656,7 @@ snapshots: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 string.prototype.trimend@1.0.8: dependencies: @@ -42966,7 +42675,7 @@ snapshots: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 string_decoder@1.1.1: dependencies: @@ -43032,13 +42741,9 @@ snapshots: style-inject@0.3.0: {} - style-loader@3.3.4(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + style-loader@3.3.4(webpack@5.98.0): dependencies: - webpack: 5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) - - style-loader@3.3.4(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): - dependencies: - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) style-mod@4.1.2: {} @@ -43080,12 +42785,12 @@ snapshots: postcss: 8.5.3 postcss-selector-parser: 6.1.2 - stylus-loader@7.1.3(stylus@0.64.0)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + stylus-loader@7.1.3(stylus@0.64.0)(webpack@5.98.0): dependencies: fast-glob: 3.3.3 normalize-path: 3.0.0 stylus: 0.64.0 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) stylus@0.64.0: dependencies: @@ -43291,50 +42996,38 @@ snapshots: temp-dir: 2.0.0 uuid: 3.4.0 - terser-webpack-plugin@5.3.10(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack@5.94.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + terser-webpack-plugin@5.3.10(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack@5.94.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4)): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.33.0 - webpack: 5.94.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.94.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) optionalDependencies: '@swc/core': 1.5.7(@swc/helpers@0.5.11) esbuild: 0.25.0 - terser-webpack-plugin@5.3.10(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + terser-webpack-plugin@5.3.10(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack@5.98.0): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.33.0 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) optionalDependencies: '@swc/core': 1.5.7(@swc/helpers@0.5.11) esbuild: 0.25.0 - terser-webpack-plugin@5.3.11(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + terser-webpack-plugin@5.3.11(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack@5.98.0): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 4.3.0 serialize-javascript: 6.0.2 terser: 5.39.0 - webpack: 5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) - optionalDependencies: - '@swc/core': 1.5.7(@swc/helpers@0.5.11) - esbuild: 0.25.0 - - terser-webpack-plugin@5.3.11(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): - dependencies: - '@jridgewell/trace-mapping': 0.3.25 - jest-worker: 27.5.1 - schema-utils: 4.3.0 - serialize-javascript: 6.0.2 - terser: 5.39.0 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) optionalDependencies: '@swc/core': 1.5.7(@swc/helpers@0.5.11) esbuild: 0.25.0 @@ -43573,7 +43266,7 @@ snapshots: babel-jest: 29.7.0(@babel/core@7.25.2) esbuild: 0.25.0 - ts-loader@9.5.1(typescript@5.7.3)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + ts-loader@9.5.1(typescript@5.7.3)(webpack@5.98.0): dependencies: chalk: 4.1.2 enhanced-resolve: 5.17.1 @@ -43581,7 +43274,7 @@ snapshots: semver: 7.6.3 source-map: 0.7.4 typescript: 5.7.3 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) ts-node@10.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@types/node@20.16.10)(typescript@5.7.3): dependencies: @@ -43720,7 +43413,7 @@ snapshots: dependencies: call-bind: 1.0.7 for-each: 0.3.3 - gopd: 1.0.1 + gopd: 1.2.0 has-proto: 1.0.3 is-typed-array: 1.1.13 @@ -43737,7 +43430,7 @@ snapshots: available-typed-arrays: 1.0.7 call-bind: 1.0.7 for-each: 0.3.3 - gopd: 1.0.1 + gopd: 1.2.0 has-proto: 1.0.3 is-typed-array: 1.1.13 @@ -43755,7 +43448,7 @@ snapshots: dependencies: call-bind: 1.0.7 for-each: 0.3.3 - gopd: 1.0.1 + gopd: 1.2.0 has-proto: 1.0.3 is-typed-array: 1.1.13 possible-typed-array-names: 1.0.0 @@ -43825,7 +43518,7 @@ snapshots: dependencies: call-bind: 1.0.7 has-bigints: 1.0.2 - has-symbols: 1.0.3 + has-symbols: 1.1.0 which-boxed-primitive: 1.0.2 unbox-primitive@1.1.0: @@ -44842,9 +44535,9 @@ snapshots: webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0): dependencies: '@discoveryjs/json-ext': 0.5.7 - '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack-dev-server@5.2.1(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4)(webpack@5.98.0) + '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4)(webpack@5.98.0) + '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4)(webpack-dev-server@5.2.1)(webpack@5.98.0) colorette: 2.0.20 commander: 10.0.1 cross-spawn: 7.0.3 @@ -44853,12 +44546,12 @@ snapshots: import-local: 3.2.0 interpret: 3.1.1 rechoir: 0.8.0 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) webpack-merge: 5.10.0 optionalDependencies: - webpack-dev-server: 5.2.1(bufferutil@4.0.7)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + webpack-dev-server: 5.2.1(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0) - webpack-dev-middleware@6.1.3(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + webpack-dev-middleware@6.1.3(webpack@5.98.0): dependencies: colorette: 2.0.20 memfs: 3.6.0 @@ -44866,9 +44559,9 @@ snapshots: range-parser: 1.2.1 schema-utils: 4.3.0 optionalDependencies: - webpack: 5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) - webpack-dev-middleware@7.4.2(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + webpack-dev-middleware@7.4.2(webpack@5.98.0): dependencies: colorette: 2.0.20 memfs: 4.12.0 @@ -44877,9 +44570,9 @@ snapshots: range-parser: 1.2.1 schema-utils: 4.3.0 optionalDependencies: - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) - webpack-dev-server@5.0.4(bufferutil@4.0.7)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + webpack-dev-server@5.0.4(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -44909,10 +44602,10 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.2(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + webpack-dev-middleware: 7.4.2(webpack@5.98.0) ws: 8.18.0(bufferutil@4.0.7) optionalDependencies: - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0) transitivePeerDependencies: - bufferutil @@ -44920,7 +44613,7 @@ snapshots: - supports-color - utf-8-validate - webpack-dev-server@5.2.0(bufferutil@4.0.7)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + webpack-dev-server@5.2.0(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -44947,10 +44640,10 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.2(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + webpack-dev-middleware: 7.4.2(webpack@5.98.0) ws: 8.18.0(bufferutil@4.0.7) optionalDependencies: - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0) transitivePeerDependencies: - bufferutil @@ -44958,7 +44651,7 @@ snapshots: - supports-color - utf-8-validate - webpack-dev-server@5.2.1(bufferutil@4.0.7)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + webpack-dev-server@5.2.1(bufferutil@4.0.7)(webpack-cli@5.1.4)(webpack@5.98.0): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -44986,10 +44679,10 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.2(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + webpack-dev-middleware: 7.4.2(webpack@5.98.0) ws: 8.18.0(bufferutil@4.0.7) optionalDependencies: - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0) transitivePeerDependencies: - bufferutil @@ -45019,49 +44712,16 @@ snapshots: webpack-sources@3.2.3: {} - webpack-subresource-integrity@5.1.0(html-webpack-plugin@5.5.0(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))))(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))): + webpack-subresource-integrity@5.1.0(html-webpack-plugin@5.5.0(webpack@5.98.0))(webpack@5.98.0): dependencies: typed-assert: 1.0.9 - webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)) + webpack: 5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4) optionalDependencies: - html-webpack-plugin: 5.5.0(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + html-webpack-plugin: 5.5.0(webpack@5.98.0) webpack-virtual-modules@0.6.2: {} - webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)): - dependencies: - '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.6 - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/wasm-edit': 1.12.1 - '@webassemblyjs/wasm-parser': 1.12.1 - acorn: 8.12.1 - acorn-import-assertions: 1.9.0(acorn@8.12.1) - browserslist: 4.24.4 - chrome-trace-event: 1.0.4 - enhanced-resolve: 5.17.1 - es-module-lexer: 1.5.4 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 3.3.0 - tapable: 2.2.1 - terser-webpack-plugin: 5.3.11(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) - watchpack: 2.4.2 - webpack-sources: 3.2.3 - optionalDependencies: - webpack-cli: 5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0) - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js - - webpack@5.94.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)): + webpack@5.94.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4): dependencies: '@types/estree': 1.0.6 '@webassemblyjs/ast': 1.12.1 @@ -45083,7 +44743,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack@5.94.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + terser-webpack-plugin: 5.3.10(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack@5.94.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4)) watchpack: 2.4.2 webpack-sources: 3.2.3 optionalDependencies: @@ -45093,7 +44753,7 @@ snapshots: - esbuild - uglify-js - webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0)): + webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.6 @@ -45115,7 +44775,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.11(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack@5.98.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack-cli@5.1.4(webpack-dev-server@5.2.1)(webpack@5.98.0))) + terser-webpack-plugin: 5.3.11(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.25.0)(webpack@5.98.0) watchpack: 2.4.2 webpack-sources: 3.2.3 optionalDependencies: diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000000..0c548fd01a --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,18 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * For more detailed information on multi-project builds, please refer to https://docs.gradle.org/8.5/userguide/building_swift_projects.html in the Gradle documentation. + */ + + +pluginManagement { + repositories { + mavenLocal() + mavenCentral() + gradlePluginPortal() + } +} + +rootProject.name = "nx" +includeBuild("./packages/gradle/project-graph")