From 6193056bd43660ceac72161a316cd4766e0ad5b6 Mon Sep 17 00:00:00 2001 From: Jimmy Gaussen Date: Tue, 19 Mar 2024 20:35:33 +0100 Subject: [PATCH 1/9] feat(plugin-typescript): check workspace tsconfig.json --- packages/docusaurus/static/configuration/yarnrc.json | 2 +- packages/plugin-typescript/README.md | 4 ++++ packages/plugin-typescript/sources/index.ts | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/docusaurus/static/configuration/yarnrc.json b/packages/docusaurus/static/configuration/yarnrc.json index 3d9e96827df9..78755d5735c2 100644 --- a/packages/docusaurus/static/configuration/yarnrc.json +++ b/packages/docusaurus/static/configuration/yarnrc.json @@ -835,7 +835,7 @@ "tsEnableAutoTypes": { "_package": "@yarnpkg/plugin-typescript", "title": "Define whether to automatically install @types dependencies.", - "description": "If true, Yarn will automatically add `@types` dependencies when running `yarn add` with packages that don't provide their own typings (as reported by the Algolia npm database). This behavior is enabled by default if you have a tsconfig file at the root of your project.", + "description": "If true, Yarn will automatically add `@types` dependencies when running `yarn add` with packages that don't provide their own typings (as reported by the Algolia npm database). This behavior is enabled by default if you have a tsconfig.json file at the root of your project, or in your current workspace.", "type": "boolean", "examples": [true] }, diff --git a/packages/plugin-typescript/README.md b/packages/plugin-typescript/README.md index 2ad9172c5687..b3f2ed7f7741 100644 --- a/packages/plugin-typescript/README.md +++ b/packages/plugin-typescript/README.md @@ -9,6 +9,10 @@ This plugin is included by default starting from Yarn 4. +## Configuration + +This plugin is enabled by default if you have a `tsconfig.json` file at the root of your project, or in your current workspace. See [`tsEnableAutoTypes`](https://yarnpkg.com/configuration/yarnrc#tsEnableAutoTypes) for more information. + ## Example ``` diff --git a/packages/plugin-typescript/sources/index.ts b/packages/plugin-typescript/sources/index.ts index e9f21c14c40e..b9f535302829 100644 --- a/packages/plugin-typescript/sources/index.ts +++ b/packages/plugin-typescript/sources/index.ts @@ -27,6 +27,7 @@ const afterWorkspaceDependencyAddition = async ( const {configuration} = project; const tsEnableAutoTypes = configuration.get(`tsEnableAutoTypes`) + ?? xfs.existsSync(ppath.join(workspace.cwd, `tsconfig.json`)) ?? xfs.existsSync(ppath.join(project.cwd, `tsconfig.json`)); if (!tsEnableAutoTypes) From be68fe1fe582fcf8ac26a96afd2c09fefaeb7433 Mon Sep 17 00:00:00 2001 From: Jimmy Gaussen Date: Tue, 19 Mar 2024 20:58:08 +0100 Subject: [PATCH 2/9] chore: add integ test --- .../sources/plugins/plugin-typescript.test.ts | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts b/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts index e247fdb7c54b..c907e9c6d907 100644 --- a/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts +++ b/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts @@ -27,7 +27,7 @@ describe(`Plugins`, () => { ); test( - `it should automatically enable automatic @types insertion when a tsconfig is detected`, + `it should automatically enable automatic @types insertion when a tsconfig is detected at the root of the project`, makeTemporaryEnv({}, async ({path, run, source}) => { await xfs.writeFilePromise(ppath.join(path, `tsconfig.json`), ``); @@ -44,6 +44,28 @@ describe(`Plugins`, () => { }), ); + test( + `it should automatically enable automatic @types insertion when a tsconfig is detected in the current workspace`, + makeTemporaryMonorepoEnv({ + workspaces: [`packages/*`], + }, {[`packages/foo`]: {}}, async ({path, run, source}) => { + await xfs.writeFilePromise(ppath.join(path, `packages/foo/tsconfig.json`), ``); + + await run(`add`, `is-number`, { + cwd: `${path}/packages/foo` as PortablePath, + }); + + await expect(readManifest(`${path}/packages/foo` as PortablePath)).resolves.toMatchObject({ + dependencies: { + [`is-number`]: `^2.0.0`, + }, + devDependencies: { + [`@types/is-number`]: `^2`, + }, + }); + }), + ); + test( `it should automatically add @types to devDependencies when package doesn't provide types`, makeTemporaryEnv({}, { From c0a892d133955125dda81ef0e77d493243deded3 Mon Sep 17 00:00:00 2001 From: Jimmy Gaussen Date: Tue, 19 Mar 2024 21:01:31 +0100 Subject: [PATCH 3/9] chore: release strategy --- .yarn/versions/dca3f277.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .yarn/versions/dca3f277.yml diff --git a/.yarn/versions/dca3f277.yml b/.yarn/versions/dca3f277.yml new file mode 100644 index 000000000000..04499aa94f53 --- /dev/null +++ b/.yarn/versions/dca3f277.yml @@ -0,0 +1,23 @@ +releases: + "@yarnpkg/cli": minor + "@yarnpkg/plugin-typescript": minor + +declined: + - "@yarnpkg/plugin-compat" + - "@yarnpkg/plugin-constraints" + - "@yarnpkg/plugin-dlx" + - "@yarnpkg/plugin-essentials" + - "@yarnpkg/plugin-init" + - "@yarnpkg/plugin-interactive-tools" + - "@yarnpkg/plugin-nm" + - "@yarnpkg/plugin-npm-cli" + - "@yarnpkg/plugin-pack" + - "@yarnpkg/plugin-patch" + - "@yarnpkg/plugin-pnp" + - "@yarnpkg/plugin-pnpm" + - "@yarnpkg/plugin-stage" + - "@yarnpkg/plugin-version" + - "@yarnpkg/plugin-workspace-tools" + - "@yarnpkg/builder" + - "@yarnpkg/core" + - "@yarnpkg/doctor" From d6cdcf4ba1de1237c2495d7f9825d718eda4579b Mon Sep 17 00:00:00 2001 From: Jimmy Gaussen Date: Tue, 19 Mar 2024 21:11:13 +0100 Subject: [PATCH 4/9] chore: add sibling test --- .../sources/plugins/plugin-typescript.test.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts b/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts index c907e9c6d907..3fd798b0d6f2 100644 --- a/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts +++ b/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts @@ -66,6 +66,26 @@ describe(`Plugins`, () => { }), ); + + test( + `it should not automatically enable automatic @types insertion when a tsconfig is present in a sibling workspace`, + makeTemporaryMonorepoEnv({ + workspaces: [`packages/*`], + }, {[`packages/foo`]: {}, [`packages/bar`]: {}}, async ({path, run, source}) => { + await xfs.writeFilePromise(ppath.join(path, `packages/foo/tsconfig.json`), ``); + + await run(`add`, `is-number`, { + cwd: `${path}/packages/bar` as PortablePath, + }); + + await expect(readManifest(`${path}/packages/bar` as PortablePath)).resolves.toMatchObject({ + dependencies: { + [`is-number`]: `^2.0.0`, + }, + }); + }), + ); + test( `it should automatically add @types to devDependencies when package doesn't provide types`, makeTemporaryEnv({}, { From 80d8c832cdbbaeca8c03ced572c643d91cd9b2bf Mon Sep 17 00:00:00 2001 From: Jimmy Gaussen Date: Tue, 19 Mar 2024 21:24:50 +0100 Subject: [PATCH 5/9] chore: add test --- .../sources/plugins/plugin-typescript.test.ts | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts b/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts index 3fd798b0d6f2..0be648858846 100644 --- a/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts +++ b/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts @@ -66,7 +66,6 @@ describe(`Plugins`, () => { }), ); - test( `it should not automatically enable automatic @types insertion when a tsconfig is present in a sibling workspace`, makeTemporaryMonorepoEnv({ @@ -86,6 +85,25 @@ describe(`Plugins`, () => { }), ); + test( + `it should not automatically enable automatic @types insertion when a tsconfig is detected in the root project of the current workspace`, + makeTemporaryMonorepoEnv({ + workspaces: [`packages/*`], + }, {[`packages/foo`]: {}}, async ({path, run, source}) => { + await xfs.writeFilePromise(ppath.join(path, `tsconfig.json`), ``); + + await run(`add`, `is-number`, { + cwd: `${path}/packages/foo` as PortablePath, + }); + + await expect(readManifest(`${path}/packages/foo` as PortablePath)).resolves.toMatchObject({ + dependencies: { + [`is-number`]: `^2.0.0`, + }, + }); + }), + ); + test( `it should automatically add @types to devDependencies when package doesn't provide types`, makeTemporaryEnv({}, { From 66f863a037702a9a020bbb84ba86164cf9a1139c Mon Sep 17 00:00:00 2001 From: Jimmy Gaussen Date: Tue, 19 Mar 2024 21:59:58 +0100 Subject: [PATCH 6/9] fix: handle remove, add tests --- .../sources/plugins/plugin-typescript.test.ts | 135 +++++++++++++++++- packages/plugin-typescript/sources/index.ts | 1 + 2 files changed, 135 insertions(+), 1 deletion(-) diff --git a/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts b/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts index 0be648858846..a80ef0f76a1c 100644 --- a/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts +++ b/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts @@ -51,6 +51,26 @@ describe(`Plugins`, () => { }, {[`packages/foo`]: {}}, async ({path, run, source}) => { await xfs.writeFilePromise(ppath.join(path, `packages/foo/tsconfig.json`), ``); + await run(`add`, `is-number`); + + await expect(readManifest(`${path}/packages/foo` as PortablePath)).resolves.toMatchObject({ + dependencies: { + [`is-number`]: `^2.0.0`, + }, + devDependencies: { + [`@types/is-number`]: `^2`, + }, + }); + }), + ); + + test( + `it should automatically enable automatic @types insertion in the current workspace when tsEnableAutoTypes is set to true`, + makeTemporaryMonorepoEnv({ + workspaces: [`packages/*`], + }, {[`packages/foo`]: {}}, async ({path, run, source}) => { + await run(`config`, `set`, `tsEnableAutoTypes`, `true`); + await run(`add`, `is-number`, { cwd: `${path}/packages/foo` as PortablePath, }); @@ -357,7 +377,24 @@ describe(`Plugins`, () => { describe(`Removing types`, () => { for (const type of Manifest.allDependencies) { test( - `it should automatically remove @types from ${type}`, + `it should not automatically remove @types from ${type} without tsconfig or tsEnableAutoTypes`, + makeTemporaryEnv(merge({ + dependencies: { + [`is-number`]: `^1.0.0`, + }, + }, { + [type]: { + [`@types/is-number`]: `1.0.0`, + }, + }), {}, async ({path, run, source}) => { + await run(`remove`, `is-number`); + + await expect(readManifest(path)).resolves.toHaveProperty(`${type}.@types/is-number`); + }), + ); + + test( + `it should automatically remove @types from ${type} with tsEnableAutoTypes set to true`, makeTemporaryEnv(merge({ dependencies: { [`is-number`]: `^1.0.0`, @@ -374,6 +411,102 @@ describe(`Plugins`, () => { await expect(readManifest(path)).resolves.not.toHaveProperty(`${type}.@types/is-number`); }), ); + + test( + `it should automatically remove @types from ${type} with tsconfig.json present`, + makeTemporaryEnv(merge({ + dependencies: { + [`is-number`]: `^1.0.0`, + }, + }, { + [type]: { + [`@types/is-number`]: `1.0.0`, + }, + }), {}, async ({path, run, source}) => { + await xfs.writeFilePromise(ppath.join(path, `tsconfig.json`), ``); + + await run(`remove`, `is-number`); + + await expect(readManifest(path)).resolves.not.toHaveProperty(`${type}.@types/is-number`); + }), + ); + + test( + `it should not automatically remove @types ${type} from the current workspace without tsconfig.json present or tsEnableAutoTypes`, + makeTemporaryMonorepoEnv({ + workspaces: [`packages/*`], + }, + merge( + {[`packages/foo`]: {dependencies: {[`is-number`]: `^1.0.0`}}}, + {[`packages/foo`]: {[type]: {[`@types/is-number`]: `1.0.0`}}}, + ), + async ({path, run, source}) => { + await run(`remove`, `is-number`, { + cwd: `${path}/packages/foo` as PortablePath, + }); + + await expect(readManifest(`${path}/packages/foo` as PortablePath)).resolves.toHaveProperty(`${type}.@types/is-number`); + }), + ); + + test( + `it should not automatically remove @types ${type} from the current workspace when a tsconfig is detected in the root project of the current workspace`, + makeTemporaryMonorepoEnv({ + workspaces: [`packages/*`], + }, + merge( + {[`packages/foo`]: {dependencies: {[`is-number`]: `^1.0.0`}}}, + {[`packages/foo`]: {[type]: {[`@types/is-number`]: `1.0.0`}}}, + ), + async ({path, run, source}) => { + await xfs.writeFilePromise(ppath.join(path, `tsconfig.json`), ``); + + await run(`remove`, `is-number`, { + cwd: `${path}/packages/foo` as PortablePath, + }); + + await expect(readManifest(`${path}/packages/foo` as PortablePath)).resolves.toHaveProperty(`${type}.@types/is-number`); + }), + ); + + test( + `it should automatically remove @types ${type} from the current workspace with tsEnableAutoTypes set to true`, + makeTemporaryMonorepoEnv({ + workspaces: [`packages/*`], + }, + merge( + {[`packages/foo`]: {dependencies: {[`is-number`]: `^1.0.0`}}}, + {[`packages/foo`]: {[type]: {[`@types/is-number`]: `1.0.0`}}}, + ), + async ({path, run, source}) => { + await run(`config`, `set`, `tsEnableAutoTypes`, `true`); + await run(`remove`, `is-number`, { + cwd: `${path}/packages/foo` as PortablePath, + }); + + await expect(readManifest(`${path}/packages/foo` as PortablePath)).resolves.not.toHaveProperty(`${type}.@types/is-number`); + }), + ); + + test( + `it should automatically remove @types ${type} from the current workspace with tsconfig.json present`, + makeTemporaryMonorepoEnv({ + workspaces: [`packages/*`], + }, + merge( + {[`packages/foo`]: {dependencies: {[`is-number`]: `^1.0.0`}}}, + {[`packages/foo`]: {[type]: {[`@types/is-number`]: `1.0.0`}}}, + ), + async ({path, run, source}) => { + await xfs.writeFilePromise(ppath.join(path, `packages/foo/tsconfig.json`), ``); + + await run(`remove`, `is-number`, { + cwd: `${path}/packages/foo` as PortablePath, + }); + + await expect(readManifest(`${path}/packages/foo` as PortablePath)).resolves.not.toHaveProperty(`${type}.@types/is-number`); + }), + ); } test( diff --git a/packages/plugin-typescript/sources/index.ts b/packages/plugin-typescript/sources/index.ts index b9f535302829..b84001eb504b 100644 --- a/packages/plugin-typescript/sources/index.ts +++ b/packages/plugin-typescript/sources/index.ts @@ -120,6 +120,7 @@ const afterWorkspaceDependencyRemoval = async ( const {configuration} = project; const tsEnableAutoTypes = configuration.get(`tsEnableAutoTypes`) + ?? xfs.existsSync(ppath.join(workspace.cwd, `tsconfig.json`)) ?? xfs.existsSync(ppath.join(project.cwd, `tsconfig.json`)); if (!tsEnableAutoTypes) From e31dbab55f55c542d40f1c32f99b4fc9b276f1a0 Mon Sep 17 00:00:00 2001 From: Jimmy Gaussen Date: Tue, 19 Mar 2024 22:03:16 +0100 Subject: [PATCH 7/9] fix: tsEnableAutoTypes condition --- packages/plugin-typescript/sources/index.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/plugin-typescript/sources/index.ts b/packages/plugin-typescript/sources/index.ts index b84001eb504b..d3b388023890 100644 --- a/packages/plugin-typescript/sources/index.ts +++ b/packages/plugin-typescript/sources/index.ts @@ -26,9 +26,10 @@ const afterWorkspaceDependencyAddition = async ( const {project} = workspace; const {configuration} = project; - const tsEnableAutoTypes = configuration.get(`tsEnableAutoTypes`) - ?? xfs.existsSync(ppath.join(workspace.cwd, `tsconfig.json`)) - ?? xfs.existsSync(ppath.join(project.cwd, `tsconfig.json`)); + const tsEnableAutoTypes = configuration.get(`tsEnableAutoTypes`) ?? ( + xfs.existsSync(ppath.join(workspace.cwd, `tsconfig.json`)) + || xfs.existsSync(ppath.join(project.cwd, `tsconfig.json`)) + ); if (!tsEnableAutoTypes) return; @@ -119,9 +120,10 @@ const afterWorkspaceDependencyRemoval = async ( const {project} = workspace; const {configuration} = project; - const tsEnableAutoTypes = configuration.get(`tsEnableAutoTypes`) - ?? xfs.existsSync(ppath.join(workspace.cwd, `tsconfig.json`)) - ?? xfs.existsSync(ppath.join(project.cwd, `tsconfig.json`)); + const tsEnableAutoTypes = configuration.get(`tsEnableAutoTypes`) ?? ( + xfs.existsSync(ppath.join(workspace.cwd, `tsconfig.json`)) + || xfs.existsSync(ppath.join(project.cwd, `tsconfig.json`)) + ); if (!tsEnableAutoTypes) return; From 9b16663625885b940ca245ed689212111583fde8 Mon Sep 17 00:00:00 2001 From: Jimmy Gaussen Date: Tue, 19 Mar 2024 22:08:17 +0100 Subject: [PATCH 8/9] chore: fix tests --- .../sources/plugins/plugin-typescript.test.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts b/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts index a80ef0f76a1c..cbdd8eeaeff8 100644 --- a/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts +++ b/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts @@ -106,7 +106,7 @@ describe(`Plugins`, () => { ); test( - `it should not automatically enable automatic @types insertion when a tsconfig is detected in the root project of the current workspace`, + `it should automatically enable automatic @types insertion when a tsconfig is detected in the root project of the current workspace`, makeTemporaryMonorepoEnv({ workspaces: [`packages/*`], }, {[`packages/foo`]: {}}, async ({path, run, source}) => { @@ -120,6 +120,9 @@ describe(`Plugins`, () => { dependencies: { [`is-number`]: `^2.0.0`, }, + devDependencies: { + [`@types/is-number`]: `^2`, + }, }); }), ); @@ -450,7 +453,7 @@ describe(`Plugins`, () => { ); test( - `it should not automatically remove @types ${type} from the current workspace when a tsconfig is detected in the root project of the current workspace`, + `it should automatically remove @types ${type} from the current workspace when a tsconfig is detected in the root project of the current workspace`, makeTemporaryMonorepoEnv({ workspaces: [`packages/*`], }, @@ -465,7 +468,7 @@ describe(`Plugins`, () => { cwd: `${path}/packages/foo` as PortablePath, }); - await expect(readManifest(`${path}/packages/foo` as PortablePath)).resolves.toHaveProperty(`${type}.@types/is-number`); + await expect(readManifest(`${path}/packages/foo` as PortablePath)).resolves.not.toHaveProperty(`${type}.@types/is-number`); }), ); From 45e3df03a1409e00afcb21531f5235362160539d Mon Sep 17 00:00:00 2001 From: Jimmy Gaussen Date: Tue, 19 Mar 2024 23:07:10 +0100 Subject: [PATCH 9/9] chore: fix test --- .../pkg-tests-specs/sources/plugins/plugin-typescript.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts b/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts index cbdd8eeaeff8..ff5e9ffe61dd 100644 --- a/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts +++ b/packages/acceptance-tests/pkg-tests-specs/sources/plugins/plugin-typescript.test.ts @@ -51,7 +51,9 @@ describe(`Plugins`, () => { }, {[`packages/foo`]: {}}, async ({path, run, source}) => { await xfs.writeFilePromise(ppath.join(path, `packages/foo/tsconfig.json`), ``); - await run(`add`, `is-number`); + await run(`add`, `is-number`, { + cwd: `${path}/packages/foo` as PortablePath, + }); await expect(readManifest(`${path}/packages/foo` as PortablePath)).resolves.toMatchObject({ dependencies: {