WIP - add extractor, generate snippet_data
This commit is contained in:
5
node_modules/babel-plugin-macros/dist/__tests__/__snapshots__/create-macros.js.snap
generated
vendored
Normal file
5
node_modules/babel-plugin-macros/dist/__tests__/__snapshots__/create-macros.js.snap
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`attempting to create a macros with the configName of options throws an error 1`] = `"You cannot use the configName \\"options\\". It is reserved for babel-plugin-macros."`;
|
||||
|
||||
exports[`throws error if it is not transpiled 1`] = `"The macro you imported from \\"untranspiled.macro\\" is being executed outside the context of compilation with babel-plugin-macros. This indicates that you don't have the babel plugin \\"babel-plugin-macros\\" configured correctly. Please see the documentation for how to configure babel-plugin-macros properly: https://github.com/kentcdodds/babel-plugin-macros/blob/master/other/docs/user.md"`;
|
||||
381
node_modules/babel-plugin-macros/dist/__tests__/__snapshots__/index.js.snap
generated
vendored
Normal file
381
node_modules/babel-plugin-macros/dist/__tests__/__snapshots__/index.js.snap
generated
vendored
Normal file
@ -0,0 +1,381 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`macros Macros are applied in the order respecting plugins order: Macros are applied in the order respecting plugins order 1`] = `
|
||||
|
||||
import Wrap from "./fixtures/jsx-id-prefix.macro";
|
||||
|
||||
const bar = Wrap(<div id="d1"><p id="p1"></p></div>);
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
const bar = Wrap(<div id="plugin-macro-d1"><p id="plugin-macro-p1"></p></div>);
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros Supports named imports: Supports named imports 1`] = `
|
||||
|
||||
import {css as CSS, styled as STYLED} from './fixtures/emotion.macro'
|
||||
const red = CSS\`
|
||||
background-color: red;
|
||||
\`
|
||||
|
||||
const Div = STYLED.div\`
|
||||
composes: \${red}
|
||||
color: blue;
|
||||
\`
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
const red = "background-color: red;";
|
||||
const Div = STYLED.div\`undefined\`;
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros Works as a JSXElement: Works as a JSXElement 1`] = `
|
||||
|
||||
import MyEval from './fixtures/eval.macro'
|
||||
const x = <MyEval>34 + 45</MyEval>
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
const x = 79;
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros appends the npm URL for errors thrown by node modules with a slash: appends the npm URL for errors thrown by node modules with a slash 1`] = `
|
||||
|
||||
import errorThrower from 'babel-plugin-macros-test-error-thrower/macro'
|
||||
errorThrower('hi')
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
Error: not helpful Learn more: https://www.npmjs.com/package/babel-plugin-macros-test-error-thrower
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros appends the npm URL for errors thrown by node modules: appends the npm URL for errors thrown by node modules 1`] = `
|
||||
|
||||
import errorThrower from 'babel-plugin-macros-test-error-thrower.macro'
|
||||
errorThrower('hi')
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
Error: not helpful Learn more: https://www.npmjs.com/package/babel-plugin-macros-test-error-thrower.macro
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros does nothing but remove macros if it is unused: does nothing but remove macros if it is unused 1`] = `
|
||||
|
||||
import foo from "./fixtures/eval.macro";
|
||||
|
||||
const bar = 42;
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
const bar = 42;
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros forwards MacroErrors thrown by the macro: forwards MacroErrors thrown by the macro 1`] = `
|
||||
|
||||
import errorThrower from './fixtures/macro-error-thrower.macro'
|
||||
errorThrower('hey')
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
MacroError: very helpful
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros macros can set their configName and get their config: macros can set their configName and get their config 1`] = `
|
||||
|
||||
import configured from './configurable.macro'
|
||||
|
||||
// eslint-disable-next-line babel/no-unused-expressions
|
||||
configured\`stuff\`
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
// eslint-disable-next-line babel/no-unused-expressions
|
||||
configured\`stuff\`;
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros optionally keep imports (import declaration): optionally keep imports (import declaration) 1`] = `
|
||||
|
||||
import macro from './fixtures/keep-imports.macro'
|
||||
const red = macro('noop');
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
import macro from './fixtures/keep-imports.macro';
|
||||
const red = macro('noop');
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros optionally keep imports (variable assignment): optionally keep imports (variable assignment) 1`] = `
|
||||
|
||||
const macro = require('./fixtures/keep-imports.macro')
|
||||
const red = macro('noop');
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
const macro = require('./fixtures/keep-imports.macro');
|
||||
|
||||
const red = macro('noop');
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros optionally keep imports in combination with babel-preset-env (#80): optionally keep imports in combination with babel-preset-env (#80) 1`] = `
|
||||
|
||||
import macro from './fixtures/keep-imports.macro'
|
||||
const red = macro('noop')
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
import macro from './fixtures/keep-imports.macro';
|
||||
const red = macro('noop');
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros prepends the relative path for errors thrown by the macro: prepends the relative path for errors thrown by the macro 1`] = `
|
||||
|
||||
import errorThrower from './fixtures/error-thrower.macro'
|
||||
errorThrower('hey')
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
Error: very unhelpful
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros raises an error if macro does not exist: raises an error if macro does not exist 1`] = `
|
||||
|
||||
import foo from './some-macros-that-doesnt-even-need-to-exist.macro'
|
||||
export default 'something else'
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
Error: Cannot find module './some-macros-that-doesnt-even-need-to-exist.macro' from '<PROJECT_ROOT>/src/__tests__'
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros supports compiled macros (\`__esModule\` + \`export default\`): supports compiled macros (\`__esModule\` + \`export default\`) 1`] = `
|
||||
|
||||
import {css, styled} from './fixtures/emotion-esm.macro'
|
||||
const red = css\`
|
||||
background-color: red;
|
||||
\`
|
||||
|
||||
const Div = styled.div\`
|
||||
composes: \${red}
|
||||
color: blue;
|
||||
\`
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
const red = css\`
|
||||
background-color: red;
|
||||
\`;
|
||||
const Div = styled.div\`
|
||||
composes: \${red}
|
||||
color: blue;
|
||||
\`;
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros supports macros from node_modules: supports macros from node_modules 1`] = `
|
||||
|
||||
import fakeMacro from 'babel-plugin-macros-test-fake/macro'
|
||||
fakeMacro('hi')
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
fakeMacro('hi');
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros throws an error if the macro is not properly wrapped: throws an error if the macro is not properly wrapped 1`] = `
|
||||
|
||||
import unwrapped from './fixtures/non-wrapped.macro'
|
||||
unwrapped('hey')
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
Error: https://github.com/kentcdodds/babel-plugin-macros/blob/master/other/docs/author.md#writing-a-macro
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros when a plugin that replaces paths is used, macros still work properly: when a plugin that replaces paths is used, macros still work properly 1`] = `
|
||||
|
||||
import myEval from '../eval.macro'
|
||||
|
||||
const result = myEval\`+('4' + '2')\`
|
||||
|
||||
global.result = result
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
const result = ("foobar", 42);
|
||||
global.result = result;
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros when configuration is specified in plugin options: when configuration is specified in plugin options 1`] = `
|
||||
|
||||
import configured from './configurable.macro'
|
||||
|
||||
// eslint-disable-next-line babel/no-unused-expressions
|
||||
configured\`stuff\`
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
// eslint-disable-next-line babel/no-unused-expressions
|
||||
configured\`stuff\`;
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros when configuration is specified in plugin options: when configuration is specified in plugin options 2`] = `
|
||||
|
||||
const configured = require('./configurable.macro')
|
||||
|
||||
// eslint-disable-next-line babel/no-unused-expressions
|
||||
configured\`stuff\`
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
// eslint-disable-next-line babel/no-unused-expressions
|
||||
configured\`stuff\`;
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros when configuration is specified incorrectly in plugin options: when configuration is specified incorrectly in plugin options 1`] = `
|
||||
|
||||
import configured from './configurable.macro'
|
||||
|
||||
// eslint-disable-next-line babel/no-unused-expressions
|
||||
configured\`stuff\`
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
// eslint-disable-next-line babel/no-unused-expressions
|
||||
configured\`stuff\`;
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros when plugin options configuration cannot be merged with file configuration: when plugin options configuration cannot be merged with file configuration 1`] = `
|
||||
|
||||
import configured from './configurable.macro'
|
||||
|
||||
// eslint-disable-next-line babel/no-unused-expressions
|
||||
configured\`stuff\`
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
Error: <PROJECT_ROOT>/src/__tests__/fixtures/primitive-config/babel-plugin-macros.config.js specified a configurableMacro config of type object, but the the macros plugin's options.configurableMacro did contain an object. Both configs must contain objects for their options to be mergeable.
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros when there is an error reading the config, a helpful message is logged 1`] = `
|
||||
Array [
|
||||
There was an error trying to load the config "configurableMacro" for the macro imported from "./configurable.macro. Please see the error thrown for more information.,
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`macros when there is an error reading the config, a helpful message is logged: when there is an error reading the config, a helpful message is logged 1`] = `
|
||||
|
||||
import configured from './configurable.macro'
|
||||
|
||||
// eslint-disable-next-line babel/no-unused-expressions
|
||||
configured\`stuff\`
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
Error: this is a cosmiconfig error
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros when there is no config to load, then no config is passed: when there is no config to load, then no config is passed 1`] = `
|
||||
|
||||
import configured from './configurable.macro'
|
||||
|
||||
// eslint-disable-next-line babel/no-unused-expressions
|
||||
configured\`stuff\`
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
// eslint-disable-next-line babel/no-unused-expressions
|
||||
configured\`stuff\`;
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros works with function calls: works with function calls 1`] = `
|
||||
|
||||
import myEval from './fixtures/eval.macro'
|
||||
const x = myEval('34 + 45')
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
const x = 79;
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros works with import: works with import 1`] = `
|
||||
|
||||
import myEval from './fixtures/eval.macro'
|
||||
const x = myEval\`34 + 45\`
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
const x = 79;
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros works with require destructuring and aliasing: works with require destructuring and aliasing 1`] = `
|
||||
|
||||
const {css: CSS, styled: STYLED} = require('./fixtures/emotion.macro')
|
||||
const red = CSS\`
|
||||
background-color: red;
|
||||
\`
|
||||
|
||||
const Div = STYLED.div\`
|
||||
composes: \${red}
|
||||
color: blue;
|
||||
\`
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
const red = "background-color: red;";
|
||||
const Div = STYLED.div\`undefined\`;
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros works with require destructuring: works with require destructuring 1`] = `
|
||||
|
||||
const {css, styled} = require('./fixtures/emotion.macro')
|
||||
const red = css\`
|
||||
background-color: red;
|
||||
\`
|
||||
|
||||
const Div = styled.div\`
|
||||
composes: \${red}
|
||||
color: blue;
|
||||
\`
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
const red = "background-color: red;";
|
||||
const Div = styled.div\`undefined\`;
|
||||
|
||||
`;
|
||||
|
||||
exports[`macros works with require: works with require 1`] = `
|
||||
|
||||
const evaler = require('./fixtures/eval.macro')
|
||||
const x = evaler\`34 + 45\`
|
||||
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
|
||||
const x = 79;
|
||||
|
||||
`;
|
||||
14
node_modules/babel-plugin-macros/dist/__tests__/create-macros.js
generated
vendored
Normal file
14
node_modules/babel-plugin-macros/dist/__tests__/create-macros.js
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
const {createMacro} = require('../')
|
||||
|
||||
test('throws error if it is not transpiled', () => {
|
||||
const untranspiledMacro = createMacro(() => {})
|
||||
expect(() =>
|
||||
untranspiledMacro({source: 'untranspiled.macro'}),
|
||||
).toThrowErrorMatchingSnapshot()
|
||||
})
|
||||
|
||||
test('attempting to create a macros with the configName of options throws an error', () => {
|
||||
expect(() =>
|
||||
createMacro(() => {}, {configName: 'options'}),
|
||||
).toThrowErrorMatchingSnapshot()
|
||||
})
|
||||
6
node_modules/babel-plugin-macros/dist/__tests__/fixtures/config/babel-plugin-macros.config.js
generated
vendored
Normal file
6
node_modules/babel-plugin-macros/dist/__tests__/fixtures/config/babel-plugin-macros.config.js
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
configurableMacro: {
|
||||
fileConfig: true,
|
||||
someConfig: true,
|
||||
},
|
||||
}
|
||||
4
node_modules/babel-plugin-macros/dist/__tests__/fixtures/config/cjs-code.js
generated
vendored
Normal file
4
node_modules/babel-plugin-macros/dist/__tests__/fixtures/config/cjs-code.js
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
const configured = require('./configurable.macro')
|
||||
|
||||
// eslint-disable-next-line babel/no-unused-expressions
|
||||
configured`stuff`
|
||||
4
node_modules/babel-plugin-macros/dist/__tests__/fixtures/config/code.js
generated
vendored
Normal file
4
node_modules/babel-plugin-macros/dist/__tests__/fixtures/config/code.js
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
import configured from './configurable.macro'
|
||||
|
||||
// eslint-disable-next-line babel/no-unused-expressions
|
||||
configured`stuff`
|
||||
10
node_modules/babel-plugin-macros/dist/__tests__/fixtures/config/configurable.macro.js
generated
vendored
Normal file
10
node_modules/babel-plugin-macros/dist/__tests__/fixtures/config/configurable.macro.js
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
const {createMacro} = require('../../../../')
|
||||
|
||||
const configName = 'configurableMacro'
|
||||
const realMacro = jest.fn()
|
||||
module.exports = createMacro(realMacro, {configName})
|
||||
// for testing purposes only
|
||||
Object.assign(module.exports, {
|
||||
realMacro,
|
||||
configName,
|
||||
})
|
||||
8
node_modules/babel-plugin-macros/dist/__tests__/fixtures/emotion-esm.macro.js
generated
vendored
Normal file
8
node_modules/babel-plugin-macros/dist/__tests__/fixtures/emotion-esm.macro.js
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
const {createMacro} = require('../../')
|
||||
|
||||
export default createMacro(evalMacro)
|
||||
|
||||
function evalMacro() {
|
||||
// we're lazy right now
|
||||
// we don't want to eval
|
||||
}
|
||||
29
node_modules/babel-plugin-macros/dist/__tests__/fixtures/emotion.macro.js
generated
vendored
Normal file
29
node_modules/babel-plugin-macros/dist/__tests__/fixtures/emotion.macro.js
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// this is a fake version of emotion
|
||||
// const printAST = require('ast-pretty-print')
|
||||
const {createMacro} = require('../../')
|
||||
|
||||
module.exports = createMacro(emotionMacro)
|
||||
|
||||
function emotionMacro({references, babel}) {
|
||||
const {types: t} = babel
|
||||
references.css.forEach(cssRef => {
|
||||
if (cssRef.parentPath.type === 'TaggedTemplateExpression') {
|
||||
cssRef.parentPath.replaceWith(
|
||||
t.stringLiteral(
|
||||
cssRef.parentPath
|
||||
.get('quasi')
|
||||
.evaluate()
|
||||
.value.trim(),
|
||||
),
|
||||
)
|
||||
}
|
||||
})
|
||||
references.styled.forEach(styledRef => {
|
||||
if (styledRef.parentPath.parentPath.type === 'TaggedTemplateExpression') {
|
||||
const quasi = styledRef.parentPath.parentPath.get('quasi')
|
||||
const val = quasi.evaluate().value.trim()
|
||||
const replacement = t.templateLiteral([t.templateElement(val)], [])
|
||||
quasi.replaceWith(replacement)
|
||||
}
|
||||
})
|
||||
}
|
||||
8
node_modules/babel-plugin-macros/dist/__tests__/fixtures/error-thrower.macro.js
generated
vendored
Normal file
8
node_modules/babel-plugin-macros/dist/__tests__/fixtures/error-thrower.macro.js
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
// const printAST = require('ast-pretty-print')
|
||||
const {createMacro} = require('../../')
|
||||
|
||||
module.exports = createMacro(evalMacro)
|
||||
|
||||
function evalMacro() {
|
||||
throw new Error('very unhelpful')
|
||||
}
|
||||
54
node_modules/babel-plugin-macros/dist/__tests__/fixtures/eval.macro.js
generated
vendored
Normal file
54
node_modules/babel-plugin-macros/dist/__tests__/fixtures/eval.macro.js
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
const {parse} = require('@babel/parser')
|
||||
// const printAST = require('ast-pretty-print')
|
||||
const {createMacro} = require('../../')
|
||||
|
||||
module.exports = createMacro(evalMacro)
|
||||
|
||||
function evalMacro({references, state}) {
|
||||
references.default.forEach(referencePath => {
|
||||
if (referencePath.parentPath.type === 'TaggedTemplateExpression') {
|
||||
asTag(referencePath.parentPath.get('quasi'), state)
|
||||
} else if (referencePath.parentPath.type === 'CallExpression') {
|
||||
asFunction(referencePath.parentPath.get('arguments'), state)
|
||||
} else if (referencePath.parentPath.type === 'JSXOpeningElement') {
|
||||
asJSX(
|
||||
{
|
||||
attributes: referencePath.parentPath.get('attributes'),
|
||||
children: referencePath.parentPath.parentPath.get('children'),
|
||||
},
|
||||
state,
|
||||
)
|
||||
} else {
|
||||
// TODO: throw a helpful error message
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function asTag(quasiPath) {
|
||||
const value = quasiPath.parentPath.get('quasi').evaluate().value
|
||||
quasiPath.parentPath.replaceWith(evalToAST(value))
|
||||
}
|
||||
|
||||
function asFunction(argumentsPaths) {
|
||||
const value = argumentsPaths[0].evaluate().value
|
||||
argumentsPaths[0].parentPath.replaceWith(evalToAST(value))
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
function asJSX({attributes, children}) {
|
||||
// It's a shame you cannot use evaluate() with JSX
|
||||
const value = children[0].node.value
|
||||
children[0].parentPath.replaceWith(evalToAST(value))
|
||||
}
|
||||
|
||||
function evalToAST(value) {
|
||||
let x
|
||||
// eslint-disable-next-line
|
||||
eval(`x = ${value}`)
|
||||
return thingToAST(x)
|
||||
}
|
||||
|
||||
function thingToAST(object) {
|
||||
const fileNode = parse(`var x = ${JSON.stringify(object)}`)
|
||||
return fileNode.program.body[0].declarations[0].init
|
||||
}
|
||||
20
node_modules/babel-plugin-macros/dist/__tests__/fixtures/jsx-id-prefix.macro.js
generated
vendored
Normal file
20
node_modules/babel-plugin-macros/dist/__tests__/fixtures/jsx-id-prefix.macro.js
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
// adds "prefix-" to each `id` attribute
|
||||
const {createMacro} = require('../../')
|
||||
|
||||
module.exports = createMacro(wrapWidget)
|
||||
|
||||
function wrapWidget({references, babel}) {
|
||||
const {types: t} = babel
|
||||
references.default.forEach(wrap => {
|
||||
wrap.parentPath.traverse({
|
||||
JSXAttribute(path) {
|
||||
const name = path.get('name')
|
||||
if (t.isJSXIdentifier(name) && name.node.name === 'id') {
|
||||
const value = path.get('value')
|
||||
if (t.isStringLiteral(value))
|
||||
value.replaceWith(t.stringLiteral(`macro-${value.node.value}`))
|
||||
}
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
23
node_modules/babel-plugin-macros/dist/__tests__/fixtures/jsx-id-prefix.plugin.js
generated
vendored
Normal file
23
node_modules/babel-plugin-macros/dist/__tests__/fixtures/jsx-id-prefix.plugin.js
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
// babel-plugin adding `plugin-` prefix to each "id" JSX attribute
|
||||
module.exports = main
|
||||
|
||||
function main({types: t}) {
|
||||
return {
|
||||
visitor: {
|
||||
// intentionally traversing from Program,
|
||||
// if it matches JSXAttribute here the issue won't be reproduced
|
||||
Program(progPath) {
|
||||
progPath.traverse({
|
||||
JSXAttribute(path) {
|
||||
const name = path.get('name')
|
||||
if (t.isJSXIdentifier(name) && name.node.name === 'id') {
|
||||
const value = path.get('value')
|
||||
if (t.isStringLiteral(value))
|
||||
value.replaceWith(t.stringLiteral(`plugin-${value.node.value}`))
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
7
node_modules/babel-plugin-macros/dist/__tests__/fixtures/keep-imports.macro.js
generated
vendored
Normal file
7
node_modules/babel-plugin-macros/dist/__tests__/fixtures/keep-imports.macro.js
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
const {createMacro} = require('../../')
|
||||
|
||||
module.exports = createMacro(keepImportMacro)
|
||||
|
||||
function keepImportMacro() {
|
||||
return {keepImports: true}
|
||||
}
|
||||
8
node_modules/babel-plugin-macros/dist/__tests__/fixtures/macro-error-thrower.macro.js
generated
vendored
Normal file
8
node_modules/babel-plugin-macros/dist/__tests__/fixtures/macro-error-thrower.macro.js
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
// const printAST = require('ast-pretty-print')
|
||||
const {createMacro, MacroError} = require('../../')
|
||||
|
||||
module.exports = createMacro(evalMacro)
|
||||
|
||||
function evalMacro() {
|
||||
throw new MacroError('very helpful')
|
||||
}
|
||||
1
node_modules/babel-plugin-macros/dist/__tests__/fixtures/non-wrapped.macro.js
generated
vendored
Normal file
1
node_modules/babel-plugin-macros/dist/__tests__/fixtures/non-wrapped.macro.js
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
module.exports = () => {}
|
||||
5
node_modules/babel-plugin-macros/dist/__tests__/fixtures/path-replace-issue/variable-assignment.js
generated
vendored
Normal file
5
node_modules/babel-plugin-macros/dist/__tests__/fixtures/path-replace-issue/variable-assignment.js
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
import myEval from '../eval.macro'
|
||||
|
||||
const result = myEval`+('4' + '2')`
|
||||
|
||||
global.result = result
|
||||
3
node_modules/babel-plugin-macros/dist/__tests__/fixtures/primitive-config/babel-plugin-macros.config.js
generated
vendored
Normal file
3
node_modules/babel-plugin-macros/dist/__tests__/fixtures/primitive-config/babel-plugin-macros.config.js
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
configurableMacro: 4,
|
||||
}
|
||||
4
node_modules/babel-plugin-macros/dist/__tests__/fixtures/primitive-config/code.js
generated
vendored
Normal file
4
node_modules/babel-plugin-macros/dist/__tests__/fixtures/primitive-config/code.js
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
import configured from './configurable.macro'
|
||||
|
||||
// eslint-disable-next-line babel/no-unused-expressions
|
||||
configured`stuff`
|
||||
10
node_modules/babel-plugin-macros/dist/__tests__/fixtures/primitive-config/configurable.macro.js
generated
vendored
Normal file
10
node_modules/babel-plugin-macros/dist/__tests__/fixtures/primitive-config/configurable.macro.js
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
const {createMacro} = require('../../../../')
|
||||
|
||||
const configName = 'configurableMacro'
|
||||
const realMacro = jest.fn()
|
||||
module.exports = createMacro(realMacro, {configName})
|
||||
// for testing purposes only
|
||||
Object.assign(module.exports, {
|
||||
realMacro,
|
||||
configName,
|
||||
})
|
||||
452
node_modules/babel-plugin-macros/dist/__tests__/index.js
generated
vendored
Normal file
452
node_modules/babel-plugin-macros/dist/__tests__/index.js
generated
vendored
Normal file
@ -0,0 +1,452 @@
|
||||
/* eslint no-console:0 */
|
||||
import path from 'path'
|
||||
import cosmiconfigMock from 'cosmiconfig'
|
||||
import cpy from 'cpy'
|
||||
import babel from '@babel/core'
|
||||
import pluginTester from 'babel-plugin-tester'
|
||||
import plugin from '../'
|
||||
|
||||
const projectRoot = path.join(__dirname, '../../')
|
||||
|
||||
jest.mock('cosmiconfig', () => {
|
||||
const mockSearchSync = jest.fn()
|
||||
Object.assign(mockSearchSync, {
|
||||
mockReset() {
|
||||
return mockSearchSync.mockImplementation(
|
||||
(filename, configuredCosmiconfig) =>
|
||||
configuredCosmiconfig.searchSync(filename),
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
mockSearchSync.mockReset()
|
||||
|
||||
const _cosmiconfigMock = (...args) => ({
|
||||
searchSync(filename) {
|
||||
return mockSearchSync(
|
||||
filename,
|
||||
require.requireActual('cosmiconfig')(...args),
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
return Object.assign(_cosmiconfigMock, {mockSearchSync})
|
||||
})
|
||||
|
||||
beforeAll(() => {
|
||||
// copy our mock modules to the node_modules directory
|
||||
// so we can test how things work when importing a macro
|
||||
// from the node_modules directory.
|
||||
return cpy(['**/*.js'], path.join('..', '..', 'node_modules'), {
|
||||
parents: true,
|
||||
cwd: path.join(projectRoot, 'other', 'mock-modules'),
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
// eslint-disable-next-line
|
||||
require('babel-plugin-macros-test-fake/macro').innerFn.mockClear()
|
||||
cosmiconfigMock.mockSearchSync.mockReset()
|
||||
})
|
||||
|
||||
expect.addSnapshotSerializer({
|
||||
print(val) {
|
||||
return (
|
||||
val
|
||||
.split(projectRoot)
|
||||
.join('<PROJECT_ROOT>/')
|
||||
.replace(/\\/g, '/')
|
||||
// Remove the path of file which thrown an error
|
||||
.replace(/Error:[^:]*:/, 'Error:')
|
||||
)
|
||||
},
|
||||
test(val) {
|
||||
return typeof val === 'string'
|
||||
},
|
||||
})
|
||||
|
||||
pluginTester({
|
||||
plugin,
|
||||
snapshot: true,
|
||||
babelOptions: {
|
||||
filename: __filename,
|
||||
parserOpts: {
|
||||
plugins: ['jsx'],
|
||||
},
|
||||
generatorOpts: {quotes: 'double'},
|
||||
},
|
||||
tests: [
|
||||
{
|
||||
title: 'does nothing to code that does not import macro',
|
||||
snapshot: false,
|
||||
code: `
|
||||
import foo from "./some-file-without-macro";
|
||||
|
||||
const bar = require("./some-other-file-without-macro");
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: 'does nothing but remove macros if it is unused',
|
||||
snapshot: true,
|
||||
code: `
|
||||
import foo from "./fixtures/eval.macro";
|
||||
|
||||
const bar = 42;
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: 'raises an error if macro does not exist',
|
||||
error: true,
|
||||
code: `
|
||||
import foo from './some-macros-that-doesnt-even-need-to-exist.macro'
|
||||
export default 'something else'
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: 'works with import',
|
||||
code: `
|
||||
import myEval from './fixtures/eval.macro'
|
||||
const x = myEval\`34 + 45\`
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: 'works with require',
|
||||
code: `
|
||||
const evaler = require('./fixtures/eval.macro')
|
||||
const x = evaler\`34 + 45\`
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: 'works with require destructuring',
|
||||
code: `
|
||||
const {css, styled} = require('./fixtures/emotion.macro')
|
||||
const red = css\`
|
||||
background-color: red;
|
||||
\`
|
||||
|
||||
const Div = styled.div\`
|
||||
composes: \${red}
|
||||
color: blue;
|
||||
\`
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: 'works with require destructuring and aliasing',
|
||||
code: `
|
||||
const {css: CSS, styled: STYLED} = require('./fixtures/emotion.macro')
|
||||
const red = CSS\`
|
||||
background-color: red;
|
||||
\`
|
||||
|
||||
const Div = STYLED.div\`
|
||||
composes: \${red}
|
||||
color: blue;
|
||||
\`
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: 'works with function calls',
|
||||
code: `
|
||||
import myEval from './fixtures/eval.macro'
|
||||
const x = myEval('34 + 45')
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: 'Works as a JSXElement',
|
||||
code: `
|
||||
import MyEval from './fixtures/eval.macro'
|
||||
const x = <MyEval>34 + 45</MyEval>
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: 'Supports named imports',
|
||||
code: `
|
||||
import {css as CSS, styled as STYLED} from './fixtures/emotion.macro'
|
||||
const red = CSS\`
|
||||
background-color: red;
|
||||
\`
|
||||
|
||||
const Div = STYLED.div\`
|
||||
composes: \${red}
|
||||
color: blue;
|
||||
\`
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: 'supports compiled macros (`__esModule` + `export default`)',
|
||||
code: `
|
||||
import {css, styled} from './fixtures/emotion-esm.macro'
|
||||
const red = css\`
|
||||
background-color: red;
|
||||
\`
|
||||
|
||||
const Div = styled.div\`
|
||||
composes: \${red}
|
||||
color: blue;
|
||||
\`
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: 'supports macros from node_modules',
|
||||
code: `
|
||||
import fakeMacro from 'babel-plugin-macros-test-fake/macro'
|
||||
fakeMacro('hi')
|
||||
`,
|
||||
teardown() {
|
||||
try {
|
||||
// kinda abusing the babel-plugin-tester API here
|
||||
// to make an extra assertion
|
||||
// eslint-disable-next-line
|
||||
const fakeMacro = require('babel-plugin-macros-test-fake/macro')
|
||||
expect(fakeMacro.innerFn).toHaveBeenCalledTimes(1)
|
||||
expect(fakeMacro.innerFn).toHaveBeenCalledWith({
|
||||
references: expect.any(Object),
|
||||
source: expect.stringContaining(
|
||||
'babel-plugin-macros-test-fake/macro',
|
||||
),
|
||||
state: expect.any(Object),
|
||||
babel: expect.any(Object),
|
||||
isBabelMacrosCall: true,
|
||||
})
|
||||
expect(fakeMacro.innerFn.mock.calls[0].babel).toBe(babel)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
throw e
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'optionally keep imports (variable assignment)',
|
||||
code: `
|
||||
const macro = require('./fixtures/keep-imports.macro')
|
||||
const red = macro('noop');
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: 'optionally keep imports (import declaration)',
|
||||
code: `
|
||||
import macro from './fixtures/keep-imports.macro'
|
||||
const red = macro('noop');
|
||||
`,
|
||||
},
|
||||
{
|
||||
title:
|
||||
'optionally keep imports in combination with babel-preset-env (#80)',
|
||||
code: `
|
||||
import macro from './fixtures/keep-imports.macro'
|
||||
const red = macro('noop')
|
||||
`,
|
||||
babelOptions: {
|
||||
plugins: [
|
||||
require.resolve('babel-plugin-transform-es2015-modules-commonjs'),
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'throws an error if the macro is not properly wrapped',
|
||||
error: true,
|
||||
code: `
|
||||
import unwrapped from './fixtures/non-wrapped.macro'
|
||||
unwrapped('hey')
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: 'forwards MacroErrors thrown by the macro',
|
||||
error: true,
|
||||
code: `
|
||||
import errorThrower from './fixtures/macro-error-thrower.macro'
|
||||
errorThrower('hey')
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: 'prepends the relative path for errors thrown by the macro',
|
||||
error: true,
|
||||
code: `
|
||||
import errorThrower from './fixtures/error-thrower.macro'
|
||||
errorThrower('hey')
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: 'appends the npm URL for errors thrown by node modules',
|
||||
error: true,
|
||||
code: `
|
||||
import errorThrower from 'babel-plugin-macros-test-error-thrower.macro'
|
||||
errorThrower('hi')
|
||||
`,
|
||||
},
|
||||
{
|
||||
title:
|
||||
'appends the npm URL for errors thrown by node modules with a slash',
|
||||
error: true,
|
||||
code: `
|
||||
import errorThrower from 'babel-plugin-macros-test-error-thrower/macro'
|
||||
errorThrower('hi')
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: 'macros can set their configName and get their config',
|
||||
fixture: path.join(__dirname, 'fixtures/config/code.js'),
|
||||
teardown() {
|
||||
try {
|
||||
const babelMacrosConfig = require('./fixtures/config/babel-plugin-macros.config')
|
||||
const configurableMacro = require('./fixtures/config/configurable.macro')
|
||||
expect(configurableMacro.realMacro).toHaveBeenCalledTimes(1)
|
||||
expect(configurableMacro.realMacro.mock.calls[0][0].config).toEqual(
|
||||
babelMacrosConfig[configurableMacro.configName],
|
||||
)
|
||||
|
||||
configurableMacro.realMacro.mockClear()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
throw e
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title:
|
||||
'when there is an error reading the config, a helpful message is logged',
|
||||
error: true,
|
||||
fixture: path.join(__dirname, 'fixtures/config/code.js'),
|
||||
setup() {
|
||||
cosmiconfigMock.mockSearchSync.mockImplementationOnce(() => {
|
||||
throw new Error('this is a cosmiconfig error')
|
||||
})
|
||||
const originalError = console.error
|
||||
console.error = jest.fn()
|
||||
return function teardown() {
|
||||
try {
|
||||
expect(console.error).toHaveBeenCalledTimes(1)
|
||||
expect(console.error.mock.calls[0]).toMatchSnapshot()
|
||||
console.error = originalError
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'when there is no config to load, then no config is passed',
|
||||
fixture: path.join(__dirname, 'fixtures/config/code.js'),
|
||||
setup() {
|
||||
cosmiconfigMock.mockSearchSync.mockImplementationOnce(() => null)
|
||||
return function teardown() {
|
||||
try {
|
||||
const configurableMacro = require('./fixtures/config/configurable.macro')
|
||||
expect(configurableMacro.realMacro).toHaveBeenCalledTimes(1)
|
||||
expect(configurableMacro.realMacro.mock.calls[0][0].config).toEqual(
|
||||
{},
|
||||
)
|
||||
configurableMacro.realMacro.mockClear()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'when configuration is specified in plugin options',
|
||||
pluginOptions: {
|
||||
configurableMacro: {
|
||||
someConfig: false,
|
||||
somePluginConfig: true,
|
||||
},
|
||||
},
|
||||
fixture: path.join(__dirname, 'fixtures/config/code.js'),
|
||||
teardown() {
|
||||
try {
|
||||
const configurableMacro = require('./fixtures/config/configurable.macro')
|
||||
expect(configurableMacro.realMacro).toHaveBeenCalledTimes(1)
|
||||
expect(configurableMacro.realMacro.mock.calls[0][0].config).toEqual({
|
||||
fileConfig: true,
|
||||
someConfig: true,
|
||||
somePluginConfig: true,
|
||||
})
|
||||
configurableMacro.realMacro.mockClear()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
throw e
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'when configuration is specified in plugin options',
|
||||
pluginOptions: {
|
||||
configurableMacro: {
|
||||
someConfig: false,
|
||||
somePluginConfig: true,
|
||||
},
|
||||
},
|
||||
fixture: path.join(__dirname, 'fixtures/config/cjs-code.js'),
|
||||
teardown() {
|
||||
try {
|
||||
const configurableMacro = require('./fixtures/config/configurable.macro')
|
||||
expect(configurableMacro.realMacro).toHaveBeenCalledTimes(1)
|
||||
expect(configurableMacro.realMacro.mock.calls[0][0].config).toEqual({
|
||||
fileConfig: true,
|
||||
someConfig: true,
|
||||
somePluginConfig: true,
|
||||
})
|
||||
configurableMacro.realMacro.mockClear()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
throw e
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'when configuration is specified incorrectly in plugin options',
|
||||
fixture: path.join(__dirname, 'fixtures/config/code.js'),
|
||||
pluginOptions: {
|
||||
configurableMacro: 2,
|
||||
},
|
||||
teardown() {
|
||||
try {
|
||||
const configurableMacro = require('./fixtures/config/configurable.macro')
|
||||
expect(configurableMacro.realMacro).toHaveBeenCalledTimes(1)
|
||||
expect(configurableMacro.realMacro).not.toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
config: expect.any,
|
||||
}),
|
||||
)
|
||||
configurableMacro.realMacro.mockClear()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
throw e
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title:
|
||||
'when plugin options configuration cannot be merged with file configuration',
|
||||
error: true,
|
||||
fixture: path.join(__dirname, 'fixtures/primitive-config/code.js'),
|
||||
pluginOptions: {
|
||||
configurableMacro: {},
|
||||
},
|
||||
},
|
||||
{
|
||||
title:
|
||||
'when a plugin that replaces paths is used, macros still work properly',
|
||||
fixture: path.join(
|
||||
__dirname,
|
||||
'fixtures/path-replace-issue/variable-assignment.js',
|
||||
),
|
||||
babelOptions: {
|
||||
babelrc: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Macros are applied in the order respecting plugins order',
|
||||
code: `
|
||||
import Wrap from "./fixtures/jsx-id-prefix.macro";
|
||||
|
||||
const bar = Wrap(<div id="d1"><p id="p1"></p></div>);
|
||||
`,
|
||||
babelOptions: {
|
||||
presets: [{plugins: [require('./fixtures/jsx-id-prefix.plugin')]}],
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
350
node_modules/babel-plugin-macros/dist/index.js
generated
vendored
Normal file
350
node_modules/babel-plugin-macros/dist/index.js
generated
vendored
Normal file
@ -0,0 +1,350 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
|
||||
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
||||
|
||||
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
|
||||
|
||||
const p = require('path');
|
||||
|
||||
const resolve = require('resolve'); // const printAST = require('ast-pretty-print')
|
||||
|
||||
|
||||
const macrosRegex = /[./]macro(\.js)?$/; // https://stackoverflow.com/a/32749533/971592
|
||||
|
||||
class MacroError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = 'MacroError';
|
||||
/* istanbul ignore else */
|
||||
|
||||
if (typeof Error.captureStackTrace === 'function') {
|
||||
Error.captureStackTrace(this, this.constructor);
|
||||
} else if (!this.stack) {
|
||||
this.stack = new Error(message).stack;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let _configExplorer = null;
|
||||
|
||||
function getConfigExporer() {
|
||||
return _configExplorer = _configExplorer || // Lazy load cosmiconfig since it is a relatively large bundle
|
||||
require('cosmiconfig')('babel-plugin-macros', {
|
||||
searchPlaces: ['package.json', '.babel-plugin-macrosrc', '.babel-plugin-macrosrc.json', '.babel-plugin-macrosrc.yaml', '.babel-plugin-macrosrc.yml', '.babel-plugin-macrosrc.js', 'babel-plugin-macros.config.js'],
|
||||
packageProp: 'babelMacros',
|
||||
sync: true
|
||||
});
|
||||
}
|
||||
|
||||
function createMacro(macro, options = {}) {
|
||||
if (options.configName === 'options') {
|
||||
throw new Error(`You cannot use the configName "options". It is reserved for babel-plugin-macros.`);
|
||||
}
|
||||
|
||||
macroWrapper.isBabelMacro = true;
|
||||
macroWrapper.options = options;
|
||||
return macroWrapper;
|
||||
|
||||
function macroWrapper(args) {
|
||||
const {
|
||||
source,
|
||||
isBabelMacrosCall
|
||||
} = args;
|
||||
|
||||
if (!isBabelMacrosCall) {
|
||||
throw new MacroError(`The macro you imported from "${source}" is being executed outside the context of compilation with babel-plugin-macros. ` + `This indicates that you don't have the babel plugin "babel-plugin-macros" configured correctly. ` + `Please see the documentation for how to configure babel-plugin-macros properly: ` + 'https://github.com/kentcdodds/babel-plugin-macros/blob/master/other/docs/user.md');
|
||||
}
|
||||
|
||||
return macro(args);
|
||||
}
|
||||
}
|
||||
|
||||
function nodeResolvePath(source, basedir) {
|
||||
return resolve.sync(source, {
|
||||
basedir
|
||||
});
|
||||
}
|
||||
|
||||
function macrosPlugin(babel, _ref = {}) {
|
||||
let {
|
||||
require: _require = require,
|
||||
resolvePath = nodeResolvePath
|
||||
} = _ref,
|
||||
options = (0, _objectWithoutPropertiesLoose2.default)(_ref, ["require", "resolvePath"]);
|
||||
|
||||
function interopRequire(path) {
|
||||
// eslint-disable-next-line import/no-dynamic-require
|
||||
const o = _require(path);
|
||||
|
||||
return o && o.__esModule && o.default ? o.default : o;
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'macros',
|
||||
visitor: {
|
||||
Program(progPath, state) {
|
||||
progPath.traverse({
|
||||
ImportDeclaration(path) {
|
||||
const isMacros = looksLike(path, {
|
||||
node: {
|
||||
source: {
|
||||
value: v => macrosRegex.test(v)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!isMacros) {
|
||||
return;
|
||||
}
|
||||
|
||||
const imports = path.node.specifiers.map(s => ({
|
||||
localName: s.local.name,
|
||||
importedName: s.type === 'ImportDefaultSpecifier' ? 'default' : s.imported.name
|
||||
}));
|
||||
const source = path.node.source.value;
|
||||
const result = applyMacros({
|
||||
path,
|
||||
imports,
|
||||
source,
|
||||
state,
|
||||
babel,
|
||||
interopRequire,
|
||||
resolvePath,
|
||||
options
|
||||
});
|
||||
|
||||
if (!result || !result.keepImports) {
|
||||
path.remove();
|
||||
}
|
||||
},
|
||||
|
||||
VariableDeclaration(path) {
|
||||
const isMacros = child => looksLike(child, {
|
||||
node: {
|
||||
init: {
|
||||
callee: {
|
||||
type: 'Identifier',
|
||||
name: 'require'
|
||||
},
|
||||
arguments: args => args.length === 1 && macrosRegex.test(args[0].value)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
path.get('declarations').filter(isMacros).forEach(child => {
|
||||
const imports = child.node.id.name ? [{
|
||||
localName: child.node.id.name,
|
||||
importedName: 'default'
|
||||
}] : child.node.id.properties.map(property => ({
|
||||
localName: property.value.name,
|
||||
importedName: property.key.name
|
||||
}));
|
||||
const call = child.get('init');
|
||||
const source = call.node.arguments[0].value;
|
||||
const result = applyMacros({
|
||||
path: call,
|
||||
imports,
|
||||
source,
|
||||
state,
|
||||
babel,
|
||||
interopRequire,
|
||||
resolvePath,
|
||||
options
|
||||
});
|
||||
|
||||
if (!result || !result.keepImports) {
|
||||
child.remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
} // eslint-disable-next-line complexity
|
||||
|
||||
|
||||
function applyMacros({
|
||||
path,
|
||||
imports,
|
||||
source,
|
||||
state,
|
||||
babel,
|
||||
interopRequire,
|
||||
resolvePath,
|
||||
options
|
||||
}) {
|
||||
/* istanbul ignore next (pretty much only useful for astexplorer I think) */
|
||||
const {
|
||||
file: {
|
||||
opts: {
|
||||
filename = ''
|
||||
}
|
||||
}
|
||||
} = state;
|
||||
let hasReferences = false;
|
||||
const referencePathsByImportName = imports.reduce((byName, {
|
||||
importedName,
|
||||
localName
|
||||
}) => {
|
||||
const binding = path.scope.getBinding(localName);
|
||||
byName[importedName] = binding.referencePaths;
|
||||
hasReferences = hasReferences || Boolean(byName[importedName].length);
|
||||
return byName;
|
||||
}, {});
|
||||
const isRelative = source.indexOf('.') === 0;
|
||||
const requirePath = resolvePath(source, p.dirname(getFullFilename(filename)));
|
||||
const macro = interopRequire(requirePath);
|
||||
|
||||
if (!macro.isBabelMacro) {
|
||||
throw new Error(`The macro imported from "${source}" must be wrapped in "createMacro" ` + `which you can get from "babel-plugin-macros". ` + `Please refer to the documentation to see how to do this properly: https://github.com/kentcdodds/babel-plugin-macros/blob/master/other/docs/author.md#writing-a-macro`);
|
||||
}
|
||||
|
||||
const config = getConfig(macro, filename, source, options);
|
||||
let result;
|
||||
|
||||
try {
|
||||
/**
|
||||
* Other plugins that run before babel-plugin-macros might use path.replace, where a path is
|
||||
* put into its own replacement. Apparently babel does not update the scope after such
|
||||
* an operation. As a remedy, the whole scope is traversed again with an empty "Identifier"
|
||||
* visitor - this makes the problem go away.
|
||||
*
|
||||
* See: https://github.com/kentcdodds/import-all.macro/issues/7
|
||||
*/
|
||||
state.file.scope.path.traverse({
|
||||
Identifier() {}
|
||||
|
||||
});
|
||||
result = macro({
|
||||
references: referencePathsByImportName,
|
||||
source,
|
||||
state,
|
||||
babel,
|
||||
config,
|
||||
isBabelMacrosCall: true
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.name === 'MacroError') {
|
||||
throw error;
|
||||
}
|
||||
|
||||
error.message = `${source}: ${error.message}`;
|
||||
|
||||
if (!isRelative) {
|
||||
error.message = `${error.message} Learn more: https://www.npmjs.com/package/${source.replace( // remove everything after package name
|
||||
// @org/package/macro -> @org/package
|
||||
// package/macro -> package
|
||||
/^((?:@[^/]+\/)?[^/]+).*/, '$1')}`;
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function getConfigFromFile(configName, filename) {
|
||||
try {
|
||||
const loaded = getConfigExporer().searchSync(filename);
|
||||
|
||||
if (loaded) {
|
||||
return {
|
||||
options: loaded.config[configName],
|
||||
path: loaded.filepath
|
||||
};
|
||||
}
|
||||
} catch (e) {
|
||||
return {
|
||||
error: e
|
||||
};
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
function getConfigFromOptions(configName, options) {
|
||||
if (options.hasOwnProperty(configName)) {
|
||||
if (options[configName] && typeof options[configName] !== 'object') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`The macro plugin options' ${configName} property was not an object or null.`);
|
||||
} else {
|
||||
return {
|
||||
options: options[configName]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
function getConfig(macro, filename, source, options) {
|
||||
const {
|
||||
configName
|
||||
} = macro.options;
|
||||
|
||||
if (configName) {
|
||||
const fileConfig = getConfigFromFile(configName, filename);
|
||||
const optionsConfig = getConfigFromOptions(configName, options);
|
||||
|
||||
if (optionsConfig.options === undefined && fileConfig.options === undefined) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`There was an error trying to load the config "${configName}" ` + `for the macro imported from "${source}. ` + `Please see the error thrown for more information.`);
|
||||
|
||||
if (fileConfig.error !== undefined) {
|
||||
throw fileConfig.error;
|
||||
}
|
||||
}
|
||||
|
||||
if (fileConfig.options !== undefined && optionsConfig.options !== undefined && typeof fileConfig.options !== 'object') {
|
||||
throw new Error(`${fileConfig.path} specified a ${configName} config of type ` + `${typeof optionsConfig.options}, but the the macros plugin's ` + `options.${configName} did contain an object. Both configs must ` + `contain objects for their options to be mergeable.`);
|
||||
}
|
||||
|
||||
return (0, _extends2.default)({}, optionsConfig.options, fileConfig.options);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
/*
|
||||
istanbul ignore next
|
||||
because this is hard to test
|
||||
and not worth it...
|
||||
*/
|
||||
|
||||
|
||||
function getFullFilename(filename) {
|
||||
if (p.isAbsolute(filename)) {
|
||||
return filename;
|
||||
}
|
||||
|
||||
return p.join(process.cwd(), filename);
|
||||
}
|
||||
|
||||
function looksLike(a, b) {
|
||||
return a && b && Object.keys(b).every(bKey => {
|
||||
const bVal = b[bKey];
|
||||
const aVal = a[bKey];
|
||||
|
||||
if (typeof bVal === 'function') {
|
||||
return bVal(aVal);
|
||||
}
|
||||
|
||||
return isPrimitive(bVal) ? bVal === aVal : looksLike(aVal, bVal);
|
||||
});
|
||||
}
|
||||
|
||||
function isPrimitive(val) {
|
||||
// eslint-disable-next-line
|
||||
return val == null || /^[sbn]/.test(typeof val);
|
||||
}
|
||||
|
||||
module.exports = macrosPlugin;
|
||||
Object.assign(module.exports, {
|
||||
createMacro,
|
||||
MacroError
|
||||
});
|
||||
Reference in New Issue
Block a user