You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
194 lines
4.6 KiB
194 lines
4.6 KiB
// @flow
|
|
import nodePath from 'path'
|
|
|
|
type LabelFormatOptions = {
|
|
name: string,
|
|
path: string
|
|
}
|
|
|
|
const invalidClassNameCharacters = /[!"#$%&'()*+,./:;<=>?@[\]^`|}~{]/g
|
|
|
|
const sanitizeLabelPart = (labelPart: string) =>
|
|
labelPart.trim().replace(invalidClassNameCharacters, '-')
|
|
|
|
function getLabel(
|
|
identifierName?: string,
|
|
labelFormat?: string | (LabelFormatOptions => string),
|
|
filename: string
|
|
) {
|
|
if (!identifierName) return null
|
|
|
|
const sanitizedName = sanitizeLabelPart(identifierName)
|
|
|
|
if (!labelFormat) {
|
|
return sanitizedName
|
|
}
|
|
|
|
if (typeof labelFormat === 'function') {
|
|
return labelFormat({
|
|
name: sanitizedName,
|
|
path: filename
|
|
})
|
|
}
|
|
|
|
const parsedPath = nodePath.parse(filename)
|
|
let localDirname = nodePath.basename(parsedPath.dir)
|
|
let localFilename = parsedPath.name
|
|
|
|
if (localFilename === 'index') {
|
|
localFilename = localDirname
|
|
}
|
|
|
|
return labelFormat
|
|
.replace(/\[local\]/gi, sanitizedName)
|
|
.replace(/\[filename\]/gi, sanitizeLabelPart(localFilename))
|
|
.replace(/\[dirname\]/gi, sanitizeLabelPart(localDirname))
|
|
}
|
|
|
|
export function getLabelFromPath(path: *, state: *, t: *) {
|
|
return getLabel(
|
|
getIdentifierName(path, t),
|
|
state.opts.labelFormat,
|
|
state.file.opts.filename
|
|
)
|
|
}
|
|
|
|
const 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
|
|
const parent = path.findParent(
|
|
p =>
|
|
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()) {
|
|
let { left } = parent.node
|
|
if (t.isIdentifier(left)) {
|
|
return left.name
|
|
}
|
|
if (t.isMemberExpression(left)) {
|
|
let memberExpression = left
|
|
let 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
|
|
const objPropertyLikeName = getObjPropertyLikeName(parent, t)
|
|
|
|
if (objPropertyLikeName) {
|
|
return objPropertyLikeName
|
|
}
|
|
|
|
let variableDeclarator = parent.findParent(p => p.isVariableDeclarator())
|
|
if (!variableDeclarator || !variableDeclarator.get('id').isIdentifier()) {
|
|
return ''
|
|
}
|
|
return variableDeclarator.node.id.name
|
|
}
|
|
|
|
function getIdentifierName(path: *, t: *) {
|
|
let objPropertyLikeName = getObjPropertyLikeName(path.parentPath, t)
|
|
|
|
if (objPropertyLikeName) {
|
|
return objPropertyLikeName
|
|
}
|
|
|
|
// $FlowFixMe
|
|
let classOrClassPropertyParent = path.findParent(
|
|
p => 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
|
|
: ''
|
|
}
|
|
}
|
|
|
|
let 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
|
|
}
|