diff --git a/.changeset/silent-steaks-chew.md b/.changeset/silent-steaks-chew.md new file mode 100644 index 000000000..18725edc9 --- /dev/null +++ b/.changeset/silent-steaks-chew.md @@ -0,0 +1,5 @@ +--- +'@hypermod/validator': patch +--- + +Fixes usage of fetchConfig to account for undefined. Now errors should be reported correctly diff --git a/.changeset/slimy-mangos-refuse.md b/.changeset/slimy-mangos-refuse.md new file mode 100644 index 000000000..582abc5ff --- /dev/null +++ b/.changeset/slimy-mangos-refuse.md @@ -0,0 +1,5 @@ +--- +'@hypermod/fetcher': patch +--- + +Correctly types fetchConfig function to correctly show that this function can return `undefined` diff --git a/.changeset/wild-pigs-care.md b/.changeset/wild-pigs-care.md new file mode 100644 index 000000000..4ce333297 --- /dev/null +++ b/.changeset/wild-pigs-care.md @@ -0,0 +1,5 @@ +--- +'@hypermod/mod-atlaskit__textfield': patch +--- + +Removes unused variables diff --git a/community/@atlaskit__textfield/src/5.0.0/__tests__/remove-imports.spec.ts b/community/@atlaskit__textfield/src/5.0.0/__tests__/remove-imports.spec.ts index 55752094e..50f3e2046 100644 --- a/community/@atlaskit__textfield/src/5.0.0/__tests__/remove-imports.spec.ts +++ b/community/@atlaskit__textfield/src/5.0.0/__tests__/remove-imports.spec.ts @@ -15,10 +15,6 @@ function transformer( return source.toSource(options.printOptions); } -const importToDoComment = ` -/* TODO: (@hypermod) This file uses exports used to help theme @atlaskit/textfield which - has now been removed due to its poor performance characteristics. */`; - describe('Remove imports', () => { it('should remove theme imports from Textfield and leave a comment', async () => { const result = await applyTransform( diff --git a/community/@atlaskit__textfield/src/5.0.0/__tests__/remove-prop.spec.ts b/community/@atlaskit__textfield/src/5.0.0/__tests__/remove-prop.spec.ts index 86693f8f3..c50e6a118 100644 --- a/community/@atlaskit__textfield/src/5.0.0/__tests__/remove-prop.spec.ts +++ b/community/@atlaskit__textfield/src/5.0.0/__tests__/remove-prop.spec.ts @@ -15,12 +15,6 @@ function transformer( return source.toSource(options.printOptions); } -const themeToDoComment = ` -/* TODO: (@hypermod) This file uses the @atlaskit/textfield \`theme\` prop which - has now been removed due to its poor performance characteristics. We have not replaced - theme with an equivalent API due to minimal usage of the \`theme\` prop. - The appearance of TextField will have likely changed. */`; - describe('Remove prop', () => { it('should remove theme from Textfield and leave a comment', async () => { const result = await applyTransform( diff --git a/community/hypermod/src/defineInlineTest-to-applyTransform/transform.ts b/community/hypermod/src/defineInlineTest-to-applyTransform/transform.ts index 3ff8964e2..e59841cf4 100644 --- a/community/hypermod/src/defineInlineTest-to-applyTransform/transform.ts +++ b/community/hypermod/src/defineInlineTest-to-applyTransform/transform.ts @@ -1,6 +1,6 @@ import core, { API, FileInfo, Options, Collection } from 'jscodeshift'; -import { hasImportDeclaration, hasImportSpecifier } from '@hypermod/utils'; +import { hasImportSpecifier } from '@hypermod/utils'; export default function transformer( file: FileInfo, diff --git a/packages/fetcher/src/index.spec.ts b/packages/fetcher/src/index.spec.ts index cb734b8fc..9fd72464b 100644 --- a/packages/fetcher/src/index.spec.ts +++ b/packages/fetcher/src/index.spec.ts @@ -42,10 +42,10 @@ describe('fetcher', () => { { virtual: true }, ); - const { filePath, config } = await fetchConfig(mockBasePath); + const configMeta = await fetchConfig(mockBasePath); - expect(config).toEqual(mockConfig); - expect(filePath).toEqual(mockFilePath); + expect(configMeta!.config).toEqual(mockConfig); + expect(configMeta!.filePath).toEqual(mockFilePath); }); it('fetches config with named export', async () => { @@ -57,10 +57,12 @@ describe('fetcher', () => { }, ); - const { filePath, config } = await fetchConfig(mockBasePath); + const configMeta = await fetchConfig(mockBasePath); - expect(config).toEqual(mockConfig); - expect(filePath).toEqual(path.join(mockBasePath, 'hypermod.config.js')); + expect(configMeta!.config).toEqual(mockConfig); + expect(configMeta!.filePath).toEqual( + path.join(mockBasePath, 'hypermod.config.js'), + ); }); it('fetches first matched config when multiple are found', async () => { @@ -81,10 +83,10 @@ describe('fetcher', () => { path.join(mockBasePath, 'codemods', 'hypermod.config.tsx'), ]; - const { config, filePath } = await fetchConfig(mockBasePath); + const configMeta = await fetchConfig(mockBasePath); - expect(config).toEqual(mockConfig); - expect(filePath).toEqual( + expect(configMeta!.config).toEqual(mockConfig); + expect(configMeta!.filePath).toEqual( path.join(mockBasePath, 'src', 'hypermod.config.ts'), ); }); @@ -107,13 +109,13 @@ describe('fetcher', () => { require: jest.fn().mockReturnValue(mockConfig), }; - const { filePath, config } = await fetchPackage( + const configMeta = await fetchPackage( 'fake-package', mockPackageManager as unknown as PluginManager, ); - expect(config).toEqual(mockConfig); - expect(filePath).toEqual(mockFilePath); + expect(configMeta!.config).toEqual(mockConfig); + expect(configMeta!.filePath).toEqual(mockFilePath); }); it('should throw if fetching fails', async () => { @@ -146,13 +148,15 @@ describe('fetcher', () => { }), }; - const { config, filePath } = await fetchRemotePackage( + const configMeta = await fetchRemotePackage( 'fake-package', mockPackageManager as unknown as PluginManager, ); - expect(config).toEqual(mockConfig); - expect(filePath).toEqual(mockBasePath + '/hypermod.config.js'); + expect(configMeta!.config).toEqual(mockConfig); + expect(configMeta!.filePath).toEqual( + mockBasePath + '/hypermod.config.js', + ); }); it('should throw if fetching fails', async () => { @@ -179,13 +183,13 @@ describe('fetcher', () => { }), }; - const { config, filePath } = await fetchRemotePackage( + const configMeta = await fetchRemotePackage( 'fake-package', mockPackageManager as unknown as PluginManager, ); - expect(config).toEqual(mockConfig); - expect(filePath).toEqual(mockBasePath + '/index.js'); + expect(configMeta!.config).toEqual(mockConfig); + expect(configMeta!.filePath).toEqual(mockBasePath + '/index.js'); }); it('throws if entrypoint-based config does not contain a valid config (and there are no config files available elsewhere)', async () => { diff --git a/packages/fetcher/src/index.ts b/packages/fetcher/src/index.ts index 1b424ae2f..7155a62cd 100644 --- a/packages/fetcher/src/index.ts +++ b/packages/fetcher/src/index.ts @@ -28,7 +28,9 @@ function requireConfig(filePath: string, resolvedPath: string) { } } -export async function fetchConfig(filePath: string): Promise { +export async function fetchConfig( + filePath: string, +): Promise { const configs = await fetchConfigs(filePath); return configs[0]; } @@ -94,7 +96,7 @@ export async function fetchPackage( export async function fetchRemotePackage( packageName: string, packageManager: PluginManager, -): Promise { +): Promise { if (['javascript', 'typescript'].includes(packageName)) { throw new Error(`'${packageName}' is ignored as a remote package.`); } diff --git a/packages/validator/src/index.spec.ts b/packages/validator/src/index.spec.ts index 5b94d305a..0a9d1a1dc 100644 --- a/packages/validator/src/index.spec.ts +++ b/packages/validator/src/index.spec.ts @@ -134,6 +134,16 @@ describe('validator', () => { ); }); + it('should error if config file is not found', async () => { + const filePath = 'path/to/'; + + (fetchConfig as jest.Mock).mockResolvedValue(undefined); + + await expect(isValidConfigAtPath(filePath)).rejects.toThrowError( + `Unable to locate config file at path: ${filePath}`, + ); + }); + it('should error if config contains multiple invalid properties', async () => { (fetchConfig as jest.Mock).mockResolvedValue({ location: 'path/to/hypermod.config.js', diff --git a/packages/validator/src/index.ts b/packages/validator/src/index.ts index ca012a83d..9e16abf0d 100644 --- a/packages/validator/src/index.ts +++ b/packages/validator/src/index.ts @@ -38,25 +38,25 @@ export function isValidConfig(config: CodeshiftConfig) { } export async function isValidConfigAtPath(filePath: string) { - const { config } = await fetchConfig(filePath); + const configMeta = await fetchConfig(filePath); - if (!config) { + if (!configMeta) { throw new Error(`Unable to locate config file at path: ${filePath}`); } - const invalidProperites = getInvalidProperties(config); + const invalidProperites = getInvalidProperties(configMeta.config); if (invalidProperites.length) { throw new Error( `Invalid transform ids found: ${invalidProperites.join(', ')}`, ); } - if (!hasValidTransforms(config)) { + if (!hasValidTransforms(configMeta.config)) { throw new Error(`Invalid transform ids found for config at "${filePath}". Please make sure all transforms are identified by a valid semver version. ie 10.0.0`); } - if (!hasValidPresets(config)) { + if (!hasValidPresets(configMeta.config)) { throw new Error(`Invalid preset ids found for config at "${filePath}". Please make sure all presets are kebab case and contain no spaces or special characters. ie sort-imports-by-scope`); } diff --git a/scripts/docs.ts b/scripts/docs.ts index 0c7db6b6e..b2cb780f7 100644 --- a/scripts/docs.ts +++ b/scripts/docs.ts @@ -73,13 +73,13 @@ async function main() { const directories = communityCodemods.filter(dir => junk.not(dir)); for (const dir of directories) { - const { config } = await fetchConfig(path.join(COMMUNITY_PATH, dir)); + const configMeta = await fetchConfig(path.join(COMMUNITY_PATH, dir)); - if (!config) { + if (!configMeta || !configMeta.config) { throw new Error(`Unable to locate config for path: ${dir}`); } - data.push({ name: dir, config }); + data.push({ name: dir, config: configMeta.config }); } cleanTargetDir(DOCS_PATH);