chore(repo): remove v16 migrations (#28220)
<!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior <!-- This is the behavior we have today --> ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
This commit is contained in:
parent
3b278e6755
commit
a637f9eef9
@ -1,173 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generators": {
|
"generators": {
|
||||||
"install-required-packages": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "15.7.0-beta.1",
|
|
||||||
"description": "Install the required angular-devkit packages as we do not directly depend on them anymore",
|
|
||||||
"factory": "./src/migrations/update-15-7-0/install-required-packages"
|
|
||||||
},
|
|
||||||
"remove-show-circular-dependencies-option": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "14.2.0-beta.0",
|
|
||||||
"description": "Remove 'showCircularDependencies' option from browser and server executors.",
|
|
||||||
"factory": "./src/migrations/update-14-2-0/remove-show-circular-dependencies-option"
|
|
||||||
},
|
|
||||||
"update-angular-cli-version": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "14.2.0-beta.0",
|
|
||||||
"description": "Update the @angular/cli package version.",
|
|
||||||
"factory": "./src/migrations/update-14-2-0/update-angular-cli"
|
|
||||||
},
|
|
||||||
"update-libraries-secondary-entrypoints": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "14.2.0-beta.0",
|
|
||||||
"description": "Remove 'package.json' files from library projects secondary entrypoints.",
|
|
||||||
"factory": "./src/migrations/update-14-2-0/update-libraries-secondary-entrypoints"
|
|
||||||
},
|
|
||||||
"update-postinstall-script-ngcc-target": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "14.2.0-beta.0",
|
|
||||||
"description": "Update postinstall script running ngcc to use ES2020 target.",
|
|
||||||
"factory": "./src/migrations/update-14-2-0/update-ngcc-target"
|
|
||||||
},
|
|
||||||
"update-tsconfig-target": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "14.2.0-beta.0",
|
|
||||||
"description": "Update TypeScript compilation target to 'ES2020'.",
|
|
||||||
"factory": "./src/migrations/update-14-2-0/update-tsconfig-target"
|
|
||||||
},
|
|
||||||
"update-router-initial-navigation": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "14.2.0-beta.6",
|
|
||||||
"description": "Update `initialNavigation: 'enabled'` to `initialNavigation: 'enabledBlocking'`.",
|
|
||||||
"factory": "./src/migrations/update-14-2-0/update-router-initial-navigation"
|
|
||||||
},
|
|
||||||
"migrate-mfe-to-mf": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "14.5.0-beta.0",
|
|
||||||
"description": "Update any references of MFE to MF.",
|
|
||||||
"factory": "./src/migrations/update-14-5-0/migrate-mfe-to-mf"
|
|
||||||
},
|
|
||||||
"update-angular-cli-version-14-1-0": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "14.5.2-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"@angular/core": ">=14.1.0"
|
|
||||||
},
|
|
||||||
"description": "Update the @angular/cli package version to ~14.1.0.",
|
|
||||||
"factory": "./src/migrations/update-14-5-2/update-angular-cli"
|
|
||||||
},
|
|
||||||
"update-angular-cli-version-14-2-0": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "14.6.0-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"@angular/core": ">=14.2.0"
|
|
||||||
},
|
|
||||||
"description": "Update the @angular/cli package version to ~14.2.0.",
|
|
||||||
"factory": "./src/migrations/update-14-6-0/update-angular-cli"
|
|
||||||
},
|
|
||||||
"rename-webpack-server-executor": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "15.0.0-beta.0",
|
|
||||||
"description": "Rename @nrwl/angular:webpack-server executor to @nrwl/angular:webpack-dev-server",
|
|
||||||
"factory": "./src/migrations/update-14-8-0/rename-webpack-server"
|
|
||||||
},
|
|
||||||
"switch-to-jasmine-marbles": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "15.0.0-beta.0",
|
|
||||||
"description": "Update the usages of @nrwl/angular/testing to import jasmine-marbles symbols from jasmine-marbles itself.",
|
|
||||||
"factory": "./src/migrations/update-15-0-0/switch-to-jasmine-marbles"
|
|
||||||
},
|
|
||||||
"add-karma-inputs": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "15.0.0-beta.1",
|
|
||||||
"description": "Stop hashing karma spec files and config files for build targets and dependent tasks",
|
|
||||||
"factory": "./src/migrations/update-15-0-0/add-karma-inputs"
|
|
||||||
},
|
|
||||||
"update-angular-cli-version-15-0-0": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "15.2.0-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"@angular/core": ">=15.0.0"
|
|
||||||
},
|
|
||||||
"description": "Update the @angular/cli package version to ~15.0.0.",
|
|
||||||
"factory": "./src/migrations/update-15-2-0/update-angular-cli"
|
|
||||||
},
|
|
||||||
"remove-browserlist-config": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "15.2.0-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"@angular/core": ">=15.0.0"
|
|
||||||
},
|
|
||||||
"description": "Remove browserslist config as it's handled by build-angular",
|
|
||||||
"factory": "./src/migrations/update-15-2-0/remove-browserlist-config"
|
|
||||||
},
|
|
||||||
"update-typescript-target": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "15.2.0-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"@angular/core": ">=15.0.0"
|
|
||||||
},
|
|
||||||
"description": "Update typescript target to ES2022",
|
|
||||||
"factory": "./src/migrations/update-15-2-0/update-typescript-target"
|
|
||||||
},
|
|
||||||
"update-workspace-config": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "15.2.0-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"@angular/core": ">=15.0.0"
|
|
||||||
},
|
|
||||||
"description": "Remove bundleDependencies from server targets",
|
|
||||||
"factory": "./src/migrations/update-15-2-0/update-workspace-config"
|
|
||||||
},
|
|
||||||
"update-platform-server-exports": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "15.2.0-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"@angular/core": ">=15.0.0"
|
|
||||||
},
|
|
||||||
"description": "Remove exported `@angular/platform-server` `renderModule` method. The `renderModule` method is now exported by the Angular CLI.",
|
|
||||||
"factory": "./src/migrations/update-15-2-0/remove-platform-server-exports"
|
|
||||||
},
|
|
||||||
"update-karma-main-file": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "15.2.0-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"@angular/core": ">=15.0.0"
|
|
||||||
},
|
|
||||||
"description": "Remove no longer needed require calls in Karma builder main file.",
|
|
||||||
"factory": "./src/migrations/update-15-2-0/update-karma-main-file"
|
|
||||||
},
|
|
||||||
"update-angular-cli-version-15-1-0": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "15.5.0-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"@angular/core": ">=15.1.0"
|
|
||||||
},
|
|
||||||
"description": "Update the @angular/cli package version to ~15.1.0.",
|
|
||||||
"factory": "./src/migrations/update-15-5-0/update-angular-cli"
|
|
||||||
},
|
|
||||||
"update-angular-cli-version-15-2-0": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "15.8.0-beta.4",
|
|
||||||
"requires": {
|
|
||||||
"@angular/core": ">=15.2.0"
|
|
||||||
},
|
|
||||||
"description": "Update the @angular/cli package version to ~15.2.0.",
|
|
||||||
"factory": "./src/migrations/update-15-8-0/update-angular-cli"
|
|
||||||
},
|
|
||||||
"update-tsconfig-spec-jest": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "15.9.0-beta.3",
|
|
||||||
"description": "Update the tsconfig.spec.json to use target es2016 for jest-preset-angular v13",
|
|
||||||
"factory": "./src/migrations/update-15-9-0/update-testing-tsconfig"
|
|
||||||
},
|
|
||||||
"update-file-server-executor": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "15.9.0-beta.9",
|
|
||||||
"description": "Update the file-server executor to use @nrwl/web:file-server",
|
|
||||||
"factory": "./src/migrations/update-15-9-0/update-file-server-executor"
|
|
||||||
},
|
|
||||||
"remove-library-generator-simple-module-name-option": {
|
"remove-library-generator-simple-module-name-option": {
|
||||||
"cli": "nx",
|
"cli": "nx",
|
||||||
"version": "16.0.0-beta.1",
|
"version": "16.0.0-beta.1",
|
||||||
@ -437,819 +269,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packageJsonUpdates": {
|
"packageJsonUpdates": {
|
||||||
"14.1.8": {
|
|
||||||
"version": "14.1.8-beta.0",
|
|
||||||
"packages": {
|
|
||||||
"postcss-import": {
|
|
||||||
"version": "~14.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"postcss-preset-env": {
|
|
||||||
"version": "~7.5.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"postcss-url": {
|
|
||||||
"version": "~10.1.3",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"14.2.0": {
|
|
||||||
"version": "14.2.0-beta.6",
|
|
||||||
"packages": {
|
|
||||||
"@angular-devkit/architect": {
|
|
||||||
"version": "~0.1400.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/build-angular": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/build-webpack": {
|
|
||||||
"version": "~0.1400.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/core": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/schematics": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@schematics/angular": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/pwa": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/core": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": true
|
|
||||||
},
|
|
||||||
"@angular/common": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/forms": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/elements": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/compiler": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/compiler-cli": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/localize": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/platform-browser": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/platform-browser-dynamic": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/platform-server": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/router": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/upgrade": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/language-service": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/animations": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/service-worker": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/material": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/cdk": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"ng-packagr": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-eslint/eslint-plugin": {
|
|
||||||
"version": "~13.2.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-eslint/eslint-plugin-template": {
|
|
||||||
"version": "~13.2.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-eslint/template-parser": {
|
|
||||||
"version": "~13.2.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/store": {
|
|
||||||
"version": "~13.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/effects": {
|
|
||||||
"version": "~13.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/entity": {
|
|
||||||
"version": "~13.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/router-store": {
|
|
||||||
"version": "~13.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/schematics": {
|
|
||||||
"version": "~13.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/store-devtools": {
|
|
||||||
"version": "~13.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/component-store": {
|
|
||||||
"version": "~13.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"jest-preset-angular": {
|
|
||||||
"version": "~11.1.2",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"karma-jasmine": {
|
|
||||||
"version": "~5.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"jasmine-core": {
|
|
||||||
"version": "~4.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"jasmine-spec-reporter": {
|
|
||||||
"version": "~7.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@types/jasmine": {
|
|
||||||
"version": "~4.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"14.3.7": {
|
|
||||||
"version": "14.3.7-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"@angular/core": "^14.0.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"@ngrx/store": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/effects": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/entity": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/router-store": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/schematics": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/store-devtools": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/component-store": {
|
|
||||||
"version": "~14.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"14.4.0": {
|
|
||||||
"version": "14.4.0-beta.1",
|
|
||||||
"requires": {
|
|
||||||
"eslint": "^7.0.0 || ^8.0.0",
|
|
||||||
"@angular/core": ">=14.0.0 <15.0.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"@angular-eslint/eslint-plugin": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-eslint/eslint-plugin-template": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-eslint/template-parser": {
|
|
||||||
"version": "~14.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"14.5.2": {
|
|
||||||
"version": "14.5.2-beta.0",
|
|
||||||
"x-prompt": "Do you want to update the Angular version to v14.1?",
|
|
||||||
"requires": {
|
|
||||||
"@angular/core": ">=14.0.0 <14.1.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"@angular-devkit/architect": {
|
|
||||||
"version": "~0.1401.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/build-angular": {
|
|
||||||
"version": "~14.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/build-webpack": {
|
|
||||||
"version": "~0.1401.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/core": {
|
|
||||||
"version": "~14.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/schematics": {
|
|
||||||
"version": "~14.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/pwa": {
|
|
||||||
"version": "~14.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@schematics/angular": {
|
|
||||||
"version": "~14.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/core": {
|
|
||||||
"version": "~14.1.0",
|
|
||||||
"alwaysAddToPackageJson": true
|
|
||||||
},
|
|
||||||
"@angular/material": {
|
|
||||||
"version": "~14.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"ng-packagr": {
|
|
||||||
"version": "~14.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"karma": {
|
|
||||||
"version": "~6.4.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"karma-jasmine": {
|
|
||||||
"version": "~5.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"karma-jasmine-html-reporter": {
|
|
||||||
"version": "~2.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"jasmine-core": {
|
|
||||||
"version": "~4.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"14.5.3": {
|
|
||||||
"version": "14.5.3-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"@angular/core": "14.1.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"@angular-devkit/architect": {
|
|
||||||
"version": "~0.1401.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/build-angular": {
|
|
||||||
"version": "~14.1.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/build-webpack": {
|
|
||||||
"version": "~0.1401.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/core": {
|
|
||||||
"version": "~14.1.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/schematics": {
|
|
||||||
"version": "~14.1.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/pwa": {
|
|
||||||
"version": "~14.1.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@schematics/angular": {
|
|
||||||
"version": "~14.1.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/core": {
|
|
||||||
"version": "~14.1.1",
|
|
||||||
"alwaysAddToPackageJson": true
|
|
||||||
},
|
|
||||||
"@angular/material": {
|
|
||||||
"version": "~14.1.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/cdk": {
|
|
||||||
"version": "~14.1.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"14.5.5": {
|
|
||||||
"version": "14.5.5-beta.0",
|
|
||||||
"packages": {
|
|
||||||
"ts-node": {
|
|
||||||
"version": "10.9.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"14.6.0-angular": {
|
|
||||||
"version": "14.6.0-beta.0",
|
|
||||||
"x-prompt": "Do you want to update the Angular version to v14.2?",
|
|
||||||
"requires": {
|
|
||||||
"@angular/core": ">=14.1.0 <14.2.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"@angular-devkit/architect": {
|
|
||||||
"version": "~0.1402.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/build-angular": {
|
|
||||||
"version": "~14.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/build-webpack": {
|
|
||||||
"version": "~0.1402.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/core": {
|
|
||||||
"version": "~14.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/schematics": {
|
|
||||||
"version": "~14.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/pwa": {
|
|
||||||
"version": "~14.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@schematics/angular": {
|
|
||||||
"version": "~14.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/core": {
|
|
||||||
"version": "~14.2.0",
|
|
||||||
"alwaysAddToPackageJson": true
|
|
||||||
},
|
|
||||||
"@angular/material": {
|
|
||||||
"version": "~14.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/cdk": {
|
|
||||||
"version": "~14.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"ng-packagr": {
|
|
||||||
"version": "~14.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"14.6.0-jest-preset-angular": {
|
|
||||||
"version": "14.6.0-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"@angular-devkit/build-angular": ">=0.1102.19 <15.0.0",
|
|
||||||
"@angular/compiler-cli": ">=11.2.14 <15.0.0",
|
|
||||||
"@angular/core": ">=11.2.14 <15.0.0",
|
|
||||||
"@angular/platform-browser-dynamic": ">=11.2.14 <15.0.0",
|
|
||||||
"jest": "^28.0.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"jest-preset-angular": {
|
|
||||||
"version": "12.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"14.6.0-rxjs": {
|
|
||||||
"version": "14.6.0-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"rxjs": ">=7.0.0 <7.5.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"rxjs": {
|
|
||||||
"version": "~7.5.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"14.8.0-angular-eslint": {
|
|
||||||
"version": "14.8.0-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"eslint": "^7.0.0 || ^8.0.0",
|
|
||||||
"@angular/core": ">=14.0.0 <15.0.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"@angular-eslint/eslint-plugin": {
|
|
||||||
"version": "~14.0.4",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-eslint/eslint-plugin-template": {
|
|
||||||
"version": "~14.0.4",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-eslint/template-parser": {
|
|
||||||
"version": "~14.0.4",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"14.8.0-jest-preset-angular": {
|
|
||||||
"version": "14.8.0-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"@angular-devkit/build-angular": ">=0.1102.19 <15.0.0",
|
|
||||||
"@angular/compiler-cli": ">=11.2.14 <15.0.0",
|
|
||||||
"@angular/core": ">=11.2.14 <15.0.0",
|
|
||||||
"@angular/platform-browser-dynamic": ">=11.2.14 <15.0.0",
|
|
||||||
"jest": "^28.0.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"jest-preset-angular": {
|
|
||||||
"version": "12.2.2",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"15.2.0": {
|
|
||||||
"version": "15.2.0-beta.0",
|
|
||||||
"x-prompt": "Do you want to update the Angular version to v15?",
|
|
||||||
"requires": {
|
|
||||||
"@angular/core": "^14.2.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"@angular-devkit/architect": {
|
|
||||||
"version": "~0.1500.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/build-angular": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/build-webpack": {
|
|
||||||
"version": "~0.1500.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/core": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/schematics": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/pwa": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@schematics/angular": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/core": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": true
|
|
||||||
},
|
|
||||||
"@angular/material": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/cdk": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@nguniversal/common": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@nguniversal/express-engine": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@nguniversal/builders": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"ng-packagr": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"15.2.2-angular-eslint": {
|
|
||||||
"version": "15.2.2-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"eslint": "^7.20.0 || ^8.0.0",
|
|
||||||
"@angular/core": ">=15.0.0 <16.0.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"@angular-eslint/eslint-plugin": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-eslint/eslint-plugin-template": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-eslint/template-parser": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"15.2.2-jest": {
|
|
||||||
"version": "15.2.2-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"@angular-devkit/build-angular": ">=12.2.18 <16.0.0",
|
|
||||||
"@angular/compiler-cli": ">=12.2.16 <16.0.0",
|
|
||||||
"@angular/core": ">=12.2.16 <16.0.0",
|
|
||||||
"@angular/platform-browser-dynamic": ">=12.2.16 <16.0.0",
|
|
||||||
"jest": "^28.0.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"jest-preset-angular": {
|
|
||||||
"version": "12.2.3",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"15.3.1": {
|
|
||||||
"version": "15.3.1-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"@angular/core": "^15.0.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"@ngrx/store": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/effects": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/entity": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/router-store": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/schematics": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/store-devtools": {
|
|
||||||
"version": "~15.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/component-store": {
|
|
||||||
"version": "~15.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"15.5.0": {
|
|
||||||
"version": "15.5.0-beta.0",
|
|
||||||
"x-prompt": "Do you want to update the Angular version to v15.1?",
|
|
||||||
"requires": {
|
|
||||||
"@angular/core": ">=15.0.0 <15.1.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"@angular-devkit/architect": {
|
|
||||||
"version": "~0.1501.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/build-angular": {
|
|
||||||
"version": "~15.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/build-webpack": {
|
|
||||||
"version": "~0.1501.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/core": {
|
|
||||||
"version": "~15.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/schematics": {
|
|
||||||
"version": "~15.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/pwa": {
|
|
||||||
"version": "~15.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/core": {
|
|
||||||
"version": "~15.1.0",
|
|
||||||
"alwaysAddToPackageJson": true
|
|
||||||
},
|
|
||||||
"@angular/material": {
|
|
||||||
"version": "~15.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/cdk": {
|
|
||||||
"version": "~15.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@schematics/angular": {
|
|
||||||
"version": "~15.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"ng-packagr": {
|
|
||||||
"version": "~15.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"15.5.2": {
|
|
||||||
"version": "15.5.2-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"@angular-devkit/build-angular": ">=15.0.0 <16.0.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"@nguniversal/builders": {
|
|
||||||
"version": "~15.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@nguniversal/express-engine": {
|
|
||||||
"version": "~15.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"15.8.0": {
|
|
||||||
"version": "15.8.0-beta.4",
|
|
||||||
"x-prompt": "Do you want to update the Angular version to v15.2?",
|
|
||||||
"requires": {
|
|
||||||
"@angular/core": ">=15.1.0 <15.2.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"@angular-devkit/architect": {
|
|
||||||
"version": "~0.1502.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/build-angular": {
|
|
||||||
"version": "~15.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/build-webpack": {
|
|
||||||
"version": "~0.1502.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/core": {
|
|
||||||
"version": "~15.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular-devkit/schematics": {
|
|
||||||
"version": "~15.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/pwa": {
|
|
||||||
"version": "~15.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/core": {
|
|
||||||
"version": "~15.2.0",
|
|
||||||
"alwaysAddToPackageJson": true
|
|
||||||
},
|
|
||||||
"@angular/material": {
|
|
||||||
"version": "~15.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@angular/cdk": {
|
|
||||||
"version": "~15.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@schematics/angular": {
|
|
||||||
"version": "~15.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@nguniversal/express-engine": {
|
|
||||||
"version": "~15.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@nguniversal/build-angular": {
|
|
||||||
"version": "~15.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"ng-packagr": {
|
|
||||||
"version": "~15.2.2",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"zone.js": {
|
|
||||||
"version": "~0.12.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"15.8.0-jest": {
|
|
||||||
"version": "15.8.0-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"@angular-devkit/build-angular": ">=13.0.0 <16.0.0",
|
|
||||||
"@angular/compiler-cli": ">=13.0.0 <16.0.0",
|
|
||||||
"@angular/core": ">=13.0.0 <16.0.0",
|
|
||||||
"@angular/platform-browser-dynamic": ">=13.0.0 <16.0.0",
|
|
||||||
"jest": "^29.0.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"jest-preset-angular": {
|
|
||||||
"version": "13.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"15.8.0-ngrx": {
|
|
||||||
"version": "15.8.0-beta.6",
|
|
||||||
"requires": {
|
|
||||||
"@angular/core": "^15.0.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"@ngrx/store": {
|
|
||||||
"version": "~15.3.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/effects": {
|
|
||||||
"version": "~15.3.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/entity": {
|
|
||||||
"version": "~15.3.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/router-store": {
|
|
||||||
"version": "~15.3.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/schematics": {
|
|
||||||
"version": "~15.3.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/store-devtools": {
|
|
||||||
"version": "~15.3.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@ngrx/component-store": {
|
|
||||||
"version": "~15.3.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"15.8.6-rxjs": {
|
|
||||||
"version": "15.8.6-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"rxjs": ">=7.5.0 <7.6.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"rxjs": {
|
|
||||||
"version": "~7.8.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.1.0": {
|
"16.1.0": {
|
||||||
"version": "16.1.0-beta.1",
|
"version": "16.1.0-beta.1",
|
||||||
"x-prompt": "Do you want to update the Angular version to v16?",
|
"x-prompt": "Do you want to update the Angular version to v16?",
|
||||||
|
|||||||
@ -1,29 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generators": {
|
"generators": {
|
||||||
"update-16-0-0-add-nx-packages": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.0.0-beta.1",
|
|
||||||
"description": "Replace @nrwl/cypress with @nx/cypress",
|
|
||||||
"implementation": "./src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages"
|
|
||||||
},
|
|
||||||
"update-16-2-0-normalize-tsconfigs": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.2.0-beta.0",
|
|
||||||
"description": "Normalize tsconfig.cy.json files to be located at '<projectRoot>/cypress/tsconfig.json'",
|
|
||||||
"implementation": "./src/migrations/update-16-2-0/update-cy-tsconfig"
|
|
||||||
},
|
|
||||||
"update-16-3-0-remove-old-tsconfigs": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.4.0-beta.10",
|
|
||||||
"description": "Remove tsconfig.e2e.json and add settings to project tsconfig.json. tsConfigs executor option is now deprecated. The project level tsconfig.json file should be used instead.",
|
|
||||||
"implementation": "./src/migrations/update-16-4-0/tsconfig-sourcemaps"
|
|
||||||
},
|
|
||||||
"update-16-8-0-cypress-13": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.8.0-beta.4",
|
|
||||||
"description": "Update to Cypress v13. Most noteable change is video recording is off by default. This migration will only update if the workspace is already on Cypress v12. https://docs.cypress.io/guides/references/migration-guide#Migrating-to-Cypress-130",
|
|
||||||
"implementation": "./src/migrations/update-16-8-0/cypress-13"
|
|
||||||
},
|
|
||||||
"update-cypress-version-13-6-6": {
|
"update-cypress-version-13-6-6": {
|
||||||
"cli": "nx",
|
"cli": "nx",
|
||||||
"version": "18.1.0-beta.3",
|
"version": "18.1.0-beta.3",
|
||||||
@ -38,39 +14,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packageJsonUpdates": {
|
"packageJsonUpdates": {
|
||||||
"16.1.0": {
|
|
||||||
"version": "16.1.0-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"cypress": ">=12.0.0 <12.11.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"cypress": {
|
|
||||||
"version": "^12.11.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.5.0": {
|
|
||||||
"version": "16.5.0-beta.0",
|
|
||||||
"requires": {
|
|
||||||
"cypress": ">=12.0.0 <12.16.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"cypress": {
|
|
||||||
"version": "^12.16.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.7.0": {
|
|
||||||
"version": "16.7.0-beta.3",
|
|
||||||
"packages": {
|
|
||||||
"eslint-plugin-cypress": {
|
|
||||||
"version": "^2.13.4",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"17.2.0-beta.2": {
|
"17.2.0-beta.2": {
|
||||||
"version": "17.2.0-beta.2",
|
"version": "17.2.0-beta.2",
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
import { Tree, readJson, updateJson } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import replacePackage from './update-16-0-0-add-nx-packages';
|
|
||||||
|
|
||||||
describe('update-16-0-0-add-nx-packages', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
|
|
||||||
updateJson(tree, 'package.json', (json) => {
|
|
||||||
json.devDependencies['@nrwl/cypress'] = '16.0.0';
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the dependency on @nrwl/cypress', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').dependencies['@nrwl/cypress']
|
|
||||||
).not.toBeDefined();
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nrwl/cypress']
|
|
||||||
).not.toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add a dependency on @nx/cypress', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
const packageJson = readJson(tree, 'package.json');
|
|
||||||
const newDependencyVersion =
|
|
||||||
packageJson.devDependencies['@nx/cypress'] ??
|
|
||||||
packageJson.dependencies['@nx/cypress'];
|
|
||||||
|
|
||||||
expect(newDependencyVersion).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import { Tree, formatFiles } from '@nx/devkit';
|
|
||||||
import { replaceNrwlPackageWithNxPackage } from '@nx/devkit/src/utils/replace-package';
|
|
||||||
|
|
||||||
export default async function replacePackage(tree: Tree): Promise<void> {
|
|
||||||
await replaceNrwlPackageWithNxPackage(tree, '@nrwl/cypress', '@nx/cypress');
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,250 +0,0 @@
|
|||||||
import 'nx/src/internal-testing-utils/mock-project-graph';
|
|
||||||
|
|
||||||
import {
|
|
||||||
Tree,
|
|
||||||
readJson,
|
|
||||||
readProjectConfiguration,
|
|
||||||
updateJson,
|
|
||||||
updateProjectConfiguration,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from 'nx/src/devkit-testing-exports';
|
|
||||||
import { normalizeCyTsConfigNames } from './update-cy-tsconfig';
|
|
||||||
import { libraryGenerator } from '@nx/js';
|
|
||||||
|
|
||||||
describe('Cypress Migration - update-cy-tsconfig', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
||||||
});
|
|
||||||
it('should do nothing if cypress/tsconfig.json exists', async () => {
|
|
||||||
await libraryGenerator(tree, { directory: 'libs/my-lib' });
|
|
||||||
addCyExecutor(tree, 'my-lib');
|
|
||||||
const tsconfig = {
|
|
||||||
extends: '../tsconfig.json',
|
|
||||||
compilerOptions: {
|
|
||||||
sourceMap: false,
|
|
||||||
outDir: '../../../dist/out-tsc',
|
|
||||||
allowJs: true,
|
|
||||||
types: ['cypress', 'node'],
|
|
||||||
},
|
|
||||||
include: ['**/*.ts', '**/*.js', '../cypress.config.ts'],
|
|
||||||
};
|
|
||||||
|
|
||||||
tree.write(
|
|
||||||
'libs/my-lib/cypress/tsconfig.json',
|
|
||||||
JSON.stringify(tsconfig, null, 2)
|
|
||||||
);
|
|
||||||
updateJson(tree, 'libs/my-lib/tsconfig.json', (json) => {
|
|
||||||
json.references ??= [];
|
|
||||||
json.references.push({ path: './cypress/tsconfig.json' });
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
|
|
||||||
await normalizeCyTsConfigNames(tree);
|
|
||||||
expect(readJson(tree, 'libs/my-lib/tsconfig.json').references).toEqual(
|
|
||||||
expect.arrayContaining([{ path: './cypress/tsconfig.json' }])
|
|
||||||
);
|
|
||||||
expect(readJson(tree, 'libs/my-lib/cypress/tsconfig.json')).toEqual(
|
|
||||||
tsconfig
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should move cypress/tsconfig.cy.json to cypress/tsconfig.json', async () => {
|
|
||||||
await libraryGenerator(tree, { directory: 'libs/my-lib' });
|
|
||||||
addCyExecutor(tree, 'my-lib');
|
|
||||||
const tsconfig = {
|
|
||||||
extends: '../tsconfig.json',
|
|
||||||
compilerOptions: {
|
|
||||||
outDir: '../../../dist/out-tsc',
|
|
||||||
module: 'commonjs',
|
|
||||||
types: ['cypress', 'node'],
|
|
||||||
sourceMap: false,
|
|
||||||
},
|
|
||||||
include: [
|
|
||||||
'support/**/*.ts',
|
|
||||||
'../cypress.config.ts',
|
|
||||||
'../**/*.cy.ts',
|
|
||||||
'../**/*.cy.tsx',
|
|
||||||
'../**/*.cy.js',
|
|
||||||
'../**/*.cy.jsx',
|
|
||||||
'../**/*.d.ts',
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
tree.write(
|
|
||||||
'libs/my-lib/cypress/tsconfig.cy.json',
|
|
||||||
JSON.stringify(tsconfig, null, 2)
|
|
||||||
);
|
|
||||||
|
|
||||||
updateJson(tree, 'libs/my-lib/tsconfig.json', (json) => {
|
|
||||||
json.references ??= [];
|
|
||||||
json.references.push({ path: './cypress/tsconfig.cy.json' });
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
|
|
||||||
await normalizeCyTsConfigNames(tree);
|
|
||||||
expect(tree.exists('libs/my-lib/cypress/tsconfig.cy.json')).toBeFalsy();
|
|
||||||
expect(readJson(tree, 'libs/my-lib/tsconfig.json').references).toEqual(
|
|
||||||
expect.arrayContaining([{ path: './cypress/tsconfig.json' }])
|
|
||||||
);
|
|
||||||
expect(readJson(tree, 'libs/my-lib/cypress/tsconfig.json')).toEqual(
|
|
||||||
tsconfig
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should move tsconfig.cy.json to cypress/tsconfig.json', async () => {
|
|
||||||
await libraryGenerator(tree, { directory: 'libs/my-lib' });
|
|
||||||
addCyExecutor(tree, 'my-lib');
|
|
||||||
const tsconfig = {
|
|
||||||
extends: './tsconfig.json',
|
|
||||||
compilerOptions: {
|
|
||||||
outDir: '../../dist/out-tsc',
|
|
||||||
module: 'commonjs',
|
|
||||||
types: ['cypress', 'node'],
|
|
||||||
sourceMap: false,
|
|
||||||
},
|
|
||||||
include: [
|
|
||||||
'cypress/support/**/*.ts',
|
|
||||||
'cypress.config.ts',
|
|
||||||
'**/*.cy.ts',
|
|
||||||
'**/*.cy.tsx',
|
|
||||||
'**/*.cy.js',
|
|
||||||
'**/*.cy.jsx',
|
|
||||||
'**/*.d.ts',
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
tree.write(
|
|
||||||
'libs/my-lib/tsconfig.cy.json',
|
|
||||||
JSON.stringify(tsconfig, null, 2)
|
|
||||||
);
|
|
||||||
updateJson(tree, 'libs/my-lib/tsconfig.json', (json) => {
|
|
||||||
json.references ??= [];
|
|
||||||
json.references.push({ path: './tsconfig.cy.json' });
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
|
|
||||||
await normalizeCyTsConfigNames(tree);
|
|
||||||
expect(tree.exists('libs/my-lib/tsconfig.cy.json')).toBeFalsy();
|
|
||||||
expect(readJson(tree, 'libs/my-lib/tsconfig.json').references).toEqual(
|
|
||||||
expect.arrayContaining([{ path: './cypress/tsconfig.json' }])
|
|
||||||
);
|
|
||||||
expect(readJson(tree, 'libs/my-lib/cypress/tsconfig.json')).toEqual({
|
|
||||||
extends: '../tsconfig.json',
|
|
||||||
compilerOptions: {
|
|
||||||
outDir: '../../../dist/out-tsc',
|
|
||||||
module: 'commonjs',
|
|
||||||
types: ['cypress', 'node'],
|
|
||||||
sourceMap: false,
|
|
||||||
},
|
|
||||||
include: [
|
|
||||||
'support/**/*.ts',
|
|
||||||
'../cypress.config.ts',
|
|
||||||
'../**/*.cy.ts',
|
|
||||||
'../**/*.cy.tsx',
|
|
||||||
'../**/*.cy.js',
|
|
||||||
'../**/*.cy.jsx',
|
|
||||||
'../**/*.d.ts',
|
|
||||||
],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be idepotent', async () => {
|
|
||||||
await libraryGenerator(tree, { directory: 'libs/my-lib' });
|
|
||||||
addCyExecutor(tree, 'my-lib');
|
|
||||||
const tsconfig = {
|
|
||||||
extends: './tsconfig.json',
|
|
||||||
compilerOptions: {
|
|
||||||
outDir: '../../dist/out-tsc',
|
|
||||||
module: 'commonjs',
|
|
||||||
types: ['cypress', 'node'],
|
|
||||||
sourceMap: false,
|
|
||||||
},
|
|
||||||
include: [
|
|
||||||
'cypress/support/**/*.ts',
|
|
||||||
'cypress.config.ts',
|
|
||||||
'**/*.cy.ts',
|
|
||||||
'**/*.cy.tsx',
|
|
||||||
'**/*.cy.js',
|
|
||||||
'**/*.cy.jsx',
|
|
||||||
'**/*.d.ts',
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
tree.write(
|
|
||||||
'libs/my-lib/tsconfig.cy.json',
|
|
||||||
JSON.stringify(tsconfig, null, 2)
|
|
||||||
);
|
|
||||||
updateJson(tree, 'libs/my-lib/tsconfig.json', (json) => {
|
|
||||||
json.references ??= [];
|
|
||||||
json.references.push({ path: './tsconfig.cy.json' });
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
|
|
||||||
await normalizeCyTsConfigNames(tree);
|
|
||||||
expect(tree.exists('libs/my-lib/tsconfig.cy.json')).toBeFalsy();
|
|
||||||
expect(readJson(tree, 'libs/my-lib/tsconfig.json').references).toEqual(
|
|
||||||
expect.arrayContaining([{ path: './cypress/tsconfig.json' }])
|
|
||||||
);
|
|
||||||
expect(readJson(tree, 'libs/my-lib/cypress/tsconfig.json')).toEqual({
|
|
||||||
extends: '../tsconfig.json',
|
|
||||||
compilerOptions: {
|
|
||||||
outDir: '../../../dist/out-tsc',
|
|
||||||
module: 'commonjs',
|
|
||||||
types: ['cypress', 'node'],
|
|
||||||
sourceMap: false,
|
|
||||||
},
|
|
||||||
include: [
|
|
||||||
'support/**/*.ts',
|
|
||||||
'../cypress.config.ts',
|
|
||||||
'../**/*.cy.ts',
|
|
||||||
'../**/*.cy.tsx',
|
|
||||||
'../**/*.cy.js',
|
|
||||||
'../**/*.cy.jsx',
|
|
||||||
'../**/*.d.ts',
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
await normalizeCyTsConfigNames(tree);
|
|
||||||
expect(tree.exists('libs/my-lib/tsconfig.cy.json')).toBeFalsy();
|
|
||||||
expect(readJson(tree, 'libs/my-lib/tsconfig.json').references).toEqual([
|
|
||||||
{ path: './tsconfig.lib.json' },
|
|
||||||
{ path: './tsconfig.spec.json' },
|
|
||||||
{ path: './cypress/tsconfig.json' },
|
|
||||||
]);
|
|
||||||
expect(readJson(tree, 'libs/my-lib/cypress/tsconfig.json')).toEqual({
|
|
||||||
extends: '../tsconfig.json',
|
|
||||||
compilerOptions: {
|
|
||||||
outDir: '../../../dist/out-tsc',
|
|
||||||
module: 'commonjs',
|
|
||||||
types: ['cypress', 'node'],
|
|
||||||
sourceMap: false,
|
|
||||||
},
|
|
||||||
include: [
|
|
||||||
'support/**/*.ts',
|
|
||||||
'../cypress.config.ts',
|
|
||||||
'../**/*.cy.ts',
|
|
||||||
'../**/*.cy.tsx',
|
|
||||||
'../**/*.cy.js',
|
|
||||||
'../**/*.cy.jsx',
|
|
||||||
'../**/*.d.ts',
|
|
||||||
],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function addCyExecutor(tree: Tree, projectName: string) {
|
|
||||||
const pc = readProjectConfiguration(tree, projectName);
|
|
||||||
|
|
||||||
pc.targets['e2e'] = {
|
|
||||||
executor: '@nx/cypress:cypress',
|
|
||||||
options: {
|
|
||||||
testingType: 'e2e',
|
|
||||||
devServerTarget: `${projectName}:serve`,
|
|
||||||
cypressConfig: `${projectName}/cypress.config.ts`,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
updateProjectConfiguration(tree, projectName, pc);
|
|
||||||
}
|
|
||||||
@ -1,128 +0,0 @@
|
|||||||
import {
|
|
||||||
ProjectConfiguration,
|
|
||||||
Tree,
|
|
||||||
formatFiles,
|
|
||||||
getProjects,
|
|
||||||
joinPathFragments,
|
|
||||||
updateJson,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils';
|
|
||||||
|
|
||||||
export async function normalizeCyTsConfigNames(tree: Tree) {
|
|
||||||
const projects = getProjects(tree);
|
|
||||||
|
|
||||||
forEachExecutorOptions(tree, '@nx/cypress:cypress', (_, projectName) => {
|
|
||||||
const projectConfig = projects.get(projectName);
|
|
||||||
const newTsConfigPath = joinPathFragments(
|
|
||||||
projectConfig.root,
|
|
||||||
'cypress',
|
|
||||||
'tsconfig.json'
|
|
||||||
);
|
|
||||||
|
|
||||||
// if there is already a tsconfig.json in the cypress folder, then assume things are setup already
|
|
||||||
if (!tree.exists(newTsConfigPath)) {
|
|
||||||
moveProjectTsCyConfig(tree, projectConfig, newTsConfigPath);
|
|
||||||
moveCyDirTsCyConfig(tree, projectConfig, newTsConfigPath);
|
|
||||||
updateCyDirTsConfigReferences(tree, projectConfig);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
|
|
||||||
function moveProjectTsCyConfig(
|
|
||||||
tree: Tree,
|
|
||||||
projectConfig: ProjectConfiguration,
|
|
||||||
newTsConfigPath: string
|
|
||||||
) {
|
|
||||||
if (tree.exists(joinPathFragments(projectConfig.root, 'tsconfig.cy.json'))) {
|
|
||||||
tree.rename(
|
|
||||||
joinPathFragments(projectConfig.root, 'tsconfig.cy.json'),
|
|
||||||
newTsConfigPath
|
|
||||||
);
|
|
||||||
updateJson(tree, newTsConfigPath, (json) => {
|
|
||||||
json.extends = '../tsconfig.json';
|
|
||||||
|
|
||||||
json.compilerOptions ??= {};
|
|
||||||
json.compilerOptions = {
|
|
||||||
...json.compilerOptions,
|
|
||||||
sourceMap: false,
|
|
||||||
outDir: '../../../dist/out-tsc',
|
|
||||||
};
|
|
||||||
|
|
||||||
json.include ??= [];
|
|
||||||
json.include = json.include.map((p) => {
|
|
||||||
if (p.startsWith('cypress/')) {
|
|
||||||
return p.replace('cypress/', '');
|
|
||||||
}
|
|
||||||
return `../${p}`;
|
|
||||||
});
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function moveCyDirTsCyConfig(
|
|
||||||
tree: Tree,
|
|
||||||
projectConfig: ProjectConfiguration,
|
|
||||||
newTsConfigPath: string
|
|
||||||
) {
|
|
||||||
if (
|
|
||||||
tree.exists(
|
|
||||||
joinPathFragments(projectConfig.root, 'cypress', 'tsconfig.cy.json')
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
tree.rename(
|
|
||||||
joinPathFragments(projectConfig.root, 'cypress', 'tsconfig.cy.json'),
|
|
||||||
newTsConfigPath
|
|
||||||
);
|
|
||||||
updateJson(tree, newTsConfigPath, (json) => {
|
|
||||||
json.compilerOptions ??= {};
|
|
||||||
json.compilerOptions = {
|
|
||||||
...json.compilerOptions,
|
|
||||||
sourceMap: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateCyDirTsConfigReferences(
|
|
||||||
tree: Tree,
|
|
||||||
projectConfig: ProjectConfiguration
|
|
||||||
) {
|
|
||||||
if (
|
|
||||||
!tree.exists(
|
|
||||||
joinPathFragments(projectConfig.root, 'cypress', 'tsconfig.json')
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
updateJson(
|
|
||||||
tree,
|
|
||||||
joinPathFragments(projectConfig.root, 'tsconfig.json'),
|
|
||||||
(json) => {
|
|
||||||
json.references ??= [];
|
|
||||||
if (!json.references) {
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
const cyFile = json.references.find((p) =>
|
|
||||||
p.path.includes('tsconfig.cy.json')
|
|
||||||
);
|
|
||||||
|
|
||||||
if (cyFile) {
|
|
||||||
json.references.splice(json.references.indexOf(cyFile), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!json.references.some((r) => r.path === './cypress/tsconfig.json')) {
|
|
||||||
json.references.push({
|
|
||||||
path: './cypress/tsconfig.json',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default normalizeCyTsConfigNames;
|
|
||||||
@ -1,175 +0,0 @@
|
|||||||
import {
|
|
||||||
Tree,
|
|
||||||
addProjectConfiguration,
|
|
||||||
readJson,
|
|
||||||
readProjectConfiguration,
|
|
||||||
updateJson,
|
|
||||||
updateProjectConfiguration,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from 'nx/src/devkit-testing-exports';
|
|
||||||
import { fixLegacyCypressTsconfig } from './tsconfig-sourcemaps';
|
|
||||||
|
|
||||||
describe('Cypress Migration: tsconfig-sourcemaps', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove tsconfig.e2e.json and update tsconfig.json', async () => {
|
|
||||||
addLegacyProject(tree);
|
|
||||||
|
|
||||||
await fixLegacyCypressTsconfig(tree);
|
|
||||||
expect(readProjectConfiguration(tree, 'legacy-e2e').targets.e2e)
|
|
||||||
.toMatchInlineSnapshot(`
|
|
||||||
{
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"devServerTarget": "legacy-e2e:serve:production",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"executor": "@nx/cypress:cypress",
|
|
||||||
"options": {
|
|
||||||
"cypressConfig": "apps/legacy-e2e/cypress.config.ts",
|
|
||||||
"devServerTarget": "legacy-e2e:serve",
|
|
||||||
"testingType": "e2e",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
expect(readJson(tree, 'apps/legacy-e2e/tsconfig.json'))
|
|
||||||
.toMatchInlineSnapshot(`
|
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"outDir": "../../dist/out-tsc",
|
|
||||||
"resolveJsonModule": true,
|
|
||||||
"sourceMap": false,
|
|
||||||
"strict": true,
|
|
||||||
"types": [
|
|
||||||
"cypress",
|
|
||||||
"node",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
"exclude": [],
|
|
||||||
"extends": "../../tsconfig.base.json",
|
|
||||||
"files": [],
|
|
||||||
"include": [
|
|
||||||
"cypress.ci.1.config.ts",
|
|
||||||
"cypress.ci.2.config.ts",
|
|
||||||
"cypress.ci.3.config.ts",
|
|
||||||
"cypress.ci.4.config.ts",
|
|
||||||
"src/**/*.ts",
|
|
||||||
"cypress.config.ts",
|
|
||||||
],
|
|
||||||
"references": [],
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
expect(tree.exists('apps/legacy-e2e/tsconfig.e2e.json')).toBeFalsy();
|
|
||||||
expect(tree.exists('apps/legacy-e2e/tsconfig.e2e.prod.json')).toBeFalsy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should do nothing if tsconfig option is not used', async () => {
|
|
||||||
addLegacyProject(tree);
|
|
||||||
|
|
||||||
tree.delete('apps/legacy-e2e/tsconfig.e2e.json');
|
|
||||||
tree.delete('apps/legacy-e2e/tsconfig.e2e.prod.json');
|
|
||||||
const pc = readProjectConfiguration(tree, 'legacy-e2e');
|
|
||||||
|
|
||||||
delete pc.targets.e2e.options.tsConfig;
|
|
||||||
delete pc.targets.e2e.configurations;
|
|
||||||
|
|
||||||
const existingProjectConfig = pc.targets.e2e;
|
|
||||||
|
|
||||||
updateProjectConfiguration(tree, 'legacy-e2e', pc);
|
|
||||||
|
|
||||||
updateJson(tree, 'apps/legacy-e2e/tsconfig.json', (json) => {
|
|
||||||
json.references = [];
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
|
|
||||||
const existingTsConfig = readJson(tree, 'apps/legacy-e2e/tsconfig.json');
|
|
||||||
|
|
||||||
await fixLegacyCypressTsconfig(tree);
|
|
||||||
|
|
||||||
expect(readProjectConfiguration(tree, 'legacy-e2e').targets.e2e).toEqual(
|
|
||||||
existingProjectConfig
|
|
||||||
);
|
|
||||||
expect(readJson(tree, 'apps/legacy-e2e/tsconfig.json')).toEqual(
|
|
||||||
existingTsConfig
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function addLegacyProject(tree: Tree) {
|
|
||||||
addProjectConfiguration(tree, 'legacy-e2e', {
|
|
||||||
root: 'apps/legacy-e2e',
|
|
||||||
sourceRoot: 'apps/legacy-e2e/src',
|
|
||||||
targets: {
|
|
||||||
e2e: {
|
|
||||||
executor: '@nx/cypress:cypress',
|
|
||||||
options: {
|
|
||||||
cypressConfig: 'apps/legacy-e2e/cypress.config.ts',
|
|
||||||
tsConfig: 'apps/legacy-e2e/tsconfig.e2e.json',
|
|
||||||
devServerTarget: 'legacy-e2e:serve',
|
|
||||||
testingType: 'e2e',
|
|
||||||
},
|
|
||||||
configurations: {
|
|
||||||
production: {
|
|
||||||
devServerTarget: 'legacy-e2e:serve:production',
|
|
||||||
tsConfig: 'apps/legacy-e2e/tsconfig.e2e.prod.json',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
tree.write(
|
|
||||||
'apps/legacy-e2e/tsconfig.e2e.json',
|
|
||||||
JSON.stringify({
|
|
||||||
extends: './tsconfig.json',
|
|
||||||
compilerOptions: {
|
|
||||||
sourceMap: false,
|
|
||||||
outDir: '../../dist/out-tsc',
|
|
||||||
types: ['cypress', 'node'],
|
|
||||||
},
|
|
||||||
include: ['src/**/*.ts', 'cypress.config.ts'],
|
|
||||||
})
|
|
||||||
);
|
|
||||||
tree.write(
|
|
||||||
'apps/legacy-e2e/tsconfig.e2e.prod.json',
|
|
||||||
JSON.stringify({
|
|
||||||
extends: './tsconfig.e2e.json',
|
|
||||||
compilerOptions: {
|
|
||||||
sourceMap: false,
|
|
||||||
outDir: '../../dist/out-tsc',
|
|
||||||
types: ['cypress', 'node'],
|
|
||||||
strict: true,
|
|
||||||
},
|
|
||||||
include: ['src/**/*.ts', 'cypress.config.ts'],
|
|
||||||
})
|
|
||||||
);
|
|
||||||
tree.write(
|
|
||||||
'apps/legacy-e2e/tsconfig.json',
|
|
||||||
JSON.stringify({
|
|
||||||
extends: '../../tsconfig.base.json',
|
|
||||||
compilerOptions: {
|
|
||||||
types: ['cypress', 'node'],
|
|
||||||
resolveJsonModule: true,
|
|
||||||
},
|
|
||||||
include: [
|
|
||||||
'cypress.ci.1.config.ts',
|
|
||||||
'cypress.ci.2.config.ts',
|
|
||||||
'cypress.ci.3.config.ts',
|
|
||||||
'cypress.ci.4.config.ts',
|
|
||||||
],
|
|
||||||
files: [],
|
|
||||||
references: [
|
|
||||||
{
|
|
||||||
path: './tsconfig.e2e.json',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: './tsconfig.e2e.prod.json',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,102 +0,0 @@
|
|||||||
import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils';
|
|
||||||
import { CypressExecutorOptions } from '../../executors/cypress/cypress.impl';
|
|
||||||
import {
|
|
||||||
updateJson,
|
|
||||||
Tree,
|
|
||||||
getProjects,
|
|
||||||
joinPathFragments,
|
|
||||||
readJson,
|
|
||||||
updateProjectConfiguration,
|
|
||||||
formatFiles,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import { posix } from 'path';
|
|
||||||
|
|
||||||
export async function fixLegacyCypressTsconfig(tree: Tree) {
|
|
||||||
const projects = getProjects(tree);
|
|
||||||
forEachExecutorOptions<CypressExecutorOptions>(
|
|
||||||
tree,
|
|
||||||
'@nx/cypress:cypress',
|
|
||||||
(options, projectName, targetName, configName) => {
|
|
||||||
const projectConfig = projects.get(projectName);
|
|
||||||
|
|
||||||
if (
|
|
||||||
options.testingType !== 'e2e' &&
|
|
||||||
projectConfig.targets[targetName]?.options?.testingType !== 'e2e'
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const tsconfigToRemove =
|
|
||||||
options.tsConfig ??
|
|
||||||
joinPathFragments(projectConfig.root, 'tsconfig.e2e.json');
|
|
||||||
|
|
||||||
const projectLevelConfigPath = joinPathFragments(
|
|
||||||
projectConfig.root,
|
|
||||||
'tsconfig.json'
|
|
||||||
);
|
|
||||||
|
|
||||||
if (
|
|
||||||
!tree.exists(projectLevelConfigPath) ||
|
|
||||||
!tree.exists(tsconfigToRemove)
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tsconfigToRemove === projectLevelConfigPath) {
|
|
||||||
updateJson(tree, projectLevelConfigPath, (json) => {
|
|
||||||
json.compilerOptions = {
|
|
||||||
sourceMap: false,
|
|
||||||
...json.compilerOptions,
|
|
||||||
};
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const e2eConfig = readJson(tree, tsconfigToRemove);
|
|
||||||
|
|
||||||
updateJson(tree, projectLevelConfigPath, (json) => {
|
|
||||||
json.compilerOptions = {
|
|
||||||
sourceMap: false,
|
|
||||||
...json.compilerOptions,
|
|
||||||
...e2eConfig.compilerOptions,
|
|
||||||
};
|
|
||||||
json.files = Array.from(
|
|
||||||
new Set([...(json.files ?? []), ...(e2eConfig.files ?? [])])
|
|
||||||
);
|
|
||||||
json.include = Array.from(
|
|
||||||
new Set([...(json.include ?? []), ...(e2eConfig.include ?? [])])
|
|
||||||
);
|
|
||||||
json.exclude = Array.from(
|
|
||||||
new Set([...(json.exclude ?? []), ...(e2eConfig.exclude ?? [])])
|
|
||||||
);
|
|
||||||
|
|
||||||
// these paths will always be 'unix style'
|
|
||||||
// and on windows relative will not work on these paths
|
|
||||||
const tsConfigFromProjRoot = posix.relative(
|
|
||||||
projectConfig.root,
|
|
||||||
tsconfigToRemove
|
|
||||||
);
|
|
||||||
|
|
||||||
json.references = (json.references ?? []).filter(
|
|
||||||
({ path }) => !path.includes(tsConfigFromProjRoot)
|
|
||||||
);
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
|
|
||||||
tree.delete(tsconfigToRemove);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configName) {
|
|
||||||
delete projectConfig.targets[targetName].configurations[configName]
|
|
||||||
.tsConfig;
|
|
||||||
} else {
|
|
||||||
delete projectConfig.targets[targetName].options.tsConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateProjectConfiguration(tree, projectName, projectConfig);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default fixLegacyCypressTsconfig;
|
|
||||||
@ -1,243 +0,0 @@
|
|||||||
import { Tree, addProjectConfiguration, readJson } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from 'nx/src/devkit-testing-exports';
|
|
||||||
import { updateToCypress13 } from './cypress-13';
|
|
||||||
|
|
||||||
describe('Cypress 13', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update deps to cypress v13', async () => {
|
|
||||||
setup(tree, { name: 'my-app' });
|
|
||||||
|
|
||||||
await updateToCypress13(tree);
|
|
||||||
expect(readJson(tree, 'package.json').devDependencies.cypress).toEqual(
|
|
||||||
'^13.0.0'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update videoUploadOnPasses from config w/setupNodeEvents', async () => {
|
|
||||||
setup(tree, { name: 'my-app-video-upload-on-passes' });
|
|
||||||
await updateToCypress13(tree);
|
|
||||||
expect(
|
|
||||||
tree.read('apps/my-app-video-upload-on-passes/cypress.config.ts', 'utf-8')
|
|
||||||
).toMatchInlineSnapshot(`
|
|
||||||
"import fs from 'fs';
|
|
||||||
|
|
||||||
import { defineConfig } from 'cypress';
|
|
||||||
import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset';
|
|
||||||
import { nxComponentTestingPreset } from '@nx/react/plugins/component-testing';
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
something: 'blah',
|
|
||||||
// nodeVersion: 'system',
|
|
||||||
// videoUploadOnPasses: false ,
|
|
||||||
e2e: {
|
|
||||||
...nxE2EPreset(__filename),
|
|
||||||
setupNodeEvents(on, config) {
|
|
||||||
const a = '';
|
|
||||||
removePassedSpecs(on);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
component: {
|
|
||||||
...nxComponentTestingPreset(__filename),
|
|
||||||
setupNodeEvents: (on, config) => {
|
|
||||||
const b = '';
|
|
||||||
removePassedSpecs(on);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete videos for specs that do not contain failing or retried tests.
|
|
||||||
* This function is to be used in the 'setupNodeEvents' configuration option as a replacement to
|
|
||||||
* 'videoUploadOnPasses' which has been removed.
|
|
||||||
*
|
|
||||||
* https://docs.cypress.io/guides/guides/screenshots-and-videos#Delete-videos-for-specs-without-failing-or-retried-tests
|
|
||||||
**/
|
|
||||||
function removePassedSpecs(on) {
|
|
||||||
on('after:spec', (spec, results) => {
|
|
||||||
if (results && results.vide) {
|
|
||||||
const hasFailures = results.tests.some((t) =>
|
|
||||||
t.attempts.some((a) => a.state === 'failed')
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!hasFailures) {
|
|
||||||
fs.unlinkSync(results.video);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
"
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
it('should remove nodeVersion from config', async () => {
|
|
||||||
setup(tree, { name: 'my-app-node-version' });
|
|
||||||
await updateToCypress13(tree);
|
|
||||||
expect(tree.read('apps/my-app-node-version/cypress.config.ts', 'utf-8'))
|
|
||||||
.toMatchInlineSnapshot(`
|
|
||||||
"import fs from 'fs';
|
|
||||||
|
|
||||||
import { defineConfig } from 'cypress';
|
|
||||||
import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset';
|
|
||||||
import { nxComponentTestingPreset } from '@nx/react/plugins/component-testing';
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
something: 'blah',
|
|
||||||
// nodeVersion: 'system',
|
|
||||||
// videoUploadOnPasses: false ,
|
|
||||||
e2e: {
|
|
||||||
...nxE2EPreset(__filename),
|
|
||||||
setupNodeEvents(on, config) {
|
|
||||||
const a = '';
|
|
||||||
removePassedSpecs(on);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
component: {
|
|
||||||
...nxComponentTestingPreset(__filename),
|
|
||||||
setupNodeEvents: (on, config) => {
|
|
||||||
const b = '';
|
|
||||||
removePassedSpecs(on);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete videos for specs that do not contain failing or retried tests.
|
|
||||||
* This function is to be used in the 'setupNodeEvents' configuration option as a replacement to
|
|
||||||
* 'videoUploadOnPasses' which has been removed.
|
|
||||||
*
|
|
||||||
* https://docs.cypress.io/guides/guides/screenshots-and-videos#Delete-videos-for-specs-without-failing-or-retried-tests
|
|
||||||
**/
|
|
||||||
function removePassedSpecs(on) {
|
|
||||||
on('after:spec', (spec, results) => {
|
|
||||||
if (results && results.vide) {
|
|
||||||
const hasFailures = results.tests.some((t) =>
|
|
||||||
t.attempts.some((a) => a.state === 'failed')
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!hasFailures) {
|
|
||||||
fs.unlinkSync(results.video);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
"
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should comment about overriding readFile command', async () => {
|
|
||||||
setup(tree, { name: 'my-app-read-file' });
|
|
||||||
const testContent = `describe('something', () => {
|
|
||||||
it('should do the thing', () => {
|
|
||||||
cy.readFile('my-data.json').its('name').should('eq', 'Nx');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
`;
|
|
||||||
tree.write('apps/my-app-read-file/src/something.cy.ts', testContent);
|
|
||||||
|
|
||||||
tree.write(
|
|
||||||
'apps/my-app-read-file/cypress/support/commands.ts',
|
|
||||||
`declare namespace Cypress {
|
|
||||||
interface Chainable<Subject> {
|
|
||||||
login(email: string, password: string): void;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// -- This is a parent command --
|
|
||||||
Cypress.Commands.add('login', (email, password) => {
|
|
||||||
console.log('Custom command example: Login', email, password);
|
|
||||||
});
|
|
||||||
Cypress.Commands.overwrite('readFile', () => {});
|
|
||||||
|
|
||||||
`
|
|
||||||
);
|
|
||||||
await updateToCypress13(tree);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
tree.read('apps/my-app-read-file/src/something.cy.ts', 'utf-8')
|
|
||||||
).toEqual(testContent);
|
|
||||||
expect(
|
|
||||||
tree.read('apps/my-app-read-file/cypress/support/commands.ts', 'utf-8')
|
|
||||||
).toMatchInlineSnapshot(`
|
|
||||||
"declare namespace Cypress {
|
|
||||||
interface Chainable<Subject> {
|
|
||||||
login(email: string, password: string): void;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// -- This is a parent command --
|
|
||||||
Cypress.Commands.add('login', (email, password) => {
|
|
||||||
console.log('Custom command example: Login', email, password);
|
|
||||||
});
|
|
||||||
/**
|
|
||||||
* TODO(@nx/cypress): This command can no longer be overridden
|
|
||||||
* Consider using a different name like 'custom_readFile'
|
|
||||||
* More info: https://docs.cypress.io/guides/references/migration-guide#readFile-can-no-longer-be-overwritten-with-CypressCommandsoverwrite
|
|
||||||
**/
|
|
||||||
Cypress.Commands.overwrite('readFile', () => {});
|
|
||||||
"
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function setup(tree: Tree, options: { name: string }) {
|
|
||||||
tree.write(
|
|
||||||
`apps/${options.name}/cypress.config.ts`,
|
|
||||||
`
|
|
||||||
import { defineConfig} from 'cypress';
|
|
||||||
import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset';
|
|
||||||
import { nxComponentTestingPreset } from '@nx/react/plugins/component-testing';
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
something: 'blah',
|
|
||||||
nodeVersion: 'system',
|
|
||||||
videoUploadOnPasses: false,
|
|
||||||
e2e: {
|
|
||||||
...nxE2EPreset(__filename),
|
|
||||||
videoUploadOnPasses: false,
|
|
||||||
nodeVersion: 'bundled',
|
|
||||||
setupNodeEvents(on, config) {
|
|
||||||
const a = '';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
component: {
|
|
||||||
...nxComponentTestingPreset(__filename),
|
|
||||||
videoUploadOnPasses: false,
|
|
||||||
nodeVersion: 'something',
|
|
||||||
setupNodeEvents: (on, config) => {
|
|
||||||
const b = '';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
`
|
|
||||||
);
|
|
||||||
tree.write(
|
|
||||||
'package.json',
|
|
||||||
JSON.stringify({ devDependencies: { cypress: '^12.16.0' } })
|
|
||||||
);
|
|
||||||
addProjectConfiguration(tree, options.name, {
|
|
||||||
root: `apps/${options.name}`,
|
|
||||||
sourceRoot: `apps/${options.name}/src`,
|
|
||||||
targets: {
|
|
||||||
e2e: {
|
|
||||||
executor: '@nx/cypress:cypress',
|
|
||||||
options: {
|
|
||||||
testingType: 'e2e',
|
|
||||||
cypressConfig: `apps/${options.name}/cypress.config.ts`,
|
|
||||||
devServerTarget: 'app:serve',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'component-test': {
|
|
||||||
executor: '@nx/cypress:cypress',
|
|
||||||
options: {
|
|
||||||
testingType: 'component',
|
|
||||||
cypressConfig: `apps/${options.name}/ct-cypress.config.ts`,
|
|
||||||
skipServe: true,
|
|
||||||
devServerTarget: 'app:build',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@ -1,246 +0,0 @@
|
|||||||
import {
|
|
||||||
updateJson,
|
|
||||||
installPackagesTask,
|
|
||||||
getProjects,
|
|
||||||
visitNotIgnoredFiles,
|
|
||||||
formatFiles,
|
|
||||||
type Tree,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import { installedCypressVersion } from '../../utils/cypress-version';
|
|
||||||
import {
|
|
||||||
isObjectLiteralExpression,
|
|
||||||
isCallExpression,
|
|
||||||
type CallExpression,
|
|
||||||
type MethodDeclaration,
|
|
||||||
type PropertyAccessExpression,
|
|
||||||
type PropertyAssignment,
|
|
||||||
} from 'typescript';
|
|
||||||
import { tsquery } from '@phenomnomnominal/tsquery';
|
|
||||||
import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils';
|
|
||||||
import type { CypressExecutorOptions } from '../../executors/cypress/cypress.impl';
|
|
||||||
|
|
||||||
const JS_TS_FILE_MATCHER = /\.[jt]sx?$/;
|
|
||||||
|
|
||||||
export async function updateToCypress13(tree: Tree) {
|
|
||||||
if (installedCypressVersion() < 12) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const projects = getProjects(tree);
|
|
||||||
|
|
||||||
forEachExecutorOptions<CypressExecutorOptions>(
|
|
||||||
tree,
|
|
||||||
'@nx/cypress:cypress',
|
|
||||||
(options, projectName) => {
|
|
||||||
if (!options.cypressConfig || !tree.exists(options.cypressConfig)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const projectConfig = projects.get(projectName);
|
|
||||||
|
|
||||||
removeNodeVersionOption(tree, options.cypressConfig);
|
|
||||||
removeVideoUploadOnPassesOption(tree, options.cypressConfig);
|
|
||||||
|
|
||||||
visitNotIgnoredFiles(tree, projectConfig.root, (filePath) => {
|
|
||||||
if (!JS_TS_FILE_MATCHER.test(filePath)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
shouldNotOverrideReadFile(tree, filePath);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
updateJson(tree, 'package.json', (json) => {
|
|
||||||
json.devDependencies ??= {};
|
|
||||||
json.devDependencies.cypress = '^13.0.0';
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeVideoUploadOnPassesOption(tree: Tree, configPath: string) {
|
|
||||||
const config = tree.read(configPath, 'utf-8');
|
|
||||||
const isUsingDeprecatedOption =
|
|
||||||
tsquery.query(config, getPropertyQuery('videoUploadOnPasses'))?.length > 0;
|
|
||||||
|
|
||||||
if (!isUsingDeprecatedOption) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const importStatement = configPath.endsWith('.ts')
|
|
||||||
? "import fs from 'fs';"
|
|
||||||
: "const fs = require('fs');";
|
|
||||||
|
|
||||||
const replacementFunction = `/**
|
|
||||||
* Delete videos for specs that do not contain failing or retried tests.
|
|
||||||
* This function is to be used in the 'setupNodeEvents' configuration option as a replacement to
|
|
||||||
* 'videoUploadOnPasses' which has been removed.
|
|
||||||
*
|
|
||||||
* https://docs.cypress.io/guides/guides/screenshots-and-videos#Delete-videos-for-specs-without-failing-or-retried-tests
|
|
||||||
**/
|
|
||||||
function removePassedSpecs(on) {
|
|
||||||
on('after:spec', (spec, results) => {
|
|
||||||
if(results && results.vide) {
|
|
||||||
const hasFailures = results.tests.some(t => t.attempts.some(a => a.state === 'failed'));
|
|
||||||
|
|
||||||
if(!hasFailures) {
|
|
||||||
fs.unlinkSync(results.video);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}`;
|
|
||||||
|
|
||||||
const withReplacementFn = `${importStatement}\n${config}\n${replacementFunction}`;
|
|
||||||
|
|
||||||
// setupNodeEvents can be a property or method.
|
|
||||||
const setupNodeEventsQuery =
|
|
||||||
'ExportAssignment ObjectLiteralExpression > :matches(PropertyAssignment:has(Identifier[name="setupNodeEvents"]), MethodDeclaration:has(Identifier[name="setupNodeEvents"]))';
|
|
||||||
|
|
||||||
const hasSetupNodeEvents =
|
|
||||||
tsquery.query(withReplacementFn, setupNodeEventsQuery)?.length > 0;
|
|
||||||
|
|
||||||
let updatedWithSetupNodeEvents = withReplacementFn;
|
|
||||||
if (hasSetupNodeEvents) {
|
|
||||||
// if have setupNodeEvents, update existing fn to use removePassedSpecs helper and remove videoUploadOnPasses
|
|
||||||
const noVideoUploadOption = tsquery.replace(
|
|
||||||
withReplacementFn,
|
|
||||||
getPropertyQuery('videoUploadOnPasses'),
|
|
||||||
(node: PropertyAssignment) => {
|
|
||||||
if (isObjectLiteralExpression(node.initializer)) {
|
|
||||||
// is a nested config object
|
|
||||||
const key = node.name.getText().trim();
|
|
||||||
const listOfProperties = node.initializer.properties
|
|
||||||
.map((j) => j.getText())
|
|
||||||
.filter((j) => !j.includes('videoUploadOnPasses'))
|
|
||||||
.join(',\n');
|
|
||||||
|
|
||||||
return `${key}: {
|
|
||||||
${listOfProperties}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
} else {
|
|
||||||
if (isPropertyTopLevel(node)) {
|
|
||||||
return `// ${node.getText()} `;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
updatedWithSetupNodeEvents = tsquery.replace(
|
|
||||||
noVideoUploadOption,
|
|
||||||
`${setupNodeEventsQuery} Block`,
|
|
||||||
(node: PropertyAssignment | MethodDeclaration) => {
|
|
||||||
const blockWithoutBraces = node
|
|
||||||
.getFullText()
|
|
||||||
.trim()
|
|
||||||
.slice(1, -1)
|
|
||||||
.trim();
|
|
||||||
return `{
|
|
||||||
${blockWithoutBraces}
|
|
||||||
removePassedSpecs(on);
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
},
|
|
||||||
{ visitAllChildren: false }
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// if don't have setupNodeEvents, replace videoUploadOnPasses with setupNodeEvents method
|
|
||||||
updatedWithSetupNodeEvents = tsquery.replace(
|
|
||||||
withReplacementFn,
|
|
||||||
getPropertyQuery('videoUploadOnPasses'),
|
|
||||||
() => {
|
|
||||||
return `setupNodeEvents(on, config) {
|
|
||||||
removePassedSpecs(on);
|
|
||||||
}`;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
tree.write(configPath, updatedWithSetupNodeEvents);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* remove the nodeVersion option from the config file
|
|
||||||
**/
|
|
||||||
function removeNodeVersionOption(tree: Tree, configPath: string) {
|
|
||||||
const config = tree.read(configPath, 'utf-8');
|
|
||||||
|
|
||||||
const updated = tsquery.replace(
|
|
||||||
config,
|
|
||||||
getPropertyQuery('nodeVersion'),
|
|
||||||
(node: PropertyAssignment) => {
|
|
||||||
if (isObjectLiteralExpression(node.initializer)) {
|
|
||||||
// is a nested config object
|
|
||||||
const key = node.name.getText().trim();
|
|
||||||
const listOfProperties = node.initializer.properties
|
|
||||||
.map((j) => j.getFullText())
|
|
||||||
.filter((j) => !j.includes('nodeVersion'))
|
|
||||||
.join(', ');
|
|
||||||
return `${key}: {
|
|
||||||
${listOfProperties}
|
|
||||||
}`;
|
|
||||||
} else {
|
|
||||||
if (isPropertyTopLevel(node)) {
|
|
||||||
return `// ${node.getText()}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (updated !== config) {
|
|
||||||
tree.write(configPath, updated);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* leave a comment on all usages of overriding built-ins that are now banned
|
|
||||||
**/
|
|
||||||
export function shouldNotOverrideReadFile(tree: Tree, filePath: string) {
|
|
||||||
const content = tree.read(filePath, 'utf-8');
|
|
||||||
const markedOverrideUsage = tsquery.replace(
|
|
||||||
content,
|
|
||||||
'PropertyAccessExpression:has(Identifier[name="overwrite"]):has(Identifier[name="Cypress"])',
|
|
||||||
(node: PropertyAccessExpression) => {
|
|
||||||
if (isAlreadyCommented(node)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const expression = node.expression.getText().trim();
|
|
||||||
// prevent grabbing other Cypress.<something>.defaults
|
|
||||||
|
|
||||||
if (expression === 'Cypress.Commands') {
|
|
||||||
// get value.
|
|
||||||
const overwriteExpression = node.parent as CallExpression;
|
|
||||||
|
|
||||||
const command = (overwriteExpression.arguments?.[0] as any)?.text; // need string without quotes
|
|
||||||
if (command === 'readFile') {
|
|
||||||
// overwrite
|
|
||||||
return `/**
|
|
||||||
* TODO(@nx/cypress): This command can no longer be overridden
|
|
||||||
* Consider using a different name like 'custom_${command}'
|
|
||||||
* More info: https://docs.cypress.io/guides/references/migration-guide#readFile-can-no-longer-be-overwritten-with-CypressCommandsoverwrite
|
|
||||||
**/
|
|
||||||
${node.getText()}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
tree.write(filePath, markedOverrideUsage);
|
|
||||||
}
|
|
||||||
|
|
||||||
function isAlreadyCommented(node: PropertyAccessExpression) {
|
|
||||||
return node.getFullText().includes('TODO(@nx/cypress)');
|
|
||||||
}
|
|
||||||
|
|
||||||
function isPropertyTopLevel(node: PropertyAssignment) {
|
|
||||||
return (
|
|
||||||
node.parent &&
|
|
||||||
isObjectLiteralExpression(node.parent) &&
|
|
||||||
node.parent.parent &&
|
|
||||||
isCallExpression(node.parent.parent)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const getPropertyQuery = (propertyName: string) =>
|
|
||||||
`ExportAssignment ObjectLiteralExpression > PropertyAssignment:has(Identifier[name="${propertyName}"])`;
|
|
||||||
|
|
||||||
export default updateToCypress13;
|
|
||||||
@ -1,69 +1,6 @@
|
|||||||
{
|
{
|
||||||
"generators": {
|
"generators": {},
|
||||||
"update-16-0-0-add-nx-packages": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.0.0-beta.1",
|
|
||||||
"description": "Replace @nrwl/detox with @nx/detox",
|
|
||||||
"implementation": "./src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages"
|
|
||||||
},
|
|
||||||
"update-16-0-0-update-detoxrc": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.0.0-beta.3",
|
|
||||||
"description": "Update .detoxrc.json and jest.config.json for detox 20",
|
|
||||||
"implementation": "./src/migrations/update-16-0-0/update-detoxrc-json"
|
|
||||||
},
|
|
||||||
"update-detoxrc-json-expo-16-1-4": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.1.4-beta.0",
|
|
||||||
"description": "Update .detoxrc.json for expo",
|
|
||||||
"implementation": "./src/migrations/update-16-1-4/update-detoxrc-json-expo"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"packageJsonUpdates": {
|
"packageJsonUpdates": {
|
||||||
"16.0.0": {
|
|
||||||
"version": "16.0.0-beta.3",
|
|
||||||
"packages": {
|
|
||||||
"detox": {
|
|
||||||
"version": "~20.7.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.1.1": {
|
|
||||||
"version": "16.1.1-beta.0",
|
|
||||||
"packages": {
|
|
||||||
"detox": {
|
|
||||||
"version": "~20.8.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@config-plugins/detox": {
|
|
||||||
"version": "~5.0.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.1.5": {
|
|
||||||
"version": "16.1.5-beta.0",
|
|
||||||
"packages": {
|
|
||||||
"detox": {
|
|
||||||
"version": "^20.9.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.6.0": {
|
|
||||||
"version": "16.6.0-beta.6",
|
|
||||||
"packages": {
|
|
||||||
"detox": {
|
|
||||||
"version": "^20.11.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@config-plugins/detox": {
|
|
||||||
"version": "~6.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"18.0.0": {
|
"18.0.0": {
|
||||||
"version": "18.0.0-beta.0",
|
"version": "18.0.0-beta.0",
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
import { Tree, readJson, updateJson } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import replacePackage from './update-16-0-0-add-nx-packages';
|
|
||||||
|
|
||||||
describe('update-16-0-0-add-nx-packages', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
|
|
||||||
updateJson(tree, 'package.json', (json) => {
|
|
||||||
json.devDependencies['@nrwl/detox'] = '16.0.0';
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the dependency on @nrwl/detox', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').dependencies['@nrwl/detox']
|
|
||||||
).not.toBeDefined();
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nrwl/detox']
|
|
||||||
).not.toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add a dependency on @nx/detox', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
const packageJson = readJson(tree, 'package.json');
|
|
||||||
const newDependencyVersion =
|
|
||||||
packageJson.devDependencies['@nx/detox'] ??
|
|
||||||
packageJson.dependencies['@nx/detox'];
|
|
||||||
|
|
||||||
expect(newDependencyVersion).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import { Tree, formatFiles } from '@nx/devkit';
|
|
||||||
import { replaceNrwlPackageWithNxPackage } from '@nx/devkit/src/utils/replace-package';
|
|
||||||
|
|
||||||
export default async function replacePackage(tree: Tree): Promise<void> {
|
|
||||||
replaceNrwlPackageWithNxPackage(tree, '@nrwl/detox', '@nx/detox');
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
import { addProjectConfiguration, readJson, Tree } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
|
|
||||||
import update from './update-detoxrc-json';
|
|
||||||
|
|
||||||
describe('Update detoxrc for detox 20', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
||||||
addProjectConfiguration(tree, 'products', {
|
|
||||||
root: 'apps/products',
|
|
||||||
sourceRoot: 'apps/products/src',
|
|
||||||
targets: {
|
|
||||||
'test-ios': {
|
|
||||||
executor: '@nx/detox:test',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
tree.write('apps/products/jest.config.json', `{"transform": {}}`);
|
|
||||||
tree.write('apps/products/.detoxrc.json', '{}');
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should update jest.config.json`, async () => {
|
|
||||||
await update(tree);
|
|
||||||
|
|
||||||
const jestConfig = readJson(tree, 'apps/products/jest.config.json');
|
|
||||||
expect(jestConfig).toEqual({
|
|
||||||
rootDir: '.',
|
|
||||||
testMatch: [
|
|
||||||
'<rootDir>/src/**/*.test.ts?(x)',
|
|
||||||
'<rootDir>/src/**/*.spec.ts?(x)',
|
|
||||||
],
|
|
||||||
globalSetup: 'detox/runners/jest/globalSetup',
|
|
||||||
globalTeardown: 'detox/runners/jest/globalTeardown',
|
|
||||||
reporter: ['detox/runners/jest/reporter'],
|
|
||||||
verbose: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should update .detoxrc.json`, async () => {
|
|
||||||
await update(tree);
|
|
||||||
|
|
||||||
const detoxrcJson = readJson(tree, 'apps/products/.detoxrc.json');
|
|
||||||
expect(detoxrcJson).toEqual({
|
|
||||||
testRunner: {
|
|
||||||
args: {
|
|
||||||
$0: 'jest',
|
|
||||||
config: './jest.config.json',
|
|
||||||
},
|
|
||||||
jest: {
|
|
||||||
setupTimeout: 120000,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,71 +0,0 @@
|
|||||||
import {
|
|
||||||
Tree,
|
|
||||||
formatFiles,
|
|
||||||
getProjects,
|
|
||||||
updateJson,
|
|
||||||
ProjectConfiguration,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update .detoxrc.json under detox project:
|
|
||||||
* - remove deprecated keys: testRunner
|
|
||||||
* - update keys: runnerConfig
|
|
||||||
* Update jest.config.json under detox project:
|
|
||||||
* - remove key: transform
|
|
||||||
* - add key: rootDir, testMatch, reporter, globalSetup, globalTeardown, verbose
|
|
||||||
*/
|
|
||||||
export default async function update(tree: Tree) {
|
|
||||||
const projects = getProjects(tree);
|
|
||||||
|
|
||||||
projects.forEach((project) => {
|
|
||||||
if (project.targets?.['test-ios']?.executor !== '@nx/detox:test') return;
|
|
||||||
updateDetoxrcJson(tree, project);
|
|
||||||
updateJestConfigJson(tree, project);
|
|
||||||
});
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateDetoxrcJson(host: Tree, project: ProjectConfiguration) {
|
|
||||||
const detoxConfigPath = `${project.root}/.detoxrc.json`;
|
|
||||||
if (!host.exists(detoxConfigPath)) return;
|
|
||||||
updateJson(host, detoxConfigPath, (json) => {
|
|
||||||
json.testRunner = {
|
|
||||||
args: {
|
|
||||||
$0: 'jest',
|
|
||||||
config: './jest.config.json',
|
|
||||||
},
|
|
||||||
jest: {
|
|
||||||
setupTimeout: 120000,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
if (json.runnerConfig) {
|
|
||||||
delete json.runnerConfig;
|
|
||||||
}
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateJestConfigJson(host: Tree, project: ProjectConfiguration) {
|
|
||||||
const jestConfigPath = `${project.root}/jest.config.json`;
|
|
||||||
if (!host.exists(jestConfigPath)) return;
|
|
||||||
updateJson(host, jestConfigPath, (json) => {
|
|
||||||
if (json.transform) {
|
|
||||||
delete json.transform;
|
|
||||||
}
|
|
||||||
if (!json.rootDir) {
|
|
||||||
json.rootDir = '.';
|
|
||||||
}
|
|
||||||
if (!json.testMatch) {
|
|
||||||
json.testMatch = [
|
|
||||||
'<rootDir>/src/**/*.test.ts?(x)',
|
|
||||||
'<rootDir>/src/**/*.spec.ts?(x)',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
json.reporter = ['detox/runners/jest/reporter'];
|
|
||||||
json.globalSetup = 'detox/runners/jest/globalSetup';
|
|
||||||
json.globalTeardown = 'detox/runners/jest/globalTeardown';
|
|
||||||
json.verbose = true;
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@ -1,127 +0,0 @@
|
|||||||
import { addProjectConfiguration, readJson, Tree } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
|
|
||||||
import update from './update-detoxrc-json-expo';
|
|
||||||
|
|
||||||
describe('Update detoxrc for expo projects', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
||||||
addProjectConfiguration(tree, 'products', {
|
|
||||||
root: 'apps/products',
|
|
||||||
sourceRoot: 'apps/products/src',
|
|
||||||
targets: {
|
|
||||||
'test-ios': {
|
|
||||||
executor: '@nx/detox:test',
|
|
||||||
options: {
|
|
||||||
detoxConfiguration: 'ios.sim.eas',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'build-ios': {
|
|
||||||
executor: '@nx/detox:build',
|
|
||||||
options: {
|
|
||||||
detoxConfiguration: 'random value',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'test-android': {
|
|
||||||
executor: '@nx/detox:test',
|
|
||||||
options: {
|
|
||||||
detoxConfiguration: 'android.sim.eas',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'build-android': {
|
|
||||||
executor: '@nx/detox:build',
|
|
||||||
options: {
|
|
||||||
detoxConfiguration: 'random value',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
tree.write('apps/products/jest.config.json', `{"transform": {}}`);
|
|
||||||
tree.write(
|
|
||||||
'apps/products/.detoxrc.json',
|
|
||||||
`{"apps": {"ios.eas": {}, "android.eas": {}, "ios.local": {}, "android.local": {}}}`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should update .detoxrc.json`, async () => {
|
|
||||||
await update(tree);
|
|
||||||
|
|
||||||
const detoxrcJson = readJson(tree, 'apps/products/.detoxrc.json');
|
|
||||||
expect(detoxrcJson).toEqual({
|
|
||||||
apps: {
|
|
||||||
'ios.eas': {
|
|
||||||
build:
|
|
||||||
'npx nx run products:download --platform ios --distribution simulator --output=../../apps/products/dist/',
|
|
||||||
},
|
|
||||||
'android.eas': {
|
|
||||||
build:
|
|
||||||
'npx nx run products:download --platform android --distribution simulator --output=../../apps/products/dist/',
|
|
||||||
type: 'android.apk',
|
|
||||||
},
|
|
||||||
'ios.local': {
|
|
||||||
build:
|
|
||||||
'npx nx run products:build --platform ios --profile preview --wait --local --no-interactive --output=../../apps/products/dist/Products.tar.gz',
|
|
||||||
},
|
|
||||||
'android.local': {
|
|
||||||
build:
|
|
||||||
'npx nx run products:build --platform android --profile preview --wait --local --no-interactive --output=../../apps/products/dist/Products.apk',
|
|
||||||
type: 'android.apk',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should update project.json`, async () => {
|
|
||||||
await update(tree);
|
|
||||||
|
|
||||||
const projectJson = readJson(tree, 'apps/products/project.json');
|
|
||||||
expect(projectJson).toEqual({
|
|
||||||
$schema: '../../node_modules/nx/schemas/project-schema.json',
|
|
||||||
name: 'products',
|
|
||||||
sourceRoot: 'apps/products/src',
|
|
||||||
targets: {
|
|
||||||
'build-android': {
|
|
||||||
executor: '@nx/detox:build',
|
|
||||||
options: {
|
|
||||||
detoxConfiguration: 'android.sim.eas',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'build-ios': {
|
|
||||||
executor: '@nx/detox:build',
|
|
||||||
options: {
|
|
||||||
detoxConfiguration: 'ios.sim.eas',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'test-android': {
|
|
||||||
configurations: {
|
|
||||||
bare: {
|
|
||||||
buildTarget: 'products:build-android:bare',
|
|
||||||
detoxConfiguration: 'android.emu.debug',
|
|
||||||
},
|
|
||||||
local: {
|
|
||||||
buildTarget: 'products:build-android:local',
|
|
||||||
detoxConfiguration: 'android.emu.local',
|
|
||||||
},
|
|
||||||
production: {
|
|
||||||
buildTarget: 'products:build-android:production',
|
|
||||||
detoxConfiguration: 'android.emu.release',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
executor: '@nx/detox:test',
|
|
||||||
options: {
|
|
||||||
buildTarget: 'products:build-android',
|
|
||||||
detoxConfiguration: 'android.sim.eas',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'test-ios': {
|
|
||||||
executor: '@nx/detox:test',
|
|
||||||
options: {
|
|
||||||
detoxConfiguration: 'ios.sim.eas',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,104 +0,0 @@
|
|||||||
import {
|
|
||||||
Tree,
|
|
||||||
formatFiles,
|
|
||||||
getProjects,
|
|
||||||
updateJson,
|
|
||||||
ProjectConfiguration,
|
|
||||||
offsetFromRoot,
|
|
||||||
detectPackageManager,
|
|
||||||
getPackageManagerCommand,
|
|
||||||
names,
|
|
||||||
updateProjectConfiguration,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update .detoxrc.json under detox project for expo:
|
|
||||||
* - fix the eas build command
|
|
||||||
* - fix the local build command
|
|
||||||
* - update project.json targets
|
|
||||||
*/
|
|
||||||
export default async function update(tree: Tree) {
|
|
||||||
const projects = getProjects(tree);
|
|
||||||
|
|
||||||
projects.forEach((project) => {
|
|
||||||
if (project.targets?.['test-ios']?.executor !== '@nx/detox:test') return;
|
|
||||||
updateDetoxrcJson(tree, project);
|
|
||||||
updateProjectJson(tree, project);
|
|
||||||
});
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateDetoxrcJson(host: Tree, project: ProjectConfiguration) {
|
|
||||||
const detoxConfigPath = `${project.root}/.detoxrc.json`;
|
|
||||||
const projectName = project.name?.endsWith('-e2e')
|
|
||||||
? project.name.substring(0, project.name.indexOf('-e2e'))
|
|
||||||
: project.name;
|
|
||||||
const appRoot = getProjects(host).get(projectName)?.root;
|
|
||||||
const appName = names(projectName).className;
|
|
||||||
const offset = offsetFromRoot(project.root);
|
|
||||||
const exec = getPackageManagerCommand(detectPackageManager(host.root)).exec;
|
|
||||||
if (!host.exists(detoxConfigPath)) return;
|
|
||||||
updateJson(host, detoxConfigPath, (json) => {
|
|
||||||
if (json.apps?.['ios.eas']) {
|
|
||||||
json.apps[
|
|
||||||
'ios.eas'
|
|
||||||
].build = `${exec} nx run ${projectName}:download --platform ios --distribution simulator --output=${offset}${appRoot}/dist/`;
|
|
||||||
}
|
|
||||||
if (json.apps?.['android.eas']) {
|
|
||||||
json.apps[
|
|
||||||
'android.eas'
|
|
||||||
].build = `${exec} nx run ${projectName}:download --platform android --distribution simulator --output=${offset}${appRoot}/dist/`;
|
|
||||||
json.apps['android.eas'].type = 'android.apk';
|
|
||||||
}
|
|
||||||
if (json.apps?.['ios.local']) {
|
|
||||||
json.apps[
|
|
||||||
'ios.local'
|
|
||||||
].build = `${exec} nx run ${projectName}:build --platform ios --profile preview --wait --local --no-interactive --output=${offset}${appRoot}/dist/${appName}.tar.gz`;
|
|
||||||
}
|
|
||||||
if (json.apps?.['android.local']) {
|
|
||||||
json.apps[
|
|
||||||
'android.local'
|
|
||||||
].build = `${exec} nx run ${projectName}:build --platform android --profile preview --wait --local --no-interactive --output=${offset}${appRoot}/dist/${appName}.apk`;
|
|
||||||
json.apps['android.local'].type = 'android.apk';
|
|
||||||
}
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateProjectJson(host: Tree, project: ProjectConfiguration) {
|
|
||||||
if (
|
|
||||||
project.targets?.['test-ios']?.options?.detoxConfiguration == 'ios.sim.eas'
|
|
||||||
) {
|
|
||||||
project.targets['build-ios'].options.detoxConfiguration = 'ios.sim.eas';
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
project.targets?.['test-android']?.options?.detoxConfiguration ==
|
|
||||||
'android.sim.eas'
|
|
||||||
) {
|
|
||||||
project.targets['build-android'].options.detoxConfiguration =
|
|
||||||
'android.sim.eas';
|
|
||||||
project.targets['test-android'] = {
|
|
||||||
executor: '@nx/detox:test',
|
|
||||||
options: {
|
|
||||||
detoxConfiguration: 'android.sim.eas',
|
|
||||||
buildTarget: `${project.name}:build-android`,
|
|
||||||
},
|
|
||||||
configurations: {
|
|
||||||
local: {
|
|
||||||
detoxConfiguration: 'android.emu.local',
|
|
||||||
buildTarget: `${project.name}:build-android:local`,
|
|
||||||
},
|
|
||||||
bare: {
|
|
||||||
detoxConfiguration: 'android.emu.debug',
|
|
||||||
buildTarget: `${project.name}:build-android:bare`,
|
|
||||||
},
|
|
||||||
production: {
|
|
||||||
detoxConfiguration: 'android.emu.release',
|
|
||||||
buildTarget: `${project.name}:build-android:production`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
updateProjectConfiguration(host, project.name, project);
|
|
||||||
}
|
|
||||||
@ -1,18 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generators": {
|
"generators": {},
|
||||||
"update-16-0-0-add-nx-packages": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.0.0-beta.1",
|
|
||||||
"description": "Replace @nrwl/devkit with @nx/devkit",
|
|
||||||
"implementation": "./src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages"
|
|
||||||
},
|
|
||||||
"update-16-9-0-migrate-mf-usage-to-webpack": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.9.0-beta.1",
|
|
||||||
"description": "Replace imports of Module Federation utils frm @nx/devkit to @nx/webpack",
|
|
||||||
"implementation": "./src/migrations/update-16-9-0/migrate-mf-util-usage"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"packageJsonUpdates": {},
|
"packageJsonUpdates": {},
|
||||||
"version": "0.1"
|
"version": "0.1"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,41 +0,0 @@
|
|||||||
import { assertRunsAgainstNxRepo } from 'nx/src/internal-testing-utils/run-migration-against-this-workspace';
|
|
||||||
import { createTreeWithEmptyWorkspace } from 'nx/src/generators/testing-utils/create-tree-with-empty-workspace';
|
|
||||||
import { Tree } from 'nx/src/generators/tree';
|
|
||||||
import { readJson, updateJson } from 'nx/src/generators/utils/json';
|
|
||||||
import replacePackage from './update-16-0-0-add-nx-packages';
|
|
||||||
|
|
||||||
describe('update-16-0-0-add-nx-packages', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
|
|
||||||
updateJson(tree, 'package.json', (json) => {
|
|
||||||
json.devDependencies['@nrwl/devkit'] = '16.0.0';
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the dependency on @nrwl/devkit', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').dependencies['@nrwl/devkit']
|
|
||||||
).not.toBeDefined();
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nrwl/devkit']
|
|
||||||
).not.toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add a dependency on @nx/devkit', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
const packageJson = readJson(tree, 'package.json');
|
|
||||||
const newDependencyVersion =
|
|
||||||
packageJson.devDependencies['@nx/devkit'] ??
|
|
||||||
packageJson.dependencies['@nx/devkit'];
|
|
||||||
|
|
||||||
expect(newDependencyVersion).toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
assertRunsAgainstNxRepo(replacePackage);
|
|
||||||
});
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
import type { Tree } from 'nx/src/devkit-exports';
|
|
||||||
import { formatFiles } from '../../generators/format-files';
|
|
||||||
import { replaceNrwlPackageWithNxPackage } from '../../utils/replace-package';
|
|
||||||
|
|
||||||
export default async function replacePackage(tree: Tree): Promise<void> {
|
|
||||||
await replaceNrwlPackageWithNxPackage(tree, '@nrwl/devkit', '@nx/devkit');
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,231 +0,0 @@
|
|||||||
import { createTreeWithEmptyWorkspace } from 'nx/src/generators/testing-utils/create-tree-with-empty-workspace';
|
|
||||||
import { stripIndents } from 'nx/src/utils/strip-indents';
|
|
||||||
import { readJson } from 'nx/src/generators/utils/json';
|
|
||||||
|
|
||||||
import migrateMfUtilUsage from './migrate-mf-util-usage';
|
|
||||||
|
|
||||||
describe('migrate-mf-util-usage', () => {
|
|
||||||
it('should do nothing if it does not find files using the mf public api', async () => {
|
|
||||||
// ARRANGE
|
|
||||||
const testFileContents = `${stripIndents`import { readFileSync } from 'fs';
|
|
||||||
const file = readFileSync('test.ts');`}\n`;
|
|
||||||
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
tree.write('test.ts', testFileContents);
|
|
||||||
|
|
||||||
// ACT
|
|
||||||
await migrateMfUtilUsage(tree);
|
|
||||||
|
|
||||||
// ASSERT
|
|
||||||
expect(tree.read('test.ts', 'utf-8')).toEqual(testFileContents);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should do nothing if it does not find files using the mf public api even if they use devkit', async () => {
|
|
||||||
// ARRANGE
|
|
||||||
const testFileContents = `${stripIndents`import { readJson } from '@nx/devkit';
|
|
||||||
const file = readJson('test.json');`}\n`;
|
|
||||||
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
tree.write('test.ts', testFileContents);
|
|
||||||
|
|
||||||
// ACT
|
|
||||||
await migrateMfUtilUsage(tree);
|
|
||||||
|
|
||||||
// ASSERT
|
|
||||||
expect(tree.read('test.ts', 'utf-8')).toEqual(testFileContents);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should replace imports to utils from devkit with webpack', async () => {
|
|
||||||
// ARRANGE
|
|
||||||
const testFileContents = stripIndents`import {ModuleFederationConfig} from '@nx/devkit';
|
|
||||||
const config: ModuleFederationConfig = {};
|
|
||||||
`;
|
|
||||||
const expectedTestFileContents = `${stripIndents`import { ModuleFederationConfig } from '@nx/webpack';
|
|
||||||
const config: ModuleFederationConfig = {};`}\n`;
|
|
||||||
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
tree.write('test.ts', testFileContents);
|
|
||||||
|
|
||||||
// ACT
|
|
||||||
await migrateMfUtilUsage(tree);
|
|
||||||
|
|
||||||
// ASSERT
|
|
||||||
expect(tree.read('test.ts', 'utf-8')).toEqual(expectedTestFileContents);
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nx/webpack']
|
|
||||||
).toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should extract imports to utils from devkit and replace with imports from webpack', async () => {
|
|
||||||
// ARRANGE
|
|
||||||
const testFileContents = stripIndents`import {joinPathFragments, ModuleFederationConfig} from '@nx/devkit';
|
|
||||||
const config: ModuleFederationConfig = {};
|
|
||||||
`;
|
|
||||||
const expectedTestFileContents = `${stripIndents`import { joinPathFragments } from '@nx/devkit';
|
|
||||||
import { ModuleFederationConfig } from '@nx/webpack';
|
|
||||||
const config: ModuleFederationConfig = {};`}\n`;
|
|
||||||
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
tree.write('test.ts', testFileContents);
|
|
||||||
|
|
||||||
// ACT
|
|
||||||
await migrateMfUtilUsage(tree);
|
|
||||||
|
|
||||||
// ASSERT
|
|
||||||
expect(tree.read('test.ts', 'utf-8')).toEqual(expectedTestFileContents);
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nx/webpack']
|
|
||||||
).toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should extract imports to utils from devkit and replace with imports from webpack, even with multiple devkit imports', async () => {
|
|
||||||
// ARRANGE
|
|
||||||
const testFileContents = stripIndents`import {joinPathFragments, ModuleFederationConfig} from '@nx/devkit';
|
|
||||||
import {readJson, WorkspaceLibrary} from '@nx/devkit';
|
|
||||||
const config: ModuleFederationConfig = {};
|
|
||||||
`;
|
|
||||||
const expectedTestFileContents = `${stripIndents`import { joinPathFragments } from '@nx/devkit';
|
|
||||||
import { readJson } from '@nx/devkit';
|
|
||||||
import { ModuleFederationConfig, WorkspaceLibrary } from '@nx/webpack';
|
|
||||||
const config: ModuleFederationConfig = {};`}\n`;
|
|
||||||
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
tree.write('test.ts', testFileContents);
|
|
||||||
|
|
||||||
// ACT
|
|
||||||
await migrateMfUtilUsage(tree);
|
|
||||||
|
|
||||||
// ASSERT
|
|
||||||
expect(tree.read('test.ts', 'utf-8')).toEqual(expectedTestFileContents);
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nx/webpack']
|
|
||||||
).toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('require()', () => {
|
|
||||||
it('should do nothing if it does not find files using the mf public api', async () => {
|
|
||||||
// ARRANGE
|
|
||||||
const testFileContents = `${stripIndents`const { readFileSync } = require('fs');
|
|
||||||
const file = readFileSync('test.ts');`}\n`;
|
|
||||||
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
tree.write('test.ts', testFileContents);
|
|
||||||
|
|
||||||
// ACT
|
|
||||||
await migrateMfUtilUsage(tree);
|
|
||||||
|
|
||||||
// ASSERT
|
|
||||||
expect(tree.read('test.ts', 'utf-8')).toEqual(testFileContents);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should do nothing if it does not find files using the mf public api even if they use devkit', async () => {
|
|
||||||
// ARRANGE
|
|
||||||
const testFileContents = `${stripIndents`const { readJson } = require('@nx/devkit');
|
|
||||||
const file = readJson('test.json');`}\n`;
|
|
||||||
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
tree.write('test.ts', testFileContents);
|
|
||||||
|
|
||||||
// ACT
|
|
||||||
await migrateMfUtilUsage(tree);
|
|
||||||
|
|
||||||
// ASSERT
|
|
||||||
expect(tree.read('test.ts', 'utf-8')).toEqual(testFileContents);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should replace imports to utils from devkit with webpack', async () => {
|
|
||||||
// ARRANGE
|
|
||||||
const testFileContents = stripIndents`const {ModuleFederationConfig} = require('@nx/devkit');
|
|
||||||
const config: ModuleFederationConfig = {};
|
|
||||||
`;
|
|
||||||
const expectedTestFileContents = `${stripIndents`const { ModuleFederationConfig } = require('@nx/webpack');
|
|
||||||
const config: ModuleFederationConfig = {};`}\n`;
|
|
||||||
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
tree.write('test.ts', testFileContents);
|
|
||||||
|
|
||||||
// ACT
|
|
||||||
await migrateMfUtilUsage(tree);
|
|
||||||
|
|
||||||
// ASSERT
|
|
||||||
expect(tree.read('test.ts', 'utf-8')).toEqual(expectedTestFileContents);
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nx/webpack']
|
|
||||||
).toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should extract imports to utils from devkit and replace with imports from webpack', async () => {
|
|
||||||
// ARRANGE
|
|
||||||
const testFileContents = stripIndents`const {joinPathFragments, ModuleFederationConfig} = require("@nx/devkit");
|
|
||||||
const config: ModuleFederationConfig = {};
|
|
||||||
`;
|
|
||||||
const expectedTestFileContents = `${stripIndents`const { joinPathFragments } = require('@nx/devkit');
|
|
||||||
const { ModuleFederationConfig } = require('@nx/webpack');
|
|
||||||
const config: ModuleFederationConfig = {};`}\n`;
|
|
||||||
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
tree.write('test.ts', testFileContents);
|
|
||||||
|
|
||||||
// ACT
|
|
||||||
await migrateMfUtilUsage(tree);
|
|
||||||
|
|
||||||
// ASSERT
|
|
||||||
expect(tree.read('test.ts', 'utf-8')).toEqual(expectedTestFileContents);
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nx/webpack']
|
|
||||||
).toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should extract imports to utils from devkit and replace with imports from webpack, even with multiple devkit imports', async () => {
|
|
||||||
// ARRANGE
|
|
||||||
const testFileContents = stripIndents`const {joinPathFragments, ModuleFederationConfig} = require('@nx/devkit');
|
|
||||||
const {readJson, WorkspaceLibrary} = require('@nx/devkit');
|
|
||||||
const config: ModuleFederationConfig = {};
|
|
||||||
`;
|
|
||||||
const expectedTestFileContents = `${stripIndents`const { joinPathFragments } = require('@nx/devkit');
|
|
||||||
const { readJson } = require('@nx/devkit');
|
|
||||||
const { ModuleFederationConfig, WorkspaceLibrary } = require('@nx/webpack');
|
|
||||||
const config: ModuleFederationConfig = {};`}\n`;
|
|
||||||
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
tree.write('test.ts', testFileContents);
|
|
||||||
|
|
||||||
// ACT
|
|
||||||
await migrateMfUtilUsage(tree);
|
|
||||||
|
|
||||||
// ASSERT
|
|
||||||
expect(tree.read('test.ts', 'utf-8')).toEqual(expectedTestFileContents);
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nx/webpack']
|
|
||||||
).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should replace imports to utils from devkit with webpack in JSDoc comments', async () => {
|
|
||||||
// ARRANGE
|
|
||||||
const testFileContents = stripIndents`
|
|
||||||
/**
|
|
||||||
* @type {import('@nx/devkit').ModuleFederationConfig}
|
|
||||||
**/
|
|
||||||
const config = {};
|
|
||||||
`;
|
|
||||||
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
tree.write('test.js', testFileContents);
|
|
||||||
|
|
||||||
// ACT
|
|
||||||
await migrateMfUtilUsage(tree);
|
|
||||||
|
|
||||||
// ASSERT
|
|
||||||
expect(tree.read('test.js', 'utf-8')).toMatchInlineSnapshot(`
|
|
||||||
"/**
|
|
||||||
* @type {import('@nx/webpack').ModuleFederationConfig}
|
|
||||||
**/
|
|
||||||
const config = {};
|
|
||||||
"
|
|
||||||
`);
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nx/webpack']
|
|
||||||
).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,321 +0,0 @@
|
|||||||
import type { Node, SyntaxKind } from 'typescript';
|
|
||||||
import { visitNotIgnoredFiles } from '../../generators/visit-not-ignored-files';
|
|
||||||
import { formatFiles } from '../../generators/format-files';
|
|
||||||
import {
|
|
||||||
addDependenciesToPackageJson,
|
|
||||||
ensurePackage,
|
|
||||||
} from '../../utils/package-json';
|
|
||||||
import { typescriptVersion } from '../../utils/versions';
|
|
||||||
|
|
||||||
import { GeneratorCallback, readJson, Tree } from 'nx/src/devkit-exports';
|
|
||||||
|
|
||||||
let tsModule: typeof import('typescript');
|
|
||||||
|
|
||||||
const MODULE_FEDERATION_PUBLIC_TOKENS = [
|
|
||||||
'AdditionalSharedConfig',
|
|
||||||
'ModuleFederationConfig',
|
|
||||||
'SharedLibraryConfig',
|
|
||||||
'SharedWorkspaceLibraryConfig',
|
|
||||||
'WorkspaceLibrary',
|
|
||||||
'SharedFunction',
|
|
||||||
'WorkspaceLibrarySecondaryEntryPoint',
|
|
||||||
'Remotes',
|
|
||||||
'ModuleFederationLibrary',
|
|
||||||
'applySharedFunction',
|
|
||||||
'applyAdditionalShared',
|
|
||||||
'getNpmPackageSharedConfig',
|
|
||||||
'shareWorkspaceLibraries',
|
|
||||||
'sharePackages',
|
|
||||||
'mapRemotes',
|
|
||||||
'mapRemotesForSSR',
|
|
||||||
'getDependentPackagesForProject',
|
|
||||||
'readRootPackageJson',
|
|
||||||
];
|
|
||||||
|
|
||||||
export default async (tree: Tree): Promise<GeneratorCallback | void> => {
|
|
||||||
let hasFileToMigrate = false;
|
|
||||||
visitNotIgnoredFiles(tree, '/', (path) => {
|
|
||||||
if (!path.endsWith('.ts') && !path.endsWith('.js')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let fileContents = tree.read(path, 'utf-8');
|
|
||||||
if (
|
|
||||||
MODULE_FEDERATION_PUBLIC_TOKENS.every(
|
|
||||||
(token) => !fileContents.includes(token)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasFileToMigrate = true;
|
|
||||||
|
|
||||||
fileContents = replaceTSImports(tree, path, fileContents);
|
|
||||||
fileContents = replaceRequireCalls(tree, path, fileContents);
|
|
||||||
fileContents = replaceJSDoc(tree, path, fileContents);
|
|
||||||
tree.write(path, fileContents);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (hasFileToMigrate) {
|
|
||||||
await formatFiles(tree);
|
|
||||||
|
|
||||||
const pkgJson = readJson(tree, 'package.json');
|
|
||||||
const nxVersion =
|
|
||||||
pkgJson.devDependencies?.['nx'] ??
|
|
||||||
pkgJson.dependencies?.['nx'] ??
|
|
||||||
'17.0.0';
|
|
||||||
return addDependenciesToPackageJson(tree, {}, { '@nx/webpack': nxVersion });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function replaceJSDoc(tree: Tree, path: string, fileContents: string) {
|
|
||||||
let newFileContents = fileContents;
|
|
||||||
for (const token of MODULE_FEDERATION_PUBLIC_TOKENS) {
|
|
||||||
newFileContents = newFileContents.replaceAll(
|
|
||||||
new RegExp(
|
|
||||||
`(@type)+\\s({)+(\\s)*(import\\(('|")+@nx\/devkit('|")+\\)\.)+(${token})+\\s*(})+`,
|
|
||||||
'g'
|
|
||||||
),
|
|
||||||
`@type {import('@nx/webpack').${token}}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return newFileContents;
|
|
||||||
}
|
|
||||||
|
|
||||||
function replaceRequireCalls(
|
|
||||||
tree: Tree,
|
|
||||||
path: string,
|
|
||||||
fileContents: string
|
|
||||||
): string {
|
|
||||||
if (!tsModule) {
|
|
||||||
tsModule = ensurePackage('typescript', typescriptVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
const sourceFile = tsModule.createSourceFile(
|
|
||||||
path,
|
|
||||||
fileContents,
|
|
||||||
tsModule.ScriptTarget.Latest,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
const allDevkitRequires = findNodes(
|
|
||||||
sourceFile,
|
|
||||||
tsModule.SyntaxKind.VariableStatement
|
|
||||||
)
|
|
||||||
.filter((node) =>
|
|
||||||
[`require("@nx/devkit")`, `require('@nx/devkit')`].some((r) =>
|
|
||||||
node.getText().includes(r)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.filter(
|
|
||||||
(node) => findNodes(node, tsModule.SyntaxKind.ObjectBindingPattern).length
|
|
||||||
);
|
|
||||||
|
|
||||||
const mfUtilRequires = allDevkitRequires.filter((node) =>
|
|
||||||
MODULE_FEDERATION_PUBLIC_TOKENS.some((token) =>
|
|
||||||
node.getText().includes(token)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!mfUtilRequires.length) {
|
|
||||||
return fileContents;
|
|
||||||
}
|
|
||||||
|
|
||||||
const mfUtilTokens = mfUtilRequires.map((node) => {
|
|
||||||
const allTokens = findNodes(node, tsModule.SyntaxKind.BindingElement);
|
|
||||||
const mfTokens = allTokens.filter((node) =>
|
|
||||||
MODULE_FEDERATION_PUBLIC_TOKENS.some((token) => node.getText() === token)
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
requireNode: node,
|
|
||||||
onlyMf: allTokens.length === mfTokens.length,
|
|
||||||
mfTokens,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const changes: {
|
|
||||||
startPosition: number;
|
|
||||||
endPosition?: number;
|
|
||||||
content: string;
|
|
||||||
}[] = [];
|
|
||||||
for (const mfUtilRequireData of mfUtilTokens) {
|
|
||||||
if (mfUtilRequireData.onlyMf) {
|
|
||||||
changes.push({
|
|
||||||
startPosition: mfUtilRequireData.requireNode.getStart(),
|
|
||||||
endPosition: mfUtilRequireData.requireNode.getEnd(),
|
|
||||||
content: '',
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
for (const mfToken of mfUtilRequireData.mfTokens) {
|
|
||||||
const replaceTrailingComma =
|
|
||||||
mfToken.getText().charAt(mfToken.getEnd() + 1) === ',';
|
|
||||||
changes.push({
|
|
||||||
startPosition: mfToken.getStart(),
|
|
||||||
endPosition: replaceTrailingComma
|
|
||||||
? mfToken.getEnd() + 1
|
|
||||||
: mfToken.getEnd(),
|
|
||||||
content: '',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
changes.push({
|
|
||||||
startPosition: mfUtilTokens[mfUtilTokens.length - 1].requireNode.getEnd(),
|
|
||||||
content: `\nconst { ${mfUtilTokens
|
|
||||||
.map((mfUtilToken) => mfUtilToken.mfTokens.map((node) => node.getText()))
|
|
||||||
.join(', ')} } = require('@nx/webpack');`,
|
|
||||||
});
|
|
||||||
|
|
||||||
let newFileContents = fileContents;
|
|
||||||
while (changes.length) {
|
|
||||||
const change = changes.pop();
|
|
||||||
newFileContents = `${newFileContents.substring(0, change.startPosition)}${
|
|
||||||
change.content
|
|
||||||
}${newFileContents.substring(
|
|
||||||
change.endPosition ? change.endPosition : change.startPosition
|
|
||||||
)}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return newFileContents;
|
|
||||||
}
|
|
||||||
|
|
||||||
function replaceTSImports(
|
|
||||||
tree: Tree,
|
|
||||||
path: string,
|
|
||||||
fileContents: string
|
|
||||||
): string {
|
|
||||||
if (!tsModule) {
|
|
||||||
tsModule = ensurePackage('typescript', typescriptVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
const sourceFile = tsModule.createSourceFile(
|
|
||||||
path,
|
|
||||||
fileContents,
|
|
||||||
tsModule.ScriptTarget.Latest,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
const allImports = findNodes(
|
|
||||||
sourceFile,
|
|
||||||
tsModule.SyntaxKind.ImportDeclaration
|
|
||||||
);
|
|
||||||
const devkitImports = allImports.filter((i) =>
|
|
||||||
i.getText().includes(`'@nx/devkit';`)
|
|
||||||
);
|
|
||||||
const mfUtilsImports = devkitImports.filter((i) =>
|
|
||||||
MODULE_FEDERATION_PUBLIC_TOKENS.some((token) => i.getText().includes(token))
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!mfUtilsImports.length) {
|
|
||||||
return fileContents;
|
|
||||||
}
|
|
||||||
|
|
||||||
const mfUtilsWithMultipleImports = mfUtilsImports.map((i) => {
|
|
||||||
const importSpecifierNodes = findNodes(
|
|
||||||
i,
|
|
||||||
tsModule.SyntaxKind.ImportSpecifier
|
|
||||||
);
|
|
||||||
const mfImportSpecifierNodes = importSpecifierNodes.filter((node) =>
|
|
||||||
MODULE_FEDERATION_PUBLIC_TOKENS.some((token) =>
|
|
||||||
node.getText().includes(token)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
importDeclarationNode: i,
|
|
||||||
onlyMf: mfImportSpecifierNodes.length === importSpecifierNodes.length,
|
|
||||||
mfImportSpecifierNodes,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const changes: {
|
|
||||||
startPosition: number;
|
|
||||||
endPosition?: number;
|
|
||||||
content: string;
|
|
||||||
}[] = [];
|
|
||||||
for (const importDeclaration of mfUtilsWithMultipleImports) {
|
|
||||||
if (importDeclaration.onlyMf) {
|
|
||||||
changes.push({
|
|
||||||
startPosition: importDeclaration.importDeclarationNode.getStart(),
|
|
||||||
endPosition: importDeclaration.importDeclarationNode.getEnd(),
|
|
||||||
content: '',
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
for (const mfImportSpecifierNodes of importDeclaration.mfImportSpecifierNodes) {
|
|
||||||
const replaceTrailingComma =
|
|
||||||
importDeclaration.importDeclarationNode
|
|
||||||
.getText()
|
|
||||||
.charAt(mfImportSpecifierNodes.getEnd() + 1) === ',';
|
|
||||||
changes.push({
|
|
||||||
startPosition: mfImportSpecifierNodes.getStart(),
|
|
||||||
endPosition: replaceTrailingComma
|
|
||||||
? mfImportSpecifierNodes.getEnd() + 1
|
|
||||||
: mfImportSpecifierNodes.getEnd(),
|
|
||||||
content: '',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
changes.push({
|
|
||||||
startPosition:
|
|
||||||
mfUtilsWithMultipleImports[
|
|
||||||
mfUtilsWithMultipleImports.length - 1
|
|
||||||
].importDeclarationNode.getEnd(),
|
|
||||||
content: `\nimport { ${mfUtilsWithMultipleImports
|
|
||||||
.map((importDeclaration) =>
|
|
||||||
importDeclaration.mfImportSpecifierNodes.map((node) => node.getText())
|
|
||||||
)
|
|
||||||
.join(', ')} } from '@nx/webpack';`,
|
|
||||||
});
|
|
||||||
|
|
||||||
let newFileContents = fileContents;
|
|
||||||
while (changes.length) {
|
|
||||||
const change = changes.pop();
|
|
||||||
newFileContents = `${newFileContents.substring(0, change.startPosition)}${
|
|
||||||
change.content
|
|
||||||
}${newFileContents.substring(
|
|
||||||
change.endPosition ? change.endPosition : change.startPosition
|
|
||||||
)}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return newFileContents;
|
|
||||||
}
|
|
||||||
|
|
||||||
function findNodes(
|
|
||||||
node: Node,
|
|
||||||
kind: SyntaxKind | SyntaxKind[],
|
|
||||||
max = Infinity
|
|
||||||
): Node[] {
|
|
||||||
if (!node || max == 0) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const arr: Node[] = [];
|
|
||||||
const hasMatch = Array.isArray(kind)
|
|
||||||
? kind.includes(node.kind)
|
|
||||||
: node.kind === kind;
|
|
||||||
if (hasMatch) {
|
|
||||||
arr.push(node);
|
|
||||||
max--;
|
|
||||||
}
|
|
||||||
if (max > 0) {
|
|
||||||
for (const child of node.getChildren()) {
|
|
||||||
findNodes(child, kind, max).forEach((node) => {
|
|
||||||
if (max > 0) {
|
|
||||||
arr.push(node);
|
|
||||||
}
|
|
||||||
max--;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (max <= 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
@ -1,36 +1,4 @@
|
|||||||
{
|
{
|
||||||
"generators": {
|
"generators": {},
|
||||||
"update-16-0-0-add-nx-packages": {
|
"packageJsonUpdates": {}
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.0.0-beta.1",
|
|
||||||
"description": "Replace @nrwl/esbuild with @nx/esbuild",
|
|
||||||
"implementation": "./src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages"
|
|
||||||
},
|
|
||||||
"update-16-0-1-set-thirdparty-true": {
|
|
||||||
"version": "16.0.1-beta.0",
|
|
||||||
"description": "Set thirdParty to true to maintain the existing behavior of bundling dependencies.",
|
|
||||||
"cli": "nx",
|
|
||||||
"implementation": "./src/migrations/update-16-0-1-set-thirdparty-true/update-16-0-1-set-thirdparty-true"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"packageJsonUpdates": {
|
|
||||||
"16.0.0": {
|
|
||||||
"version": "16.0.0-beta.5",
|
|
||||||
"packages": {
|
|
||||||
"esbuild": {
|
|
||||||
"version": "0.17.17",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.8.0": {
|
|
||||||
"version": "16.8.0-beta.2",
|
|
||||||
"packages": {
|
|
||||||
"esbuild": {
|
|
||||||
"version": "^0.19.2",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
import { Tree, readJson, updateJson } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import replacePackage from './update-16-0-0-add-nx-packages';
|
|
||||||
|
|
||||||
describe('update-16-0-0-add-nx-packages', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
|
|
||||||
updateJson(tree, 'package.json', (json) => {
|
|
||||||
json.devDependencies['@nrwl/esbuild'] = '16.0.0';
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the dependency on @nrwl/esbuild', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').dependencies['@nrwl/esbuild']
|
|
||||||
).not.toBeDefined();
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nrwl/esbuild']
|
|
||||||
).not.toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add a dependency on @nx/esbuild', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
const packageJson = readJson(tree, 'package.json');
|
|
||||||
const newDependencyVersion =
|
|
||||||
packageJson.devDependencies['@nx/esbuild'] ??
|
|
||||||
packageJson.dependencies['@nx/esbuild'];
|
|
||||||
|
|
||||||
expect(newDependencyVersion).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import { Tree, formatFiles } from '@nx/devkit';
|
|
||||||
import { replaceNrwlPackageWithNxPackage } from '@nx/devkit/src/utils/replace-package';
|
|
||||||
|
|
||||||
export default async function replacePackage(tree: Tree): Promise<void> {
|
|
||||||
await replaceNrwlPackageWithNxPackage(tree, '@nrwl/esbuild', '@nx/esbuild');
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,109 +0,0 @@
|
|||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import {
|
|
||||||
addProjectConfiguration,
|
|
||||||
readProjectConfiguration,
|
|
||||||
Tree,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
|
|
||||||
import update from './update-16-0-1-set-thirdparty-true';
|
|
||||||
|
|
||||||
describe('update-16-0-1-set-thirdparty-true', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should skip migration targets are not set on the project', async () => {
|
|
||||||
addProjectConfiguration(tree, 'myapp', {
|
|
||||||
root: 'myapp',
|
|
||||||
});
|
|
||||||
await update(tree);
|
|
||||||
|
|
||||||
const config = readProjectConfiguration(tree, 'myapp');
|
|
||||||
|
|
||||||
expect(config.targets).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add thirdParty property if bundling is enabled implicitly', async () => {
|
|
||||||
addProjectConfiguration(tree, 'myapp', {
|
|
||||||
root: 'myapp',
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
executor: '@nx/esbuild:esbuild',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await update(tree);
|
|
||||||
|
|
||||||
const config = readProjectConfiguration(tree, 'myapp');
|
|
||||||
|
|
||||||
expect(config.targets.build.options).toEqual({
|
|
||||||
thirdParty: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add thirdParty property if bundling is enabled explicitly', async () => {
|
|
||||||
addProjectConfiguration(tree, 'myapp', {
|
|
||||||
root: 'myapp',
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
executor: '@nx/esbuild:esbuild',
|
|
||||||
options: {
|
|
||||||
bundle: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await update(tree);
|
|
||||||
|
|
||||||
const config = readProjectConfiguration(tree, 'myapp');
|
|
||||||
|
|
||||||
expect(config.targets.build.options).toEqual({
|
|
||||||
bundle: true,
|
|
||||||
thirdParty: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not add thirdParty property if bundling is disabled', async () => {
|
|
||||||
addProjectConfiguration(tree, 'myapp', {
|
|
||||||
root: 'myapp',
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
executor: '@nx/esbuild:esbuild',
|
|
||||||
options: {
|
|
||||||
bundle: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await update(tree);
|
|
||||||
|
|
||||||
const config = readProjectConfiguration(tree, 'myapp');
|
|
||||||
|
|
||||||
expect(config.targets.build.options).toEqual({
|
|
||||||
bundle: false,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not set thirdParty property if it was already set', async () => {
|
|
||||||
addProjectConfiguration(tree, 'myapp', {
|
|
||||||
root: 'myapp',
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
executor: '@nx/esbuild:esbuild',
|
|
||||||
options: {
|
|
||||||
thirdParty: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await update(tree);
|
|
||||||
|
|
||||||
const config = readProjectConfiguration(tree, 'myapp');
|
|
||||||
|
|
||||||
expect(config.targets.build.options).toEqual({
|
|
||||||
thirdParty: false,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
||||||
import {
|
|
||||||
formatFiles,
|
|
||||||
getProjects,
|
|
||||||
Tree,
|
|
||||||
updateProjectConfiguration,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
|
|
||||||
export default async function update(host: Tree) {
|
|
||||||
const projects = getProjects(host);
|
|
||||||
|
|
||||||
projects.forEach((projectConfig, projectName) => {
|
|
||||||
if (!projectConfig.targets) return;
|
|
||||||
|
|
||||||
let shouldUpdate = false;
|
|
||||||
|
|
||||||
Object.entries(projectConfig.targets).forEach(
|
|
||||||
([targetName, targetConfig]) => {
|
|
||||||
if (
|
|
||||||
targetConfig.executor === '@nrwl/esbuild:esbuild' ||
|
|
||||||
targetConfig.executor === '@nx/esbuild:esbuild'
|
|
||||||
) {
|
|
||||||
projectConfig.targets[targetName].options ??= {};
|
|
||||||
if (projectConfig.targets[targetName].options.bundle !== false) {
|
|
||||||
shouldUpdate = true;
|
|
||||||
|
|
||||||
projectConfig.targets[targetName].options.thirdParty ??= true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (shouldUpdate) {
|
|
||||||
updateProjectConfiguration(host, projectName, projectConfig);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
await formatFiles(host);
|
|
||||||
}
|
|
||||||
@ -1,11 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generators": {
|
"generators": {
|
||||||
"update-16-0-0-add-nx-packages": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.0.0-beta.1",
|
|
||||||
"description": "Replace @nrwl/eslint-plugin-nx with @nx/eslint-plugin",
|
|
||||||
"implementation": "./src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages"
|
|
||||||
},
|
|
||||||
"update-17-2-6-rename-workspace-rules": {
|
"update-17-2-6-rename-workspace-rules": {
|
||||||
"cli": "nx",
|
"cli": "nx",
|
||||||
"version": "17.2.6-beta.1",
|
"version": "17.2.6-beta.1",
|
||||||
|
|||||||
@ -1,83 +0,0 @@
|
|||||||
import { Tree, readJson, updateJson, writeJson } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import replacePackage from './update-16-0-0-add-nx-packages';
|
|
||||||
|
|
||||||
describe('update-16-0-0-add-nx-packages', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
|
|
||||||
updateJson(tree, 'package.json', (json) => {
|
|
||||||
json.devDependencies['@nrwl/eslint-plugin-nx'] = '16.0.0';
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the dependency on @nrwl/eslint-plugin-nx', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').dependencies['@nrwl/eslint-plugin-nx']
|
|
||||||
).not.toBeDefined();
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nrwl/eslint-plugin-nx']
|
|
||||||
).not.toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add a dependency on @nx/eslint-plugin', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
const packageJson = readJson(tree, 'package.json');
|
|
||||||
const newDependencyVersion =
|
|
||||||
packageJson.devDependencies['@nx/eslint-plugin'] ??
|
|
||||||
packageJson.dependencies['@nx/eslint-plugin'];
|
|
||||||
|
|
||||||
expect(newDependencyVersion).toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should replace the eslint plugin', async () => {
|
|
||||||
writeJson(tree, '.eslintrc.json', {
|
|
||||||
plugins: ['@nrwl/nx'],
|
|
||||||
rules: {
|
|
||||||
'@nrwl/nx/enforce-module-boundaries': ['error', {}],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
expect(readJson(tree, '.eslintrc.json')).toMatchInlineSnapshot(`
|
|
||||||
{
|
|
||||||
"plugins": [
|
|
||||||
"@nx",
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"@nx/enforce-module-boundaries": [
|
|
||||||
"error",
|
|
||||||
{},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should replace eslint-ignore comments', async () => {
|
|
||||||
tree.write(
|
|
||||||
'ignored-file.ts',
|
|
||||||
'// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries\n /*\n* eslint-disable @nrwl/nx/enforce-module-boundaries\n*/\n // eslint-disable-line @nrwl/nx/enforce-module-boundaries'
|
|
||||||
);
|
|
||||||
tree.write('plugin.ts', `import * as p from '@nrwl/nx-plugin'`);
|
|
||||||
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
expect(tree.read('ignored-file.ts').toString()).toMatchInlineSnapshot(`
|
|
||||||
"// eslint-disable-next-line @nx/enforce-module-boundaries
|
|
||||||
/*
|
|
||||||
* eslint-disable @nx/enforce-module-boundaries
|
|
||||||
*/
|
|
||||||
// eslint-disable-line @nx/enforce-module-boundaries"
|
|
||||||
`);
|
|
||||||
expect(tree.read('plugin.ts').toString()).toMatchInlineSnapshot(
|
|
||||||
`"import * as p from '@nrwl/nx-plugin'"`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
import { Tree, formatFiles, visitNotIgnoredFiles } from '@nx/devkit';
|
|
||||||
import { replaceNrwlPackageWithNxPackage } from '@nx/devkit/src/utils/replace-package';
|
|
||||||
|
|
||||||
import { basename } from 'path';
|
|
||||||
import { isBinaryPath } from '@nx/devkit/src/utils/binary-extensions';
|
|
||||||
|
|
||||||
const eslintFileNames = [
|
|
||||||
'.eslintrc',
|
|
||||||
'.eslintrc.js',
|
|
||||||
'.eslintrc.cjs',
|
|
||||||
'.eslintrc.yaml',
|
|
||||||
'.eslintrc.yml',
|
|
||||||
'.eslintrc.json',
|
|
||||||
'eslint.config.js', // new format that requires `ESLINT_USE_FLAT_CONFIG=true`
|
|
||||||
];
|
|
||||||
|
|
||||||
export default async function replacePackage(tree: Tree): Promise<void> {
|
|
||||||
await replaceNrwlPackageWithNxPackage(
|
|
||||||
tree,
|
|
||||||
'@nrwl/eslint-plugin-nx',
|
|
||||||
'@nx/eslint-plugin'
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Matches:
|
|
||||||
* * // eslint-disable-next-line @nrwl/nx/...
|
|
||||||
* * // eslint-disable-line @nrwl/nx/...
|
|
||||||
* * /* eslint-disable @nrwl/nx/...
|
|
||||||
*/
|
|
||||||
const ignoreLineRegex = /(eslint-disable(?:(?:-next)?-line)?\s*)@nrwl\/nx/g;
|
|
||||||
visitNotIgnoredFiles(tree, '.', (path) => {
|
|
||||||
if (isBinaryPath(path)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let contents = tree.read(path).toString();
|
|
||||||
if (eslintFileNames.includes(basename(path))) {
|
|
||||||
if (!contents.includes('@nrwl/nx')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
contents = contents.replace(new RegExp('@nrwl/nx', 'g'), '@nx');
|
|
||||||
}
|
|
||||||
if (ignoreLineRegex.test(contents)) {
|
|
||||||
contents = contents.replace(ignoreLineRegex, '$1@nx');
|
|
||||||
}
|
|
||||||
tree.write(path, contents);
|
|
||||||
});
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,16 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generators": {
|
"generators": {
|
||||||
"update-16-0-0-add-nx-packages": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.0.0-beta.1",
|
|
||||||
"description": "Replace @nrwl/linter with @nx/linter",
|
|
||||||
"implementation": "./src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages"
|
|
||||||
},
|
|
||||||
"update-16-8-0-add-ignored-files": {
|
|
||||||
"version": "16.8.0",
|
|
||||||
"description": "update-16-8-0-add-ignored-files",
|
|
||||||
"implementation": "./src/migrations/update-16-8-0-add-ignored-files/update-16-8-0-add-ignored-files"
|
|
||||||
},
|
|
||||||
"update-17-0-0-rename-to-eslint": {
|
"update-17-0-0-rename-to-eslint": {
|
||||||
"version": "17.0.0-beta.7",
|
"version": "17.0.0-beta.7",
|
||||||
"description": "update-17-0-0-rename-to-eslint",
|
"description": "update-17-0-0-rename-to-eslint",
|
||||||
@ -33,51 +22,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packageJsonUpdates": {
|
"packageJsonUpdates": {
|
||||||
"16.0.0": {
|
|
||||||
"version": "16.0.0-beta.0",
|
|
||||||
"packages": {
|
|
||||||
"@typescript-eslint/parser": {
|
|
||||||
"version": "^5.58.0"
|
|
||||||
},
|
|
||||||
"@typescript-eslint/eslint-plugin": {
|
|
||||||
"version": "^5.58.0"
|
|
||||||
},
|
|
||||||
"@typescript-eslint/utils": {
|
|
||||||
"version": "^5.58.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.5.0": {
|
|
||||||
"version": "16.5.0-beta.2",
|
|
||||||
"packages": {
|
|
||||||
"@typescript-eslint/parser": {
|
|
||||||
"version": "^5.60.1"
|
|
||||||
},
|
|
||||||
"@typescript-eslint/eslint-plugin": {
|
|
||||||
"version": "^5.60.1"
|
|
||||||
},
|
|
||||||
"@typescript-eslint/utils": {
|
|
||||||
"version": "^5.60.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.7.0": {
|
|
||||||
"version": "16.7.0-beta.2",
|
|
||||||
"packages": {
|
|
||||||
"eslint": {
|
|
||||||
"version": "~8.46.0"
|
|
||||||
},
|
|
||||||
"@typescript-eslint/parser": {
|
|
||||||
"version": "^5.60.1"
|
|
||||||
},
|
|
||||||
"@typescript-eslint/eslint-plugin": {
|
|
||||||
"version": "^5.60.1"
|
|
||||||
},
|
|
||||||
"@typescript-eslint/utils": {
|
|
||||||
"version": "^5.60.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"17.0.0": {
|
"17.0.0": {
|
||||||
"version": "17.0.0-rc.2",
|
"version": "17.0.0-rc.2",
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
import { Tree, readJson, updateJson } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import replacePackage from './update-16-0-0-add-nx-packages';
|
|
||||||
|
|
||||||
describe('update-16-0-0-add-nx-packages', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
|
|
||||||
updateJson(tree, 'package.json', (json) => {
|
|
||||||
json.devDependencies['@nrwl/linter'] = '16.0.0';
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the dependency on @nrwl/linter', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').dependencies['@nrwl/linter']
|
|
||||||
).not.toBeDefined();
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nrwl/linter']
|
|
||||||
).not.toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add a dependency on @nx/linter', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
const packageJson = readJson(tree, 'package.json');
|
|
||||||
const newDependencyVersion =
|
|
||||||
packageJson.devDependencies['@nx/linter'] ??
|
|
||||||
packageJson.dependencies['@nx/linter'];
|
|
||||||
|
|
||||||
expect(newDependencyVersion).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import { Tree, formatFiles } from '@nx/devkit';
|
|
||||||
import { replaceNrwlPackageWithNxPackage } from '@nx/devkit/src/utils/replace-package';
|
|
||||||
|
|
||||||
export default async function replacePackage(tree: Tree): Promise<void> {
|
|
||||||
await replaceNrwlPackageWithNxPackage(tree, '@nrwl/linter', '@nx/linter');
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,194 +0,0 @@
|
|||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import { addProjectConfiguration, readJson, Tree, writeJson } from '@nx/devkit';
|
|
||||||
|
|
||||||
import update from './update-16-8-0-add-ignored-files';
|
|
||||||
|
|
||||||
describe('update-16-8-0-add-ignored-files migration', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
tree.write('.eslintrc.json', '{}');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should run successfully when eslint config is not present', async () => {
|
|
||||||
addProjectConfiguration(tree, 'my-pkg', {
|
|
||||||
root: 'packages/my-pkg',
|
|
||||||
sourceRoot: 'packages/my-pkg/src',
|
|
||||||
projectType: 'library',
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
executor: '@nx/vite:build',
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(() => update(tree)).not.toThrow();
|
|
||||||
});
|
|
||||||
|
|
||||||
it.each`
|
|
||||||
executor | expectedPattern
|
|
||||||
${'@nx/vite:build'} | ${'{projectRoot}/vite.config.{js,ts,mjs,mts}'}
|
|
||||||
${'@nx/vite:test'} | ${'{projectRoot}/vite.config.{js,ts,mjs,mts}'}
|
|
||||||
${'@nx/esbuild:esbuild'} | ${'{projectRoot}/esbuild.config.{js,ts,mjs,mts}'}
|
|
||||||
${'@nx/rollup:rollup'} | ${'{projectRoot}/rollup.config.{js,ts,mjs,mts}'}
|
|
||||||
`(
|
|
||||||
'should add ignoredFiles to projects using vite, esbuild, and rollup',
|
|
||||||
async ({ executor, expectedPattern }) => {
|
|
||||||
addProjectConfiguration(tree, 'my-pkg', {
|
|
||||||
root: 'packages/my-pkg',
|
|
||||||
sourceRoot: 'packages/my-pkg/src',
|
|
||||||
projectType: 'library',
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
executor,
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
writeJson(tree, `packages/my-pkg/.eslintrc.json`, {
|
|
||||||
root: true,
|
|
||||||
ignorePatterns: ['!**/*'],
|
|
||||||
plugins: ['@nx'],
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
files: ['*.json'],
|
|
||||||
parser: 'jsonc-eslint-parser',
|
|
||||||
rules: {
|
|
||||||
'@nx/dependency-checks': 'error',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
update(tree);
|
|
||||||
|
|
||||||
expect(readJson(tree, 'packages/my-pkg/.eslintrc.json')).toEqual({
|
|
||||||
root: true,
|
|
||||||
ignorePatterns: ['!**/*'],
|
|
||||||
plugins: ['@nx'],
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
files: ['*.json'],
|
|
||||||
parser: 'jsonc-eslint-parser',
|
|
||||||
rules: {
|
|
||||||
'@nx/dependency-checks': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
ignoredFiles: [expectedPattern],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
it('should retain existing severity', () => {
|
|
||||||
addProjectConfiguration(tree, 'my-pkg', {
|
|
||||||
root: 'packages/my-pkg',
|
|
||||||
sourceRoot: 'packages/my-pkg/src',
|
|
||||||
projectType: 'library',
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
executor: '@nx/vite:build',
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
writeJson(tree, `packages/my-pkg/.eslintrc.json`, {
|
|
||||||
root: true,
|
|
||||||
ignorePatterns: ['!**/*'],
|
|
||||||
plugins: ['@nx'],
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
files: ['*.json'],
|
|
||||||
parser: 'jsonc-eslint-parser',
|
|
||||||
rules: {
|
|
||||||
'@nx/dependency-checks': 'warn',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
update(tree);
|
|
||||||
|
|
||||||
expect(readJson(tree, 'packages/my-pkg/.eslintrc.json')).toEqual({
|
|
||||||
root: true,
|
|
||||||
ignorePatterns: ['!**/*'],
|
|
||||||
plugins: ['@nx'],
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
files: ['*.json'],
|
|
||||||
parser: 'jsonc-eslint-parser',
|
|
||||||
rules: {
|
|
||||||
'@nx/dependency-checks': [
|
|
||||||
'warn',
|
|
||||||
{
|
|
||||||
ignoredFiles: ['{projectRoot}/vite.config.{js,ts,mjs,mts}'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should retain existing options', () => {
|
|
||||||
addProjectConfiguration(tree, 'my-pkg', {
|
|
||||||
root: 'packages/my-pkg',
|
|
||||||
sourceRoot: 'packages/my-pkg/src',
|
|
||||||
projectType: 'library',
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
executor: '@nx/vite:build',
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
writeJson(tree, `packages/my-pkg/.eslintrc.json`, {
|
|
||||||
root: true,
|
|
||||||
ignorePatterns: ['!**/*'],
|
|
||||||
plugins: ['@nx'],
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
files: ['*.json'],
|
|
||||||
parser: 'jsonc-eslint-parser',
|
|
||||||
rules: {
|
|
||||||
'@nx/dependency-checks': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
checkVersionMismatches: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
update(tree);
|
|
||||||
|
|
||||||
expect(readJson(tree, 'packages/my-pkg/.eslintrc.json')).toEqual({
|
|
||||||
root: true,
|
|
||||||
ignorePatterns: ['!**/*'],
|
|
||||||
plugins: ['@nx'],
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
files: ['*.json'],
|
|
||||||
parser: 'jsonc-eslint-parser',
|
|
||||||
rules: {
|
|
||||||
'@nx/dependency-checks': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
checkVersionMismatches: false,
|
|
||||||
ignoredFiles: ['{projectRoot}/vite.config.{js,ts,mjs,mts}'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,80 +0,0 @@
|
|||||||
import { getProjects, Tree } from '@nx/devkit';
|
|
||||||
import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils';
|
|
||||||
import {
|
|
||||||
findEslintFile,
|
|
||||||
isEslintConfigSupported,
|
|
||||||
lintConfigHasOverride,
|
|
||||||
updateOverrideInLintConfig,
|
|
||||||
} from '../../generators/utils/eslint-file';
|
|
||||||
|
|
||||||
// Add `ignoredFiles` pattern to projects using vite, esbuild, and rollup.
|
|
||||||
// This is needed because the @nx/dependency-checks lint rule will complain
|
|
||||||
// about dependencies used in build config files, even though they are not
|
|
||||||
// production dependencies.
|
|
||||||
export default function update(tree: Tree) {
|
|
||||||
const projects = getProjects(tree);
|
|
||||||
|
|
||||||
const addIgnorePattern =
|
|
||||||
(ignorePattern: string) => (_options: unknown, projectName: string) => {
|
|
||||||
const project = projects.get(projectName);
|
|
||||||
if (
|
|
||||||
!findEslintFile(tree, project.root) ||
|
|
||||||
!isEslintConfigSupported(tree)
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
lintConfigHasOverride(
|
|
||||||
tree,
|
|
||||||
project.root,
|
|
||||||
(o) =>
|
|
||||||
Array.isArray(o.files)
|
|
||||||
? o.files.some((f) => f.match(/\.json$/))
|
|
||||||
: !!o.files?.match(/\.json$/),
|
|
||||||
true
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
updateOverrideInLintConfig(
|
|
||||||
tree,
|
|
||||||
project.root,
|
|
||||||
(o) => !!o.rules?.['@nx/dependency-checks'],
|
|
||||||
(o) => {
|
|
||||||
const value = o.rules['@nx/dependency-checks'];
|
|
||||||
let ruleSeverity: 0 | 1 | 2 | 'error' | 'warn' | 'off';
|
|
||||||
let ruleOptions: any;
|
|
||||||
if (Array.isArray(value)) {
|
|
||||||
ruleSeverity = value[0];
|
|
||||||
ruleOptions = value[1];
|
|
||||||
} else {
|
|
||||||
ruleSeverity = value;
|
|
||||||
ruleOptions = {};
|
|
||||||
}
|
|
||||||
ruleOptions.ignoredFiles = [ignorePattern];
|
|
||||||
o.rules['@nx/dependency-checks'] = [ruleSeverity, ruleOptions];
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
forEachExecutorOptions(
|
|
||||||
tree,
|
|
||||||
'@nx/vite:build',
|
|
||||||
addIgnorePattern('{projectRoot}/vite.config.{js,ts,mjs,mts}')
|
|
||||||
);
|
|
||||||
forEachExecutorOptions(
|
|
||||||
tree,
|
|
||||||
'@nx/vite:test',
|
|
||||||
addIgnorePattern('{projectRoot}/vite.config.{js,ts,mjs,mts}')
|
|
||||||
);
|
|
||||||
forEachExecutorOptions(
|
|
||||||
tree,
|
|
||||||
'@nx/esbuild:esbuild',
|
|
||||||
addIgnorePattern('{projectRoot}/esbuild.config.{js,ts,mjs,mts}')
|
|
||||||
);
|
|
||||||
forEachExecutorOptions(
|
|
||||||
tree,
|
|
||||||
'@nx/rollup:rollup',
|
|
||||||
addIgnorePattern('{projectRoot}/rollup.config.{js,ts,mjs,mts}')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,47 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generators": {
|
"generators": {
|
||||||
"remove-deprecated-expo-targets": {
|
|
||||||
"version": "16.0.0-beta.0",
|
|
||||||
"cli": "nx",
|
|
||||||
"description": "Remove deprecated expo targets",
|
|
||||||
"factory": "./src/migrations/update-16-0-0/remove-deprecated-targets"
|
|
||||||
},
|
|
||||||
"update-16-0-0-add-nx-packages": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.0.0-beta.1",
|
|
||||||
"description": "Replace @nrwl/expo with @nx/expo",
|
|
||||||
"implementation": "./src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages"
|
|
||||||
},
|
|
||||||
"update-eas-scripts-16-1-4": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.1.4-beta.0",
|
|
||||||
"description": "Update package.json eas build lifecycle scripts",
|
|
||||||
"implementation": "./src/migrations/update-16-1-4/update-eas-scripts"
|
|
||||||
},
|
|
||||||
"update-16-6-0-add-dependsOn": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.6.0-beta.0",
|
|
||||||
"description": "Add dependsOn like ensure-symlink or sync-deps to targets",
|
|
||||||
"implementation": "./src/migrations/update-16-6-0/add-depends-on"
|
|
||||||
},
|
|
||||||
"update-16-6-0-update-metro-config": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.6.0-beta.0",
|
|
||||||
"description": "Update metro.config.js to use the new metro config format",
|
|
||||||
"implementation": "./src/migrations/update-16-6-0/update-metro-config"
|
|
||||||
},
|
|
||||||
"update-16-9-0-remove-types-react-native": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.9.0-beta.1",
|
|
||||||
"description": "Remove @types/react-native from package.json",
|
|
||||||
"implementation": "./src/migrations/update-16-9-0/remove-types-react-native"
|
|
||||||
},
|
|
||||||
"update-16-9-0-update-eas-json-cli-version": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.9.0-beta.1",
|
|
||||||
"description": "Update eas.json cli version",
|
|
||||||
"implementation": "./src/migrations/update-16-9-0/update-eas-cli-version"
|
|
||||||
},
|
|
||||||
"update-18-0-0-remove-block-list": {
|
"update-18-0-0-remove-block-list": {
|
||||||
"cli": "nx",
|
"cli": "nx",
|
||||||
"version": "18.0.0-beta.0",
|
"version": "18.0.0-beta.0",
|
||||||
@ -86,226 +44,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packageJsonUpdates": {
|
"packageJsonUpdates": {
|
||||||
"16.0.0": {
|
|
||||||
"version": "16.0.0-beta.0",
|
|
||||||
"packages": {
|
|
||||||
"expo": {
|
|
||||||
"version": "48.0.11",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"react-native": {
|
|
||||||
"version": "0.71.6",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@types/react-native": {
|
|
||||||
"version": "0.71.6",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"eas-cli": {
|
|
||||||
"version": "~3.10.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@expo/cli": {
|
|
||||||
"version": "~0.7.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@testing-library/react-native": {
|
|
||||||
"version": "12.0.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"jest-expo": {
|
|
||||||
"version": "~48.0.2",
|
|
||||||
"alwaysAddToPackageJson": false,
|
|
||||||
"addToPackageJson": "devDependencies"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.0.2": {
|
|
||||||
"version": "16.0.2-beta.0",
|
|
||||||
"packages": {
|
|
||||||
"expo": {
|
|
||||||
"version": "48.0.15",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"react-native": {
|
|
||||||
"version": "0.71.7",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"eas-cli": {
|
|
||||||
"version": "~3.10.2",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@expo/cli": {
|
|
||||||
"version": "~0.7.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"expo-splash-screen": {
|
|
||||||
"version": "~0.18.2",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.1.5": {
|
|
||||||
"version": "16.1.5-beta.0",
|
|
||||||
"packages": {
|
|
||||||
"expo": {
|
|
||||||
"version": "^48.0.16",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"eas-cli": {
|
|
||||||
"version": "~3.12.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@testing-library/react-native": {
|
|
||||||
"version": "12.1.2",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.2.2": {
|
|
||||||
"version": "16.2.2-beta.0",
|
|
||||||
"packages": {
|
|
||||||
"expo": {
|
|
||||||
"version": "^48.0.17",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"eas-cli": {
|
|
||||||
"version": "~3.13.2",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"react-native": {
|
|
||||||
"version": "0.71.8",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@types/react-native": {
|
|
||||||
"version": "0.71.7",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.4.0": {
|
|
||||||
"version": "16.4.0-beta.5",
|
|
||||||
"packages": {
|
|
||||||
"expo": {
|
|
||||||
"version": "^48.0.19",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"eas-cli": {
|
|
||||||
"version": "~3.13.3",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@expo/cli": {
|
|
||||||
"version": "~0.7.3",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.6.0": {
|
|
||||||
"version": "16.6.0-beta.0",
|
|
||||||
"packages": {
|
|
||||||
"expo": {
|
|
||||||
"version": "^49.0.3",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@expo/metro-config": {
|
|
||||||
"version": "~0.10.6",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"expo-splash-screen": {
|
|
||||||
"version": "~0.20.4",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"expo-status-bar": {
|
|
||||||
"version": "~1.6.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@expo/cli": {
|
|
||||||
"version": "~0.10.10",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"eas-cli": {
|
|
||||||
"version": "~3.15.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"babel-preset-expo": {
|
|
||||||
"version": "~9.5.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"jest-expo": {
|
|
||||||
"version": "~49.0.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"metro-resolver": {
|
|
||||||
"version": "0.76.7",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"metro": {
|
|
||||||
"version": "0.76.7",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"react-native": {
|
|
||||||
"version": "0.72.3",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@types/react-native": {
|
|
||||||
"version": "0.72.2",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"react-native-web": {
|
|
||||||
"version": "~0.19.6",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"react-native-svg": {
|
|
||||||
"version": "13.9.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.9.0": {
|
|
||||||
"version": "16.9.0-beta.1",
|
|
||||||
"packages": {
|
|
||||||
"expo": {
|
|
||||||
"version": "49.0.10",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@expo/metro-config": {
|
|
||||||
"version": "~0.10.7",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"expo-splash-screen": {
|
|
||||||
"version": "~0.20.5",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@expo/cli": {
|
|
||||||
"version": "~0.10.12",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"eas-cli": {
|
|
||||||
"version": "~5.2.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"babel-preset-expo": {
|
|
||||||
"version": "~9.5.2",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"react-native": {
|
|
||||||
"version": "0.72.4",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"react-native-web": {
|
|
||||||
"version": "~0.19.8",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@testing-library/react-native": {
|
|
||||||
"version": "~12.3.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@testing-library/jest-native": {
|
|
||||||
"version": "~5.4.3",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"17.1.0": {
|
"17.1.0": {
|
||||||
"version": "17.1.0-beta.0",
|
"version": "17.1.0-beta.0",
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
import { Tree, readJson, updateJson } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import replacePackage from './update-16-0-0-add-nx-packages';
|
|
||||||
|
|
||||||
describe('update-16-0-0-add-nx-packages', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
|
|
||||||
updateJson(tree, 'package.json', (json) => {
|
|
||||||
json.devDependencies['@nrwl/expo'] = '16.0.0';
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the dependency on @nrwl/expo', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').dependencies['@nrwl/expo']
|
|
||||||
).not.toBeDefined();
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nrwl/expo']
|
|
||||||
).not.toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add a dependency on @nx/expo', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
const packageJson = readJson(tree, 'package.json');
|
|
||||||
const newDependencyVersion =
|
|
||||||
packageJson.devDependencies['@nx/expo'] ??
|
|
||||||
packageJson.dependencies['@nx/expo'];
|
|
||||||
|
|
||||||
expect(newDependencyVersion).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import { Tree, formatFiles } from '@nx/devkit';
|
|
||||||
import { replaceNrwlPackageWithNxPackage } from '@nx/devkit/src/utils/replace-package';
|
|
||||||
|
|
||||||
export default async function replacePackage(tree: Tree): Promise<void> {
|
|
||||||
await replaceNrwlPackageWithNxPackage(tree, '@nrwl/expo', '@nx/expo');
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
import {
|
|
||||||
Tree,
|
|
||||||
formatFiles,
|
|
||||||
getProjects,
|
|
||||||
updateProjectConfiguration,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove deprecated @expo/cli targets
|
|
||||||
*/
|
|
||||||
export default async function update(tree: Tree) {
|
|
||||||
const projects = getProjects(tree);
|
|
||||||
|
|
||||||
for (const [name, config] of projects.entries()) {
|
|
||||||
if (
|
|
||||||
config.targets?.['start']?.executor === '@nrwl/expo:start' ||
|
|
||||||
config.targets?.['start']?.executor === '@nx/expo:start'
|
|
||||||
) {
|
|
||||||
const targetsToDelete = [
|
|
||||||
'build-ios',
|
|
||||||
'build-android',
|
|
||||||
'build-web',
|
|
||||||
'build-status',
|
|
||||||
'publish',
|
|
||||||
'publish-set',
|
|
||||||
'rollback',
|
|
||||||
'eject',
|
|
||||||
];
|
|
||||||
targetsToDelete.forEach((target) => {
|
|
||||||
if (config.targets[target]) {
|
|
||||||
delete config.targets[target];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
updateProjectConfiguration(tree, name, config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
import {
|
|
||||||
Tree,
|
|
||||||
addProjectConfiguration,
|
|
||||||
readJson,
|
|
||||||
updateJson,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import update from './update-eas-scripts';
|
|
||||||
|
|
||||||
describe('update-eas-scripts', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
|
|
||||||
addProjectConfiguration(tree, 'products', {
|
|
||||||
root: 'apps/products',
|
|
||||||
sourceRoot: 'apps/products/src',
|
|
||||||
targets: {
|
|
||||||
start: {
|
|
||||||
executor: '@nrwl/expo:start',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
tree.write('apps/products/package.json', JSON.stringify({}));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add scripts', async () => {
|
|
||||||
update(tree);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
tree.exists('tools/scripts/eas-build-post-install.mjs')
|
|
||||||
).toBeTruthy();
|
|
||||||
const packageJson = readJson(tree, 'apps/products/package.json');
|
|
||||||
expect(packageJson.scripts['eas-build-post-install']).toEqual(
|
|
||||||
'cd ../../ && node tools/scripts/eas-build-post-install.mjs . apps/products'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove postinstall script', async () => {
|
|
||||||
updateJson(tree, 'apps/products/package.json', (json) => {
|
|
||||||
json.scripts = {
|
|
||||||
postinstall: 'some script',
|
|
||||||
};
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
update(tree);
|
|
||||||
|
|
||||||
const packageJson = readJson(tree, 'apps/products/package.json');
|
|
||||||
expect(packageJson.scripts['postinstall']).toBeUndefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
import {
|
|
||||||
Tree,
|
|
||||||
getProjects,
|
|
||||||
logger,
|
|
||||||
offsetFromRoot,
|
|
||||||
updateJson,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import { addEasScripts } from '../../generators/application/lib/add-eas-scripts';
|
|
||||||
import { join } from 'path';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update app's package.json to use eas-build-post-install scripts.
|
|
||||||
*/
|
|
||||||
export default function update(tree: Tree) {
|
|
||||||
const projects = getProjects(tree);
|
|
||||||
|
|
||||||
for (const [name, config] of projects.entries()) {
|
|
||||||
if (
|
|
||||||
config.targets?.['start']?.executor === '@nrwl/expo:start' ||
|
|
||||||
config.targets?.['start']?.executor === '@nx/expo:start'
|
|
||||||
) {
|
|
||||||
try {
|
|
||||||
addEasScripts(tree);
|
|
||||||
updateJson(tree, join(config.root, 'package.json'), (packageJson) => {
|
|
||||||
if (packageJson.scripts?.['postinstall']) {
|
|
||||||
delete packageJson.scripts['postinstall'];
|
|
||||||
}
|
|
||||||
const offset = offsetFromRoot(config.root);
|
|
||||||
packageJson.scripts = {
|
|
||||||
...packageJson.scripts,
|
|
||||||
'eas-build-post-install': `cd ${offset} && node tools/scripts/eas-build-post-install.mjs . ${config.root}`,
|
|
||||||
};
|
|
||||||
return packageJson;
|
|
||||||
});
|
|
||||||
} catch {
|
|
||||||
logger.error(`Unable to update package.json for project ${name}.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
import { Tree, getProjects, updateProjectConfiguration } from '@nx/devkit';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This migration adds dependsOn to project.json.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export default async function update(tree: Tree) {
|
|
||||||
const projects = getProjects(tree);
|
|
||||||
|
|
||||||
for (const [name, config] of projects.entries()) {
|
|
||||||
if (config.targets?.['start']?.executor === '@nx/expo:start') {
|
|
||||||
config.targets['start'].dependsOn = ['ensure-symlink', 'sync-deps'];
|
|
||||||
}
|
|
||||||
if (config.targets?.['run-ios']?.executor === '@nx/expo:run') {
|
|
||||||
config.targets['run-ios'].dependsOn = ['ensure-symlink', 'sync-deps'];
|
|
||||||
}
|
|
||||||
if (config.targets?.['run-android']?.executor === '@nx/expo:run') {
|
|
||||||
config.targets['run-android'].dependsOn = ['ensure-symlink', 'sync-deps'];
|
|
||||||
}
|
|
||||||
if (config.targets?.['prebuild']?.executor === '@nx/expo:prebuild') {
|
|
||||||
config.targets['prebuild'].dependsOn = ['ensure-symlink', 'sync-deps'];
|
|
||||||
}
|
|
||||||
if (config.targets?.['export']?.executor === '@nx/expo:export') {
|
|
||||||
config.targets['export'].dependsOn = ['ensure-symlink', 'sync-deps'];
|
|
||||||
}
|
|
||||||
|
|
||||||
updateProjectConfiguration(tree, name, config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
import { Tree, getProjects } from '@nx/devkit';
|
|
||||||
import { join } from 'path';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This migration updates metro.config.js to export config as a default.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export default async function update(tree: Tree) {
|
|
||||||
const projects = getProjects(tree);
|
|
||||||
|
|
||||||
for (const [_, config] of projects.entries()) {
|
|
||||||
if (config.targets?.['start']?.executor === '@nx/expo:start') {
|
|
||||||
if (tree.exists(join(config.root, 'metro.config.js'))) {
|
|
||||||
const oldConfig = tree
|
|
||||||
.read(join(config.root, 'metro.config.js'))
|
|
||||||
.toString();
|
|
||||||
tree.write(
|
|
||||||
join(config.root, 'metro-v71.config.js'),
|
|
||||||
oldConfigComment + oldConfig
|
|
||||||
);
|
|
||||||
tree.write(join(config.root, 'metro.config.js'), content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const oldConfigComment = `/**
|
|
||||||
* Old custom configuration for React Native v0.71.
|
|
||||||
* From @react-native/metro-config 0.72.1, it is no longer necessary to use a config function to access the complete default config.
|
|
||||||
* Please port your custom configuration to metro.config.js.
|
|
||||||
* Please see https://docs.expo.dev/guides/customizing-metro/ to learn about configuration.
|
|
||||||
*/
|
|
||||||
`;
|
|
||||||
|
|
||||||
const content = `
|
|
||||||
const { withNxMetro } = require('@nx/expo');
|
|
||||||
const { getDefaultConfig } = require('@expo/metro-config');
|
|
||||||
const { mergeConfig } = require('metro-config');
|
|
||||||
|
|
||||||
const defaultConfig = getDefaultConfig(__dirname);
|
|
||||||
const { assetExts, sourceExts } = defaultConfig.resolver;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Metro configuration
|
|
||||||
* https://facebook.github.io/metro/docs/configuration
|
|
||||||
*
|
|
||||||
* @type {import('metro-config').MetroConfig}
|
|
||||||
*/
|
|
||||||
const customConfig = {
|
|
||||||
transformer: {
|
|
||||||
babelTransformerPath: require.resolve('react-native-svg-transformer'),
|
|
||||||
},
|
|
||||||
resolver: {
|
|
||||||
assetExts: assetExts.filter((ext) => ext !== 'svg'),
|
|
||||||
sourceExts: [...sourceExts, 'cjs', 'mjs', 'svg'],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = withNxMetro(mergeConfig(defaultConfig, customConfig), {
|
|
||||||
// Change this to true to see debugging info.
|
|
||||||
// Useful if you have issues resolving modules
|
|
||||||
debug: false,
|
|
||||||
// all the file extensions used for imports other than 'ts', 'tsx', 'js', 'jsx', 'json'
|
|
||||||
extensions: [],
|
|
||||||
// Specify folders to watch, in addition to Nx defaults (workspace libraries and node_modules)
|
|
||||||
watchFolders: [],
|
|
||||||
});
|
|
||||||
`;
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
import {
|
|
||||||
formatFiles,
|
|
||||||
removeDependenciesFromPackageJson,
|
|
||||||
Tree,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove @types/react-native package since it is no longer required. It would be a part of react native package.
|
|
||||||
* @param tree
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export default async function update(tree: Tree) {
|
|
||||||
removeDependenciesFromPackageJson(tree, [], ['@types/react-native']);
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
import { addProjectConfiguration, getProjects, Tree } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import update from './update-eas-cli-version';
|
|
||||||
|
|
||||||
describe('update-eas-cli-version', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
||||||
addProjectConfiguration(tree, 'product', {
|
|
||||||
root: 'apps/product',
|
|
||||||
sourceRoot: 'apps/product/src',
|
|
||||||
targets: {
|
|
||||||
start: {
|
|
||||||
executor: '@nx/expo:start',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
tree.write('apps/product/eas.json', '{"cli":{"version": "1.2.3"}}');
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should update eas.json with greater than version`, async () => {
|
|
||||||
await update(tree);
|
|
||||||
|
|
||||||
const easJson = JSON.parse(tree.read('apps/product/eas.json').toString());
|
|
||||||
expect(easJson.cli.version).toContain('>=');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
import { Tree, getProjects, updateJson } from '@nx/devkit';
|
|
||||||
|
|
||||||
export default async function update(tree: Tree) {
|
|
||||||
const projects = getProjects(tree);
|
|
||||||
|
|
||||||
for (const [name, config] of projects.entries()) {
|
|
||||||
if (config.targets?.['start']?.executor === '@nx/expo:start') {
|
|
||||||
updateJson(tree, `${config.root}/eas.json`, (easJson) => {
|
|
||||||
if (easJson?.cli?.version) {
|
|
||||||
easJson.cli.version = `>= 5`;
|
|
||||||
}
|
|
||||||
return easJson;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +1,4 @@
|
|||||||
{
|
{
|
||||||
"generators": {
|
"generators": {},
|
||||||
"update-16-0-0-add-nx-packages": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.0.0-beta.1",
|
|
||||||
"description": "Replace @nrwl/express with @nx/express",
|
|
||||||
"implementation": "./src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"packageJsonUpdates": {}
|
"packageJsonUpdates": {}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
import { Tree, readJson, updateJson } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import replacePackage from './update-16-0-0-add-nx-packages';
|
|
||||||
|
|
||||||
describe('update-16-0-0-add-nx-packages', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
|
|
||||||
updateJson(tree, 'package.json', (json) => {
|
|
||||||
json.devDependencies['@nrwl/express'] = '16.0.0';
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the dependency on @nrwl/express', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').dependencies['@nrwl/express']
|
|
||||||
).not.toBeDefined();
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nrwl/express']
|
|
||||||
).not.toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add a dependency on @nx/express', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
const packageJson = readJson(tree, 'package.json');
|
|
||||||
const newDependencyVersion =
|
|
||||||
packageJson.devDependencies['@nx/express'] ??
|
|
||||||
packageJson.dependencies['@nx/express'];
|
|
||||||
|
|
||||||
expect(newDependencyVersion).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import { Tree, formatFiles } from '@nx/devkit';
|
|
||||||
import { replaceNrwlPackageWithNxPackage } from '@nx/devkit/src/utils/replace-package';
|
|
||||||
|
|
||||||
export default async function replacePackage(tree: Tree): Promise<void> {
|
|
||||||
await replaceNrwlPackageWithNxPackage(tree, '@nrwl/express', '@nx/express');
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,17 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generators": {
|
"generators": {
|
||||||
"update-16-0-0-add-nx-packages": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.0.0-beta.1",
|
|
||||||
"description": "Replace @nrwl/jest with @nx/jest",
|
|
||||||
"implementation": "./src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages"
|
|
||||||
},
|
|
||||||
"add-test-setup-to-inputs-ignore": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.5.0-beta.2",
|
|
||||||
"description": "Add test-setup.ts to ignored files in production input",
|
|
||||||
"implementation": "./src/migrations/update-16-5-0/add-test-setup-to-inputs-ignore"
|
|
||||||
},
|
|
||||||
"move-options-to-target-defaults": {
|
"move-options-to-target-defaults": {
|
||||||
"version": "17.1.0-beta.2",
|
"version": "17.1.0-beta.2",
|
||||||
"description": "Move jest executor options to nx.json targetDefaults",
|
"description": "Move jest executor options to nx.json targetDefaults",
|
||||||
@ -19,15 +7,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packageJsonUpdates": {
|
"packageJsonUpdates": {
|
||||||
"16.0.0": {
|
|
||||||
"version": "16.0.0-beta.4",
|
|
||||||
"packages": {
|
|
||||||
"ts-jest": {
|
|
||||||
"version": "~29.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"17.2.0": {
|
"17.2.0": {
|
||||||
"version": "17.2.0-beta.2",
|
"version": "17.2.0-beta.2",
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
import { Tree, readJson, updateJson } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import replacePackage from './update-16-0-0-add-nx-packages';
|
|
||||||
|
|
||||||
describe('update-16-0-0-add-nx-packages', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
|
|
||||||
updateJson(tree, 'package.json', (json) => {
|
|
||||||
json.devDependencies['@nrwl/jest'] = '16.0.0';
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the dependency on @nrwl/jest', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').dependencies['@nrwl/jest']
|
|
||||||
).not.toBeDefined();
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nrwl/jest']
|
|
||||||
).not.toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add a dependency on @nx/jest', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
const packageJson = readJson(tree, 'package.json');
|
|
||||||
const newDependencyVersion =
|
|
||||||
packageJson.devDependencies['@nx/jest'] ??
|
|
||||||
packageJson.dependencies['@nx/jest'];
|
|
||||||
|
|
||||||
expect(newDependencyVersion).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import { Tree, formatFiles } from '@nx/devkit';
|
|
||||||
import { replaceNrwlPackageWithNxPackage } from '@nx/devkit/src/utils/replace-package';
|
|
||||||
|
|
||||||
export default async function replacePackage(tree: Tree): Promise<void> {
|
|
||||||
await replaceNrwlPackageWithNxPackage(tree, '@nrwl/jest', '@nx/jest');
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
import { Tree, readNxJson, updateNxJson } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import addTestSetupToIgnoredInputs from './add-test-setup-to-inputs-ignore';
|
|
||||||
|
|
||||||
describe('Jest Migration - jest 29 mocked usage in tests', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add inputs configuration for test-setup if missing', async () => {
|
|
||||||
updateNxJson(tree, {
|
|
||||||
namedInputs: {
|
|
||||||
default: ['{projectRoot}/**/*', 'sharedGlobals'],
|
|
||||||
sharedGlobals: [],
|
|
||||||
production: ['default'],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await addTestSetupToIgnoredInputs(tree);
|
|
||||||
|
|
||||||
const updated = readNxJson(tree);
|
|
||||||
expect(updated.namedInputs.production).toMatchInlineSnapshot(`
|
|
||||||
[
|
|
||||||
"default",
|
|
||||||
"!{projectRoot}/src/test-setup.[jt]s",
|
|
||||||
]
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not add inputs configuration for test-setup if existing', async () => {
|
|
||||||
updateNxJson(tree, {
|
|
||||||
namedInputs: {
|
|
||||||
default: ['{projectRoot}/**/*', 'sharedGlobals'],
|
|
||||||
sharedGlobals: [],
|
|
||||||
production: ['!{projectRoot}/src/test-setup.[jt]s', 'default'],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await addTestSetupToIgnoredInputs(tree);
|
|
||||||
|
|
||||||
const updated = readNxJson(tree);
|
|
||||||
expect(updated.namedInputs.production).toMatchInlineSnapshot(`
|
|
||||||
[
|
|
||||||
"!{projectRoot}/src/test-setup.[jt]s",
|
|
||||||
"default",
|
|
||||||
]
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
import {
|
|
||||||
NxJsonConfiguration,
|
|
||||||
Tree,
|
|
||||||
formatFiles,
|
|
||||||
readNxJson,
|
|
||||||
updateNxJson,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
|
|
||||||
export async function addTestSetupToIgnoredInputs(tree: Tree) {
|
|
||||||
const nxJson: NxJsonConfiguration = readNxJson(tree);
|
|
||||||
|
|
||||||
if (!nxJson) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
nxJson.namedInputs?.production &&
|
|
||||||
!nxJson.namedInputs.production.includes(
|
|
||||||
'!{projectRoot}/src/test-setup.[jt]s'
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
nxJson.namedInputs.production.push('!{projectRoot}/src/test-setup.[jt]s');
|
|
||||||
updateNxJson(tree, nxJson);
|
|
||||||
}
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default addTestSetupToIgnoredInputs;
|
|
||||||
@ -1,23 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generators": {
|
"generators": {
|
||||||
"update-16-0-0-add-nx-packages": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.0.0-beta.1",
|
|
||||||
"description": "Replace @nrwl/js with @nx/js",
|
|
||||||
"implementation": "./src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages"
|
|
||||||
},
|
|
||||||
"explicitly-set-projects-to-update-buildable-deps": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.6.0-beta.0",
|
|
||||||
"description": "Explicitly set 'updateBuildableProjectDepsInPackageJson' to 'true' in targets that rely on that value as the default.",
|
|
||||||
"factory": "./src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps"
|
|
||||||
},
|
|
||||||
"16-8-2-update-swcrc": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.8.2-beta.0",
|
|
||||||
"description": "Remove invalid options (strict, noInterop) for ES6 type modules.",
|
|
||||||
"factory": "./src/migrations/update-16-8-2/update-swcrc"
|
|
||||||
},
|
|
||||||
"update-17-0-0-remove-deprecated-build-options": {
|
"update-17-0-0-remove-deprecated-build-options": {
|
||||||
"cli": "nx",
|
"cli": "nx",
|
||||||
"version": "17.0.2",
|
"version": "17.0.2",
|
||||||
@ -26,65 +8,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packageJsonUpdates": {
|
"packageJsonUpdates": {
|
||||||
"16.0.0": {
|
|
||||||
"version": "16.0.0-beta.3",
|
|
||||||
"packages": {
|
|
||||||
"@swc/cli": {
|
|
||||||
"version": "~0.1.62",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@swc/helpers": {
|
|
||||||
"version": "~0.5.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.1.0": {
|
|
||||||
"version": "16.1.0-beta.0",
|
|
||||||
"x-prompt": "Do you want to update to TypeScript v5.0?",
|
|
||||||
"requires": {
|
|
||||||
"typescript": ">=4.9.5 <5.0.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"typescript": {
|
|
||||||
"version": "~5.0.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.4.0": {
|
|
||||||
"version": "16.4.0-beta.11",
|
|
||||||
"x-prompt": "Do you want to update to TypeScript v5.1?",
|
|
||||||
"requires": {
|
|
||||||
"typescript": ">=5.0.0 <5.1.0"
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"typescript": {
|
|
||||||
"version": "~5.1.3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.8.2": {
|
|
||||||
"version": "16.8.2-beta.0",
|
|
||||||
"packages": {
|
|
||||||
"@swc/core": {
|
|
||||||
"version": "~1.3.85",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@swc/helpers": {
|
|
||||||
"version": "~0.5.2",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.9.2": {
|
|
||||||
"version": "16.9.2-beta.0",
|
|
||||||
"packages": {
|
|
||||||
"@swc-node/register": {
|
|
||||||
"version": "~1.6.7",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"17.0.0": {
|
"17.0.0": {
|
||||||
"version": "17.0.0-rc.2",
|
"version": "17.0.0-rc.2",
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
import { Tree, readJson, updateJson } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import replacePackage from './update-16-0-0-add-nx-packages';
|
|
||||||
|
|
||||||
describe('update-16-0-0-add-nx-packages', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
|
|
||||||
updateJson(tree, 'package.json', (json) => {
|
|
||||||
json.devDependencies['@nrwl/js'] = '16.0.0';
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the dependency on @nrwl/js', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').dependencies['@nrwl/js']
|
|
||||||
).not.toBeDefined();
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nrwl/js']
|
|
||||||
).not.toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add a dependency on @nx/js', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
const packageJson = readJson(tree, 'package.json');
|
|
||||||
const newDependencyVersion =
|
|
||||||
packageJson.devDependencies['@nx/js'] ??
|
|
||||||
packageJson.dependencies['@nx/js'];
|
|
||||||
|
|
||||||
expect(newDependencyVersion).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import { Tree, formatFiles } from '@nx/devkit';
|
|
||||||
import { replaceNrwlPackageWithNxPackage } from '@nx/devkit/src/utils/replace-package';
|
|
||||||
|
|
||||||
export default async function replacePackage(tree: Tree): Promise<void> {
|
|
||||||
await replaceNrwlPackageWithNxPackage(tree, '@nrwl/js', '@nx/js');
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,119 +0,0 @@
|
|||||||
import {
|
|
||||||
ProjectConfiguration,
|
|
||||||
ProjectGraph,
|
|
||||||
Tree,
|
|
||||||
addProjectConfiguration,
|
|
||||||
readProjectConfiguration,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import migration from './explicitly-set-projects-to-update-buildable-deps';
|
|
||||||
|
|
||||||
let projectGraph: ProjectGraph;
|
|
||||||
jest.mock('@nx/devkit', () => ({
|
|
||||||
...jest.requireActual('@nx/devkit'),
|
|
||||||
createProjectGraphAsync: () => Promise.resolve(projectGraph),
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('explicitly-set-projects-to-update-buildable-deps migration', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
});
|
|
||||||
|
|
||||||
it.each(['@nx/js:swc', '@nrwl/js:swc', '@nx/js:tsc', '@nrwl/js:tsc'])(
|
|
||||||
'should set updateBuildableProjectDepsInPackageJson option to "true" when not specified in target using "%s"',
|
|
||||||
async (executor) => {
|
|
||||||
addProject(tree, 'lib1', {
|
|
||||||
root: 'lib1',
|
|
||||||
projectType: 'library',
|
|
||||||
targets: { build: { executor, options: {} } },
|
|
||||||
});
|
|
||||||
|
|
||||||
await migration(tree);
|
|
||||||
|
|
||||||
const project = readProjectConfiguration(tree, 'lib1');
|
|
||||||
expect(
|
|
||||||
project.targets.build.options.updateBuildableProjectDepsInPackageJson
|
|
||||||
).toBe(true);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
it.each(['@nx/js:swc', '@nrwl/js:swc', '@nx/js:tsc', '@nrwl/js:tsc'])(
|
|
||||||
'should set updateBuildableProjectDepsInPackageJson option to "true" when target has no options object defined using "%s"',
|
|
||||||
async (executor) => {
|
|
||||||
addProject(tree, 'lib1', {
|
|
||||||
root: 'lib1',
|
|
||||||
projectType: 'library',
|
|
||||||
targets: { build: { executor } },
|
|
||||||
});
|
|
||||||
|
|
||||||
await migration(tree);
|
|
||||||
|
|
||||||
const project = readProjectConfiguration(tree, 'lib1');
|
|
||||||
expect(
|
|
||||||
project.targets.build.options.updateBuildableProjectDepsInPackageJson
|
|
||||||
).toBe(true);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
it.each(['@nx/js:swc', '@nrwl/js:swc', '@nx/js:tsc', '@nrwl/js:tsc'])(
|
|
||||||
'should not overwrite updateBuildableProjectDepsInPackageJson option when it is specified in target using "%s"',
|
|
||||||
async (executor) => {
|
|
||||||
addProject(tree, 'lib1', {
|
|
||||||
root: 'lib1',
|
|
||||||
projectType: 'library',
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
executor,
|
|
||||||
options: { updateBuildableProjectDepsInPackageJson: false },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await migration(tree);
|
|
||||||
|
|
||||||
const project = readProjectConfiguration(tree, 'lib1');
|
|
||||||
expect(
|
|
||||||
project.targets.build.options.updateBuildableProjectDepsInPackageJson
|
|
||||||
).toBe(false);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
it('should not update targets using other executors', async () => {
|
|
||||||
const originalProjectConfig: ProjectConfiguration = {
|
|
||||||
root: 'lib1',
|
|
||||||
projectType: 'library',
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
executor: 'some-executor',
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
addProject(tree, 'lib1', originalProjectConfig);
|
|
||||||
|
|
||||||
await migration(tree);
|
|
||||||
|
|
||||||
const project = readProjectConfiguration(tree, 'lib1');
|
|
||||||
expect(project.targets).toStrictEqual(originalProjectConfig.targets);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function addProject(
|
|
||||||
tree: Tree,
|
|
||||||
projectName: string,
|
|
||||||
config: ProjectConfiguration
|
|
||||||
): void {
|
|
||||||
projectGraph = {
|
|
||||||
dependencies: {},
|
|
||||||
nodes: {
|
|
||||||
[projectName]: {
|
|
||||||
data: config,
|
|
||||||
name: projectName,
|
|
||||||
type: config.projectType === 'application' ? 'app' : 'lib',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
addProjectConfiguration(tree, projectName, config);
|
|
||||||
}
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
import {
|
|
||||||
createProjectGraphAsync,
|
|
||||||
formatFiles,
|
|
||||||
readProjectConfiguration,
|
|
||||||
Tree,
|
|
||||||
updateProjectConfiguration,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
|
|
||||||
const executors = new Set([
|
|
||||||
'@nx/js:swc',
|
|
||||||
'@nrwl/js:swc',
|
|
||||||
'@nx/js:tsc',
|
|
||||||
'@nrwl/js:tsc',
|
|
||||||
]);
|
|
||||||
|
|
||||||
export default async function (tree: Tree) {
|
|
||||||
// use project graph to get the expanded target configurations
|
|
||||||
const projectGraph = await createProjectGraphAsync();
|
|
||||||
|
|
||||||
for (const [projectName, { data: projectData }] of Object.entries(
|
|
||||||
projectGraph.nodes
|
|
||||||
)) {
|
|
||||||
if (projectData.projectType !== 'library') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const [targetName, target] of Object.entries(
|
|
||||||
projectData.targets || {}
|
|
||||||
)) {
|
|
||||||
if (!executors.has(target.executor)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
!target.options ||
|
|
||||||
target.options.updateBuildableProjectDepsInPackageJson === undefined
|
|
||||||
) {
|
|
||||||
// read the project configuration to write the explicit project configuration
|
|
||||||
// and avoid writing the expanded target configuration
|
|
||||||
const project = readProjectConfiguration(tree, projectName);
|
|
||||||
project.targets[targetName].options ??= {};
|
|
||||||
project.targets[
|
|
||||||
targetName
|
|
||||||
].options.updateBuildableProjectDepsInPackageJson = true;
|
|
||||||
updateProjectConfiguration(tree, projectName, project);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
import { addProjectConfiguration, readJson, Tree, writeJson } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import update from './update-swcrc';
|
|
||||||
|
|
||||||
describe('Migration: update .swcrc', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove invalid options for ES6 modules', async () => {
|
|
||||||
addProjectConfiguration(tree, 'pkg', {
|
|
||||||
root: 'pkg',
|
|
||||||
});
|
|
||||||
writeJson(tree, 'pkg/.swcrc', {
|
|
||||||
module: {
|
|
||||||
type: 'es6',
|
|
||||||
strict: true,
|
|
||||||
noInterop: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await update(tree);
|
|
||||||
|
|
||||||
expect(readJson(tree, 'pkg/.swcrc')).toEqual({
|
|
||||||
module: {
|
|
||||||
type: 'es6',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should keep options for CommonJS modules', async () => {
|
|
||||||
addProjectConfiguration(tree, 'pkg', {
|
|
||||||
root: 'pkg',
|
|
||||||
});
|
|
||||||
writeJson(tree, 'pkg/.swcrc', {
|
|
||||||
module: {
|
|
||||||
type: 'commonjs',
|
|
||||||
strict: true,
|
|
||||||
noInterop: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await update(tree);
|
|
||||||
|
|
||||||
expect(readJson(tree, 'pkg/.swcrc')).toEqual({
|
|
||||||
module: {
|
|
||||||
type: 'commonjs',
|
|
||||||
strict: true,
|
|
||||||
noInterop: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should ignore projects without module options in .swcrc', async () => {
|
|
||||||
addProjectConfiguration(tree, 'pkg', {
|
|
||||||
root: 'pkg',
|
|
||||||
});
|
|
||||||
writeJson(tree, 'pkg/.swcrc', {
|
|
||||||
jsc: {
|
|
||||||
target: 'es2017',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await expect(update(tree)).resolves.not.toThrow();
|
|
||||||
|
|
||||||
expect(readJson(tree, 'pkg/.swcrc')).toEqual({
|
|
||||||
jsc: {
|
|
||||||
target: 'es2017',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should ignore projects without .swcrc', async () => {
|
|
||||||
addProjectConfiguration(tree, 'pkg', {
|
|
||||||
root: 'pkg',
|
|
||||||
});
|
|
||||||
|
|
||||||
await expect(update(tree)).resolves.not.toThrow();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
import {
|
|
||||||
formatFiles,
|
|
||||||
getProjects,
|
|
||||||
readJson,
|
|
||||||
Tree,
|
|
||||||
writeJson,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import { join } from 'path';
|
|
||||||
|
|
||||||
export default async function update(tree: Tree) {
|
|
||||||
const projects = getProjects(tree);
|
|
||||||
|
|
||||||
for (const config of projects.values()) {
|
|
||||||
const swcrcPath = join(config.root, '.swcrc');
|
|
||||||
if (!tree.exists(swcrcPath)) continue;
|
|
||||||
const json = readJson(tree, swcrcPath);
|
|
||||||
// No longer need strict or noInterop for es6 modules
|
|
||||||
// See: https://github.com/swc-project/swc/commit/7e8d72d
|
|
||||||
if (
|
|
||||||
json.module?.type === 'es6' &&
|
|
||||||
(json.module?.strict || json.module?.noInterop)
|
|
||||||
) {
|
|
||||||
delete json.module.noInterop;
|
|
||||||
delete json.module.strict;
|
|
||||||
writeJson(tree, swcrcPath, json);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,76 +1,4 @@
|
|||||||
{
|
{
|
||||||
"generators": {
|
"generators": {},
|
||||||
"update-16-0-0-add-nx-packages": {
|
"packageJsonUpdates": {}
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.0.0-beta.1",
|
|
||||||
"description": "Replace @nrwl/nest with @nx/nest",
|
|
||||||
"implementation": "./src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages"
|
|
||||||
},
|
|
||||||
"update-16-4-0-support-nestjs-10": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.4.0-beta.16",
|
|
||||||
"description": "Update TsConfig target to es2021 and CacheModule if being used. Read more at https://docs.nestjs.com/migration-guide",
|
|
||||||
"implementation": "./src/migrations/update-16-4-0-cache-manager/nestjs-10-updates"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"packageJsonUpdates": {
|
|
||||||
"16.1.0": {
|
|
||||||
"version": "16.1.0-beta.0",
|
|
||||||
"packages": {
|
|
||||||
"@nestjs/common": {
|
|
||||||
"version": "^9.1.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@nestjs/core": {
|
|
||||||
"version": "^9.1.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@nestjs/platform-express": {
|
|
||||||
"version": "^9.1.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@nestjs/schematics": {
|
|
||||||
"version": "^9.1.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@nestjs/swagger": {
|
|
||||||
"version": "^6.3.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@nestjs/testing": {
|
|
||||||
"version": "^9.1.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.4.0": {
|
|
||||||
"version": "16.4.0-beta.11",
|
|
||||||
"packages": {
|
|
||||||
"@nestjs/common": {
|
|
||||||
"version": "^10.0.2",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@nestjs/core": {
|
|
||||||
"version": "^10.0.2",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@nestjs/platform-express": {
|
|
||||||
"version": "^10.0.2",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@nestjs/schematics": {
|
|
||||||
"version": "^10.0.1",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@nestjs/swagger": {
|
|
||||||
"version": "^7.0.2",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
},
|
|
||||||
"@nestjs/testing": {
|
|
||||||
"version": "^10.0.2",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,7 +36,6 @@
|
|||||||
"@nx/js": "file:../js",
|
"@nx/js": "file:../js",
|
||||||
"@nx/eslint": "file:../eslint",
|
"@nx/eslint": "file:../eslint",
|
||||||
"@nx/node": "file:../node",
|
"@nx/node": "file:../node",
|
||||||
"@phenomnomnominal/tsquery": "~5.0.1",
|
|
||||||
"tslib": "^2.3.0"
|
"tslib": "^2.3.0"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
import { Tree, readJson, updateJson } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import replacePackage from './update-16-0-0-add-nx-packages';
|
|
||||||
|
|
||||||
describe('update-16-0-0-add-nx-packages', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
|
|
||||||
updateJson(tree, 'package.json', (json) => {
|
|
||||||
json.devDependencies['@nrwl/nest'] = '16.0.0';
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the dependency on @nrwl/nest', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').dependencies['@nrwl/nest']
|
|
||||||
).not.toBeDefined();
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nrwl/nest']
|
|
||||||
).not.toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add a dependency on @nx/nest', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
const packageJson = readJson(tree, 'package.json');
|
|
||||||
const newDependencyVersion =
|
|
||||||
packageJson.devDependencies['@nx/nest'] ??
|
|
||||||
packageJson.dependencies['@nx/nest'];
|
|
||||||
|
|
||||||
expect(newDependencyVersion).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import { Tree, formatFiles } from '@nx/devkit';
|
|
||||||
import { replaceNrwlPackageWithNxPackage } from '@nx/devkit/src/utils/replace-package';
|
|
||||||
|
|
||||||
export default async function replacePackage(tree: Tree): Promise<void> {
|
|
||||||
await replaceNrwlPackageWithNxPackage(tree, '@nrwl/nest', '@nx/nest');
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,134 +0,0 @@
|
|||||||
import {
|
|
||||||
Tree,
|
|
||||||
addDependenciesToPackageJson,
|
|
||||||
createProjectGraphAsync,
|
|
||||||
formatFiles,
|
|
||||||
getProjects,
|
|
||||||
joinPathFragments,
|
|
||||||
updateJson,
|
|
||||||
visitNotIgnoredFiles,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import { tsquery } from '@phenomnomnominal/tsquery';
|
|
||||||
import {
|
|
||||||
ImportDeclaration,
|
|
||||||
VariableStatement,
|
|
||||||
ScriptTarget,
|
|
||||||
isVariableStatement,
|
|
||||||
} from 'typescript';
|
|
||||||
|
|
||||||
const JS_TS_FILE_MATCHER = /\.[jt]sx?$/;
|
|
||||||
|
|
||||||
const importMatch =
|
|
||||||
':matches(ImportDeclaration, VariableStatement):has(Identifier[name="CacheModule"], Identifier[name="CacheModule"]):has(StringLiteral[value="@nestjs/common"])';
|
|
||||||
|
|
||||||
export async function updateNestJs10(tree: Tree) {
|
|
||||||
const nestProjects = await getNestProejcts();
|
|
||||||
if (nestProjects.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let installCacheModuleDeps = false;
|
|
||||||
const projects = getProjects(tree);
|
|
||||||
|
|
||||||
for (const projectName of nestProjects) {
|
|
||||||
const projectConfig = projects.get(projectName);
|
|
||||||
const tsConfig =
|
|
||||||
projectConfig.targets?.build?.options?.tsConfig ??
|
|
||||||
joinPathFragments(
|
|
||||||
projectConfig.root,
|
|
||||||
projectConfig.projectType === 'application'
|
|
||||||
? 'tsconfig.app.json'
|
|
||||||
: 'tsconfig.lib.json'
|
|
||||||
);
|
|
||||||
|
|
||||||
if (tree.exists(tsConfig)) {
|
|
||||||
updateTsConfigTarget(tree, tsConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
visitNotIgnoredFiles(tree, projectConfig.root, (filePath) => {
|
|
||||||
if (!JS_TS_FILE_MATCHER.test(filePath)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
installCacheModuleDeps =
|
|
||||||
updateCacheManagerImport(tree, filePath) || installCacheModuleDeps;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
|
|
||||||
return installCacheModuleDeps
|
|
||||||
? addDependenciesToPackageJson(
|
|
||||||
tree,
|
|
||||||
{
|
|
||||||
'@nestjs/cache-manager': '^2.0.0',
|
|
||||||
'cache-manager': '^5.2.3',
|
|
||||||
},
|
|
||||||
{}
|
|
||||||
)
|
|
||||||
: () => {};
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getNestProejcts(): Promise<string[]> {
|
|
||||||
const projectGraph = await createProjectGraphAsync();
|
|
||||||
|
|
||||||
return Object.entries(projectGraph.dependencies)
|
|
||||||
.filter(([node, dep]) =>
|
|
||||||
dep.some(
|
|
||||||
({ target }) =>
|
|
||||||
!projectGraph.externalNodes?.[node] && target === 'npm:@nestjs/common'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.map(([projectName]) => projectName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// change import { CacheModule } from '@nestjs/common';
|
|
||||||
// to import { CacheModule } from '@nestjs/cache-manager';
|
|
||||||
export function updateCacheManagerImport(
|
|
||||||
tree: Tree,
|
|
||||||
filePath: string
|
|
||||||
): boolean {
|
|
||||||
const content = tree.read(filePath, 'utf-8');
|
|
||||||
|
|
||||||
const updated = tsquery.replace(
|
|
||||||
content,
|
|
||||||
importMatch,
|
|
||||||
|
|
||||||
(node: ImportDeclaration | VariableStatement) => {
|
|
||||||
const text = node.getText();
|
|
||||||
return `${text.replace('CacheModule', '')}\n${
|
|
||||||
isVariableStatement(node)
|
|
||||||
? "const { CacheModule } = require('@nestjs/cache-manager')"
|
|
||||||
: "import { CacheModule } from '@nestjs/cache-manager';"
|
|
||||||
}`;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (updated !== content) {
|
|
||||||
tree.write(filePath, updated);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateTsConfigTarget(tree: Tree, tsConfigPath: string) {
|
|
||||||
updateJson(tree, tsConfigPath, (json) => {
|
|
||||||
if (!json.compilerOptions.target) {
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
const normalizedTargetName = json.compilerOptions.target.toUpperCase();
|
|
||||||
// es6 isn't apart of the ScriptTarget enum but is a valid tsconfig target in json file
|
|
||||||
const existingTarget =
|
|
||||||
normalizedTargetName === 'ES6'
|
|
||||||
? ScriptTarget.ES2015
|
|
||||||
: (ScriptTarget[normalizedTargetName] as unknown as ScriptTarget);
|
|
||||||
|
|
||||||
if (existingTarget < ScriptTarget.ES2021) {
|
|
||||||
json.compilerOptions.target = 'es2021';
|
|
||||||
}
|
|
||||||
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export default updateNestJs10;
|
|
||||||
@ -1,242 +0,0 @@
|
|||||||
import {
|
|
||||||
ProjectConfiguration,
|
|
||||||
ProjectGraph,
|
|
||||||
Tree,
|
|
||||||
addProjectConfiguration,
|
|
||||||
readJson,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import {
|
|
||||||
updateNestJs10,
|
|
||||||
updateCacheManagerImport,
|
|
||||||
updateTsConfigTarget,
|
|
||||||
} from './nestjs-10-updates';
|
|
||||||
import { createTreeWithEmptyWorkspace } from 'nx/src/devkit-testing-exports';
|
|
||||||
|
|
||||||
let projectGraph: ProjectGraph;
|
|
||||||
jest.mock('@nx/devkit', () => ({
|
|
||||||
...jest.requireActual('@nx/devkit'),
|
|
||||||
createProjectGraphAsync: () => Promise.resolve(projectGraph),
|
|
||||||
}));
|
|
||||||
describe('nestjs 10 migration changes', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
||||||
|
|
||||||
jest.resetAllMocks();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update nestjs project', async () => {
|
|
||||||
tree.write(
|
|
||||||
'apps/app1/main.ts',
|
|
||||||
`
|
|
||||||
/**
|
|
||||||
* This is not a production server yet!
|
|
||||||
* This is only a minimal backend to get started.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Logger } from '@nestjs/common';
|
|
||||||
import { NestFactory } from '@nestjs/core';
|
|
||||||
import { CacheModule } from '@nestjs/common';
|
|
||||||
import { AppModule } from './app/app.module';
|
|
||||||
|
|
||||||
async function bootstrap() {
|
|
||||||
const app = await NestFactory.create(AppModule);
|
|
||||||
const globalPrefix = 'api';
|
|
||||||
app.setGlobalPrefix(globalPrefix);
|
|
||||||
const port = process.env.PORT || 3000;
|
|
||||||
await app.listen(port);
|
|
||||||
Logger.log('🚀 Application is running on: http://localhost:' + port + '/' + globalPrefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
bootstrap();
|
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
tree.write(
|
|
||||||
'apps/app1/tsconfig.app.json',
|
|
||||||
JSON.stringify({
|
|
||||||
extends: './tsconfig.json',
|
|
||||||
compilerOptions: {
|
|
||||||
outDir: '../../dist/out-tsc',
|
|
||||||
module: 'commonjs',
|
|
||||||
types: ['node'],
|
|
||||||
emitDecoratorMetadata: true,
|
|
||||||
target: 'es2015',
|
|
||||||
},
|
|
||||||
exclude: ['jest.config.ts', 'src/**/*.spec.ts', 'src/**/*.test.ts'],
|
|
||||||
include: ['src/**/*.ts'],
|
|
||||||
})
|
|
||||||
);
|
|
||||||
addProject(
|
|
||||||
tree,
|
|
||||||
'app1',
|
|
||||||
{
|
|
||||||
root: 'apps/app1',
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
executor: '@nx/webpack:webpack',
|
|
||||||
options: {
|
|
||||||
tsConfig: 'apps/app1/tsconfig.app.json',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
['npm:@nestjs/common']
|
|
||||||
);
|
|
||||||
|
|
||||||
await updateNestJs10(tree);
|
|
||||||
|
|
||||||
expect(readJson(tree, 'package.json').dependencies).toMatchInlineSnapshot(`
|
|
||||||
{
|
|
||||||
"@nestjs/cache-manager": "^2.0.0",
|
|
||||||
"cache-manager": "^5.2.3",
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'apps/app1/tsconfig.app.json').compilerOptions.target
|
|
||||||
).toEqual('es2021');
|
|
||||||
expect(tree.read('apps/app1/main.ts', 'utf-8')).toContain(
|
|
||||||
"import { CacheModule } from '@nestjs/cache-manager';"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should work with non buildable lib', async () => {
|
|
||||||
tree.write(
|
|
||||||
'libs/lib1/src/lib/lib1.module.ts',
|
|
||||||
`
|
|
||||||
import { Module, CacheModule } from '@nestjs/common';
|
|
||||||
|
|
||||||
@Module({
|
|
||||||
controllers: [],
|
|
||||||
providers: [],
|
|
||||||
exports: [],
|
|
||||||
imports: [CacheModule.register()],
|
|
||||||
})
|
|
||||||
export class LibOneModule {}
|
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
tree.write(
|
|
||||||
'libs/lib1/tsconfig.lib.json',
|
|
||||||
JSON.stringify({
|
|
||||||
extends: './tsconfig.json',
|
|
||||||
compilerOptions: {
|
|
||||||
outDir: '../../dist/out-tsc',
|
|
||||||
module: 'commonjs',
|
|
||||||
types: ['node'],
|
|
||||||
emitDecoratorMetadata: true,
|
|
||||||
target: 'es6',
|
|
||||||
},
|
|
||||||
exclude: ['jest.config.ts', 'src/**/*.spec.ts', 'src/**/*.test.ts'],
|
|
||||||
include: ['src/**/*.ts'],
|
|
||||||
})
|
|
||||||
);
|
|
||||||
addProject(
|
|
||||||
tree,
|
|
||||||
'app1',
|
|
||||||
{
|
|
||||||
root: 'libs/lib1',
|
|
||||||
targets: {},
|
|
||||||
},
|
|
||||||
['npm:@nestjs/common']
|
|
||||||
);
|
|
||||||
|
|
||||||
await updateNestJs10(tree);
|
|
||||||
|
|
||||||
expect(readJson(tree, 'package.json').dependencies).toMatchInlineSnapshot(`
|
|
||||||
{
|
|
||||||
"@nestjs/cache-manager": "^2.0.0",
|
|
||||||
"cache-manager": "^5.2.3",
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'libs/lib1/tsconfig.lib.json').compilerOptions.target
|
|
||||||
).toEqual('es2021');
|
|
||||||
expect(tree.read('libs/lib1/src/lib/lib1.module.ts', 'utf-8')).toContain(
|
|
||||||
"import { CacheModule } from '@nestjs/cache-manager';"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update cache module import', () => {
|
|
||||||
tree.write(
|
|
||||||
'main.ts',
|
|
||||||
`
|
|
||||||
import { Module, CacheModule } from '@nestjs/common';
|
|
||||||
const { Module, CacheModule } = require('@nestjs/common');
|
|
||||||
`
|
|
||||||
);
|
|
||||||
const actual = updateCacheManagerImport(tree, 'main.ts');
|
|
||||||
|
|
||||||
expect(tree.read('main.ts', 'utf-8')).toMatchInlineSnapshot(`
|
|
||||||
"
|
|
||||||
import { Module, } from '@nestjs/common';
|
|
||||||
import { CacheModule } from '@nestjs/cache-manager';
|
|
||||||
const { Module, } = require('@nestjs/common');
|
|
||||||
const { CacheModule } = require('@nestjs/cache-manager')
|
|
||||||
"
|
|
||||||
`);
|
|
||||||
expect(actual).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should NOT update cache module imports', () => {
|
|
||||||
tree.write(
|
|
||||||
'main.ts',
|
|
||||||
`
|
|
||||||
import { AnotherModule } from '@nestjs/common';
|
|
||||||
const { AnotherModule } = require('@nestjs/common');
|
|
||||||
`
|
|
||||||
);
|
|
||||||
const actual = updateCacheManagerImport(tree, 'main.ts');
|
|
||||||
|
|
||||||
expect(tree.read('main.ts', 'utf-8')).toMatchInlineSnapshot(`
|
|
||||||
"
|
|
||||||
import { AnotherModule } from '@nestjs/common';
|
|
||||||
const { AnotherModule } = require('@nestjs/common');
|
|
||||||
"
|
|
||||||
`);
|
|
||||||
expect(actual).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update script target', () => {
|
|
||||||
tree.write(
|
|
||||||
'tsconfig.json',
|
|
||||||
JSON.stringify({ compilerOptions: { target: 'es6' } })
|
|
||||||
);
|
|
||||||
updateTsConfigTarget(tree, 'tsconfig.json');
|
|
||||||
expect(readJson(tree, 'tsconfig.json').compilerOptions.target).toBe(
|
|
||||||
'es2021'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should NOT update script if over es2021', () => {
|
|
||||||
tree.write(
|
|
||||||
'tsconfig.json',
|
|
||||||
JSON.stringify({ compilerOptions: { target: 'es2022' } })
|
|
||||||
);
|
|
||||||
updateTsConfigTarget(tree, 'tsconfig.json');
|
|
||||||
expect(readJson(tree, 'tsconfig.json').compilerOptions.target).toBe(
|
|
||||||
'es2022'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function addProject(
|
|
||||||
tree: Tree,
|
|
||||||
projectName: string,
|
|
||||||
config: ProjectConfiguration,
|
|
||||||
dependencies: string[]
|
|
||||||
): void {
|
|
||||||
projectGraph = {
|
|
||||||
dependencies: {
|
|
||||||
[projectName]: dependencies.map((d) => ({
|
|
||||||
source: projectName,
|
|
||||||
target: d,
|
|
||||||
type: 'static',
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
nodes: {
|
|
||||||
[projectName]: { data: config, name: projectName, type: 'app' },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
addProjectConfiguration(tree, projectName, config);
|
|
||||||
}
|
|
||||||
@ -1,23 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generators": {
|
"generators": {
|
||||||
"update-16-0-0-add-nx-packages": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.0.0-beta.1",
|
|
||||||
"description": "Replace @nrwl/next with @nx/next",
|
|
||||||
"implementation": "./src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages"
|
|
||||||
},
|
|
||||||
"update-16-3-0-remove-root-build-option": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.3.0-beta.9",
|
|
||||||
"description": "Remove root build option from project configurations since it is not needed.",
|
|
||||||
"implementation": "./src/migrations/update-16-3-0/remove-root-build-option"
|
|
||||||
},
|
|
||||||
"update-16-4-0-update-next-dependency": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.4.0-beta.3",
|
|
||||||
"description": "Update package.json moving @nx/next from dependency to devDependency",
|
|
||||||
"implementation": "./src/migrations/update-16-4-0/update-nx-next-dependency"
|
|
||||||
},
|
|
||||||
"update-17-2-7": {
|
"update-17-2-7": {
|
||||||
"cli": "nx",
|
"cli": "nx",
|
||||||
"version": "17.2.7",
|
"version": "17.2.7",
|
||||||
@ -26,24 +8,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packageJsonUpdates": {
|
"packageJsonUpdates": {
|
||||||
"16.0.0": {
|
|
||||||
"version": "16.0.0-beta.0",
|
|
||||||
"packages": {
|
|
||||||
"next": {
|
|
||||||
"version": "13.3.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16.4.0-beta.4": {
|
|
||||||
"version": "16.4.0-beta.4",
|
|
||||||
"packages": {
|
|
||||||
"stylus": {
|
|
||||||
"version": "^0.59.0",
|
|
||||||
"alwaysAddToPackageJson": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"17.3.1-beta.0": {
|
"17.3.1-beta.0": {
|
||||||
"version": "17.3.1-beta.0",
|
"version": "17.3.1-beta.0",
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
import { Tree, readJson, updateJson } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import replacePackage from './update-16-0-0-add-nx-packages';
|
|
||||||
|
|
||||||
describe('update-16-0-0-add-nx-packages', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
|
|
||||||
updateJson(tree, 'package.json', (json) => {
|
|
||||||
json.devDependencies['@nrwl/next'] = '16.0.0';
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the dependency on @nrwl/next', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').dependencies['@nrwl/next']
|
|
||||||
).not.toBeDefined();
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nrwl/next']
|
|
||||||
).not.toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add a dependency on @nx/next', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
const packageJson = readJson(tree, 'package.json');
|
|
||||||
const newDependencyVersion =
|
|
||||||
packageJson.devDependencies['@nx/next'] ??
|
|
||||||
packageJson.dependencies['@nx/next'];
|
|
||||||
|
|
||||||
expect(newDependencyVersion).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import { Tree, formatFiles } from '@nx/devkit';
|
|
||||||
import { replaceNrwlPackageWithNxPackage } from '@nx/devkit/src/utils/replace-package';
|
|
||||||
|
|
||||||
export default async function replacePackage(tree: Tree): Promise<void> {
|
|
||||||
await replaceNrwlPackageWithNxPackage(tree, '@nrwl/next', '@nx/next');
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,72 +0,0 @@
|
|||||||
import update from './remove-root-build-option';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import {
|
|
||||||
addProjectConfiguration,
|
|
||||||
readProjectConfiguration,
|
|
||||||
Tree,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
|
|
||||||
describe('remove-root-build-option', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the root option from the build target for @nx/next:build executor', async () => {
|
|
||||||
addProjectConfiguration(tree, 'my-app', {
|
|
||||||
root: 'my-app',
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
executor: '@nx/next:build',
|
|
||||||
options: {
|
|
||||||
root: 'my-app',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await update(tree);
|
|
||||||
|
|
||||||
const updatedConfig = readProjectConfiguration(tree, 'my-app');
|
|
||||||
expect(updatedConfig.targets.build.options.root).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the root option from the build target for @nrwl/next:build executor', async () => {
|
|
||||||
addProjectConfiguration(tree, 'my-app', {
|
|
||||||
root: 'my-app',
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
executor: '@nrwl/next:build',
|
|
||||||
options: {
|
|
||||||
root: 'my-app',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await update(tree);
|
|
||||||
|
|
||||||
const updatedConfig = readProjectConfiguration(tree, 'my-app');
|
|
||||||
expect(updatedConfig.targets.build.options.root).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should leave other executors alone', async () => {
|
|
||||||
addProjectConfiguration(tree, 'my-app', {
|
|
||||||
root: 'my-app',
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
executor: '@acme/foo:bar',
|
|
||||||
options: {
|
|
||||||
root: 'my-app',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await update(tree);
|
|
||||||
|
|
||||||
const updatedConfig = readProjectConfiguration(tree, 'my-app');
|
|
||||||
expect(updatedConfig.targets.build.options.root).toEqual('my-app');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
import {
|
|
||||||
readProjectConfiguration,
|
|
||||||
Tree,
|
|
||||||
updateProjectConfiguration,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils';
|
|
||||||
|
|
||||||
export default async function update(tree: Tree) {
|
|
||||||
forEachExecutorOptions(
|
|
||||||
tree,
|
|
||||||
'@nx/next:build',
|
|
||||||
(options, projectName, targetName) => {
|
|
||||||
const projectConfig = readProjectConfiguration(tree, projectName);
|
|
||||||
delete projectConfig.targets[targetName].options.root;
|
|
||||||
updateProjectConfiguration(tree, projectName, projectConfig);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
forEachExecutorOptions(
|
|
||||||
tree,
|
|
||||||
'@nrwl/next:build',
|
|
||||||
(options, projectName, targetName) => {
|
|
||||||
const projectConfig = readProjectConfiguration(tree, projectName);
|
|
||||||
delete projectConfig.targets[targetName].options.root;
|
|
||||||
updateProjectConfiguration(tree, projectName, projectConfig);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
import { Tree, readJson, updateJson } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from 'nx/src/devkit-testing-exports';
|
|
||||||
import update from './update-nx-next-dependency';
|
|
||||||
|
|
||||||
describe('update-nx-next-dependency', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
|
|
||||||
updateJson(tree, 'package.json', (json) => {
|
|
||||||
json.dependencies['@nx/next'] = '16.0.0';
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should move @nx/next from dependencies to devDependencies', async () => {
|
|
||||||
await update(tree);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').dependencies['@nx/next']
|
|
||||||
).not.toBeDefined();
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nx/next']
|
|
||||||
).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
import { Tree, formatFiles, updateJson } from '@nx/devkit';
|
|
||||||
import type { PackageJson } from 'nx/src/utils/package-json';
|
|
||||||
|
|
||||||
export default async function update(tree: Tree) {
|
|
||||||
if (tree.exists('./package.json')) {
|
|
||||||
updateJson<PackageJson>(tree, 'package.json', (packageJson) => {
|
|
||||||
if (packageJson.dependencies['@nx/next']) {
|
|
||||||
packageJson.devDependencies['@nx/next'] =
|
|
||||||
packageJson.dependencies['@nx/next'];
|
|
||||||
delete packageJson.dependencies['@nx/next'];
|
|
||||||
}
|
|
||||||
return packageJson;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,30 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generators": {
|
"generators": {},
|
||||||
"update-16-0-0-add-nx-packages": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.0.0-beta.1",
|
|
||||||
"description": "Replace @nrwl/node with @nx/node",
|
|
||||||
"implementation": "./src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages"
|
|
||||||
},
|
|
||||||
"update-16-0-0-update-executor": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.0.0-beta.5",
|
|
||||||
"description": "Replace @nrwl/node:webpack with @nx/node:webpack",
|
|
||||||
"implementation": "./src/migrations/update-16-0-0/update-webpack-executor"
|
|
||||||
},
|
|
||||||
"update-16-3-1-update-executor": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.3.1-beta.0",
|
|
||||||
"description": "Replace @nrwl/node:webpack and @nx/node:webpack with @nx/webpack:webpack for all project targets",
|
|
||||||
"implementation": "./src/migrations/update-16-3-1/update-webpack-executor"
|
|
||||||
},
|
|
||||||
"update-16-4-0-replace-node-executor": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.4.0-beta.8",
|
|
||||||
"description": "Replace @nx/node:node with @nx/js:node for all project targets",
|
|
||||||
"implementation": "./src/migrations/update-16-4-0/replace-node-executor"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"packageJsonUpdates": {
|
"packageJsonUpdates": {
|
||||||
"17.3.0": {
|
"17.3.0": {
|
||||||
"version": "17.3.0-beta.3",
|
"version": "17.3.0-beta.3",
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
import { Tree, readJson, updateJson } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import replacePackage from './update-16-0-0-add-nx-packages';
|
|
||||||
|
|
||||||
describe('update-16-0-0-add-nx-packages', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
|
|
||||||
updateJson(tree, 'package.json', (json) => {
|
|
||||||
json.devDependencies['@nrwl/node'] = '16.0.0';
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the dependency on @nrwl/node', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').dependencies['@nrwl/node']
|
|
||||||
).not.toBeDefined();
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nrwl/node']
|
|
||||||
).not.toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add a dependency on @nx/node', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
const packageJson = readJson(tree, 'package.json');
|
|
||||||
const newDependencyVersion =
|
|
||||||
packageJson.devDependencies['@nx/node'] ??
|
|
||||||
packageJson.dependencies['@nx/node'];
|
|
||||||
|
|
||||||
expect(newDependencyVersion).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import { Tree, formatFiles } from '@nx/devkit';
|
|
||||||
import { replaceNrwlPackageWithNxPackage } from '@nx/devkit/src/utils/replace-package';
|
|
||||||
|
|
||||||
export default async function replacePackage(tree: Tree): Promise<void> {
|
|
||||||
await replaceNrwlPackageWithNxPackage(tree, '@nrwl/node', '@nx/node');
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
import { addProjectConfiguration, readProjectConfiguration } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
|
|
||||||
import update from './update-webpack-executor';
|
|
||||||
|
|
||||||
describe('Migration: @nrwl/webpack', () => {
|
|
||||||
it(`should update usage of webpack executor`, async () => {
|
|
||||||
let tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
||||||
|
|
||||||
addProjectConfiguration(tree, 'myapp', {
|
|
||||||
root: 'apps/myapp',
|
|
||||||
sourceRoot: 'apps/myapp/src',
|
|
||||||
projectType: 'application',
|
|
||||||
targets: {
|
|
||||||
foo: {
|
|
||||||
executor: '@nrwl/node:webpack',
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
bar: {
|
|
||||||
executor: '@nx/node:webpack',
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await update(tree);
|
|
||||||
|
|
||||||
expect(readProjectConfiguration(tree, 'myapp')).toEqual({
|
|
||||||
$schema: '../../node_modules/nx/schemas/project-schema.json',
|
|
||||||
name: 'myapp',
|
|
||||||
root: 'apps/myapp',
|
|
||||||
sourceRoot: 'apps/myapp/src',
|
|
||||||
projectType: 'application',
|
|
||||||
targets: {
|
|
||||||
foo: {
|
|
||||||
executor: '@nx/webpack:webpack',
|
|
||||||
options: {
|
|
||||||
compiler: 'tsc',
|
|
||||||
target: 'node',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
bar: {
|
|
||||||
executor: '@nx/webpack:webpack',
|
|
||||||
options: {
|
|
||||||
compiler: 'tsc',
|
|
||||||
target: 'node',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
import {
|
|
||||||
formatFiles,
|
|
||||||
readProjectConfiguration,
|
|
||||||
Tree,
|
|
||||||
updateProjectConfiguration,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils';
|
|
||||||
|
|
||||||
export default async function update(tree: Tree) {
|
|
||||||
const migrateProject = (options, projectName, targetName) => {
|
|
||||||
const projectConfig = readProjectConfiguration(tree, projectName);
|
|
||||||
projectConfig.targets[targetName].executor = '@nx/webpack:webpack';
|
|
||||||
projectConfig.targets[targetName].options.compiler = 'tsc';
|
|
||||||
projectConfig.targets[targetName].options.target = 'node';
|
|
||||||
updateProjectConfiguration(tree, projectName, projectConfig);
|
|
||||||
};
|
|
||||||
|
|
||||||
forEachExecutorOptions(tree, '@nx/node:webpack', migrateProject);
|
|
||||||
forEachExecutorOptions(tree, '@nrwl/node:webpack', migrateProject);
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
import { addProjectConfiguration, readProjectConfiguration } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
|
|
||||||
import update from './update-webpack-executor';
|
|
||||||
|
|
||||||
describe('Migration: @nrwl/webpack', () => {
|
|
||||||
it(`should update usage of webpack executor`, async () => {
|
|
||||||
let tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
||||||
|
|
||||||
addProjectConfiguration(tree, 'myapp', {
|
|
||||||
root: 'apps/myapp',
|
|
||||||
sourceRoot: 'apps/myapp/src',
|
|
||||||
projectType: 'application',
|
|
||||||
targets: {
|
|
||||||
foo: {
|
|
||||||
executor: '@nrwl/node:webpack',
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
bar: {
|
|
||||||
executor: '@nx/node:webpack',
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await update(tree);
|
|
||||||
|
|
||||||
expect(readProjectConfiguration(tree, 'myapp')).toEqual({
|
|
||||||
$schema: '../../node_modules/nx/schemas/project-schema.json',
|
|
||||||
name: 'myapp',
|
|
||||||
root: 'apps/myapp',
|
|
||||||
sourceRoot: 'apps/myapp/src',
|
|
||||||
projectType: 'application',
|
|
||||||
targets: {
|
|
||||||
foo: {
|
|
||||||
executor: '@nx/webpack:webpack',
|
|
||||||
options: {
|
|
||||||
compiler: 'tsc',
|
|
||||||
target: 'node',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
bar: {
|
|
||||||
executor: '@nx/webpack:webpack',
|
|
||||||
options: {
|
|
||||||
compiler: 'tsc',
|
|
||||||
target: 'node',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
import {
|
|
||||||
formatFiles,
|
|
||||||
readProjectConfiguration,
|
|
||||||
Tree,
|
|
||||||
updateProjectConfiguration,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils';
|
|
||||||
|
|
||||||
export default async function update(tree: Tree) {
|
|
||||||
const migrateProject = (options, projectName, targetName) => {
|
|
||||||
const projectConfig = readProjectConfiguration(tree, projectName);
|
|
||||||
projectConfig.targets[targetName].executor = '@nx/webpack:webpack';
|
|
||||||
projectConfig.targets[targetName].options.compiler = 'tsc';
|
|
||||||
projectConfig.targets[targetName].options.target = 'node';
|
|
||||||
updateProjectConfiguration(tree, projectName, projectConfig);
|
|
||||||
};
|
|
||||||
|
|
||||||
forEachExecutorOptions(tree, '@nx/node:webpack', migrateProject);
|
|
||||||
forEachExecutorOptions(tree, '@nrwl/node:webpack', migrateProject);
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,79 +0,0 @@
|
|||||||
import { addProjectConfiguration, readProjectConfiguration } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import update from './replace-node-executor';
|
|
||||||
|
|
||||||
describe('Migration: replace @nx/node:node executor', () => {
|
|
||||||
it(`should replace @nx/node:node executor with @nx/js:node`, async () => {
|
|
||||||
let tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
||||||
|
|
||||||
addProjectConfiguration(tree, 'myapp', {
|
|
||||||
root: 'apps/myapp',
|
|
||||||
sourceRoot: 'apps/myapp/src',
|
|
||||||
projectType: 'application',
|
|
||||||
targets: {
|
|
||||||
foo: {
|
|
||||||
executor: '@nx/node:node',
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
bar: {
|
|
||||||
executor: '@nx/node:node',
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
addProjectConfiguration(tree, 'myapp2', {
|
|
||||||
root: 'apps/myapp2',
|
|
||||||
sourceRoot: 'apps/myapp2/src',
|
|
||||||
projectType: 'application',
|
|
||||||
targets: {
|
|
||||||
foo: {
|
|
||||||
executor: '@nx/node:node',
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
bar: {
|
|
||||||
executor: '@nx/node:node',
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await update(tree);
|
|
||||||
|
|
||||||
expect(readProjectConfiguration(tree, 'myapp')).toEqual({
|
|
||||||
$schema: '../../node_modules/nx/schemas/project-schema.json',
|
|
||||||
name: 'myapp',
|
|
||||||
root: 'apps/myapp',
|
|
||||||
sourceRoot: 'apps/myapp/src',
|
|
||||||
projectType: 'application',
|
|
||||||
targets: {
|
|
||||||
foo: {
|
|
||||||
executor: '@nx/js:node',
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
bar: {
|
|
||||||
executor: '@nx/js:node',
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(readProjectConfiguration(tree, 'myapp2')).toEqual({
|
|
||||||
$schema: '../../node_modules/nx/schemas/project-schema.json',
|
|
||||||
name: 'myapp2',
|
|
||||||
root: 'apps/myapp2',
|
|
||||||
sourceRoot: 'apps/myapp2/src',
|
|
||||||
projectType: 'application',
|
|
||||||
targets: {
|
|
||||||
foo: {
|
|
||||||
executor: '@nx/js:node',
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
bar: {
|
|
||||||
executor: '@nx/js:node',
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
import {
|
|
||||||
formatFiles,
|
|
||||||
readProjectConfiguration,
|
|
||||||
Tree,
|
|
||||||
updateProjectConfiguration,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils';
|
|
||||||
|
|
||||||
export default async function update(tree: Tree) {
|
|
||||||
const migrateProject = (_options, projectName, targetName) => {
|
|
||||||
const projectConfig = readProjectConfiguration(tree, projectName);
|
|
||||||
projectConfig.targets[targetName].executor = '@nx/js:node';
|
|
||||||
updateProjectConfiguration(tree, projectName, projectConfig);
|
|
||||||
};
|
|
||||||
|
|
||||||
forEachExecutorOptions(tree, '@nx/node:node', migrateProject);
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,42 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generators": {
|
"generators": {
|
||||||
"16.0.0-remove-nrwl-cli": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.0.0-beta.0",
|
|
||||||
"description": "Remove @nrwl/cli.",
|
|
||||||
"implementation": "./src/migrations/update-16-0-0/remove-nrwl-cli"
|
|
||||||
},
|
|
||||||
"16.0.0-tokens-for-depends-on": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.0.0-beta.9",
|
|
||||||
"description": "Replace `dependsOn.projects` and `inputs` definitions with new configuration format.",
|
|
||||||
"implementation": "./src/migrations/update-16-0-0/update-depends-on-to-tokens"
|
|
||||||
},
|
|
||||||
"16.0.0-update-nx-cloud-runner": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.0.0-beta.0",
|
|
||||||
"description": "Replace @nrwl/nx-cloud with nx-cloud",
|
|
||||||
"implementation": "./src/migrations/update-16-0-0/update-nx-cloud-runner"
|
|
||||||
},
|
|
||||||
"16.2.0-remove-output-path-from-run-commands": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.2.0-beta.0",
|
|
||||||
"description": "Remove outputPath from run commands",
|
|
||||||
"implementation": "./src/migrations/update-16-2-0/remove-run-commands-output-path"
|
|
||||||
},
|
|
||||||
"16.6.0-prefix-outputs": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.6.0-beta.6",
|
|
||||||
"description": "Prefix outputs with {workspaceRoot}/{projectRoot} if needed",
|
|
||||||
"implementation": "./src/migrations/update-15-0-0/prefix-outputs"
|
|
||||||
},
|
|
||||||
"16.8.0-escape-dollar-sign-env": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.8.0-beta.3",
|
|
||||||
"description": "Escape $ in env variables",
|
|
||||||
"implementation": "./src/migrations/update-16-8-0/escape-dollar-sign-env-variables",
|
|
||||||
"x-repair-skip": true
|
|
||||||
},
|
|
||||||
"17.0.0-move-cache-directory": {
|
"17.0.0-move-cache-directory": {
|
||||||
"cli": "nx",
|
"cli": "nx",
|
||||||
"version": "17.0.0-beta.1",
|
"version": "17.0.0-beta.1",
|
||||||
|
|||||||
@ -2,17 +2,26 @@ import { MigrationsJson, MigrationsJsonEntry } from '../config/misc-interfaces';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
export function assertValidMigrationPaths(json: MigrationsJson, root: string) {
|
export function assertValidMigrationPaths(json: MigrationsJson, root: string) {
|
||||||
|
let hasTests = false;
|
||||||
Object.entries(json.generators).forEach(([generator, m]) => {
|
Object.entries(json.generators).forEach(([generator, m]) => {
|
||||||
|
hasTests = true;
|
||||||
it(`should have valid path generator: ${generator}`, () => {
|
it(`should have valid path generator: ${generator}`, () => {
|
||||||
validateMigration(m, root);
|
validateMigration(m, root);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.entries(json.schematics ?? {}).forEach(([schematic, m]) => {
|
Object.entries(json.schematics ?? {}).forEach(([schematic, m]) => {
|
||||||
|
hasTests = true;
|
||||||
it(`should have valid path schematic: ${schematic}`, () => {
|
it(`should have valid path schematic: ${schematic}`, () => {
|
||||||
validateMigration(m, root);
|
validateMigration(m, root);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!hasTests) {
|
||||||
|
it('should pass without migrations', () => {
|
||||||
|
// no-op
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateMigration(m: MigrationsJsonEntry, root: string) {
|
function validateMigration(m: MigrationsJsonEntry, root: string) {
|
||||||
|
|||||||
@ -1,192 +0,0 @@
|
|||||||
import { createTreeWithEmptyWorkspace } from '../../generators/testing-utils/create-tree-with-empty-workspace';
|
|
||||||
import type { Tree } from '../../generators/tree';
|
|
||||||
import {
|
|
||||||
addProjectConfiguration,
|
|
||||||
readNxJson,
|
|
||||||
readProjectConfiguration,
|
|
||||||
updateNxJson,
|
|
||||||
} from '../../generators/utils/project-configuration';
|
|
||||||
import { readJson, writeJson } from '../../generators/utils/json';
|
|
||||||
import prefixOutputs from './prefix-outputs';
|
|
||||||
import { validateOutputs } from '../../tasks-runner/utils';
|
|
||||||
|
|
||||||
describe('15.0.0 migration (prefix-outputs)', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should prefix project outputs', async () => {
|
|
||||||
addProjectConfiguration(tree, 'proj', {
|
|
||||||
root: 'proj',
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
executor: 'nx:run-commands',
|
|
||||||
outputs: [
|
|
||||||
'dist',
|
|
||||||
'dist/{projectRoot}',
|
|
||||||
'dist/{projectRoot}/**/*.js',
|
|
||||||
'proj/coverage',
|
|
||||||
'./test-results',
|
|
||||||
'{projectRoot}/build',
|
|
||||||
'{options.outputDirectory}',
|
|
||||||
],
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await prefixOutputs(tree);
|
|
||||||
|
|
||||||
const updated = readProjectConfiguration(tree, 'proj');
|
|
||||||
|
|
||||||
expect(updated.targets.build.outputs).toEqual([
|
|
||||||
'{workspaceRoot}/dist',
|
|
||||||
'{workspaceRoot}/dist/{projectRoot}',
|
|
||||||
'{workspaceRoot}/dist/{projectRoot}/**/*.js',
|
|
||||||
'{projectRoot}/coverage',
|
|
||||||
'{projectRoot}/test-results',
|
|
||||||
'{projectRoot}/build',
|
|
||||||
'{options.outputDirectory}',
|
|
||||||
]);
|
|
||||||
|
|
||||||
expect(() => validateOutputs(updated.targets.build.outputs)).not.toThrow();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should prefix target default outputs', async () => {
|
|
||||||
const nxJson = readNxJson(tree);
|
|
||||||
updateNxJson(tree, {
|
|
||||||
...nxJson,
|
|
||||||
targetDefaults: {
|
|
||||||
build: {
|
|
||||||
outputs: ['dist', '{projectRoot}/build', '{options.outputPath}'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await prefixOutputs(tree);
|
|
||||||
|
|
||||||
const updated = readNxJson(tree);
|
|
||||||
|
|
||||||
expect(updated.targetDefaults).toMatchInlineSnapshot(`
|
|
||||||
{
|
|
||||||
"build": {
|
|
||||||
"outputs": [
|
|
||||||
"{workspaceRoot}/dist",
|
|
||||||
"{projectRoot}/build",
|
|
||||||
"{options.outputPath}",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should migrate package.json projects', async () => {
|
|
||||||
writeJson(tree, 'proj/package.json', {
|
|
||||||
name: 'proj',
|
|
||||||
scripts: {
|
|
||||||
build: 'echo',
|
|
||||||
},
|
|
||||||
nx: {
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
outputs: ['dist/proj', 'proj/build'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
tree.delete('workspace.json');
|
|
||||||
|
|
||||||
await prefixOutputs(tree);
|
|
||||||
|
|
||||||
expect(readJson(tree, 'proj/package.json').nx.targets.build).toEqual({
|
|
||||||
outputs: ['{workspaceRoot}/dist/proj', '{projectRoot}/build'],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not error for package.json projects', async () => {
|
|
||||||
writeJson(tree, 'proj/package.json', {
|
|
||||||
name: 'proj',
|
|
||||||
scripts: {
|
|
||||||
build: 'echo',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
tree.delete('workspace.json');
|
|
||||||
|
|
||||||
await prefixOutputs(tree);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle negated outputs', async () => {
|
|
||||||
const nxJson = readNxJson(tree);
|
|
||||||
updateNxJson(tree, {
|
|
||||||
...nxJson,
|
|
||||||
targetDefaults: {
|
|
||||||
build: {
|
|
||||||
outputs: ['!dist', '{projectRoot}/build', '{options.outputPath}'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await prefixOutputs(tree);
|
|
||||||
|
|
||||||
const updated = readNxJson(tree);
|
|
||||||
|
|
||||||
expect(updated.targetDefaults).toMatchInlineSnapshot(`
|
|
||||||
{
|
|
||||||
"build": {
|
|
||||||
"outputs": [
|
|
||||||
"!{workspaceRoot}/dist",
|
|
||||||
"{projectRoot}/build",
|
|
||||||
"{options.outputPath}",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('15.0.0 migration (prefix-outputs) (v1)', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should prefix project outputs', async () => {
|
|
||||||
addProjectConfiguration(tree, 'proj', {
|
|
||||||
root: 'proj',
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
executor: 'nx:run-commands',
|
|
||||||
outputs: [
|
|
||||||
'dist',
|
|
||||||
'dist/{projectRoot}',
|
|
||||||
'dist/{projectRoot}/**/*.js',
|
|
||||||
'proj/coverage',
|
|
||||||
'./test-results',
|
|
||||||
'{projectRoot}/build',
|
|
||||||
'{options.outputDirectory}',
|
|
||||||
],
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await prefixOutputs(tree);
|
|
||||||
|
|
||||||
const updated = readProjectConfiguration(tree, 'proj');
|
|
||||||
|
|
||||||
expect(updated.targets.build.outputs).toEqual([
|
|
||||||
'{workspaceRoot}/dist',
|
|
||||||
'{workspaceRoot}/dist/{projectRoot}',
|
|
||||||
'{workspaceRoot}/dist/{projectRoot}/**/*.js',
|
|
||||||
'{projectRoot}/coverage',
|
|
||||||
'{projectRoot}/test-results',
|
|
||||||
'{projectRoot}/build',
|
|
||||||
'{options.outputDirectory}',
|
|
||||||
]);
|
|
||||||
|
|
||||||
expect(() => validateOutputs(updated.targets.build.outputs)).not.toThrow();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
import { Tree } from '../../generators/tree';
|
|
||||||
import { formatChangedFilesWithPrettierIfAvailable } from '../../generators/internal-utils/format-changed-files-with-prettier-if-available';
|
|
||||||
import {
|
|
||||||
getProjects,
|
|
||||||
updateProjectConfiguration,
|
|
||||||
} from '../../generators/utils/project-configuration';
|
|
||||||
import { readNxJson, updateNxJson } from '../../generators/utils/nx-json';
|
|
||||||
import { joinPathFragments } from '../../utils/path';
|
|
||||||
import { join } from 'path';
|
|
||||||
import {
|
|
||||||
transformLegacyOutputs,
|
|
||||||
validateOutputs,
|
|
||||||
} from '../../tasks-runner/utils';
|
|
||||||
import { updateJson } from '../../generators/utils/json';
|
|
||||||
import { PackageJson } from '../../utils/package-json';
|
|
||||||
|
|
||||||
export default async function (tree: Tree) {
|
|
||||||
// If the workspace doesn't have a nx.json, don't make any changes
|
|
||||||
if (!tree.exists('nx.json')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const nxJson = readNxJson(tree);
|
|
||||||
|
|
||||||
for (const [projectName, project] of getProjects(tree)) {
|
|
||||||
for (const [_, target] of Object.entries(project.targets ?? {})) {
|
|
||||||
if (!target.outputs) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
target.outputs = transformLegacyOutputs(project.root, target.outputs);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
updateProjectConfiguration(tree, projectName, project);
|
|
||||||
} catch {
|
|
||||||
if (tree.exists(join(project.root, 'package.json'))) {
|
|
||||||
updateJson<PackageJson>(
|
|
||||||
tree,
|
|
||||||
join(project.root, 'package.json'),
|
|
||||||
(json) => {
|
|
||||||
for (const target of Object.values(json.nx?.targets ?? {})) {
|
|
||||||
if (target.outputs) {
|
|
||||||
target.outputs = transformLegacyOutputs(
|
|
||||||
project.root,
|
|
||||||
target.outputs
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nxJson.targetDefaults) {
|
|
||||||
for (const [_, target] of Object.entries(nxJson.targetDefaults)) {
|
|
||||||
if (!target.outputs) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
target.outputs = transformLegacyOutputs('{projectRoot}', target.outputs);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateNxJson(tree, nxJson);
|
|
||||||
}
|
|
||||||
|
|
||||||
await formatChangedFilesWithPrettierIfAvailable(tree);
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
import { Tree } from '../../generators/tree';
|
|
||||||
import { formatChangedFilesWithPrettierIfAvailable } from '../../generators/internal-utils/format-changed-files-with-prettier-if-available';
|
|
||||||
import { updateJson } from '../../generators/utils/json';
|
|
||||||
|
|
||||||
export default async function (tree: Tree) {
|
|
||||||
updateJson(tree, 'package.json', (json) => {
|
|
||||||
for (const deps of [json.dependencies, json.devDependencies]) {
|
|
||||||
if (deps) {
|
|
||||||
delete deps['@nrwl/cli'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
|
|
||||||
await formatChangedFilesWithPrettierIfAvailable(tree);
|
|
||||||
}
|
|
||||||
@ -1,131 +0,0 @@
|
|||||||
import {
|
|
||||||
addProjectConfiguration,
|
|
||||||
readNxJson,
|
|
||||||
readProjectConfiguration,
|
|
||||||
} from '../../generators/utils/project-configuration';
|
|
||||||
|
|
||||||
import update from './update-depends-on-to-tokens';
|
|
||||||
import { updateJson, writeJson } from '../../generators/utils/json';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '../../generators/testing-utils/create-tree-with-empty-workspace';
|
|
||||||
import { assertRunsAgainstNxRepo } from '../../internal-testing-utils/run-migration-against-this-workspace';
|
|
||||||
|
|
||||||
describe('update-depends-on-to-tokens', () => {
|
|
||||||
it('should update nx.json', async () => {
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
updateJson(tree, 'nx.json', (json) => {
|
|
||||||
json.targetDefaults = {
|
|
||||||
build: {
|
|
||||||
dependsOn: [
|
|
||||||
{
|
|
||||||
projects: 'self',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
inputs: [{ projects: 'self', input: 'someInput' }],
|
|
||||||
},
|
|
||||||
test: {
|
|
||||||
dependsOn: [
|
|
||||||
{
|
|
||||||
projects: 'dependencies',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
inputs: [{ projects: 'dependencies', input: 'someInput' }],
|
|
||||||
},
|
|
||||||
other: {
|
|
||||||
dependsOn: ['^deps'],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
await update(tree);
|
|
||||||
const nxJson = readNxJson(tree);
|
|
||||||
const buildDependencyConfiguration = nxJson.targetDefaults.build
|
|
||||||
.dependsOn[0] as any;
|
|
||||||
const testDependencyConfiguration = nxJson.targetDefaults.test
|
|
||||||
.dependsOn[0] as any;
|
|
||||||
const buildInputConfiguration = nxJson.targetDefaults.build
|
|
||||||
.inputs[0] as any;
|
|
||||||
const testInputConfiguration = nxJson.targetDefaults.test.inputs[0] as any;
|
|
||||||
expect(buildDependencyConfiguration.projects).not.toBeDefined();
|
|
||||||
expect(buildDependencyConfiguration.dependencies).not.toBeDefined();
|
|
||||||
expect(buildInputConfiguration.projects).not.toBeDefined();
|
|
||||||
expect(buildInputConfiguration.dependencies).not.toBeDefined();
|
|
||||||
expect(testInputConfiguration.projects).not.toBeDefined();
|
|
||||||
expect(testInputConfiguration.dependencies).toEqual(true);
|
|
||||||
expect(testDependencyConfiguration.projects).not.toBeDefined();
|
|
||||||
expect(testDependencyConfiguration.dependencies).toEqual(true);
|
|
||||||
expect(nxJson.targetDefaults.other.dependsOn).toEqual(['^deps']);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update project configurations', async () => {
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
addProjectConfiguration(tree, 'proj1', {
|
|
||||||
root: 'proj1',
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
dependsOn: [
|
|
||||||
{
|
|
||||||
projects: 'self',
|
|
||||||
target: 'build',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
inputs: [{ projects: 'self', input: 'someInput' }],
|
|
||||||
},
|
|
||||||
test: {
|
|
||||||
dependsOn: [
|
|
||||||
{
|
|
||||||
projects: 'dependencies',
|
|
||||||
target: 'test',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
inputs: [{ projects: 'dependencies', input: 'someInput' }],
|
|
||||||
},
|
|
||||||
other: {
|
|
||||||
dependsOn: ['^deps'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await update(tree);
|
|
||||||
const project = readProjectConfiguration(tree, 'proj1');
|
|
||||||
const buildDependencyConfiguration = project.targets.build
|
|
||||||
.dependsOn[0] as any;
|
|
||||||
const testDependencyConfiguration = project.targets.test
|
|
||||||
.dependsOn[0] as any;
|
|
||||||
const buildInputConfiguration = project.targets.build.inputs[0] as any;
|
|
||||||
const testInputConfiguration = project.targets.test.inputs[0] as any;
|
|
||||||
expect(buildDependencyConfiguration.projects).not.toBeDefined();
|
|
||||||
expect(buildDependencyConfiguration.dependencies).not.toBeDefined();
|
|
||||||
expect(buildInputConfiguration.projects).not.toBeDefined();
|
|
||||||
expect(buildInputConfiguration.dependencies).not.toBeDefined();
|
|
||||||
expect(testDependencyConfiguration.projects).not.toBeDefined();
|
|
||||||
expect(testDependencyConfiguration.dependencies).toEqual(true);
|
|
||||||
expect(testInputConfiguration.projects).not.toBeDefined();
|
|
||||||
expect(testInputConfiguration.dependencies).toEqual(true);
|
|
||||||
expect(project.targets.other.dependsOn).toEqual(['^deps']);
|
|
||||||
expect(project.targets.other.inputs).not.toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not throw on nulls', async () => {
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
addProjectConfiguration(tree, 'proj1', {
|
|
||||||
root: 'proj1',
|
|
||||||
});
|
|
||||||
addProjectConfiguration(tree, 'proj2', {
|
|
||||||
root: 'proj2',
|
|
||||||
targets: {
|
|
||||||
build: {},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
writeJson(tree, 'nx.json', {});
|
|
||||||
let promise = update(tree);
|
|
||||||
await expect(promise).resolves.toBeUndefined();
|
|
||||||
writeJson(tree, 'nx.json', {
|
|
||||||
targetDefaults: {
|
|
||||||
build: {},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
promise = update(tree);
|
|
||||||
await expect(promise).resolves.toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
assertRunsAgainstNxRepo(update);
|
|
||||||
});
|
|
||||||
@ -1,119 +0,0 @@
|
|||||||
import {
|
|
||||||
getProjects,
|
|
||||||
readNxJson,
|
|
||||||
updateNxJson,
|
|
||||||
updateProjectConfiguration,
|
|
||||||
} from '../../generators/utils/project-configuration';
|
|
||||||
import { Tree } from '../../generators/tree';
|
|
||||||
import { formatChangedFilesWithPrettierIfAvailable } from '../../generators/internal-utils/format-changed-files-with-prettier-if-available';
|
|
||||||
|
|
||||||
export default async function (tree: Tree) {
|
|
||||||
updateDependsOnAndInputsInsideNxJson(tree);
|
|
||||||
|
|
||||||
const projectsConfigurations = getProjects(tree);
|
|
||||||
for (const [projectName, projectConfiguration] of projectsConfigurations) {
|
|
||||||
let projectChanged = false;
|
|
||||||
for (const [targetName, targetConfiguration] of Object.entries(
|
|
||||||
projectConfiguration.targets ?? {}
|
|
||||||
)) {
|
|
||||||
for (const dependency of targetConfiguration.dependsOn ?? []) {
|
|
||||||
if (typeof dependency !== 'string') {
|
|
||||||
if (
|
|
||||||
dependency.projects === 'self' ||
|
|
||||||
dependency.projects === '{self}'
|
|
||||||
) {
|
|
||||||
delete dependency.projects;
|
|
||||||
projectChanged = true;
|
|
||||||
} else if (
|
|
||||||
dependency.projects === 'dependencies' ||
|
|
||||||
dependency.projects === '{dependencies}'
|
|
||||||
) {
|
|
||||||
delete dependency.projects;
|
|
||||||
dependency.dependencies = true;
|
|
||||||
projectChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i = 0; i < targetConfiguration.inputs?.length ?? 0; i++) {
|
|
||||||
const input = targetConfiguration.inputs[i];
|
|
||||||
if (typeof input !== 'string') {
|
|
||||||
if (
|
|
||||||
'projects' in input &&
|
|
||||||
(input.projects === 'self' || input.projects === '{self}')
|
|
||||||
) {
|
|
||||||
delete input.projects;
|
|
||||||
projectChanged = true;
|
|
||||||
} else if (
|
|
||||||
'projects' in input &&
|
|
||||||
(input.projects === 'dependencies' ||
|
|
||||||
input.projects === '{dependencies}')
|
|
||||||
) {
|
|
||||||
delete input.projects;
|
|
||||||
targetConfiguration.inputs[i] = {
|
|
||||||
...input,
|
|
||||||
dependencies: true,
|
|
||||||
};
|
|
||||||
projectChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (projectChanged) {
|
|
||||||
updateProjectConfiguration(tree, projectName, projectConfiguration);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await formatChangedFilesWithPrettierIfAvailable(tree);
|
|
||||||
}
|
|
||||||
function updateDependsOnAndInputsInsideNxJson(tree: Tree) {
|
|
||||||
const nxJson = readNxJson(tree);
|
|
||||||
let nxJsonChanged = false;
|
|
||||||
for (const [target, defaults] of Object.entries(
|
|
||||||
nxJson?.targetDefaults ?? {}
|
|
||||||
)) {
|
|
||||||
for (const dependency of defaults.dependsOn ?? []) {
|
|
||||||
if (typeof dependency !== 'string') {
|
|
||||||
if (
|
|
||||||
dependency.projects === 'self' ||
|
|
||||||
dependency.projects === '{self}'
|
|
||||||
) {
|
|
||||||
delete dependency.projects;
|
|
||||||
nxJsonChanged = true;
|
|
||||||
} else if (
|
|
||||||
dependency.projects === 'dependencies' ||
|
|
||||||
dependency.projects === '{dependencies}'
|
|
||||||
) {
|
|
||||||
delete dependency.projects;
|
|
||||||
dependency.dependencies = true;
|
|
||||||
nxJsonChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i = 0; i < defaults.inputs?.length ?? 0; i++) {
|
|
||||||
const input = defaults.inputs[i];
|
|
||||||
if (typeof input !== 'string') {
|
|
||||||
if (
|
|
||||||
'projects' in input &&
|
|
||||||
(input.projects === 'self' || input.projects === '{self}')
|
|
||||||
) {
|
|
||||||
delete input.projects;
|
|
||||||
nxJsonChanged = true;
|
|
||||||
} else if (
|
|
||||||
'projects' in input &&
|
|
||||||
(input.projects === 'dependencies' ||
|
|
||||||
input.projects === '{dependencies}')
|
|
||||||
) {
|
|
||||||
delete input.projects;
|
|
||||||
defaults.inputs[i] = {
|
|
||||||
...input,
|
|
||||||
dependencies: true,
|
|
||||||
};
|
|
||||||
nxJsonChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (nxJsonChanged) {
|
|
||||||
updateNxJson(tree, nxJson);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
import {
|
|
||||||
readNxJson,
|
|
||||||
updateNxJson,
|
|
||||||
} from '../../generators/utils/project-configuration';
|
|
||||||
import { Tree } from '../../generators/tree';
|
|
||||||
import { updateJson } from '../../generators/utils/json';
|
|
||||||
import { formatChangedFilesWithPrettierIfAvailable } from '../../generators/internal-utils/format-changed-files-with-prettier-if-available';
|
|
||||||
|
|
||||||
export default async function (tree: Tree) {
|
|
||||||
updateJson(tree, 'package.json', (json) => {
|
|
||||||
if (json.dependencies && json.dependencies['@nrwl/nx-cloud']) {
|
|
||||||
json.dependencies['nx-cloud'] = json.dependencies['@nrwl/nx-cloud'];
|
|
||||||
delete json.dependencies['@nrwl/nx-cloud'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (json.devDependencies && json.devDependencies['@nrwl/nx-cloud']) {
|
|
||||||
json.devDependencies['nx-cloud'] = json.devDependencies['@nrwl/nx-cloud'];
|
|
||||||
delete json.devDependencies['@nrwl/nx-cloud'];
|
|
||||||
}
|
|
||||||
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
|
|
||||||
const nxJson = readNxJson(tree);
|
|
||||||
if (!nxJson) return;
|
|
||||||
for (let opts of Object.values(nxJson.tasksRunnerOptions ?? {})) {
|
|
||||||
if (opts.runner === '@nrwl/nx-cloud') {
|
|
||||||
opts.runner = 'nx-cloud';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
updateNxJson(tree, nxJson);
|
|
||||||
|
|
||||||
await formatChangedFilesWithPrettierIfAvailable(tree);
|
|
||||||
}
|
|
||||||
@ -1,102 +0,0 @@
|
|||||||
import { TargetConfiguration } from '../../config/workspace-json-project-json';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '../../generators/testing-utils/create-tree-with-empty-workspace';
|
|
||||||
import { readJson, writeJson } from '../../generators/utils/json';
|
|
||||||
import {
|
|
||||||
addProjectConfiguration,
|
|
||||||
readProjectConfiguration,
|
|
||||||
} from '../../generators/utils/project-configuration';
|
|
||||||
import { assertRunsAgainstNxRepo } from '../../internal-testing-utils/run-migration-against-this-workspace';
|
|
||||||
import removeRunCommandsOutputPath from './remove-run-commands-output-path';
|
|
||||||
|
|
||||||
describe('removeRunCommandsOutputPath', () => {
|
|
||||||
it('should migrate target options correctly', () => {
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
const startingTargets: Record<string, TargetConfiguration> = {
|
|
||||||
build: {
|
|
||||||
executor: 'nx:run-commands',
|
|
||||||
outputs: ['{options.outputPath}'],
|
|
||||||
options: {
|
|
||||||
outputPath: 'dist/apps/my-app',
|
|
||||||
commands: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
other: {
|
|
||||||
executor: 'nx:run-script',
|
|
||||||
options: {
|
|
||||||
script: 'start',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
addProjectConfiguration(tree, 'my-app', {
|
|
||||||
root: 'apps/my-app',
|
|
||||||
targets: startingTargets,
|
|
||||||
});
|
|
||||||
removeRunCommandsOutputPath(tree);
|
|
||||||
const migratedTargets = readProjectConfiguration(tree, 'my-app').targets;
|
|
||||||
expect(migratedTargets.build).not.toEqual(startingTargets.build);
|
|
||||||
expect(migratedTargets.build).toEqual({
|
|
||||||
executor: 'nx:run-commands',
|
|
||||||
outputs: ['{workspaceRoot}/dist/apps/my-app'],
|
|
||||||
options: {
|
|
||||||
commands: [],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(migratedTargets.other).toEqual(startingTargets.other);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle null options correctly', () => {
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
const startingTargets: Record<string, TargetConfiguration> = {
|
|
||||||
build: {
|
|
||||||
executor: 'nx:run-commands',
|
|
||||||
outputs: ['dist/some/path'],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
addProjectConfiguration(tree, 'my-app', {
|
|
||||||
root: 'apps/my-app',
|
|
||||||
targets: startingTargets,
|
|
||||||
});
|
|
||||||
expect(() => removeRunCommandsOutputPath(tree)).not.toThrow();
|
|
||||||
const migratedTargets = readProjectConfiguration(tree, 'my-app').targets;
|
|
||||||
expect(migratedTargets.build).toEqual(startingTargets.build);
|
|
||||||
expect(migratedTargets.other).toEqual(startingTargets.other);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should migrate target defaults correctly', () => {
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
const startingTargetDefaults: Record<string, TargetConfiguration> = {
|
|
||||||
build: {
|
|
||||||
executor: 'nx:run-commands',
|
|
||||||
outputs: ['{options.outputPath}'],
|
|
||||||
options: {
|
|
||||||
outputPath: 'dist/apps/my-app',
|
|
||||||
commands: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
other: {
|
|
||||||
executor: 'nx:run-script',
|
|
||||||
options: {
|
|
||||||
script: 'start',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
writeJson(tree, 'nx.json', {
|
|
||||||
targetDefaults: startingTargetDefaults,
|
|
||||||
});
|
|
||||||
removeRunCommandsOutputPath(tree);
|
|
||||||
const migratedTargetDefaults = readJson(tree, 'nx.json').targetDefaults;
|
|
||||||
expect(migratedTargetDefaults.build).not.toEqual(
|
|
||||||
startingTargetDefaults.build
|
|
||||||
);
|
|
||||||
expect(migratedTargetDefaults.build).toEqual({
|
|
||||||
executor: 'nx:run-commands',
|
|
||||||
outputs: ['{workspaceRoot}/dist/apps/my-app'],
|
|
||||||
options: {
|
|
||||||
commands: [],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(migratedTargetDefaults.other).toEqual(startingTargetDefaults.other);
|
|
||||||
});
|
|
||||||
|
|
||||||
assertRunsAgainstNxRepo(removeRunCommandsOutputPath);
|
|
||||||
});
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
import { joinPathFragments } from '../../utils/path';
|
|
||||||
import { NxJsonConfiguration } from '../../config/nx-json';
|
|
||||||
import { TargetConfiguration } from '../../config/workspace-json-project-json';
|
|
||||||
import { formatChangedFilesWithPrettierIfAvailable } from '../../generators/internal-utils/format-changed-files-with-prettier-if-available';
|
|
||||||
import { Tree } from '../../generators/tree';
|
|
||||||
import { updateJson } from '../../generators/utils/json';
|
|
||||||
import {
|
|
||||||
getProjects,
|
|
||||||
updateProjectConfiguration,
|
|
||||||
} from '../../generators/utils/project-configuration';
|
|
||||||
|
|
||||||
export default async function removeRunCommandsOutputPath(tree: Tree) {
|
|
||||||
for (const [project, configuration] of getProjects(tree).entries()) {
|
|
||||||
const targets = configuration.targets ?? {};
|
|
||||||
let changed = false;
|
|
||||||
for (const [, target] of Object.entries(targets)) {
|
|
||||||
changed ||= updateTargetBlock(target);
|
|
||||||
}
|
|
||||||
if (changed) {
|
|
||||||
updateProjectConfiguration(tree, project, configuration);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (tree.exists('nx.json')) {
|
|
||||||
updateJson<NxJsonConfiguration>(tree, 'nx.json', (json) => {
|
|
||||||
for (const [, target] of Object.entries(json.targetDefaults ?? {})) {
|
|
||||||
updateTargetBlock(target);
|
|
||||||
}
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
await formatChangedFilesWithPrettierIfAvailable(tree);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateTargetBlock(target: TargetConfiguration): boolean {
|
|
||||||
let changed = false;
|
|
||||||
if (target.executor === 'nx:run-commands' && target.options?.outputPath) {
|
|
||||||
changed = true;
|
|
||||||
const outputs = new Set(target.outputs ?? []);
|
|
||||||
outputs.delete('{options.outputPath}');
|
|
||||||
const newOutputs = Array.isArray(target.options.outputPath)
|
|
||||||
? target.options.outputPath.map((p) =>
|
|
||||||
joinPathFragments('{workspaceRoot}', p)
|
|
||||||
)
|
|
||||||
: [joinPathFragments('{workspaceRoot}', target.options.outputPath)];
|
|
||||||
for (const outputPath of newOutputs) {
|
|
||||||
outputs.add(outputPath);
|
|
||||||
}
|
|
||||||
delete target.options.outputPath;
|
|
||||||
target.outputs = Array.from(outputs);
|
|
||||||
}
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
@ -1,132 +0,0 @@
|
|||||||
import { createTreeWithEmptyWorkspace } from '../../generators/testing-utils/create-tree-with-empty-workspace';
|
|
||||||
import { addProjectConfiguration } from '../../generators/utils/project-configuration';
|
|
||||||
import escapeDollarSignEnvVariables from './escape-dollar-sign-env-variables';
|
|
||||||
|
|
||||||
describe('escape $ in env variables', () => {
|
|
||||||
let tree;
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should escape $ in env variables in .env file', () => {
|
|
||||||
tree.write(
|
|
||||||
'.env',
|
|
||||||
`dollar=$
|
|
||||||
NX_SOME_VAR=$ABC`
|
|
||||||
);
|
|
||||||
escapeDollarSignEnvVariables(tree);
|
|
||||||
expect(tree.read('.env', 'utf-8')).toEqual(`dollar=\\$
|
|
||||||
NX_SOME_VAR=\\$ABC`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should escape $ env variables in .env file under project', () => {
|
|
||||||
addProjectConfiguration(tree, 'my-app', {
|
|
||||||
root: 'apps/my-app',
|
|
||||||
});
|
|
||||||
addProjectConfiguration(tree, 'my-app2', {
|
|
||||||
root: 'apps/my-app2',
|
|
||||||
});
|
|
||||||
tree.write(
|
|
||||||
'apps/my-app/.env',
|
|
||||||
`dollar=$
|
|
||||||
NX_SOME_VAR=$ABC`
|
|
||||||
);
|
|
||||||
tree.write(
|
|
||||||
'apps/my-app2/.env',
|
|
||||||
`dollar=$
|
|
||||||
NX_SOME_VAR=$DEF`
|
|
||||||
);
|
|
||||||
escapeDollarSignEnvVariables(tree);
|
|
||||||
expect(tree.read('apps/my-app/.env', 'utf-8')).toEqual(`dollar=\\$
|
|
||||||
NX_SOME_VAR=\\$ABC`);
|
|
||||||
expect(tree.read('apps/my-app2/.env', 'utf-8')).toEqual(`dollar=\\$
|
|
||||||
NX_SOME_VAR=\\$DEF`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should escape $ env variables in .env for target', () => {
|
|
||||||
tree.write('.env', 'dollar=$');
|
|
||||||
tree.write('.env.build', 'dollar=$');
|
|
||||||
addProjectConfiguration(tree, 'my-app', {
|
|
||||||
root: 'apps/my-app',
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
executor: '@nx/node:build',
|
|
||||||
configurations: {
|
|
||||||
production: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
tree.write(
|
|
||||||
'apps/my-app/.build.env',
|
|
||||||
`dollar=$
|
|
||||||
NX_SOME_VAR=$ABC`
|
|
||||||
);
|
|
||||||
tree.write(
|
|
||||||
'apps/my-app/.env',
|
|
||||||
`dollar=$
|
|
||||||
NX_SOME_VAR=$ABC`
|
|
||||||
);
|
|
||||||
escapeDollarSignEnvVariables(tree);
|
|
||||||
expect(tree.read('.env', 'utf-8')).toEqual(`dollar=\\$`);
|
|
||||||
expect(tree.read('apps/my-app/.env', 'utf-8')).toEqual(`dollar=\\$
|
|
||||||
NX_SOME_VAR=\\$ABC`);
|
|
||||||
expect(tree.read('apps/my-app/.build.env', 'utf-8')).toEqual(`dollar=\\$
|
|
||||||
NX_SOME_VAR=\\$ABC`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should escape $ env variables in .env for configuration', () => {
|
|
||||||
tree.write('.env', 'dollar=$');
|
|
||||||
tree.write('.env.production', 'dollar=$');
|
|
||||||
addProjectConfiguration(tree, 'my-app', {
|
|
||||||
root: 'apps/my-app',
|
|
||||||
targets: {
|
|
||||||
build: {
|
|
||||||
executor: '@nx/node:build',
|
|
||||||
configurations: {
|
|
||||||
production: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
tree.write(
|
|
||||||
'apps/my-app/.production.env',
|
|
||||||
`dollar=$
|
|
||||||
NX_SOME_VAR=$ABC`
|
|
||||||
);
|
|
||||||
tree.write(
|
|
||||||
'apps/my-app/.build.production.env',
|
|
||||||
`dollar=$
|
|
||||||
NX_SOME_VAR=$ABC`
|
|
||||||
);
|
|
||||||
tree.write(
|
|
||||||
'apps/my-app/.env',
|
|
||||||
`dollar=$
|
|
||||||
NX_SOME_VAR=$ABC`
|
|
||||||
);
|
|
||||||
escapeDollarSignEnvVariables(tree);
|
|
||||||
expect(tree.read('.env', 'utf-8')).toEqual(`dollar=\\$`);
|
|
||||||
expect(tree.read('apps/my-app/.env', 'utf-8')).toEqual(`dollar=\\$
|
|
||||||
NX_SOME_VAR=\\$ABC`);
|
|
||||||
expect(tree.read('apps/my-app/.build.production.env', 'utf-8'))
|
|
||||||
.toEqual(`dollar=\\$
|
|
||||||
NX_SOME_VAR=\\$ABC`);
|
|
||||||
expect(tree.read('apps/my-app/.production.env', 'utf-8'))
|
|
||||||
.toEqual(`dollar=\\$
|
|
||||||
NX_SOME_VAR=\\$ABC`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not escape $ env variables if it is already escaped', () => {
|
|
||||||
addProjectConfiguration(tree, 'my-app', {
|
|
||||||
root: 'apps/my-app',
|
|
||||||
});
|
|
||||||
tree.write(
|
|
||||||
'apps/my-app/.env',
|
|
||||||
`dollar=\\$
|
|
||||||
NX_SOME_VAR=\\$ABC`
|
|
||||||
);
|
|
||||||
escapeDollarSignEnvVariables(tree);
|
|
||||||
expect(tree.read('apps/my-app/.env', 'utf-8')).toEqual(`dollar=\\$
|
|
||||||
NX_SOME_VAR=\\$ABC`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,92 +0,0 @@
|
|||||||
import { logger } from '../../utils/logger';
|
|
||||||
import { Tree } from '../../generators/tree';
|
|
||||||
import { getProjects } from '../../generators/utils/project-configuration';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function escapes dollar sign in env variables
|
|
||||||
* It will go through:
|
|
||||||
* - '.env', '.local.env', '.env.local'
|
|
||||||
* - .env.[target-name], .[target-name].env
|
|
||||||
* - .env.[target-name].[configuration-name], .[target-name].[configuration-name].env
|
|
||||||
* - .env.[configuration-name], .[configuration-name].env
|
|
||||||
* at each project root and workspace root
|
|
||||||
* @param tree
|
|
||||||
*/
|
|
||||||
export default function escapeDollarSignEnvVariables(tree: Tree) {
|
|
||||||
const envFiles = ['.env', '.local.env', '.env.local'];
|
|
||||||
for (const [_, configuration] of getProjects(tree).entries()) {
|
|
||||||
envFiles.push(
|
|
||||||
`${configuration.root}/.env`,
|
|
||||||
`${configuration.root}/.local.env`,
|
|
||||||
`${configuration.root}/.env.local`
|
|
||||||
);
|
|
||||||
for (const targetName in configuration.targets) {
|
|
||||||
const task = configuration.targets[targetName];
|
|
||||||
envFiles.push(
|
|
||||||
`.env.${targetName}`,
|
|
||||||
`.${targetName}.env`,
|
|
||||||
`${configuration.root}/.env.${targetName}`,
|
|
||||||
`${configuration.root}/.${targetName}.env`
|
|
||||||
);
|
|
||||||
|
|
||||||
if (task.configurations) {
|
|
||||||
for (const configurationName in task.configurations) {
|
|
||||||
envFiles.push(
|
|
||||||
`.env.${targetName}.${configurationName}`,
|
|
||||||
`.${targetName}.${configurationName}.env`,
|
|
||||||
`.env.${configurationName}`,
|
|
||||||
`.${configurationName}.env`,
|
|
||||||
`${configuration.root}/.env.${targetName}.${configurationName}`,
|
|
||||||
`${configuration.root}/.${targetName}.${configurationName}.env`,
|
|
||||||
`${configuration.root}/.env.${configurationName}`,
|
|
||||||
`${configuration.root}/.${configurationName}.env`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const envFile of new Set(envFiles)) {
|
|
||||||
parseEnvFile(tree, envFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function parse the env file and escape dollar sign
|
|
||||||
* @param tree
|
|
||||||
* @param envFilePath
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
function parseEnvFile(tree: Tree, envFilePath: string) {
|
|
||||||
if (!tree.exists(envFilePath)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let envFileContent = tree.read(envFilePath, 'utf-8');
|
|
||||||
if (!envFileContent) {
|
|
||||||
// envFileContent is null if we fail to read the file for any reason
|
|
||||||
// e.g. the file is not utf-8 encoded
|
|
||||||
logger.info(
|
|
||||||
`Unable to update ${envFilePath}. Nx interpolates environment variables in the form of $VAR_NAME. To escape the dollar sign, use \\$VAR_NAME.`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
envFileContent = envFileContent
|
|
||||||
.split('\n')
|
|
||||||
.map((line) => {
|
|
||||||
line = line.trim();
|
|
||||||
|
|
||||||
if (!line || !line.includes('$')) {
|
|
||||||
return line;
|
|
||||||
}
|
|
||||||
|
|
||||||
const declarations = line.split('=');
|
|
||||||
if (declarations[1].includes('$') && !declarations[1].includes(`\\$`)) {
|
|
||||||
declarations[1] = declarations[1].replace('$', `\\$`);
|
|
||||||
line = declarations.join('=');
|
|
||||||
}
|
|
||||||
return line;
|
|
||||||
})
|
|
||||||
.join('\n');
|
|
||||||
tree.write(envFilePath, envFileContent);
|
|
||||||
}
|
|
||||||
@ -1,22 +1,3 @@
|
|||||||
{
|
{
|
||||||
"generators": {
|
"generators": {}
|
||||||
"update-remove-cli-prop": {
|
|
||||||
"version": "16.0.0-beta.1",
|
|
||||||
"cli": "nx",
|
|
||||||
"description": "Removes CLI property within schema.json files and moves generators and schematics to the proper root node in migrations.json",
|
|
||||||
"factory": "./src/migrations/update-16-0-0/cli-in-schema-json"
|
|
||||||
},
|
|
||||||
"update-16-0-0-add-nx-packages": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.0.0-beta.1",
|
|
||||||
"description": "Replace @nrwl/nx-plugin with @nx/plugin",
|
|
||||||
"implementation": "./src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages"
|
|
||||||
},
|
|
||||||
"update-16-2-0-replace-e2e-executor": {
|
|
||||||
"cli": "nx",
|
|
||||||
"version": "16.2.0-beta.0",
|
|
||||||
"description": "Replace @nx/plugin:e2e with @nx/jest",
|
|
||||||
"implementation": "./src/migrations/update-16-2-0/replace-e2e-executor"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,40 +0,0 @@
|
|||||||
import { Tree, readJson, updateJson } from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import { assertRunsAgainstNxRepo } from '@nx/devkit/internal-testing-utils';
|
|
||||||
import replacePackage from './update-16-0-0-add-nx-packages';
|
|
||||||
|
|
||||||
describe('update-16-0-0-add-nx-packages', () => {
|
|
||||||
let tree: Tree;
|
|
||||||
beforeEach(() => {
|
|
||||||
tree = createTreeWithEmptyWorkspace();
|
|
||||||
|
|
||||||
updateJson(tree, 'package.json', (json) => {
|
|
||||||
json.devDependencies['@nrwl/nx-plugin'] = '16.0.0';
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the dependency on @nrwl/nx-plugin', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').dependencies['@nrwl/nx-plugin']
|
|
||||||
).not.toBeDefined();
|
|
||||||
expect(
|
|
||||||
readJson(tree, 'package.json').devDependencies['@nrwl/nx-plugin']
|
|
||||||
).not.toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add a dependency on @nx/plugin', async () => {
|
|
||||||
await replacePackage(tree);
|
|
||||||
|
|
||||||
const packageJson = readJson(tree, 'package.json');
|
|
||||||
const newDependencyVersion =
|
|
||||||
packageJson.devDependencies['@nx/plugin'] ??
|
|
||||||
packageJson.dependencies['@nx/plugin'];
|
|
||||||
|
|
||||||
expect(newDependencyVersion).toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
assertRunsAgainstNxRepo(replacePackage);
|
|
||||||
});
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import { Tree, formatFiles } from '@nx/devkit';
|
|
||||||
import { replaceNrwlPackageWithNxPackage } from '@nx/devkit/src/utils/replace-package';
|
|
||||||
|
|
||||||
export default async function replacePackage(tree: Tree): Promise<void> {
|
|
||||||
await replaceNrwlPackageWithNxPackage(tree, '@nrwl/nx-plugin', '@nx/plugin');
|
|
||||||
|
|
||||||
await formatFiles(tree);
|
|
||||||
}
|
|
||||||
@ -1,281 +0,0 @@
|
|||||||
import 'nx/src/internal-testing-utils/mock-project-graph';
|
|
||||||
|
|
||||||
import {
|
|
||||||
ExecutorsJson,
|
|
||||||
GeneratorsJson,
|
|
||||||
joinPathFragments,
|
|
||||||
MigrationsJson,
|
|
||||||
readJson,
|
|
||||||
readProjectConfiguration,
|
|
||||||
Tree,
|
|
||||||
updateJson,
|
|
||||||
writeJson,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
||||||
import { Linter } from '@nx/eslint';
|
|
||||||
import { assertRunsAgainstNxRepo } from '@nx/devkit/internal-testing-utils';
|
|
||||||
import { PackageJson } from 'nx/src/utils/package-json';
|
|
||||||
import executorGenerator from '../../generators/executor/executor';
|
|
||||||
import generatorGenerator from '../../generators/generator/generator';
|
|
||||||
import pluginGenerator from '../../generators/plugin/plugin';
|
|
||||||
import { updateCliPropsForPlugins } from './cli-in-schema-json';
|
|
||||||
|
|
||||||
describe('updateCliPropsForPlugins', () => {
|
|
||||||
let originalEnv: string;
|
|
||||||
beforeEach(() => {
|
|
||||||
originalEnv = process.env.NX_ADD_PLUGINS;
|
|
||||||
process.env.NX_ADD_PLUGINS = 'false';
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
process.env.NX_ADD_PLUGINS = originalEnv;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should move non-nx generators to schematics for migrations.json', async () => {
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
const { root } = await createPlugin(tree);
|
|
||||||
updatePluginPackageJson(tree, {
|
|
||||||
'nx-migrations': 'migrations.json',
|
|
||||||
});
|
|
||||||
writeJson<MigrationsJson>(
|
|
||||||
tree,
|
|
||||||
joinPathFragments(root, 'migrations.json'),
|
|
||||||
{
|
|
||||||
version: '1.0.0',
|
|
||||||
generators: {
|
|
||||||
'migration-1': {
|
|
||||||
version: '1.0.0',
|
|
||||||
description: 'My Plugin 1',
|
|
||||||
factory: './migrations/my-plugin-1',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
await updateCliPropsForPlugins(tree);
|
|
||||||
const updated = readJson<MigrationsJson>(
|
|
||||||
tree,
|
|
||||||
joinPathFragments(root, 'migrations.json')
|
|
||||||
);
|
|
||||||
expect(updated.generators).not.toHaveProperty('migration-1');
|
|
||||||
expect(updated.schematics).toHaveProperty('migration-1');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should move nx generators to generators for migrations.json', async () => {
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
const { root } = await createPlugin(tree);
|
|
||||||
updatePluginPackageJson(tree, {
|
|
||||||
'nx-migrations': 'migrations.json',
|
|
||||||
});
|
|
||||||
writeJson<MigrationsJson>(
|
|
||||||
tree,
|
|
||||||
joinPathFragments(root, 'migrations.json'),
|
|
||||||
{
|
|
||||||
version: '1.0.0',
|
|
||||||
schematics: {
|
|
||||||
'migration-1': {
|
|
||||||
version: '1.0.0',
|
|
||||||
description: 'My Plugin 1',
|
|
||||||
factory: './migrations/my-plugin-1',
|
|
||||||
cli: 'nx',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
await updateCliPropsForPlugins(tree);
|
|
||||||
const updated = readJson<MigrationsJson>(
|
|
||||||
tree,
|
|
||||||
joinPathFragments(root, 'migrations.json')
|
|
||||||
);
|
|
||||||
expect(updated.schematics).not.toHaveProperty('migration-1');
|
|
||||||
expect(updated.generators).toHaveProperty('migration-1');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should move both nx generators to generators and non-nx schematics to schematics for migrations.json', async () => {
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
const { root } = await createPlugin(tree);
|
|
||||||
updatePluginPackageJson(tree, {
|
|
||||||
'nx-migrations': 'migrations.json',
|
|
||||||
});
|
|
||||||
writeJson<MigrationsJson>(
|
|
||||||
tree,
|
|
||||||
joinPathFragments(root, 'migrations.json'),
|
|
||||||
{
|
|
||||||
version: '1.0.0',
|
|
||||||
schematics: {
|
|
||||||
'migration-1': {
|
|
||||||
version: '1.0.0',
|
|
||||||
description: 'My Plugin 1',
|
|
||||||
factory: './migrations/my-plugin-1',
|
|
||||||
cli: 'nx',
|
|
||||||
},
|
|
||||||
'migration-2': {
|
|
||||||
version: '1.0.0',
|
|
||||||
description: 'My Plugin 2',
|
|
||||||
factory: './migrations/my-plugin-2',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
generators: {
|
|
||||||
'migration-3': {
|
|
||||||
version: '1.0.0',
|
|
||||||
description: 'My Plugin 3',
|
|
||||||
factory: './migrations/my-plugin-3',
|
|
||||||
cli: 'nx',
|
|
||||||
},
|
|
||||||
'migration-4': {
|
|
||||||
version: '1.0.0',
|
|
||||||
description: 'My Plugin 4',
|
|
||||||
factory: './migrations/my-plugin-4',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
await updateCliPropsForPlugins(tree);
|
|
||||||
const updated = readJson<MigrationsJson>(
|
|
||||||
tree,
|
|
||||||
joinPathFragments(root, 'migrations.json')
|
|
||||||
);
|
|
||||||
expect(updated.schematics).not.toHaveProperty('migration-1');
|
|
||||||
expect(updated.generators).toHaveProperty('migration-1');
|
|
||||||
expect(updated.schematics).toHaveProperty('migration-2');
|
|
||||||
expect(updated.generators).not.toHaveProperty('migration-2');
|
|
||||||
expect(updated.schematics).not.toHaveProperty('migration-3');
|
|
||||||
expect(updated.generators).toHaveProperty('migration-3');
|
|
||||||
expect(updated.schematics).toHaveProperty('migration-4');
|
|
||||||
expect(updated.generators).not.toHaveProperty('migration-4');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove cli property from executors', async () => {
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
const { root, name } = await createPlugin(tree);
|
|
||||||
await executorGenerator(tree, {
|
|
||||||
name: 'my-executor',
|
|
||||||
path: `${name}/src/executors/my-executor`,
|
|
||||||
unitTestRunner: 'jest',
|
|
||||||
includeHasher: false,
|
|
||||||
});
|
|
||||||
const schemaPath = joinPathFragments(
|
|
||||||
root,
|
|
||||||
'src/executors/my-executor/schema.json'
|
|
||||||
);
|
|
||||||
updateJson(tree, schemaPath, (schema) => {
|
|
||||||
schema.cli = 'nx';
|
|
||||||
return schema;
|
|
||||||
});
|
|
||||||
await updateCliPropsForPlugins(tree);
|
|
||||||
const updated = readJson(tree, schemaPath);
|
|
||||||
expect(updated).not.toHaveProperty('cli');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove cli property from builders', async () => {
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
const { root, name } = await createPlugin(tree);
|
|
||||||
await executorGenerator(tree, {
|
|
||||||
name: 'my-executor',
|
|
||||||
path: `${name}/src/executors/my-executor`,
|
|
||||||
unitTestRunner: 'jest',
|
|
||||||
includeHasher: false,
|
|
||||||
});
|
|
||||||
updateJson<ExecutorsJson>(
|
|
||||||
tree,
|
|
||||||
joinPathFragments(root, 'executors.json'),
|
|
||||||
(json) => {
|
|
||||||
json.builders = json.executors;
|
|
||||||
delete json.builders;
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const schemaPath = joinPathFragments(
|
|
||||||
root,
|
|
||||||
'src/executors/my-executor/schema.json'
|
|
||||||
);
|
|
||||||
updateJson(tree, schemaPath, (schema) => {
|
|
||||||
schema.cli = 'nx';
|
|
||||||
return schema;
|
|
||||||
});
|
|
||||||
await updateCliPropsForPlugins(tree);
|
|
||||||
const updated = readJson(tree, schemaPath);
|
|
||||||
expect(updated).not.toHaveProperty('cli');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove cli property from generators', async () => {
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
const { root, name } = await createPlugin(tree);
|
|
||||||
await generatorGenerator(tree, {
|
|
||||||
name: 'my-generator',
|
|
||||||
path: `${name}/src/generators/my-generator`,
|
|
||||||
unitTestRunner: 'jest',
|
|
||||||
});
|
|
||||||
const schemaPath = joinPathFragments(
|
|
||||||
root,
|
|
||||||
'src/generators/my-generator/schema.json'
|
|
||||||
);
|
|
||||||
updateJson(tree, schemaPath, (schema) => {
|
|
||||||
schema.cli = 'nx';
|
|
||||||
return schema;
|
|
||||||
});
|
|
||||||
await updateCliPropsForPlugins(tree);
|
|
||||||
const updated = readJson(tree, schemaPath);
|
|
||||||
expect(updated).not.toHaveProperty('cli');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove cli property from schematics', async () => {
|
|
||||||
const tree = createTreeWithEmptyWorkspace();
|
|
||||||
const { root, name } = await createPlugin(tree);
|
|
||||||
await generatorGenerator(tree, {
|
|
||||||
name: 'my-schematic',
|
|
||||||
path: `${name}/src/generators/my-schematic`,
|
|
||||||
unitTestRunner: 'jest',
|
|
||||||
});
|
|
||||||
updateJson<GeneratorsJson>(
|
|
||||||
tree,
|
|
||||||
joinPathFragments(root, 'generators.json'),
|
|
||||||
(json) => {
|
|
||||||
json.schematics = json.generators;
|
|
||||||
delete json.generators;
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const schemaPath = joinPathFragments(
|
|
||||||
root,
|
|
||||||
'src/generators/my-schematic/schema.json'
|
|
||||||
);
|
|
||||||
updateJson(tree, schemaPath, (schema) => {
|
|
||||||
schema.cli = 'nx';
|
|
||||||
return schema;
|
|
||||||
});
|
|
||||||
await updateCliPropsForPlugins(tree);
|
|
||||||
const updated = readJson(tree, schemaPath);
|
|
||||||
expect(updated).not.toHaveProperty('cli');
|
|
||||||
});
|
|
||||||
|
|
||||||
assertRunsAgainstNxRepo(updateCliPropsForPlugins);
|
|
||||||
});
|
|
||||||
|
|
||||||
async function createPlugin(tree: Tree) {
|
|
||||||
await pluginGenerator(tree, {
|
|
||||||
directory: 'my-plugin',
|
|
||||||
compiler: 'tsc',
|
|
||||||
linter: Linter.EsLint,
|
|
||||||
unitTestRunner: 'jest',
|
|
||||||
skipFormat: true,
|
|
||||||
skipLintChecks: false,
|
|
||||||
skipTsConfig: false,
|
|
||||||
});
|
|
||||||
return readProjectConfiguration(tree, 'my-plugin');
|
|
||||||
}
|
|
||||||
|
|
||||||
function updatePluginPackageJson(
|
|
||||||
tree: Tree,
|
|
||||||
packageJsonProps: Partial<PackageJson>
|
|
||||||
) {
|
|
||||||
const { root } = readProjectConfiguration(tree, 'my-plugin');
|
|
||||||
updateJson(tree, root + '/package.json', (json) => {
|
|
||||||
const base = { json, ...packageJsonProps };
|
|
||||||
for (const prop in base) {
|
|
||||||
if (base[prop] === null || base[prop] === undefined) {
|
|
||||||
delete json[prop];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return base;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@ -1,177 +0,0 @@
|
|||||||
import {
|
|
||||||
GeneratorsJson,
|
|
||||||
getProjects,
|
|
||||||
joinPathFragments,
|
|
||||||
MigrationsJson,
|
|
||||||
ExecutorsJson,
|
|
||||||
readJson,
|
|
||||||
Tree,
|
|
||||||
updateJson,
|
|
||||||
output,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import {
|
|
||||||
ExecutorsJsonEntry,
|
|
||||||
GeneratorsJsonEntry,
|
|
||||||
} from 'nx/src/config/misc-interfaces';
|
|
||||||
import { PackageJson, readNxMigrateConfig } from 'nx/src/utils/package-json';
|
|
||||||
import { dirname } from 'path';
|
|
||||||
|
|
||||||
export function updateCliPropsForPlugins(tree: Tree) {
|
|
||||||
const projects = getProjects(tree);
|
|
||||||
for (const project of projects.values()) {
|
|
||||||
if (tree.exists(joinPathFragments(project.root, 'package.json'))) {
|
|
||||||
const packageJson: PackageJson = readJson(
|
|
||||||
tree,
|
|
||||||
joinPathFragments(project.root, 'package.json')
|
|
||||||
);
|
|
||||||
const migrateConfig = readNxMigrateConfig(packageJson);
|
|
||||||
if (migrateConfig.migrations) {
|
|
||||||
const migrationsPath = joinPathFragments(
|
|
||||||
project.root,
|
|
||||||
migrateConfig.migrations
|
|
||||||
);
|
|
||||||
if (tree.exists(migrationsPath)) {
|
|
||||||
updateMigrationsJsonForPlugin(tree, migrationsPath);
|
|
||||||
} else {
|
|
||||||
output.warn({
|
|
||||||
title: `Migrations file specified for ${packageJson.name} does not exist: ${migrationsPath}`,
|
|
||||||
bodyLines: [
|
|
||||||
'Please ensure that migrations that use the Angular Devkit are placed inside the `schematics` property, and migrations that use the Nx Devkit are placed inside the `generators` property.',
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (packageJson.generators) {
|
|
||||||
const generatorsPath = joinPathFragments(
|
|
||||||
project.root,
|
|
||||||
packageJson.generators
|
|
||||||
);
|
|
||||||
if (tree.exists(generatorsPath)) {
|
|
||||||
removeCliFromGeneratorSchemaJsonFiles(tree, generatorsPath);
|
|
||||||
} else {
|
|
||||||
output.warn({
|
|
||||||
title: `Generators file specified for ${packageJson.name} does not exist: ${generatorsPath}`,
|
|
||||||
bodyLines: [
|
|
||||||
"The `cli` property inside generator's `schema.json` files is no longer supported.",
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (packageJson.executors) {
|
|
||||||
const executorsPath = joinPathFragments(
|
|
||||||
project.root,
|
|
||||||
packageJson.executors
|
|
||||||
);
|
|
||||||
if (tree.exists(executorsPath)) {
|
|
||||||
removeCliFromExecutorSchemaJsonFiles(tree, executorsPath);
|
|
||||||
} else {
|
|
||||||
output.warn({
|
|
||||||
title: `Executors file specified for ${packageJson.name} does not exist: ${executorsPath}`,
|
|
||||||
bodyLines: [
|
|
||||||
"The `cli` property inside executor's `schema.json` files is no longer supported.",
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (packageJson.builders) {
|
|
||||||
const buildersPath = joinPathFragments(
|
|
||||||
project.root,
|
|
||||||
packageJson.builders
|
|
||||||
);
|
|
||||||
if (tree.exists(buildersPath)) {
|
|
||||||
removeCliFromExecutorSchemaJsonFiles(tree, buildersPath);
|
|
||||||
} else {
|
|
||||||
output.warn({
|
|
||||||
title: `Builders file specified for ${packageJson.name} does not exist: ${buildersPath}`,
|
|
||||||
bodyLines: [
|
|
||||||
"The `cli` property inside builder's `schema.json` files is no longer supported.",
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (packageJson.schematics) {
|
|
||||||
const schematicsPath = joinPathFragments(
|
|
||||||
project.root,
|
|
||||||
packageJson.schematics
|
|
||||||
);
|
|
||||||
if (tree.exists(schematicsPath)) {
|
|
||||||
removeCliFromGeneratorSchemaJsonFiles(tree, schematicsPath);
|
|
||||||
} else {
|
|
||||||
output.warn({
|
|
||||||
title: `Schematics file specified for ${packageJson.name} does not exist: ${schematicsPath}`,
|
|
||||||
bodyLines: [
|
|
||||||
"The `cli` property inside schematic's `schema.json` files is no longer supported.",
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeCliFromExecutorSchemaJsonFiles(
|
|
||||||
tree: Tree,
|
|
||||||
collectionPath: string
|
|
||||||
) {
|
|
||||||
const collection: ExecutorsJson = readJson(tree, collectionPath);
|
|
||||||
for (const [name, entry] of Object.entries(collection.executors ?? {}).concat(
|
|
||||||
Object.entries(collection.builders ?? {})
|
|
||||||
)) {
|
|
||||||
deleteCliPropFromSchemaFile(collectionPath, entry, tree);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeCliFromGeneratorSchemaJsonFiles(
|
|
||||||
tree: Tree,
|
|
||||||
collectionPath: string
|
|
||||||
) {
|
|
||||||
const collection: GeneratorsJson = readJson(tree, collectionPath);
|
|
||||||
for (const [name, entry] of Object.entries(
|
|
||||||
collection.generators ?? {}
|
|
||||||
).concat(Object.entries(collection.schematics ?? {}))) {
|
|
||||||
deleteCliPropFromSchemaFile(collectionPath, entry, tree);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateMigrationsJsonForPlugin(tree: Tree, collectionPath: string) {
|
|
||||||
updateJson<MigrationsJson>(tree, collectionPath, (json) => {
|
|
||||||
for (const migration in json.generators ?? {}) {
|
|
||||||
if (!(json.generators[migration].cli === 'nx')) {
|
|
||||||
json.schematics ??= {};
|
|
||||||
json.schematics[migration] = json.generators[migration];
|
|
||||||
delete json.generators[migration];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const migration in json.schematics ?? {}) {
|
|
||||||
if (json.schematics[migration].cli === 'nx') {
|
|
||||||
json.generators ??= {};
|
|
||||||
json.generators[migration] = json.schematics[migration];
|
|
||||||
delete json.schematics[migration];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export default updateCliPropsForPlugins;
|
|
||||||
|
|
||||||
function deleteCliPropFromSchemaFile(
|
|
||||||
collectionPath: string,
|
|
||||||
entry: ExecutorsJsonEntry | GeneratorsJsonEntry,
|
|
||||||
tree: Tree
|
|
||||||
) {
|
|
||||||
if (typeof entry === 'string' || !entry.schema) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const schemaPath = joinPathFragments(dirname(collectionPath), entry.schema);
|
|
||||||
if (tree.exists(schemaPath)) {
|
|
||||||
updateJson(tree, schemaPath, (json) => {
|
|
||||||
if (json.cli) {
|
|
||||||
delete json.cli;
|
|
||||||
}
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.warn(`Could not find schema file ${schemaPath}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user