1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.collapseNamedExports = collapseNamedExports; exports.extendDefaultExportWithNamedExports = extendDefaultExportWithNamedExports; exports.filterOutExportsWhichMatchPropsOnDefault = filterOutExportsWhichMatchPropsOnDefault; exports.findPropertiesOfDeclaration = findPropertiesOfDeclaration; exports.getPropNames = getPropNames; require('source-map-support/register'); var _babelTypes = require('babel-types'); var t = _interopRequireWildcard(_babelTypes); var _arrayFlatten = require('array-flatten'); var _arrayFlatten2 = _interopRequireDefault(_arrayFlatten); var _astHelpers = require('./ast-helpers'); var _templates = require('./templates'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _interopRequireWildcard(obj) { Eif (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function collapseNamedExports(programNode, defaultExportDeclaration, namedExports, opts) { namedExports = filterOutExportsWhichMatchPropsOnDefault(programNode, defaultExportDeclaration, namedExports); if (!namedExports.length) { return []; } else if (opts.noExportExtend) { return namedExports; } else { return extendDefaultExportWithNamedExports(programNode, defaultExportDeclaration, namedExports); } } function extendDefaultExportWithNamedExports(programNode, defaultExportDeclaration, namedExports) { namedExports = [...namedExports]; // Shallow clone for safe splicing if (!defaultExportDeclaration.name) { // Something anonymous //TODO see if we can give it a name return namedExports; } else if (namedExports.some(exp => exp.conflict)) { return namedExports.conflicts.filter(exp => exp.conflict); } const id = t.isIdentifier(defaultExportDeclaration) ? defaultExportDeclaration : t.identifier(defaultExportDeclaration.name); for (const namedExport of namedExports) { programNode.body.push((0, _templates.buildAssign)({ OBJECT: id, NAME: namedExport.EXPORTED, VALUE: namedExport.LOCAL })); } return []; } function filterOutExportsWhichMatchPropsOnDefault(programNode, defaultExportDeclaration, namedExports) { namedExports = [...namedExports]; // Shallow clone for safe splicing const defaultObjectInfo = findPropertiesOfDeclaration(programNode, defaultExportDeclaration); // console.log(require('util').inspect(defaultObjectInfo, { depth: null })); // Loop through the default object's props and see if it already has a matching definition of the named exports. // If the definition matches, we can ignore the named export. If the definition does not match, mark it as a conflict. if (defaultObjectInfo.properties) { for (const _ref of defaultObjectInfo.properties) { const { key, value } = _ref; if (t.isIdentifier(value)) { //let matchingNamedExportIndex = -1 const matchingNamedExportIndex = namedExports.findIndex(namedExport => namedExport.EXPORTED.name === key.name); const matchingNamedExport = namedExports[matchingNamedExportIndex]; if (matchingNamedExport) { if (value.name === matchingNamedExport.LOCAL.name) { // Safe to ignore namedExports.splice(matchingNamedExportIndex, 1); } else { namedExports.conflict = true; } } } } } return namedExports; } function findPropertiesOfDeclaration(programNode, declaration) { const { type } = declaration; if (type === 'FunctionDeclaration' || type === 'ArrowFunctionExpression') { return { type }; } else if (t.isObjectExpression(declaration)) { return { type, properties: declaration.properties }; } else if (type === 'ClassDeclaration') { return { type, properties: [...getStaticThingsOfClassDeclaration(declaration), ...getOtherPropertyOfIdentifier(programNode, declaration.id.name)] }; } else if (t.isIdentifier(declaration)) { return { type, properties: getOtherPropertyOfIdentifier(programNode, declaration.name) }; } else if ((0, _astHelpers.isObjectAssignOrExtendsExpression)(declaration)) { return { type, properties: getPropertiesOfObjectAssignOrExtendHelper(declaration, programNode) }; } // console.log(require('util').inspect(declaration, { depth: null })); return { type }; } function getStaticThingsOfClassDeclaration(classDeclaration) { return classDeclaration.body.body.filter(item => item.static); } /** * Traverse the top level of the program body looking for either: * - ObjectExpression assignments to the object variable. * - Property assignments directly to our object (but not to nested properties). * * @return Array<{key, value}> */ function getOtherPropertyOfIdentifier(programNode, idName) { return (0, _arrayFlatten2.default)(programNode.body.map(node => { if (node.type === 'ExpressionStatement') { // ID = value | ID.key = value | ID.key.nested = value const { left, right, type } = node.expression; if (type === 'AssignmentExpression') { if (left.type === 'Identifier' && left.name === idName) { // ID = value if (right.type === 'ObjectExpression') { // ID = {} return right.properties; // Array<ObjectProperty> } } else { const { object, property: key } = left; if (object.type === 'Identifier' && object.name === idName) { // ID.key = value return { key, value: right }; // ObjectProperty-like (key, value) } } } } else if (node.type === 'VariableDeclaration') { // console.log(require('util').inspect(node, { depth: 4 })); return node.declarations.filter(declaration => declaration.id.name === idName).map(declaration => declaration.init).filter(init => init).filter(init => t.isObjectExpression(init) || (0, _astHelpers.isObjectAssignOrExtendsExpression)(init)).map(init => t.isObjectExpression(init) ? init.properties : getPropertiesOfObjectAssignOrExtendHelper(init, programNode)); } }).filter(item => item)); } function getPropertiesOfObjectAssignOrExtendHelper(node, programNode) { // Object.assign(...). Check all the args and recursively try to get props of identifiers (although they may be imported) return (0, _arrayFlatten2.default)(node.arguments.map(arg => { if (t.isObjectExpression(arg)) { return arg.properties; } else if (t.isIdentifier(arg)) { // recurse. although props will be empty if arg is an imported object return getOtherPropertyOfIdentifier(programNode, arg.name); } })); } // function getPropsFromObjectAssign() function getPropNames(namedExports) { return namedExports.map(namedExport => namedExport.EXPORTED.name); } |