diff --git a/package.json b/package.json index d6b6d2e..3c29a9a 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,8 @@ "packages", "npm", "automatic", - "update" + "update", + "rush" ], "repository": { "type": "git", diff --git a/src/update-ts-references.js b/src/update-ts-references.js index aa3ef0c..2b28499 100644 --- a/src/update-ts-references.js +++ b/src/update-ts-references.js @@ -43,7 +43,7 @@ const getAllPackageJsons = async (workspaces, cwd) => { workspaceGlobs.map( (workspace) => new Promise((resolve, reject) => { - glob(`${workspace}/${PACKAGE_JSON}`, {cwd}, (error, files) => { + glob(`${workspace}/${PACKAGE_JSON}`, { cwd }, (error, files) => { if (error) { reject(error); } @@ -103,7 +103,7 @@ const getPackageNamesAndPackageDir = (packageFilePaths, cwd) => packageFilePaths.reduce((map, packageFilePath) => { const fullPackageFilePath = path.join(cwd, packageFilePath); const packageJson = require(fullPackageFilePath); - const {name} = packageJson; + const { name } = packageJson; map.set(name, { packageDir: path.dirname(fullPackageFilePath), hasTsEntry: /\.(ts|tsx)$/.test((packageJson.main ? packageJson.main : '')) @@ -113,7 +113,7 @@ const getPackageNamesAndPackageDir = (packageFilePaths, cwd) => const getReferencesFromDependencies = ( configName, - {packageDir}, + { packageDir }, packageName, packagesMap, verbose @@ -142,7 +142,7 @@ const getReferencesFromDependencies = ( return Object.keys(mergedDependencies) .reduce((referenceArray, dependency) => { if (packagesMap.has(dependency)) { - const {packageDir: dependencyDir} = packagesMap.get(dependency); + const { packageDir: dependencyDir } = packagesMap.get(dependency); const relativePath = path.relative(packageDir, dependencyDir); const detectedConfig = detectTSConfig(dependencyDir, configName) if (detectedConfig !== null) { @@ -174,7 +174,7 @@ const updateTsConfig = ( paths, check, createPathMappings = false, - {packageDir} = {packageDir: process.cwd()}, + { packageDir } = { packageDir: process.cwd() }, ) => { const tsconfigFilePath = path.join(packageDir, configName); @@ -183,7 +183,7 @@ const updateTsConfig = ( const currentReferences = config.references || []; - const mergedReferences = references.map(({path}) => ({ + const mergedReferences = references.map(({ path }) => ({ path, ...currentReferences.find((currentRef) => currentRef.path === path), })); @@ -205,13 +205,13 @@ const updateTsConfig = ( assign(compilerOptions, paths && Object.keys(paths).length > 0 ? { paths - } : {paths: undefined}) + } : { paths: undefined }) const newTsConfig = assign(config, - { + Object.keys(compilerOptions).length > 0 ? { compilerOptions, references: mergedReferences.length ? mergedReferences : undefined, - } + } : { references: mergedReferences.length ? mergedReferences : undefined, } ); fs.writeFileSync(tsconfigFilePath, stringify(newTsConfig, null, 2) + '\n'); } @@ -220,30 +220,31 @@ const updateTsConfig = ( return 0; } catch (error) { console.error(`could not read ${tsconfigFilePath}`, error); - if(strict) + if (strict) throw new Error('Expect always a tsconfig.json in the package directory while running in strict mode') } }; function getPathsFromReferences(references, tsconfigMap, ignorePathMappings - = []) { + = []) { return references.reduce((paths, ref) => { - if(ignorePathMappings.includes(ref.name)) return paths - const rootFolder= tsconfigMap[ref.name]?.compilerOptions?.rootDir ?? 'src' + if (ignorePathMappings.includes(ref.name)) return paths + const rootFolder = tsconfigMap[ref.name]?.compilerOptions?.rootDir ?? 'src' return { - ...paths, - [`${ref.name}`]: [`${ref.folder}${rootFolder === '.' ? '' : `/${rootFolder}`}`], - }}, {}); + ...paths, + [`${ref.name}`]: [`${ref.folder}${rootFolder === '.' ? '' : `/${rootFolder}`}`], + } + }, {}); } const execute = async ({ - cwd, createTsConfig, - verbose, - check, - usecase, - strict, - ...configurable - }) => { + cwd, createTsConfig, + verbose, + check, + usecase, + strict, + ...configurable +}) => { let changesCount = 0; // eslint-disable-next-line no-console console.log('updating tsconfigs'); @@ -273,7 +274,7 @@ const execute = async ({ withoutRootConfig } = configurable - let ignorePathMappings = [] + let ignorePathMappings = [] if (fs.existsSync(path.join(cwd, usecase))) { const yamlConfig = yaml.load( @@ -292,7 +293,7 @@ const execute = async ({ console.log(`createPathMappings ${createPathMappings}`) console.log('joined workspaces', workspaces); console.log('ignorePathMappings', ignorePathMappings -); + ); } } @@ -382,13 +383,13 @@ const execute = async ({ console.log('rootReferences', rootReferences); console.log('rootPaths', rootPaths); } - if(withoutRootConfig === false) { + if (withoutRootConfig === false) { changesCount += updateTsConfig( strict, rootConfigName, rootReferences, rootPaths, - check, createPathMappings, {packageDir: cwd}, + check, createPathMappings, { packageDir: cwd }, ); } @@ -398,4 +399,4 @@ const execute = async ({ return changesCount; }; -module.exports = {execute, defaultOptions}; +module.exports = { execute, defaultOptions }; diff --git a/test-scenarios/yarn-ws-empty-compilerOptions/package.json b/test-scenarios/yarn-ws-empty-compilerOptions/package.json new file mode 100644 index 0000000..77bbc0e --- /dev/null +++ b/test-scenarios/yarn-ws-empty-compilerOptions/package.json @@ -0,0 +1,12 @@ +{ + "name": "yarn-workspace", + "version": "0.0.1", + "private": true, + "workspaces": [ + "workspace-a", + "workspace-b" + ], + "devDependencies": { + "typescript": "latest" + } +} diff --git a/test-scenarios/yarn-ws-empty-compilerOptions/tsconfig.base.json b/test-scenarios/yarn-ws-empty-compilerOptions/tsconfig.base.json new file mode 100644 index 0000000..23b6225 --- /dev/null +++ b/test-scenarios/yarn-ws-empty-compilerOptions/tsconfig.base.json @@ -0,0 +1,8 @@ +{ + "files": [], + "compilerOptions": { + /* Basic Options */ + // "allowJs": true, + "composite": true + } +} diff --git a/test-scenarios/yarn-ws-empty-compilerOptions/tsconfig.json b/test-scenarios/yarn-ws-empty-compilerOptions/tsconfig.json new file mode 100644 index 0000000..ffcbb94 --- /dev/null +++ b/test-scenarios/yarn-ws-empty-compilerOptions/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "./tsconfig.base.json" +} diff --git a/test-scenarios/yarn-ws-empty-compilerOptions/workspace-a/package.json b/test-scenarios/yarn-ws-empty-compilerOptions/workspace-a/package.json new file mode 100644 index 0000000..6b40e48 --- /dev/null +++ b/test-scenarios/yarn-ws-empty-compilerOptions/workspace-a/package.json @@ -0,0 +1,7 @@ +{ + "name": "workspace-a", + "version": "1.0.0", + "dependencies": { + "workspace-b": "1.0.0" + } +} diff --git a/test-scenarios/yarn-ws-empty-compilerOptions/workspace-a/tsconfig.json b/test-scenarios/yarn-ws-empty-compilerOptions/workspace-a/tsconfig.json new file mode 100644 index 0000000..367f4a0 --- /dev/null +++ b/test-scenarios/yarn-ws-empty-compilerOptions/workspace-a/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "references": [ + { + "path": "../some/old/ref" + } + ] +} diff --git a/test-scenarios/yarn-ws-empty-compilerOptions/workspace-b/package.json b/test-scenarios/yarn-ws-empty-compilerOptions/workspace-b/package.json new file mode 100644 index 0000000..43a4bc4 --- /dev/null +++ b/test-scenarios/yarn-ws-empty-compilerOptions/workspace-b/package.json @@ -0,0 +1,7 @@ +{ + "name": "workspace-b", + "version": "1.0.0", + "dependencies": { + "cross-env": "5.0.5" + } +} diff --git a/test-scenarios/yarn-ws-empty-compilerOptions/workspace-b/tsconfig.base.json b/test-scenarios/yarn-ws-empty-compilerOptions/workspace-b/tsconfig.base.json new file mode 100644 index 0000000..1dd8e13 --- /dev/null +++ b/test-scenarios/yarn-ws-empty-compilerOptions/workspace-b/tsconfig.base.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + } +} diff --git a/test-scenarios/yarn-ws-empty-compilerOptions/workspace-b/tsconfig.json b/test-scenarios/yarn-ws-empty-compilerOptions/workspace-b/tsconfig.json new file mode 100644 index 0000000..ffcbb94 --- /dev/null +++ b/test-scenarios/yarn-ws-empty-compilerOptions/workspace-b/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "./tsconfig.base.json" +} diff --git a/tests/update-ts-references.test.js b/tests/update-ts-references.test.js index db96ce1..6c9197c 100644 --- a/tests/update-ts-references.test.js +++ b/tests/update-ts-references.test.js @@ -1,9 +1,10 @@ const path = require('path'); const fs = require('fs'); -const {parse} = require("comment-json") -const {setup} = require('./setup'); +const { parse } = require("comment-json") +const { setup } = require('./setup'); const rootFolderYarn = path.join(process.cwd(), 'test-run', 'yarn-ws'); +const rootFolderYarnEmptyCompilerOptions = path.join(process.cwd(), 'test-run', 'yarn-ws-empty-compilerOptions') const rootFolderYarnNohoist = path.join( process.cwd(), 'test-run', @@ -27,7 +28,7 @@ const rootFolderConfigName = path.join( 'yarn-ws-custom-tsconfig-names' ); -const compilerOptions = {outDir: 'dist', rootDir: 'src'}; +const compilerOptions = { outDir: 'dist', rootDir: 'src' }; const rootTsConfig = [ @@ -168,6 +169,52 @@ const tsconfigsIncludingPrepend = [ fooBTsConfig, ]; +test('avoid adding an empty compilerOptions', async () => { + const rootTsConfig = [ + '.', + { + extends: "./tsconfig.base.json", + references: [ + { + path: 'workspace-a', + }, + { + path: 'workspace-b', + }, + ], + }, + ]; + const wsATsConfig = [ + './workspace-a', + { + compilerOptions, + references: [ + { + path: '../workspace-b', + }, + ], + }, + ]; + + const wsBTsConfig = [ + './workspace-b', + { + "extends": "./tsconfig.base.json" + }, + ]; + const configs = [rootTsConfig, wsATsConfig, wsBTsConfig] + + await setup(rootFolderYarnEmptyCompilerOptions) + + configs.forEach((tsconfig) => { + const [configPath, config] = tsconfig; + + expect( + parse(fs.readFileSync(path.join(rootFolderYarnEmptyCompilerOptions, configPath, 'tsconfig.json')).toString()) + ).toEqual(config); + }) +}) + test('Support yarn and npm workspaces', async () => { await setup(rootFolderYarn); @@ -229,7 +276,7 @@ test('create paths mappings ', async () => { { compilerOptions: { composite: true, - paths: { "foo-a": ["utils/foos/foo-a/src"] ,"foo-b": ["utils/foos/foo-b/src"] ,"workspace-a": ["workspace-a/src"],"workspace-b": ["workspace-b"] } + paths: { "foo-a": ["utils/foos/foo-a/src"], "foo-b": ["utils/foos/foo-b/src"], "workspace-a": ["workspace-a/src"], "workspace-b": ["workspace-b"] } }, files: [], references: [ @@ -254,7 +301,7 @@ test('create paths mappings ', async () => { { compilerOptions: { ...compilerOptions, - paths: {"foo-a": ["../utils/foos/foo-a/src"], "workspace-b": ["../workspace-b"]} + paths: { "foo-a": ["../utils/foos/foo-a/src"], "workspace-b": ["../workspace-b"] } }, references: [ { @@ -270,7 +317,7 @@ test('create paths mappings ', async () => { const wsBTsConfig = [ './workspace-b', { - compilerOptions: {...compilerOptions,rootDir: '.', paths: {"foo-b": ["../utils/foos/foo-b/src"]}}, + compilerOptions: { ...compilerOptions, rootDir: '.', paths: { "foo-b": ["../utils/foos/foo-b/src"] } }, references: [ { path: '../utils/foos/foo-b', @@ -323,7 +370,7 @@ test('create paths mappings with ignorePathMappings', async () => { { compilerOptions: { composite: true, - paths: { "foo-a": ["utils/foos/foo-a/src"] ,"foo-b": ["utils/foos/foo-b/src"] ,"workspace-b": ["workspace-b"] } + paths: { "foo-a": ["utils/foos/foo-a/src"], "foo-b": ["utils/foos/foo-b/src"], "workspace-b": ["workspace-b"] } }, files: [], references: [ @@ -348,7 +395,7 @@ test('create paths mappings with ignorePathMappings', async () => { { compilerOptions: { ...compilerOptions, - paths: {"foo-a": ["../utils/foos/foo-a/src"], "workspace-b": ["../workspace-b"]} + paths: { "foo-a": ["../utils/foos/foo-a/src"], "workspace-b": ["../workspace-b"] } }, references: [ { @@ -364,7 +411,7 @@ test('create paths mappings with ignorePathMappings', async () => { const wsBTsConfig = [ './workspace-b', { - compilerOptions: {...compilerOptions,rootDir: '.', paths: {"foo-b": ["../utils/foos/foo-b/src"]}}, + compilerOptions: { ...compilerOptions, rootDir: '.', paths: { "foo-b": ["../utils/foos/foo-b/src"] } }, references: [ { path: '../utils/foos/foo-b', @@ -461,7 +508,7 @@ test('Test create tsconfig', async () => { }); test('Support option --withoutRootConfig', async () => { - await setup(rootFolderTsRefNoRoot,undefined,undefined,undefined,undefined,undefined,true); + await setup(rootFolderTsRefNoRoot, undefined, undefined, undefined, undefined, undefined, true); const tsconfigs = [ [ @@ -492,7 +539,7 @@ test('Support option --withoutRootConfig', async () => { // should not touch the ignore config expect( parse(fs.readFileSync(path.join(rootFolderTsRefNoRoot, 'workspace-ignore', 'tsconfig.json')).toString()) - ).toEqual({compilerOptions}); + ).toEqual({ compilerOptions }); });