Repository: wheresrhys/fetch-mock
Pull request #834 (2024-09-19 08:27:51)

Rhys/codemod tsx


Patch:
diff --git a/eslint.config.js b/eslint.config.js
index 0960b9e..6808289 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -11,12 +11,15 @@ export default [
 		ignores: [
 			'docs/**/*.js',
 			'packages/*/test/fixtures/*',
+			'packages/**/__test__/fixtures/*',
 			'**/dist/**/*',
 			'packages/fetch-mock/types/index.test-d.ts',
 		],
 	},
 	eslint.configs.recommended,
-	...tseslint.configs.recommended,
+	...tseslint.configs.recommended.map((config) => {
+		return { ...config, ignores: ['packages/codemods/**'] };
+	}),
 	eslintConfigPrettier,
 	{
 		rules: {
diff --git a/packages/codemods/README.md b/packages/codemods/README.md
index 27ff055..4cf42a7 100644
--- a/packages/codemods/README.md
+++ b/packages/codemods/README.md
@@ -6,7 +6,7 @@ A tool for helping upgrade to fetch-mock@12.
 
 1. Install `npm i -D @fetch-mock/codemods jscodeshift`;
 2. Manually modify any code using `.sandbox()` according to the example above.
-3. Run `jscodeshift -t node_modules/@fetch-mock/codemods/wrc/index.jscodeshift .` to run over your entire project, or replace `.` with the directory/file paths you wish to modify. [The jscodeshift CLI has many options](https://jscodeshift.com/run/cli/) - adjust them to suit your project.
+3. Run `jscodeshift -t node_modules/@fetch-mock/codemods/wrc/index.jscodeshift .` to run over your entire project, or replace `.` with the directory/file paths you wish to modify. [The jscodeshift CLI has many options](https://jscodeshift.com/run/cli/) - adjust them to suit your project. **Note that the parser option should not be used as @fetch-mock/codemods forces use of the TSX parser in order to ensure compatibility with teh greatest range of projects**.
 4. For scenarios where the codemod is unable to detect which variable contains a fetch-mock instance (e.g. when it is required in a global set up file, or when using `jest.mock()`) you may pass in one or more variable names using the `FM_VARIABLES` environment variable e.g. `FM_VARIABLES=fm,fetch`
 5. After the codemods have executed, run your tests, correcting all the errors thrown. The notes on what is in/out of scope will help guide you.
 6. Once all your tests are fixed you should be able to uninstall the codemods: `npm uninstall @fetch-mock/codemods jscodeshift`
diff --git a/packages/codemods/src/codemods/methods.js b/packages/codemods/src/codemods/methods.js
index 141eb8e..5ed3cf2 100644
--- a/packages/codemods/src/codemods/methods.js
+++ b/packages/codemods/src/codemods/methods.js
@@ -1,4 +1,4 @@
-const j = require('jscodeshift');
+const j = require('jscodeshift').withParser('tsx');
 
 function getAllChainedMethodCalls(fetchMockVariableName, root) {
 	return root
@@ -27,11 +27,10 @@ function getAllChainedMethodCalls(fetchMockVariableName, root) {
 }
 
 module.exports.getAllChainedMethodCalls = getAllChainedMethodCalls;
-module.exports.simpleMethods = function(fetchMockVariableName, root) {
+module.exports.simpleMethods = function (fetchMockVariableName, root) {
 	const fetchMockMethodCalls = getAllChainedMethodCalls(
 		fetchMockVariableName,
 		root,
-		j,
 	);
 
 	fetchMockMethodCalls.forEach((path) => {
@@ -43,6 +42,7 @@ module.exports.simpleMethods = function(fetchMockVariableName, root) {
 		if (method === 'resetHistory') {
 			path.value.callee.property.name = 'clearHistory';
 		}
+
 		['get', 'post', 'put', 'delete', 'head', 'patch'].some((httpMethod) => {
 			let prependStar = false;
 			if (method === `${httpMethod}Any`) {
@@ -160,4 +160,4 @@ fetchMock.unmockGlobal();
 				.find(j.ThrowStatement)
 				.get().value,
 		);
-}
+};
diff --git a/packages/codemods/src/codemods/options.js b/packages/codemods/src/codemods/options.js
index 1ba0d9c..42db8a8 100644
--- a/packages/codemods/src/codemods/options.js
+++ b/packages/codemods/src/codemods/options.js
@@ -1,4 +1,4 @@
-const j = require('jscodeshift');
+const j = require('jscodeshift').withParser('tsx');
 const { getAllChainedMethodCalls } = require('./methods.js');
 const simpleOptionNames = ['overwriteRoutes', 'warnOnFallback', 'sendAsJson'];
 
@@ -9,7 +9,7 @@ function appendError(message, path) {
 			j(`throw new Error("${message}")`).find(j.ThrowStatement).get().value,
 		);
 }
-module.exports.simpleOptions = function(fetchMockVariableName, root) {
+module.exports.simpleOptions = function (fetchMockVariableName, root) {
 	const configSets = root
 		.find(j.CallExpression, {
 			callee: {
@@ -46,7 +46,9 @@ module.exports.simpleOptions = function(fetchMockVariableName, root) {
 				},
 			},
 		});
-		const objectAssignments = configSets.find(j.Property, { key: { name } });
+		const objectAssignments = configSets.find(j.ObjectProperty, {
+			key: { name },
+		});
 
 		if (name === 'fallbackToNetwork') {
 			const errorMessage =
@@ -102,13 +104,12 @@ module.exports.simpleOptions = function(fetchMockVariableName, root) {
 					})
 					.paths();
 			});
-
 		if (!optionsObjects.length) {
 			return;
 		}
 		simpleOptionNames.forEach((optionName) => {
 			optionsObjects
-				.find(j.Property, {
+				.find(j.ObjectProperty, {
 					key: { name: optionName },
 				})
 				.remove();
@@ -119,4 +120,4 @@ module.exports.simpleOptions = function(fetchMockVariableName, root) {
 			})
 			.remove();
 	});
-}
+};
diff --git a/packages/codemods/src/index.js b/packages/codemods/src/index.js
index 28c7abe..d081892 100644
--- a/packages/codemods/src/index.js
+++ b/packages/codemods/src/index.js
@@ -1,6 +1,6 @@
-const j = require( 'jscodeshift');
-const { simpleOptions } = require( './codemods/options.js');
-const { simpleMethods } = require( './codemods/methods.js');
+const j = require('jscodeshift').withParser('tsx');
+const { simpleOptions } = require('./codemods/options.js');
+const { simpleMethods } = require('./codemods/methods.js');
 
 function findFetchMockVariableName(root) {
 	let fetchMockVariableName;
@@ -40,7 +40,7 @@ function codemod(source, variableName) {
 	return root.toSource();
 }
 
-function transformer(file, api) {
+function transformer(file) {
 	let modifiedSource = codemod(file.source);
 	if (process.env.FM_VARIABLES) {
 		const extraVariables = process.env.FM_VARIABLES.split(',');
diff --git a/packages/codemods/try.js b/packages/codemods/try.js
index a2e89bc..09b48b8 100644
--- a/packages/codemods/try.js
+++ b/packages/codemods/try.js
@@ -1,12 +1,9 @@
-import { codemod } from './src/index.js';
-import jscodeshift from 'jscodeshift';
+const { codemod } = require('./src/index.js');
 
 console.log(
 	codemod(
-		`
-const fetchMock = require('fetch-mock');
-jest.mock('node-fetch', () => fetchMock.fetchHandler)
+		`const fetchMock = require('fetch-mock');
+fetchMock.get('*', 200, {name: 'rio', sendAsJson: true});
 `,
-		jscodeshift,
 	),
 );


Test patch:
diff --git a/packages/codemods/src/__test__/fixtures/extra-vars.js b/packages/codemods/src/__test__/fixtures/extra-vars.js
index 97a9c3d..7e57827 100644
--- a/packages/codemods/src/__test__/fixtures/extra-vars.js
+++ b/packages/codemods/src/__test__/fixtures/extra-vars.js
@@ -1,4 +1,4 @@
 const fetchMock = require('fetch-mock');
-fetchMock.mock("blah", 200);
-fm1.mock("blah", 200);
-fm2.mock("blah", 200);
+fetchMock.mock('blah', 200);
+fm1.mock('blah', 200);
+fm2.mock('blah', 200);
diff --git a/packages/codemods/src/__test__/fixtures/tsx.tsx b/packages/codemods/src/__test__/fixtures/tsx.tsx
new file mode 100644
index 0000000..633f823
--- /dev/null
+++ b/packages/codemods/src/__test__/fixtures/tsx.tsx
@@ -0,0 +1,4 @@
+import fetchMock from 'fetch-mock';
+function helper (res: number): void {
+	fetchMock.mock("blah", <div>Content</div>);
+};
diff --git a/packages/codemods/src/__test__/fixtures/typescript.ts b/packages/codemods/src/__test__/fixtures/typescript.ts
index d6dc94a..6f7acba 100644
--- a/packages/codemods/src/__test__/fixtures/typescript.ts
+++ b/packages/codemods/src/__test__/fixtures/typescript.ts
@@ -1,4 +1,4 @@
 import fetchMock from 'fetch-mock';
-function helper (res: number): {
-	fetchMock.mock("blah", res)
+function helper (res: number): void {
+	fetchMock.mock("blah", res);
 };
diff --git a/packages/codemods/src/__test__/integration.test.js b/packages/codemods/src/__test__/integration.test.js
index f87131f..22ed253 100644
--- a/packages/codemods/src/__test__/integration.test.js
+++ b/packages/codemods/src/__test__/integration.test.js
@@ -2,44 +2,40 @@ import { it, describe, expect } from 'vitest';
 const util = require('node:util');
 const exec = util.promisify(require('node:child_process').exec);
 
-function expectCodemodResult(src, expected) {
-	expect(transformer({ source: src })).toEqual(expected);
-}
-
 describe('integration', () => {
-
 	it('can operate on typescript', async () => {
-		const { stdout, stderr } = await exec('jscodeshift -d -t ./packages/codemods/src/index.js ./packages/codemods/src/__test__/fixtures/typescript.ts')
-		console.log({ stdout, stderr })
-// 		expectCodemodResult(
-// 			`import fetchMock from 'fetch-mock';
-// function helper (res: number): {
-// 	fetchMock.mock("blah", res)
-// };`
-// 			`import fetchMock from 'fetch-mock';
-// function helper (res: number): {
-// 	fetchMock.route("blah", res);
-// }`,
-// 		);
+		const { stdout } = await exec(
+			'jscodeshift --parser ts -p -d -t ./packages/codemods/src/index.js ./packages/codemods/src/__test__/fixtures/typescript.ts',
+		);
+		expect(stdout).toContain(`import fetchMock from 'fetch-mock';
+function helper (res: number): void {
+	fetchMock.route("blah", res);
+}`);
 	});
-	it('can operate on jsx', () => {
-		`import fetchMock from 'fetch-mock';
-	fetchMock.mock("blah", <div>Content</div>);`
-			`import fetchMock from 'fetch-mock';
-	fetchMock.route("blah", <div>Content</div>);`
+	it('can operate on jsx', async () => {
+		const { stdout } = await exec(
+			'jscodeshift --parser ts -p -d -t ./packages/codemods/src/index.js ./packages/codemods/src/__test__/fixtures/jsx.jsx',
+		);
+		expect(stdout).toContain(`import fetchMock from 'fetch-mock';
+fetchMock.route("blah", <div>Content</div>);`);
+	});
+
+	it('can operate on tsx', async () => {
+		const { stdout } = await exec(
+			'jscodeshift --parser ts -p -d -t ./packages/codemods/src/index.js ./packages/codemods/src/__test__/fixtures/tsx.tsx',
+		);
+		expect(stdout).toContain(`import fetchMock from 'fetch-mock';
+function helper (res: number): void {
+	fetchMock.route("blah", <div>Content</div>);
+}`);
 	});
-	it('allow passing in one or more additional variable names for fetch-mock', () => {
-		process.env.FM_VARIABLES = 'fm1,fm2';
-		expectCodemodResult(
-			`const fetchMock = require('fetch-mock');
-fetchMock.mock("blah", 200);
-fm1.mock("blah", 200);
-fm2.mock("blah", 200);`,
-			`const fetchMock = require('fetch-mock');
-fetchMock.route("blah", 200);
-fm1.route("blah", 200);
-fm2.route("blah", 200);`,
+	it('allow passing in one or more additional variable names for fetch-mock', async () => {
+		const { stdout } = await exec(
+			'FM_VARIABLES=fm1,fm2 jscodeshift --parser ts -p -d -t ./packages/codemods/src/index.js ./packages/codemods/src/__test__/fixtures/extra-vars.js',
 		);
-		delete process.env.FM_VARIABLES
+		expect(stdout).toContain(`const fetchMock = require('fetch-mock');
+fetchMock.route('blah', 200);
+fm1.route('blah', 200);
+fm2.route('blah', 200);`);
 	});
 });
diff --git a/packages/codemods/src/__test__/package.json b/packages/codemods/src/__test__/package.json
index 6990891..bedb411 100644
--- a/packages/codemods/src/__test__/package.json
+++ b/packages/codemods/src/__test__/package.json
@@ -1,1 +1,3 @@
-{"type": "module"}
+{
+	"type": "module"
+}