amis-rpc-design/node_modules/@emotion/babel-plugin/dist/emotion-babel-plugin.esm.js
2023-10-07 19:42:30 +08:00

1387 lines
44 KiB
JavaScript

import _createForOfIteratorHelperLoose from '@babel/runtime/helpers/esm/createForOfIteratorHelperLoose';
import _extends from '@babel/runtime/helpers/esm/extends';
import _objectWithoutPropertiesLoose from '@babel/runtime/helpers/esm/objectWithoutPropertiesLoose';
import nodePath from 'path';
import { SourceMapGenerator } from 'source-map';
import convert from 'convert-source-map';
import findRoot from 'find-root';
import memoize from '@emotion/memoize';
import hashString from '@emotion/hash';
import escapeRegexp from 'escape-string-regexp';
import { serializeStyles } from '@emotion/serialize';
import { compile } from 'stylis';
import { addDefault, addNamed } from '@babel/helper-module-imports';
import { createMacro } from 'babel-plugin-macros';
var invalidClassNameCharacters = /[!"#$%&'()*+,./:;<=>?@[\]^`|}~{]/g;
var sanitizeLabelPart = function sanitizeLabelPart(labelPart) {
return labelPart.trim().replace(invalidClassNameCharacters, '-');
};
function getLabel(identifierName, labelFormat, filename) {
if (!identifierName) return null;
var sanitizedName = sanitizeLabelPart(identifierName);
if (!labelFormat) {
return sanitizedName;
}
if (typeof labelFormat === 'function') {
return labelFormat({
name: sanitizedName,
path: filename
});
}
var parsedPath = nodePath.parse(filename);
var localDirname = nodePath.basename(parsedPath.dir);
var localFilename = parsedPath.name;
if (localFilename === 'index') {
localFilename = localDirname;
}
return labelFormat.replace(/\[local\]/gi, sanitizedName).replace(/\[filename\]/gi, sanitizeLabelPart(localFilename)).replace(/\[dirname\]/gi, sanitizeLabelPart(localDirname));
}
function getLabelFromPath(path, state, t) {
return getLabel(getIdentifierName(path, t), state.opts.labelFormat, state.file.opts.filename);
}
var getObjPropertyLikeName = function getObjPropertyLikeName(path, t) {
if (!t.isObjectProperty(path) && !t.isObjectMethod(path) || path.node.computed) {
return null;
}
if (t.isIdentifier(path.node.key)) {
return path.node.key.name;
}
if (t.isStringLiteral(path.node.key)) {
return path.node.key.value.replace(/\s+/g, '-');
}
return null;
};
function getDeclaratorName(path, t) {
// $FlowFixMe
var parent = path.findParent(function (p) {
return p.isVariableDeclarator() || p.isAssignmentExpression() || p.isFunctionDeclaration() || p.isFunctionExpression() || p.isArrowFunctionExpression() || p.isObjectProperty() || p.isObjectMethod();
});
if (!parent) {
return '';
} // we probably have a css call assigned to a variable
// so we'll just return the variable name
if (parent.isVariableDeclarator()) {
if (t.isIdentifier(parent.node.id)) {
return parent.node.id.name;
}
return '';
}
if (parent.isAssignmentExpression()) {
var left = parent.node.left;
if (t.isIdentifier(left)) {
return left.name;
}
if (t.isMemberExpression(left)) {
var memberExpression = left;
var name = '';
while (true) {
if (!t.isIdentifier(memberExpression.property)) {
return '';
}
name = "" + memberExpression.property.name + (name ? "-" + name : '');
if (t.isIdentifier(memberExpression.object)) {
return memberExpression.object.name + "-" + name;
}
if (!t.isMemberExpression(memberExpression.object)) {
return '';
}
memberExpression = memberExpression.object;
}
}
return '';
} // we probably have an inline css prop usage
if (parent.isFunctionDeclaration()) {
return parent.node.id.name || '';
}
if (parent.isFunctionExpression()) {
if (parent.node.id) {
return parent.node.id.name || '';
}
return getDeclaratorName(parent, t);
}
if (parent.isArrowFunctionExpression()) {
return getDeclaratorName(parent, t);
} // we could also have an object property
var objPropertyLikeName = getObjPropertyLikeName(parent, t);
if (objPropertyLikeName) {
return objPropertyLikeName;
}
var variableDeclarator = parent.findParent(function (p) {
return p.isVariableDeclarator();
});
if (!variableDeclarator || !variableDeclarator.get('id').isIdentifier()) {
return '';
}
return variableDeclarator.node.id.name;
}
function getIdentifierName(path, t) {
var objPropertyLikeName = getObjPropertyLikeName(path.parentPath, t);
if (objPropertyLikeName) {
return objPropertyLikeName;
} // $FlowFixMe
var classOrClassPropertyParent = path.findParent(function (p) {
return t.isClassProperty(p) || t.isClass(p);
});
if (classOrClassPropertyParent) {
if (t.isClassProperty(classOrClassPropertyParent) && classOrClassPropertyParent.node.computed === false && t.isIdentifier(classOrClassPropertyParent.node.key)) {
return classOrClassPropertyParent.node.key.name;
}
if (t.isClass(classOrClassPropertyParent) && classOrClassPropertyParent.node.id) {
return t.isIdentifier(classOrClassPropertyParent.node.id) ? classOrClassPropertyParent.node.id.name : '';
}
}
var declaratorName = getDeclaratorName(path, t); // if the name starts with _ it was probably generated by babel so we should ignore it
if (declaratorName.charAt(0) === '_') {
return '';
}
return declaratorName;
}
function getGeneratorOpts(file) {
return file.opts.generatorOpts ? file.opts.generatorOpts : file.opts;
}
function makeSourceMapGenerator(file) {
var generatorOpts = getGeneratorOpts(file);
var filename = generatorOpts.sourceFileName;
var generator = new SourceMapGenerator({
file: filename,
sourceRoot: generatorOpts.sourceRoot
});
generator.setSourceContent(filename, file.code);
return generator;
}
function getSourceMap(offset, state) {
var generator = makeSourceMapGenerator(state.file);
var generatorOpts = getGeneratorOpts(state.file);
if (generatorOpts.sourceFileName && generatorOpts.sourceFileName !== 'unknown') {
generator.addMapping({
generated: {
line: 1,
column: 0
},
source: generatorOpts.sourceFileName,
original: offset
});
return convert.fromObject(generator).toComment({
multiline: true
});
}
return '';
}
var hashArray = function hashArray(arr) {
return hashString(arr.join(''));
};
var unsafeRequire = require;
var getPackageRootPath = memoize(function (filename) {
return findRoot(filename);
});
var separator = new RegExp(escapeRegexp(nodePath.sep), 'g');
var normalizePath = function normalizePath(path) {
return nodePath.normalize(path).replace(separator, '/');
};
function getTargetClassName(state, t) {
if (state.emotionTargetClassNameCount === undefined) {
state.emotionTargetClassNameCount = 0;
}
var hasFilepath = state.file.opts.filename && state.file.opts.filename !== 'unknown';
var filename = hasFilepath ? state.file.opts.filename : ''; // normalize the file path to ignore folder structure
// outside the current node project and arch-specific delimiters
var moduleName = '';
var rootPath = filename;
try {
rootPath = getPackageRootPath(filename);
moduleName = unsafeRequire(rootPath + '/package.json').name;
} catch (err) {}
var finalPath = filename === rootPath ? 'root' : filename.slice(rootPath.length);
var positionInFile = state.emotionTargetClassNameCount++;
var stuffToHash = [moduleName];
if (finalPath) {
stuffToHash.push(normalizePath(finalPath));
} else {
stuffToHash.push(state.file.code);
}
var stableClassName = "e" + hashArray(stuffToHash) + positionInFile;
return stableClassName;
}
// it's meant to simplify the most common cases so i don't want to make it especially complex
// also, this will be unnecessary when prepack is ready
function simplifyObject(node, t) {
var finalString = '';
for (var i = 0; i < node.properties.length; i++) {
var _ref;
var property = node.properties[i];
if (!t.isObjectProperty(property) || property.computed || !t.isIdentifier(property.key) && !t.isStringLiteral(property.key) || !t.isStringLiteral(property.value) && !t.isNumericLiteral(property.value) && !t.isObjectExpression(property.value)) {
return node;
}
var key = property.key.name || property.key.value;
if (key === 'styles') {
return node;
}
if (t.isObjectExpression(property.value)) {
var simplifiedChild = simplifyObject(property.value, t);
if (!t.isStringLiteral(simplifiedChild)) {
return node;
}
finalString += key + "{" + simplifiedChild.value + "}";
continue;
}
var value = property.value.value;
finalString += serializeStyles([(_ref = {}, _ref[key] = value, _ref)]).styles;
}
return t.stringLiteral(finalString);
}
var haveSameLocation = function haveSameLocation(element1, element2) {
return element1.line === element2.line && element1.column === element2.column;
};
var isAutoInsertedRule = function isAutoInsertedRule(element) {
return element.type === 'rule' && element.parent && haveSameLocation(element, element.parent);
};
var toInputTree = function toInputTree(elements, tree) {
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
var parent = element.parent,
children = element.children;
if (!parent) {
tree.push(element);
} else if (!isAutoInsertedRule(element)) {
parent.children.push(element);
}
if (Array.isArray(children)) {
element.children = [];
toInputTree(children, tree);
}
}
return tree;
};
var stringifyTree = function stringifyTree(elements) {
return elements.map(function (element) {
switch (element.type) {
case 'import':
case 'decl':
return element.value;
case 'comm':
// When we encounter a standard multi-line CSS comment and it contains a '@'
// character, we keep the comment. Some Stylis plugins, such as
// the stylis-rtl via the cssjanus plugin, use this special comment syntax
// to control behavior (such as: /* @noflip */). We can do this
// with standard CSS comments because they will work with compression,
// as opposed to non-standard single-line comments that will break compressed CSS.
return element.props === '/' && element.value.includes('@') ? element.value : '';
case 'rule':
return element.value.replace(/&\f/g, '&') + "{" + stringifyTree(element.children) + "}";
default:
{
return element.value + "{" + stringifyTree(element.children) + "}";
}
}
}).join('');
};
var interleave = function interleave(strings, interpolations) {
return interpolations.reduce(function (array, interp, i) {
return array.concat([interp], strings[i + 1]);
}, [strings[0]]);
};
function getDynamicMatches(str) {
var re = /xxx(\d+):xxx/gm;
var match;
var matches = [];
while ((match = re.exec(str)) !== null) {
// so that flow doesn't complain
if (match !== null) {
matches.push({
value: match[0],
p1: parseInt(match[1], 10),
index: match.index
});
}
}
return matches;
}
function replacePlaceholdersWithExpressions(str, expressions, t) {
var matches = getDynamicMatches(str);
if (matches.length === 0) {
if (str === '') {
return [];
}
return [t.stringLiteral(str)];
}
var strings = [];
var finalExpressions = [];
var cursor = 0;
matches.forEach(function (_ref, i) {
var value = _ref.value,
p1 = _ref.p1,
index = _ref.index;
var preMatch = str.substring(cursor, index);
cursor = cursor + preMatch.length + value.length;
if (!preMatch && i === 0) {
strings.push(t.stringLiteral(''));
} else {
strings.push(t.stringLiteral(preMatch));
}
finalExpressions.push(expressions[p1]);
if (i === matches.length - 1) {
strings.push(t.stringLiteral(str.substring(index + value.length)));
}
});
return interleave(strings, finalExpressions).filter(function (node) {
return node.value !== '';
});
}
function createRawStringFromTemplateLiteral(quasi) {
var strs = quasi.quasis.map(function (x) {
return x.value.cooked;
});
var src = strs.reduce(function (arr, str, i) {
arr.push(str);
if (i !== strs.length - 1) {
arr.push("xxx" + i + ":xxx");
}
return arr;
}, []).join('').trim();
return src;
}
function minify(path, t) {
var quasi = path.node.quasi;
var raw = createRawStringFromTemplateLiteral(quasi);
var minified = stringifyTree(toInputTree(compile(raw), []));
var expressions = replacePlaceholdersWithExpressions(minified, quasi.expressions || [], t);
path.replaceWith(t.callExpression(path.node.tag, expressions));
}
// this only works correctly in modules, but we don't run on scripts anyway, so it's fine
// the difference is that in modules template objects are being cached per call site
function getTypeScriptMakeTemplateObjectPath(path) {
if (path.node.arguments.length === 0) {
return null;
}
var firstArgPath = path.get('arguments')[0];
if (firstArgPath.isLogicalExpression() && firstArgPath.get('left').isIdentifier() && firstArgPath.get('right').isAssignmentExpression() && firstArgPath.get('right.right').isCallExpression() && firstArgPath.get('right.right.callee').isIdentifier() && firstArgPath.node.right.right.callee.name.includes('makeTemplateObject') && firstArgPath.node.right.right.arguments.length === 2) {
return firstArgPath.get('right.right');
}
return null;
} // this is only used to prevent appending strings/expressions to arguments incorectly
// we could push them to found array expressions, as we do it for TS-transpile output ¯\_(ツ)_/¯
// it seems overly complicated though - mainly because we'd also have to check against existing stuff of a particular type (source maps & labels)
// considering Babel double-transpilation as a valid use case seems rather far-fetched
function isTaggedTemplateTranspiledByBabel(path) {
if (path.node.arguments.length === 0) {
return false;
}
var firstArgPath = path.get('arguments')[0];
if (!firstArgPath.isCallExpression() || !firstArgPath.get('callee').isIdentifier()) {
return false;
}
var calleeName = firstArgPath.node.callee.name;
if (!calleeName.includes('templateObject')) {
return false;
}
var bindingPath = path.scope.getBinding(calleeName).path;
if (!bindingPath.isFunction()) {
return false;
}
var functionBody = bindingPath.get('body.body');
if (!functionBody[0].isVariableDeclaration()) {
return false;
}
var declarationInit = functionBody[0].get('declarations')[0].get('init');
if (!declarationInit.isCallExpression()) {
return false;
}
var declarationInitArguments = declarationInit.get('arguments');
if (declarationInitArguments.length === 0 || declarationInitArguments.length > 2 || declarationInitArguments.some(function (argPath) {
return !argPath.isArrayExpression();
})) {
return false;
}
return true;
}
var appendStringReturningExpressionToArguments = function appendStringReturningExpressionToArguments(t, path, expression) {
var lastIndex = path.node.arguments.length - 1;
var last = path.node.arguments[lastIndex];
if (t.isStringLiteral(last)) {
if (typeof expression === 'string') {
path.node.arguments[lastIndex].value += expression;
} else {
path.node.arguments[lastIndex] = t.binaryExpression('+', last, expression);
}
} else {
var makeTemplateObjectCallPath = getTypeScriptMakeTemplateObjectPath(path);
if (makeTemplateObjectCallPath) {
makeTemplateObjectCallPath.get('arguments').forEach(function (argPath) {
var elements = argPath.get('elements');
var lastElement = elements[elements.length - 1];
if (typeof expression === 'string') {
lastElement.replaceWith(t.stringLiteral(lastElement.node.value + expression));
} else {
lastElement.replaceWith(t.binaryExpression('+', lastElement.node, t.cloneNode(expression)));
}
});
} else if (!isTaggedTemplateTranspiledByBabel(path)) {
if (typeof expression === 'string') {
path.node.arguments.push(t.stringLiteral(expression));
} else {
path.node.arguments.push(expression);
}
}
}
};
var joinStringLiterals = function joinStringLiterals(expressions, t) {
return expressions.reduce(function (finalExpressions, currentExpression, i) {
if (!t.isStringLiteral(currentExpression)) {
finalExpressions.push(currentExpression);
} else if (t.isStringLiteral(finalExpressions[finalExpressions.length - 1])) {
finalExpressions[finalExpressions.length - 1].value += currentExpression.value;
} else {
finalExpressions.push(currentExpression);
}
return finalExpressions;
}, []);
};
function createNodeEnvConditional(t, production, development) {
return t.conditionalExpression(t.binaryExpression('===', t.memberExpression(t.memberExpression(t.identifier('process'), t.identifier('env')), t.identifier('NODE_ENV')), t.stringLiteral('production')), production, development);
}
var CSS_OBJECT_STRINGIFIED_ERROR = "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop).";
var transformExpressionWithStyles = function transformExpressionWithStyles(_ref) {
var babel = _ref.babel,
state = _ref.state,
path = _ref.path,
shouldLabel = _ref.shouldLabel,
_ref$sourceMap = _ref.sourceMap,
sourceMap = _ref$sourceMap === void 0 ? '' : _ref$sourceMap;
var autoLabel = state.opts.autoLabel || 'dev-only';
var t = babel.types;
if (t.isTaggedTemplateExpression(path)) {
if (!sourceMap && state.emotionSourceMap && path.node.quasi.loc !== undefined) {
sourceMap = getSourceMap(path.node.quasi.loc.start, state);
}
minify(path, t);
}
if (t.isCallExpression(path)) {
var canAppendStrings = path.node.arguments.every(function (arg) {
return arg.type !== 'SpreadElement';
});
path.get('arguments').forEach(function (node) {
if (t.isObjectExpression(node)) {
node.replaceWith(simplifyObject(node.node, t));
}
});
path.node.arguments = joinStringLiterals(path.node.arguments, t);
if (!sourceMap && canAppendStrings && state.emotionSourceMap && path.node.loc !== undefined) {
sourceMap = getSourceMap(path.node.loc.start, state);
}
var label = shouldLabel && autoLabel !== 'never' ? getLabelFromPath(path, state, t) : null;
if (path.node.arguments.length === 1 && t.isStringLiteral(path.node.arguments[0])) {
var cssString = path.node.arguments[0].value.replace(/;$/, '');
var res = serializeStyles(["" + cssString + (label && autoLabel === 'always' ? ";label:" + label + ";" : '')]);
var prodNode = t.objectExpression([t.objectProperty(t.identifier('name'), t.stringLiteral(res.name)), t.objectProperty(t.identifier('styles'), t.stringLiteral(res.styles))]);
if (!state.emotionStringifiedCssId) {
var uid = state.file.scope.generateUidIdentifier('__EMOTION_STRINGIFIED_CSS_ERROR__');
state.emotionStringifiedCssId = uid;
var cssObjectToString = t.functionDeclaration(uid, [], t.blockStatement([t.returnStatement(t.stringLiteral(CSS_OBJECT_STRINGIFIED_ERROR))]));
cssObjectToString._compact = true;
state.file.path.unshiftContainer('body', [cssObjectToString]);
}
if (label && autoLabel === 'dev-only') {
res = serializeStyles([cssString + ";label:" + label + ";"]);
}
var devNode = t.objectExpression([t.objectProperty(t.identifier('name'), t.stringLiteral(res.name)), t.objectProperty(t.identifier('styles'), t.stringLiteral(res.styles)), sourceMap && t.objectProperty(t.identifier('map'), t.stringLiteral(sourceMap)), t.objectProperty(t.identifier('toString'), t.cloneNode(state.emotionStringifiedCssId))].filter(Boolean));
return createNodeEnvConditional(t, prodNode, devNode);
}
if (canAppendStrings && label) {
var labelString = ";label:" + label + ";";
switch (autoLabel) {
case 'dev-only':
{
var labelConditional = createNodeEnvConditional(t, t.stringLiteral(''), t.stringLiteral(labelString));
appendStringReturningExpressionToArguments(t, path, labelConditional);
break;
}
case 'always':
appendStringReturningExpressionToArguments(t, path, labelString);
break;
}
}
if (sourceMap) {
var sourceMapConditional = createNodeEnvConditional(t, t.stringLiteral(''), t.stringLiteral(sourceMap));
appendStringReturningExpressionToArguments(t, path, sourceMapConditional);
}
}
};
var getKnownProperties = function getKnownProperties(t, node) {
return new Set(node.properties.filter(function (n) {
return t.isObjectProperty(n) && !n.computed;
}).map(function (n) {
return t.isIdentifier(n.key) ? n.key.name : n.key.value;
}));
};
var createObjectSpreadLike = function createObjectSpreadLike(t, file) {
for (var _len = arguments.length, objs = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
objs[_key - 2] = arguments[_key];
}
return t.callExpression(file.addHelper('extends'), [t.objectExpression([])].concat(objs));
};
var getStyledOptions = function getStyledOptions(t, path, state) {
var autoLabel = state.opts.autoLabel || 'dev-only';
var args = path.node.arguments;
var optionsArgument = args.length >= 2 ? args[1] : null;
var prodProperties = [];
var devProperties = null;
var knownProperties = optionsArgument && t.isObjectExpression(optionsArgument) ? getKnownProperties(t, optionsArgument) : new Set();
if (!knownProperties.has('target')) {
prodProperties.push(t.objectProperty(t.identifier('target'), t.stringLiteral(getTargetClassName(state))));
}
var label = autoLabel !== 'never' && !knownProperties.has('label') ? getLabelFromPath(path, state, t) : null;
if (label) {
var labelNode = t.objectProperty(t.identifier('label'), t.stringLiteral(label));
switch (autoLabel) {
case 'always':
prodProperties.push(labelNode);
break;
case 'dev-only':
devProperties = [labelNode];
break;
}
}
if (optionsArgument) {
// for some reason `.withComponent` transformer gets requeued
// so check if this has been already transpiled to avoid double wrapping
if (t.isConditionalExpression(optionsArgument) && t.isBinaryExpression(optionsArgument.test) && t.buildMatchMemberExpression('process.env.NODE_ENV')(optionsArgument.test.left)) {
return optionsArgument;
}
if (!t.isObjectExpression(optionsArgument)) {
var prodNode = createObjectSpreadLike(t, state.file, t.objectExpression(prodProperties), optionsArgument);
return devProperties ? createNodeEnvConditional(t, prodNode, t.cloneNode(createObjectSpreadLike(t, state.file, t.objectExpression(prodProperties.concat(devProperties)), optionsArgument))) : prodNode;
}
prodProperties.unshift.apply(prodProperties, optionsArgument.properties);
}
return devProperties ? createNodeEnvConditional(t, t.objectExpression(prodProperties), t.cloneNode(t.objectExpression(prodProperties.concat(devProperties)))) : t.objectExpression(prodProperties);
};
function addImport(state, importSource, importedSpecifier, nameHint) {
var cacheKey = ['import', importSource, importedSpecifier].join(':');
if (state[cacheKey] === undefined) {
var importIdentifier;
if (importedSpecifier === 'default') {
importIdentifier = addDefault(state.file.path, importSource, {
nameHint: nameHint
});
} else {
importIdentifier = addNamed(state.file.path, importedSpecifier, importSource, {
nameHint: nameHint
});
}
state[cacheKey] = importIdentifier.name;
}
return {
type: 'Identifier',
name: state[cacheKey]
};
}
function createTransformerMacro(transformers, _ref) {
var importSource = _ref.importSource;
var macro = createMacro(function (_ref2) {
var path = _ref2.path,
source = _ref2.source,
references = _ref2.references,
state = _ref2.state,
babel = _ref2.babel,
isEmotionCall = _ref2.isEmotionCall;
if (!path) {
path = state.file.scope.path.get('body').find(function (p) {
return p.isImportDeclaration() && p.node.source.value === source;
});
}
if (/\/macro$/.test(source)) {
path.get('source').replaceWith(babel.types.stringLiteral(source.replace(/\/macro$/, '')));
}
if (!isEmotionCall) {
state.emotionSourceMap = true;
}
Object.keys(references).forEach(function (importSpecifierName) {
if (transformers[importSpecifierName]) {
references[importSpecifierName].reverse().forEach(function (reference) {
var options;
var transformer;
if (Array.isArray(transformers[importSpecifierName])) {
transformer = transformers[importSpecifierName][0];
options = transformers[importSpecifierName][1];
} else {
transformer = transformers[importSpecifierName];
options = {};
}
transformer({
state: state,
babel: babel,
path: path,
importSource: importSource,
importSpecifierName: importSpecifierName,
options: options,
reference: reference
});
});
}
});
return {
keepImports: true
};
});
macro.transformers = transformers;
return macro;
}
var isAlreadyTranspiled = function isAlreadyTranspiled(path) {
if (!path.isCallExpression()) {
return false;
}
var firstArgPath = path.get('arguments.0');
if (!firstArgPath) {
return false;
}
if (!firstArgPath.isConditionalExpression()) {
return false;
}
var alternatePath = firstArgPath.get('alternate');
if (!alternatePath.isObjectExpression()) {
return false;
}
var properties = new Set(alternatePath.get('properties').map(function (p) {
return p.node.key.name;
}));
return ['name', 'styles'].every(function (p) {
return properties.has(p);
});
};
var createEmotionTransformer = function createEmotionTransformer(isPure) {
return function (_ref) {
var state = _ref.state,
babel = _ref.babel;
_ref.importSource;
var reference = _ref.reference;
_ref.importSpecifierName;
var path = reference.parentPath;
if (isAlreadyTranspiled(path)) {
return;
}
if (isPure) {
path.addComment('leading', '#__PURE__');
}
var node = transformExpressionWithStyles({
babel: babel,
state: state,
path: path,
shouldLabel: true
});
if (node) {
path.node.arguments[0] = node;
}
};
};
var transformers$1 = {
css: createEmotionTransformer(true),
injectGlobal: createEmotionTransformer(false),
keyframes: createEmotionTransformer(true)
};
var createEmotionMacro = function createEmotionMacro(importSource) {
return createTransformerMacro(transformers$1, {
importSource: importSource
});
};
var getReferencedSpecifier = function getReferencedSpecifier(path, specifierName) {
var specifiers = path.get('specifiers');
return specifierName === 'default' ? specifiers.find(function (p) {
return p.isImportDefaultSpecifier();
}) : specifiers.find(function (p) {
return p.node.local.name === specifierName;
});
};
var styledTransformer = function styledTransformer(_ref) {
var state = _ref.state,
babel = _ref.babel,
path = _ref.path,
importSource = _ref.importSource,
reference = _ref.reference,
importSpecifierName = _ref.importSpecifierName,
_ref$options = _ref.options,
styledBaseImport = _ref$options.styledBaseImport,
isWeb = _ref$options.isWeb;
var t = babel.types;
var getStyledIdentifier = function getStyledIdentifier() {
if (!styledBaseImport || styledBaseImport[0] === importSource && styledBaseImport[1] === importSpecifierName) {
return t.cloneNode(reference.node);
}
if (path.node) {
var referencedSpecifier = getReferencedSpecifier(path, importSpecifierName);
if (referencedSpecifier) {
referencedSpecifier.remove();
}
if (!path.get('specifiers').length) {
path.remove();
}
}
var baseImportSource = styledBaseImport[0],
baseSpecifierName = styledBaseImport[1];
return addImport(state, baseImportSource, baseSpecifierName, 'styled');
};
var createStyledComponentPath = null;
if (t.isMemberExpression(reference.parent) && reference.parent.computed === false) {
if ( // checks if the first character is lowercase
// becasue we don't want to transform the member expression if
// it's in primitives/native
reference.parent.property.name.charCodeAt(0) > 96) {
reference.parentPath.replaceWith(t.callExpression(getStyledIdentifier(), [t.stringLiteral(reference.parent.property.name)]));
} else {
reference.replaceWith(getStyledIdentifier());
}
createStyledComponentPath = reference.parentPath;
} else if (reference.parentPath && t.isCallExpression(reference.parentPath) && reference.parent.callee === reference.node) {
reference.replaceWith(getStyledIdentifier());
createStyledComponentPath = reference.parentPath;
}
if (!createStyledComponentPath) {
return;
}
var styledCallLikeWithStylesPath = createStyledComponentPath.parentPath;
var node = transformExpressionWithStyles({
path: styledCallLikeWithStylesPath,
state: state,
babel: babel,
shouldLabel: false
});
if (node && isWeb) {
// we know the argument length will be 1 since that's the only time we will have a node since it will be static
styledCallLikeWithStylesPath.node.arguments[0] = node;
}
styledCallLikeWithStylesPath.addComment('leading', '#__PURE__');
if (isWeb) {
createStyledComponentPath.node.arguments[1] = getStyledOptions(t, createStyledComponentPath, state);
}
};
var createStyledMacro = function createStyledMacro(_ref2) {
var importSource = _ref2.importSource,
_ref2$originalImportS = _ref2.originalImportSource,
originalImportSource = _ref2$originalImportS === void 0 ? importSource : _ref2$originalImportS,
_ref2$baseImportName = _ref2.baseImportName,
baseImportName = _ref2$baseImportName === void 0 ? 'default' : _ref2$baseImportName,
isWeb = _ref2.isWeb;
return createTransformerMacro({
"default": [styledTransformer, {
styledBaseImport: [importSource, baseImportName],
isWeb: isWeb
}]
}, {
importSource: originalImportSource
});
};
var transformCssCallExpression = function transformCssCallExpression(_ref) {
var state = _ref.state,
babel = _ref.babel,
path = _ref.path,
sourceMap = _ref.sourceMap,
_ref$annotateAsPure = _ref.annotateAsPure,
annotateAsPure = _ref$annotateAsPure === void 0 ? true : _ref$annotateAsPure;
var node = transformExpressionWithStyles({
babel: babel,
state: state,
path: path,
shouldLabel: true,
sourceMap: sourceMap
});
if (node) {
path.replaceWith(node);
path.hoist();
} else if (annotateAsPure && path.isCallExpression()) {
path.addComment('leading', '#__PURE__');
}
};
var transformCsslessArrayExpression = function transformCsslessArrayExpression(_ref2) {
var state = _ref2.state,
babel = _ref2.babel,
path = _ref2.path;
var t = babel.types;
var expressionPath = path.get('value.expression');
var sourceMap = state.emotionSourceMap && path.node.loc !== undefined ? getSourceMap(path.node.loc.start, state) : '';
expressionPath.replaceWith(t.callExpression( // the name of this identifier doesn't really matter at all
// it'll never appear in generated code
t.identifier('___shouldNeverAppearCSS'), path.node.value.expression.elements));
transformCssCallExpression({
babel: babel,
state: state,
path: expressionPath,
sourceMap: sourceMap,
annotateAsPure: false
});
if (t.isCallExpression(expressionPath)) {
expressionPath.replaceWith(t.arrayExpression(expressionPath.node.arguments));
}
};
var transformCsslessObjectExpression = function transformCsslessObjectExpression(_ref3) {
var state = _ref3.state,
babel = _ref3.babel,
path = _ref3.path,
cssImport = _ref3.cssImport;
var t = babel.types;
var expressionPath = path.get('value.expression');
var sourceMap = state.emotionSourceMap && path.node.loc !== undefined ? getSourceMap(path.node.loc.start, state) : '';
expressionPath.replaceWith(t.callExpression( // the name of this identifier doesn't really matter at all
// it'll never appear in generated code
t.identifier('___shouldNeverAppearCSS'), [path.node.value.expression]));
transformCssCallExpression({
babel: babel,
state: state,
path: expressionPath,
sourceMap: sourceMap
});
if (t.isCallExpression(expressionPath)) {
expressionPath.get('callee').replaceWith(addImport(state, cssImport.importSource, cssImport.cssExport, 'css'));
}
};
var cssTransformer = function cssTransformer(_ref4) {
var state = _ref4.state,
babel = _ref4.babel,
reference = _ref4.reference;
transformCssCallExpression({
babel: babel,
state: state,
path: reference.parentPath
});
};
var globalTransformer = function globalTransformer(_ref5) {
var state = _ref5.state,
babel = _ref5.babel,
reference = _ref5.reference,
importSource = _ref5.importSource,
options = _ref5.options;
var t = babel.types;
if (!t.isJSXIdentifier(reference.node) || !t.isJSXOpeningElement(reference.parentPath.node)) {
return;
}
var stylesPropPath = reference.parentPath.get('attributes').find(function (p) {
return t.isJSXAttribute(p.node) && p.node.name.name === 'styles';
});
if (!stylesPropPath) {
return;
}
if (t.isJSXExpressionContainer(stylesPropPath.node.value)) {
if (t.isArrayExpression(stylesPropPath.node.value.expression)) {
transformCsslessArrayExpression({
state: state,
babel: babel,
path: stylesPropPath
});
} else if (t.isObjectExpression(stylesPropPath.node.value.expression)) {
transformCsslessObjectExpression({
state: state,
babel: babel,
path: stylesPropPath,
cssImport: options.cssExport !== undefined ? {
importSource: importSource,
cssExport: options.cssExport
} : {
importSource: '@emotion/react',
cssExport: 'css'
}
});
}
}
};
var transformers = {
// this is an empty function because this transformer is never called
// we don't run any transforms on `jsx` directly
// instead we use it as a hint to enable css prop optimization
jsx: function jsx() {},
css: cssTransformer,
Global: globalTransformer
};
var coreMacro = createTransformerMacro(transformers, {
importSource: '@emotion/react'
});
var _excluded = ["canonicalImport"];
var getCssExport = function getCssExport(reexported, importSource, mapping) {
var cssExport = Object.keys(mapping).find(function (localExportName) {
var _mapping$localExportN = mapping[localExportName].canonicalImport,
packageName = _mapping$localExportN[0],
exportName = _mapping$localExportN[1];
return packageName === '@emotion/react' && exportName === 'css';
});
if (!cssExport) {
throw new Error("You have specified that '" + importSource + "' re-exports '" + reexported + "' from '@emotion/react' but it doesn't also re-export 'css' from '@emotion/react', 'css' is necessary for certain optimisations, please re-export it from '" + importSource + "'");
}
return cssExport;
};
var webStyledMacro = createStyledMacro({
importSource: '@emotion/styled/base',
originalImportSource: '@emotion/styled',
isWeb: true
});
var nativeStyledMacro = createStyledMacro({
importSource: '@emotion/native',
originalImportSource: '@emotion/native',
isWeb: false
});
var primitivesStyledMacro = createStyledMacro({
importSource: '@emotion/primitives',
originalImportSource: '@emotion/primitives',
isWeb: false
});
var vanillaEmotionMacro = createEmotionMacro('@emotion/css');
var transformersSource = {
'@emotion/css': transformers$1,
'@emotion/react': transformers,
'@emotion/styled': {
"default": [styledTransformer, {
styledBaseImport: ['@emotion/styled/base', 'default'],
isWeb: true
}]
},
'@emotion/primitives': {
"default": [styledTransformer, {
isWeb: false
}]
},
'@emotion/native': {
"default": [styledTransformer, {
isWeb: false
}]
}
};
var macros = {
core: coreMacro,
nativeStyled: nativeStyledMacro,
primitivesStyled: primitivesStyledMacro,
webStyled: webStyledMacro,
vanillaEmotion: vanillaEmotionMacro
};
var AUTO_LABEL_VALUES = ['dev-only', 'never', 'always'];
function index (babel, options) {
if (options.autoLabel !== undefined && !AUTO_LABEL_VALUES.includes(options.autoLabel)) {
throw new Error("The 'autoLabel' option must be undefined, or one of the following: " + AUTO_LABEL_VALUES.map(function (s) {
return "\"" + s + "\"";
}).join(', '));
}
var t = babel.types;
return {
name: '@emotion',
// https://github.com/babel/babel/blob/0c97749e0fe8ad845b902e0b23a24b308b0bf05d/packages/babel-plugin-syntax-jsx/src/index.ts#L9-L18
manipulateOptions: function manipulateOptions(opts, parserOpts) {
var plugins = parserOpts.plugins;
if (plugins.some(function (p) {
var plugin = Array.isArray(p) ? p[0] : p;
return plugin === 'typescript' || plugin === 'jsx';
})) {
return;
}
plugins.push('jsx');
},
visitor: {
ImportDeclaration: function ImportDeclaration(path, state) {
var macro = state.pluginMacros[path.node.source.value]; // most of this is from https://github.com/kentcdodds/babel-plugin-macros/blob/main/src/index.js
if (macro === undefined) {
return;
}
if (t.isImportNamespaceSpecifier(path.node.specifiers[0])) {
return;
}
var imports = path.node.specifiers.map(function (s) {
return {
localName: s.local.name,
importedName: s.type === 'ImportDefaultSpecifier' ? 'default' : s.imported.name
};
});
var shouldExit = false;
var hasReferences = false;
var referencePathsByImportName = imports.reduce(function (byName, _ref) {
var importedName = _ref.importedName,
localName = _ref.localName;
var binding = path.scope.getBinding(localName);
if (!binding) {
shouldExit = true;
return byName;
}
byName[importedName] = binding.referencePaths;
hasReferences = hasReferences || Boolean(byName[importedName].length);
return byName;
}, {});
if (!hasReferences || shouldExit) {
return;
}
/**
* 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: function Identifier() {}
});
macro({
path: path,
references: referencePathsByImportName,
state: state,
babel: babel,
isEmotionCall: true,
isBabelMacrosCall: true
});
},
Program: function Program(path, state) {
var macros = {};
var jsxReactImports = [{
importSource: '@emotion/react',
"export": 'jsx',
cssExport: 'css'
}];
state.jsxReactImport = jsxReactImports[0];
Object.keys(state.opts.importMap || {}).forEach(function (importSource) {
var value = state.opts.importMap[importSource];
var transformers = {};
Object.keys(value).forEach(function (localExportName) {
var _value$localExportNam = value[localExportName],
canonicalImport = _value$localExportNam.canonicalImport,
options = _objectWithoutPropertiesLoose(_value$localExportNam, _excluded);
var packageName = canonicalImport[0],
exportName = canonicalImport[1];
if (packageName === '@emotion/react' && exportName === 'jsx') {
jsxReactImports.push({
importSource: importSource,
"export": localExportName,
cssExport: getCssExport('jsx', importSource, value)
});
return;
}
var packageTransformers = transformersSource[packageName];
if (packageTransformers === undefined) {
throw new Error("There is no transformer for the export '" + exportName + "' in '" + packageName + "'");
}
var extraOptions;
if (packageName === '@emotion/react' && exportName === 'Global') {
// this option is not supposed to be set in importMap
extraOptions = {
cssExport: getCssExport('Global', importSource, value)
};
} else if (packageName === '@emotion/styled' && exportName === 'default') {
// this is supposed to override defaultOptions value
// and let correct value to be set if coming in options
extraOptions = {
styledBaseImport: undefined
};
}
var _ref2 = // $FlowFixMe
Array.isArray(packageTransformers[exportName]) ? packageTransformers[exportName] : [packageTransformers[exportName]],
exportTransformer = _ref2[0],
defaultOptions = _ref2[1];
transformers[localExportName] = [exportTransformer, _extends({}, defaultOptions, extraOptions, options)];
});
macros[importSource] = createTransformerMacro(transformers, {
importSource: importSource
});
});
state.pluginMacros = _extends({
'@emotion/styled': webStyledMacro,
'@emotion/react': coreMacro,
'@emotion/primitives': primitivesStyledMacro,
'@emotion/native': nativeStyledMacro,
'@emotion/css': vanillaEmotionMacro
}, macros);
var _loop = function _loop() {
var node = _step.value;
if (t.isImportDeclaration(node)) {
var jsxReactImport = jsxReactImports.find(function (thing) {
return node.source.value === thing.importSource && node.specifiers.some(function (x) {
return t.isImportSpecifier(x) && x.imported.name === thing["export"];
});
});
if (jsxReactImport) {
state.jsxReactImport = jsxReactImport;
return "break";
}
}
};
for (var _iterator = _createForOfIteratorHelperLoose(path.node.body), _step; !(_step = _iterator()).done;) {
var _ret = _loop();
if (_ret === "break") break;
}
if (state.opts.cssPropOptimization === false) {
state.transformCssProp = false;
} else {
state.transformCssProp = true;
}
if (state.opts.sourceMap === false) {
state.emotionSourceMap = false;
} else {
state.emotionSourceMap = true;
}
},
JSXAttribute: function JSXAttribute(path, state) {
if (path.node.name.name !== 'css' || !state.transformCssProp) {
return;
}
if (t.isJSXExpressionContainer(path.node.value)) {
if (t.isArrayExpression(path.node.value.expression)) {
transformCsslessArrayExpression({
state: state,
babel: babel,
path: path
});
} else if (t.isObjectExpression(path.node.value.expression)) {
transformCsslessObjectExpression({
state: state,
babel: babel,
path: path,
cssImport: state.jsxReactImport
});
}
}
},
CallExpression: {
exit: function exit(path, state) {
try {
if (path.node.callee && path.node.callee.property && path.node.callee.property.name === 'withComponent') {
switch (path.node.arguments.length) {
case 1:
case 2:
{
path.node.arguments[1] = getStyledOptions(t, path, state);
}
}
}
} catch (e) {
throw path.buildCodeFrameError(e);
}
}
}
}
};
}
export { index as default, macros };