From c1b91df93787a173dee46ccd6e454a72b913fcb2 Mon Sep 17 00:00:00 2001 From: 43081j <43081j@users.noreply.github.com> Date: Wed, 21 Aug 2024 17:20:21 +0100 Subject: [PATCH] feat: add object.assign codemod Adds a codemod for `object.assign`. This also changes behaviour of `removeImport` to consider _all_ require calls with the target source, rather than only those which are directly call expressions. --- codemods/object.assign/index.js | 38 +++++++++++++++++++ codemods/shared.js | 8 ++-- index.js | 2 + .../object.assign/get-polyfill/after.js | 8 ++++ .../object.assign/get-polyfill/before.js | 10 +++++ .../object.assign/get-polyfill/result.js | 8 ++++ test/fixtures/object.assign/shim/after.js | 8 ++++ test/fixtures/object.assign/shim/before.js | 10 +++++ test/fixtures/object.assign/shim/result.js | 8 ++++ .../object.assign/simple-cjs/after.js | 8 ++++ .../object.assign/simple-cjs/before.js | 10 +++++ .../object.assign/simple-cjs/result.js | 8 ++++ test/fixtures/object.assign/simple/after.js | 8 ++++ test/fixtures/object.assign/simple/before.js | 10 +++++ test/fixtures/object.assign/simple/result.js | 8 ++++ types/codemods/object.assign/index.d.ts | 11 ++++++ 16 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 codemods/object.assign/index.js create mode 100644 test/fixtures/object.assign/get-polyfill/after.js create mode 100644 test/fixtures/object.assign/get-polyfill/before.js create mode 100644 test/fixtures/object.assign/get-polyfill/result.js create mode 100644 test/fixtures/object.assign/shim/after.js create mode 100644 test/fixtures/object.assign/shim/before.js create mode 100644 test/fixtures/object.assign/shim/result.js create mode 100644 test/fixtures/object.assign/simple-cjs/after.js create mode 100644 test/fixtures/object.assign/simple-cjs/before.js create mode 100644 test/fixtures/object.assign/simple-cjs/result.js create mode 100644 test/fixtures/object.assign/simple/after.js create mode 100644 test/fixtures/object.assign/simple/before.js create mode 100644 test/fixtures/object.assign/simple/result.js create mode 100644 types/codemods/object.assign/index.d.ts diff --git a/codemods/object.assign/index.js b/codemods/object.assign/index.js new file mode 100644 index 0000000..ea221e5 --- /dev/null +++ b/codemods/object.assign/index.js @@ -0,0 +1,38 @@ +import jscodeshift from 'jscodeshift'; +import { removeImport } from '../shared.js'; + +/** + * @typedef {import('../../types.js').Codemod} Codemod + * @typedef {import('../../types.js').CodemodOptions} CodemodOptions + */ + +/** + * @param {CodemodOptions} [options] + * @returns {Codemod} + */ +export default function (options) { + return { + name: 'object.assign', + transform: ({ file }) => { + const j = jscodeshift; + const root = j(file.source); + + const { identifier } = removeImport('object.assign', root, j); + + root + .find(j.CallExpression, { + callee: { + name: identifier, + }, + }) + .replaceWith(({ node }) => { + return j.callExpression( + j.memberExpression(j.identifier('Object'), j.identifier('assign')), + node.arguments, + ); + }); + + return root.toSource(options); + }, + }; +} diff --git a/codemods/shared.js b/codemods/shared.js index ec865f1..55c0290 100644 --- a/codemods/shared.js +++ b/codemods/shared.js @@ -21,8 +21,8 @@ export function removeImport(name, root, j) { }, }); - const requireDeclaration = root.find(j.VariableDeclarator, { - init: { + const requireDeclaration = root + .find(j.CallExpression, { callee: { name: 'require', }, @@ -31,8 +31,8 @@ export function removeImport(name, root, j) { value: name, }, ], - }, - }); + }) + .closest(j.VariableDeclarator); // Require statements without declarations like `Object.is = require("object-is");` const requireAssignment = root.find(j.AssignmentExpression, { diff --git a/index.js b/index.js index d2ad16d..5adf40c 100644 --- a/index.js +++ b/index.js @@ -109,6 +109,7 @@ import numberPrototypeToexponential from './codemods/number.prototype.toexponent import objectAssign from './codemods/object-assign/index.js'; import objectIs from './codemods/object-is/index.js'; import objectKeys from './codemods/object-keys/index.js'; +import objectAssign2 from './codemods/object.assign/index.js'; import objectDefineproperties from './codemods/object.defineproperties/index.js'; import objectEntries from './codemods/object.entries/index.js'; import objectFromentries from './codemods/object.fromentries/index.js'; @@ -273,6 +274,7 @@ export const codemods = { "object-assign": objectAssign, "object-is": objectIs, "object-keys": objectKeys, + "object.assign": objectAssign2, "object.defineproperties": objectDefineproperties, "object.entries": objectEntries, "object.fromentries": objectFromentries, diff --git a/test/fixtures/object.assign/get-polyfill/after.js b/test/fixtures/object.assign/get-polyfill/after.js new file mode 100644 index 0000000..80b5244 --- /dev/null +++ b/test/fixtures/object.assign/get-polyfill/after.js @@ -0,0 +1,8 @@ +Object.assign({}, {foo: 303}, {bar: 808}); + +Object.assign({}, {}); + +const foo = {}; +const bar = {}; + +Object.assign(foo, bar); diff --git a/test/fixtures/object.assign/get-polyfill/before.js b/test/fixtures/object.assign/get-polyfill/before.js new file mode 100644 index 0000000..403196c --- /dev/null +++ b/test/fixtures/object.assign/get-polyfill/before.js @@ -0,0 +1,10 @@ +const assign = require('object.assign').getPolyfill(); + +assign({}, {foo: 303}, {bar: 808}); + +assign({}, {}); + +const foo = {}; +const bar = {}; + +assign(foo, bar); diff --git a/test/fixtures/object.assign/get-polyfill/result.js b/test/fixtures/object.assign/get-polyfill/result.js new file mode 100644 index 0000000..80b5244 --- /dev/null +++ b/test/fixtures/object.assign/get-polyfill/result.js @@ -0,0 +1,8 @@ +Object.assign({}, {foo: 303}, {bar: 808}); + +Object.assign({}, {}); + +const foo = {}; +const bar = {}; + +Object.assign(foo, bar); diff --git a/test/fixtures/object.assign/shim/after.js b/test/fixtures/object.assign/shim/after.js new file mode 100644 index 0000000..80b5244 --- /dev/null +++ b/test/fixtures/object.assign/shim/after.js @@ -0,0 +1,8 @@ +Object.assign({}, {foo: 303}, {bar: 808}); + +Object.assign({}, {}); + +const foo = {}; +const bar = {}; + +Object.assign(foo, bar); diff --git a/test/fixtures/object.assign/shim/before.js b/test/fixtures/object.assign/shim/before.js new file mode 100644 index 0000000..0f38393 --- /dev/null +++ b/test/fixtures/object.assign/shim/before.js @@ -0,0 +1,10 @@ +const assign = require('object.assign').shim(); + +assign({}, {foo: 303}, {bar: 808}); + +assign({}, {}); + +const foo = {}; +const bar = {}; + +assign(foo, bar); diff --git a/test/fixtures/object.assign/shim/result.js b/test/fixtures/object.assign/shim/result.js new file mode 100644 index 0000000..80b5244 --- /dev/null +++ b/test/fixtures/object.assign/shim/result.js @@ -0,0 +1,8 @@ +Object.assign({}, {foo: 303}, {bar: 808}); + +Object.assign({}, {}); + +const foo = {}; +const bar = {}; + +Object.assign(foo, bar); diff --git a/test/fixtures/object.assign/simple-cjs/after.js b/test/fixtures/object.assign/simple-cjs/after.js new file mode 100644 index 0000000..80b5244 --- /dev/null +++ b/test/fixtures/object.assign/simple-cjs/after.js @@ -0,0 +1,8 @@ +Object.assign({}, {foo: 303}, {bar: 808}); + +Object.assign({}, {}); + +const foo = {}; +const bar = {}; + +Object.assign(foo, bar); diff --git a/test/fixtures/object.assign/simple-cjs/before.js b/test/fixtures/object.assign/simple-cjs/before.js new file mode 100644 index 0000000..ba9f1b9 --- /dev/null +++ b/test/fixtures/object.assign/simple-cjs/before.js @@ -0,0 +1,10 @@ +const assign = require('object.assign'); + +assign({}, {foo: 303}, {bar: 808}); + +assign({}, {}); + +const foo = {}; +const bar = {}; + +assign(foo, bar); diff --git a/test/fixtures/object.assign/simple-cjs/result.js b/test/fixtures/object.assign/simple-cjs/result.js new file mode 100644 index 0000000..80b5244 --- /dev/null +++ b/test/fixtures/object.assign/simple-cjs/result.js @@ -0,0 +1,8 @@ +Object.assign({}, {foo: 303}, {bar: 808}); + +Object.assign({}, {}); + +const foo = {}; +const bar = {}; + +Object.assign(foo, bar); diff --git a/test/fixtures/object.assign/simple/after.js b/test/fixtures/object.assign/simple/after.js new file mode 100644 index 0000000..80b5244 --- /dev/null +++ b/test/fixtures/object.assign/simple/after.js @@ -0,0 +1,8 @@ +Object.assign({}, {foo: 303}, {bar: 808}); + +Object.assign({}, {}); + +const foo = {}; +const bar = {}; + +Object.assign(foo, bar); diff --git a/test/fixtures/object.assign/simple/before.js b/test/fixtures/object.assign/simple/before.js new file mode 100644 index 0000000..2245e0e --- /dev/null +++ b/test/fixtures/object.assign/simple/before.js @@ -0,0 +1,10 @@ +import assign from 'object.assign'; + +assign({}, {foo: 303}, {bar: 808}); + +assign({}, {}); + +const foo = {}; +const bar = {}; + +assign(foo, bar); diff --git a/test/fixtures/object.assign/simple/result.js b/test/fixtures/object.assign/simple/result.js new file mode 100644 index 0000000..80b5244 --- /dev/null +++ b/test/fixtures/object.assign/simple/result.js @@ -0,0 +1,8 @@ +Object.assign({}, {foo: 303}, {bar: 808}); + +Object.assign({}, {}); + +const foo = {}; +const bar = {}; + +Object.assign(foo, bar); diff --git a/types/codemods/object.assign/index.d.ts b/types/codemods/object.assign/index.d.ts new file mode 100644 index 0000000..9dcfef7 --- /dev/null +++ b/types/codemods/object.assign/index.d.ts @@ -0,0 +1,11 @@ +/** + * @typedef {import('../../types.js').Codemod} Codemod + * @typedef {import('../../types.js').CodemodOptions} CodemodOptions + */ +/** + * @param {CodemodOptions} [options] + * @returns {Codemod} + */ +export default function _default(options?: import("../../types.js").CodemodOptions | undefined): Codemod; +export type Codemod = import("../../types.js").Codemod; +export type CodemodOptions = import("../../types.js").CodemodOptions;