diff --git a/lib/transformations/__snapshots__/utils.test.js.snap b/lib/transformations/__snapshots__/utils.test.js.snap index 79ca0a1f268..7a30f2983a4 100644 --- a/lib/transformations/__snapshots__/utils.test.js.snap +++ b/lib/transformations/__snapshots__/utils.test.js.snap @@ -1,24 +1,8 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`utils createLiteral should create basic literal 1`] = ` -Object { - "comments": null, - "loc": null, - "regex": null, - "type": "Literal", - "value": "strintLiteral", -} -`; +exports[`utils createLiteral should create basic literal 1`] = `"\\"stringLiteral\\""`; -exports[`utils createLiteral should create boolean 1`] = ` -Object { - "comments": null, - "loc": null, - "regex": null, - "type": "Literal", - "value": true, -} -`; +exports[`utils createLiteral should create boolean 1`] = `"true"`; exports[`utils createOrUpdatePluginByName should add an object as an argument 1`] = ` "[new Plugin({ @@ -71,3 +55,5 @@ exports[`utils createProperty should create properties for non-literal keys 1`] 1: \\"bar\\" }" `; + +exports[`utils getRequire should create a require statement 1`] = `"const filesys = require(\\"fs\\");"`; diff --git a/lib/transformations/outputPath/__snapshots__/outputPath.test.js.snap b/lib/transformations/outputPath/__snapshots__/outputPath.test.js.snap new file mode 100644 index 00000000000..27e07047768 --- /dev/null +++ b/lib/transformations/outputPath/__snapshots__/outputPath.test.js.snap @@ -0,0 +1,30 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`outputPath transforms correctly using "outputPath-0" data 1`] = ` +"module.exports = { + output: { + path: path.join(__dirname, 'dist') + } +} +" +`; + +exports[`outputPath transforms correctly using "outputPath-1" data 1`] = ` +"const path = require('path'); +module.exports = { + output: { + path: path.join(__dirname, 'dist') + } +} +" +`; + +exports[`outputPath transforms correctly using "outputPath-2" data 1`] = ` +"const p = require('path'); +module.exports = { + output: { + path: p.join(__dirname, 'dist') + } +} +" +`; diff --git a/lib/transformations/outputPath/__testfixtures__/outputPath-0.input.js b/lib/transformations/outputPath/__testfixtures__/outputPath-0.input.js new file mode 100644 index 00000000000..085268fadbe --- /dev/null +++ b/lib/transformations/outputPath/__testfixtures__/outputPath-0.input.js @@ -0,0 +1,5 @@ +module.exports = { + output: { + path: 'dist' + } +} diff --git a/lib/transformations/outputPath/__testfixtures__/outputPath-1.input.js b/lib/transformations/outputPath/__testfixtures__/outputPath-1.input.js new file mode 100644 index 00000000000..c7a0ed58e7a --- /dev/null +++ b/lib/transformations/outputPath/__testfixtures__/outputPath-1.input.js @@ -0,0 +1,6 @@ +const path = require('path'); +module.exports = { + output: { + path: path.join(__dirname, 'dist') + } +} diff --git a/lib/transformations/outputPath/__testfixtures__/outputPath-2.input.js b/lib/transformations/outputPath/__testfixtures__/outputPath-2.input.js new file mode 100644 index 00000000000..de8436ae6c3 --- /dev/null +++ b/lib/transformations/outputPath/__testfixtures__/outputPath-2.input.js @@ -0,0 +1,6 @@ +const p = require('path'); +module.exports = { + output: { + path: 'dist' + } +} diff --git a/lib/transformations/outputPath/outputPath.js b/lib/transformations/outputPath/outputPath.js new file mode 100644 index 00000000000..78226dc345f --- /dev/null +++ b/lib/transformations/outputPath/outputPath.js @@ -0,0 +1,51 @@ +const utils = require('../utils'); + +module.exports = function(j, ast) { + const literalOutputPath = ast + .find(j.ObjectExpression) + .filter(p => utils.safeTraverse(p, ['parentPath', 'value', 'key', 'name']) === 'output') + .find(j.Property) + .filter(p => utils.safeTraverse(p, ['value', 'key', 'name']) === 'path' + && utils.safeTraverse(p, ['value', 'value', 'type']) === 'Literal'); + + if (literalOutputPath) { + let pathVarName = 'path'; + let isPathPresent = false; + const pathDecalaration = ast + .find(j.VariableDeclarator) + .filter(p => utils.safeTraverse(p, ['value', 'init', 'callee', 'name']) === 'require') + .filter(p => utils.safeTraverse(p, ['value', 'init', 'arguments']) + && p.value.init.arguments.reduce((isPresent, a) => { + return a.type === 'Literal' && a.value === 'path' || isPresent; + }, false)); + + if (pathDecalaration) { + isPathPresent = true; + pathDecalaration.forEach(p => { + pathVarName = utils.safeTraverse(p, ['value', 'id', 'name']); + }); + } + + literalOutputPath + .find(j.Literal) + .replaceWith(p => replaceWithPath(j, p, pathVarName)); + + if(!isPathPresent){ + const pathRequire = utils.getRequire(j, 'path', 'path'); + return ast.find(j.Program) + .replaceWith(p => j.program([].concat(pathRequire).concat(p.value.body))); + } + } + return ast; +}; + +function replaceWithPath(j, p, pathVarName) { + const convertedPath = j.callExpression( + j.memberExpression( + j.identifier(pathVarName), + j.identifier('join'), + false), + [j.identifier('__dirname'), p.value]); + return convertedPath; +} + diff --git a/lib/transformations/outputPath/outputPath.test.js b/lib/transformations/outputPath/outputPath.test.js new file mode 100644 index 00000000000..d1041b30274 --- /dev/null +++ b/lib/transformations/outputPath/outputPath.test.js @@ -0,0 +1,5 @@ +const defineTest = require('../defineTest'); + +defineTest(__dirname, 'outputPath', 'outputPath-0'); +defineTest(__dirname, 'outputPath', 'outputPath-1'); +defineTest(__dirname, 'outputPath', 'outputPath-2'); diff --git a/lib/transformations/utils.js b/lib/transformations/utils.js index 5bf580d1de8..428d0e315ee 100644 --- a/lib/transformations/utils.js +++ b/lib/transformations/utils.js @@ -224,6 +224,28 @@ function findObjWithOneOfKeys (p, keyNames) { }, false); } +/* +* @function getRequire +* +* Returns constructed require symbol +* @param j — jscodeshift API +* @param { string } constName - Name of require +* @param { string } packagePath - path of required package +* @returns {NodePath} - the created ast +*/ + +function getRequire(j, constName, packagePath) { + return j.variableDeclaration('const', [ + j.variableDeclarator( + j.identifier(constName), + j.callExpression( + j.identifier('require'), + [j.literal(packagePath)] + ) + ) + ]); +} + module.exports = { safeTraverse, createProperty, @@ -233,5 +255,6 @@ module.exports = { findVariableToPlugin, isType, createLiteral, - findObjWithOneOfKeys + findObjWithOneOfKeys, + getRequire }; diff --git a/lib/transformations/utils.test.js b/lib/transformations/utils.test.js index 24160eeaf1d..73a8c93a9fc 100644 --- a/lib/transformations/utils.test.js +++ b/lib/transformations/utils.test.js @@ -136,12 +136,12 @@ var a = { plugs: [] } describe('createLiteral', () => { it('should create basic literal', () => { - const literal = utils.createLiteral(j, 'strintLiteral'); - expect(literal).toMatchSnapshot(); + const literal = utils.createLiteral(j, 'stringLiteral'); + expect(j(literal).toSource()).toMatchSnapshot(); }); it('should create boolean', () => { const literal = utils.createLiteral(j, 'true'); - expect(literal).toMatchSnapshot(); + expect(j(literal).toSource()).toMatchSnapshot(); }); }); @@ -157,4 +157,11 @@ var a = { plugs: [] } .filter(p => utils.findObjWithOneOfKeys(p, ['a'])).size()).toEqual(1); }); }); + + describe('getRequire', () => { + it('should create a require statement', () => { + const require = utils.getRequire(j, 'filesys', 'fs'); + expect(j(require).toSource()).toMatchSnapshot(); + }); + }); });