diff --git a/code/lib/cli/src/detect.test.ts b/code/lib/cli/src/detect.test.ts index 85f29d884d41..7a78fa8fa536 100644 --- a/code/lib/cli/src/detect.test.ts +++ b/code/lib/cli/src/detect.test.ts @@ -236,17 +236,28 @@ describe('Detect', () => { it(`should return type HTML if html option is passed`, async () => { const packageManager = { retrievePackageJson: () => Promise.resolve({ dependencies: {}, devDependencies: {} }), + getAllDependencies: () => Promise.resolve({}), getPackageVersion: () => Promise.resolve(null), - } as any as JsPackageManager; + } as Partial; - await expect(detect(packageManager, { html: true })).resolves.toBe(ProjectType.HTML); + await expect(detect(packageManager as any, { html: true })).resolves.toBe(ProjectType.HTML); }); it(`should return language javascript if the TS dependency is present but less than minimum supported`, async () => { (logger.warn as jest.MockedFunction).mockClear(); const packageManager = { - retrievePackageJson: () => Promise.resolve({ dependencies: {}, devDependencies: {} }), + retrievePackageJson: () => + Promise.resolve({ + dependencies: {}, + devDependencies: { + typescript: '1.0.0', + }, + }), + getAllDependencies: () => + Promise.resolve({ + typescript: '1.0.0', + }), getPackageVersion: (packageName) => { switch (packageName) { case 'typescript': @@ -266,7 +277,17 @@ describe('Detect', () => { it(`should return language typescript-3-8 if the TS dependency is >=3.8 and <4.9`, async () => { await expect( detectLanguage({ - retrievePackageJson: () => Promise.resolve({ dependencies: {}, devDependencies: {} }), + retrievePackageJson: () => + Promise.resolve({ + dependencies: {}, + devDependencies: { + typescript: '3.8.0', + }, + }), + getAllDependencies: () => + Promise.resolve({ + typescript: '3.8.0', + }), getPackageVersion: (packageName: string) => { switch (packageName) { case 'typescript': @@ -280,7 +301,17 @@ describe('Detect', () => { await expect( detectLanguage({ - retrievePackageJson: () => Promise.resolve({ dependencies: {}, devDependencies: {} }), + retrievePackageJson: () => + Promise.resolve({ + dependencies: {}, + devDependencies: { + typescript: '4.8.0', + }, + }), + getAllDependencies: () => + Promise.resolve({ + typescript: '4.8.0', + }), getPackageVersion: (packageName: string) => { switch (packageName) { case 'typescript': @@ -296,7 +327,17 @@ describe('Detect', () => { it(`should return language typescript-4-9 if the dependency is >TS4.9`, async () => { await expect( detectLanguage({ - retrievePackageJson: () => Promise.resolve({ dependencies: {}, devDependencies: {} }), + retrievePackageJson: () => + Promise.resolve({ + dependencies: {}, + devDependencies: { + typescript: '4.9.1', + }, + }), + getAllDependencies: () => + Promise.resolve({ + typescript: '4.9.1', + }), getPackageVersion: (packageName: string) => { switch (packageName) { case 'typescript': @@ -312,7 +353,17 @@ describe('Detect', () => { it(`should return language typescript if the dependency is =TS4.9`, async () => { await expect( detectLanguage({ - retrievePackageJson: () => Promise.resolve({ dependencies: {}, devDependencies: {} }), + retrievePackageJson: () => + Promise.resolve({ + dependencies: {}, + devDependencies: { + typescript: '4.9.0', + }, + }), + getAllDependencies: () => + Promise.resolve({ + typescript: '4.9.0', + }), getPackageVersion: (packageName: string) => { switch (packageName) { case 'typescript': @@ -328,7 +379,17 @@ describe('Detect', () => { it(`should return language typescript if the dependency is =TS4.9beta`, async () => { await expect( detectLanguage({ - retrievePackageJson: () => Promise.resolve({ dependencies: {}, devDependencies: {} }), + retrievePackageJson: () => + Promise.resolve({ + dependencies: {}, + devDependencies: { + typescript: '4.9.0-beta', + }, + }), + getAllDependencies: () => + Promise.resolve({ + typescript: '4.9.0-beta', + }), getPackageVersion: (packageName: string) => { switch (packageName) { case 'typescript': @@ -345,6 +406,7 @@ describe('Detect', () => { await expect( detectLanguage({ retrievePackageJson: () => Promise.resolve({ dependencies: {}, devDependencies: {} }), + getAllDependencies: () => Promise.resolve({}), getPackageVersion: () => { return Promise.resolve(null); }, @@ -352,6 +414,23 @@ describe('Detect', () => { ).resolves.toBe(SupportedLanguage.JAVASCRIPT); }); + it(`should return language Javascript even when Typescript is detected in the node_modules but not listed as a direct dependency`, async () => { + await expect( + detectLanguage({ + retrievePackageJson: () => Promise.resolve({ dependencies: {}, devDependencies: {} }), + getAllDependencies: () => Promise.resolve({}), + getPackageVersion: (packageName) => { + switch (packageName) { + case 'typescript': + return Promise.resolve('4.9.0'); + default: + return Promise.resolve(null); + } + }, + } as Partial as JsPackageManager) + ).resolves.toBe(SupportedLanguage.JAVASCRIPT); + }); + describe('detectFrameworkPreset should return', () => { afterEach(() => { jest.clearAllMocks(); diff --git a/code/lib/cli/src/detect.ts b/code/lib/cli/src/detect.ts index fa3cda1135f5..4fa86cdc280d 100644 --- a/code/lib/cli/src/detect.ts +++ b/code/lib/cli/src/detect.ts @@ -165,6 +165,10 @@ export async function detectLanguage(packageManager: JsPackageManager) { return language; } + const isTypescriptDirectDependency = await packageManager + .getAllDependencies() + .then((deps) => Boolean(deps['typescript'])); + const typescriptVersion = await packageManager.getPackageVersion('typescript'); const prettierVersion = await packageManager.getPackageVersion('prettier'); const babelPluginTransformTypescriptVersion = await packageManager.getPackageVersion( @@ -178,20 +182,21 @@ export async function detectLanguage(packageManager: JsPackageManager) { 'eslint-plugin-storybook' ); - if ( - typescriptVersion && - semver.gte(typescriptVersion, '4.9.0') && - (!prettierVersion || semver.gte(prettierVersion, '2.8.0')) && - (!babelPluginTransformTypescriptVersion || - semver.gte(babelPluginTransformTypescriptVersion, '7.20.0')) && - (!typescriptEslintParserVersion || semver.gte(typescriptEslintParserVersion, '5.44.0')) && - (!eslintPluginStorybookVersion || semver.gte(eslintPluginStorybookVersion, '0.6.8')) - ) { - language = SupportedLanguage.TYPESCRIPT_4_9; - } else if (typescriptVersion && semver.gte(typescriptVersion, '3.8.0')) { - language = SupportedLanguage.TYPESCRIPT_3_8; - } else if (typescriptVersion && semver.lt(typescriptVersion, '3.8.0')) { - logger.warn('Detected TypeScript < 3.8, populating with JavaScript examples'); + if (isTypescriptDirectDependency && typescriptVersion) { + if ( + semver.gte(typescriptVersion, '4.9.0') && + (!prettierVersion || semver.gte(prettierVersion, '2.8.0')) && + (!babelPluginTransformTypescriptVersion || + semver.gte(babelPluginTransformTypescriptVersion, '7.20.0')) && + (!typescriptEslintParserVersion || semver.gte(typescriptEslintParserVersion, '5.44.0')) && + (!eslintPluginStorybookVersion || semver.gte(eslintPluginStorybookVersion, '0.6.8')) + ) { + language = SupportedLanguage.TYPESCRIPT_4_9; + } else if (semver.gte(typescriptVersion, '3.8.0')) { + language = SupportedLanguage.TYPESCRIPT_3_8; + } else if (semver.lt(typescriptVersion, '3.8.0')) { + logger.warn('Detected TypeScript < 3.8, populating with JavaScript examples'); + } } return language;