@navikt/aksel
Version:
Aksel command line interface. Codemods and other utilities for Aksel users.
200 lines (199 loc) • 7.74 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = transformer;
const legacy_tokens_1 = require("../../../../darkside/config/legacy.tokens");
const ast_1 = require("../../../utils/ast");
const lineterminator_1 = require("../../../utils/lineterminator");
const box_new_1 = __importDefault(require("../box-new/box-new"));
const propsAffected = ["background", "borderColor", "shadow"];
function transformer(file, api) {
const j = api.jscodeshift;
const root = j(file.source);
const toSourceOptions = (0, lineterminator_1.getLineTerminator)(file.source);
if (file.source.includes("TODO: Aksel Box migration")) {
return root.toSource(toSourceOptions);
}
const localName = (0, ast_1.findComponentImport)({
root,
j,
name: "Box",
packageType: "react",
});
if (!localName) {
return;
}
const astElements = root.find(j.JSXElement, {
openingElement: {
name: {
type: "JSXIdentifier",
name: localName,
},
},
});
const predefinedReplacents = predefinedReplacentset();
const tokenComments = [];
for (const astElement of astElements.paths()) {
for (const prop of propsAffected) {
(0, ast_1.findProps)({ j, path: astElement, name: prop }).forEach((attr) => {
const attrvalue = attr.value.value;
if (attrvalue.type === "StringLiteral") {
/**
* Skips if the replacement token already set
*/
if (predefinedReplacents.has(addPrefix(attrvalue.value, prop))) {
return;
}
const config = legacy_tokens_1.legacyTokenConfig[attrvalue.value];
if (config === null || config === void 0 ? void 0 : config.replacement) {
attrvalue.value = cleanReplacementToken(config.replacement, prop);
}
else {
const tokenComment = {
prop,
token: attrvalue.value,
};
if (config === null || config === void 0 ? void 0 : config.comment) {
tokenComment.comment = config.comment;
}
tokenComments.push(tokenComment);
}
}
else if (attrvalue.type === "JSXExpressionContainer" &&
attrvalue.expression.type === "StringLiteral") {
const literal = attrvalue.expression;
/**
* Skips if the replacement token already set
*/
if (predefinedReplacents.has(addPrefix(literal.value, prop))) {
return;
}
const config = legacy_tokens_1.legacyTokenConfig[literal.value];
if (config === null || config === void 0 ? void 0 : config.replacement) {
literal.value = cleanReplacementToken(config.replacement, prop);
}
else {
const tokenComment = {
prop,
token: literal.value,
};
if (config === null || config === void 0 ? void 0 : config.comment) {
tokenComment.comment = config.comment;
}
tokenComments.push(tokenComment);
}
}
});
}
(0, ast_1.findProps)({ j, path: astElement, name: "borderRadius" }).forEach((attr) => {
const attrValue = attr.value.value;
if (attrValue.type === "StringLiteral") {
/* borderRadius="xlarge" */
attrValue.value = convertBorderRadiusToRadius(attrValue.value);
}
else if (attrValue.type === "JSXExpressionContainer") {
/* borderRadius={{xs: "xlarge", sm: "large"}} */
const expression = attrValue.expression;
if (expression.type === "ObjectExpression") {
/* xs, md, sm */
expression.properties.forEach((property) => {
if (property.type === "ObjectProperty") {
if (property.value.type === "StringLiteral") {
property.value.value = convertBorderRadiusToRadius(property.value.value);
}
}
});
}
else if (expression.type === "StringLiteral") {
expression.value = convertBorderRadiusToRadius(expression.value);
}
}
});
}
const blockComment = createFileComments({ tokenComments });
if (blockComment) {
return `${blockComment ? blockComment + "\n\n" : ""}${root.toSource(toSourceOptions)}`;
}
file.source = root.toSource(toSourceOptions);
return (0, box_new_1.default)(file, api);
}
const createFileComments = ({ tokenComments, }) => {
if (tokenComments.length === 0) {
return null;
}
let constructedComment = "/*\nTODO: Aksel Box migration:\nCould not migrate the following:\n";
for (const { prop, token, comment } of tokenComments.values()) {
constructedComment += ` - ${prop}=${token}\n`;
if (comment) {
constructedComment += ` - ${comment}\n`;
}
}
constructedComment += "*/";
return constructedComment;
};
const legacyBorderRadiusNameTokenLookup = {
full: "full",
xlarge: "12",
large: "8",
medium: "4",
small: "2",
};
/**
* Takes an old valid border-radius token and returns the new converted radius token
* oldValue: "xlarge", "full"
* @returns "12", "full"
*/
function convertBorderRadiusToRadius(oldValue) {
const radiusTokens = oldValue.split(" ");
const newRadius = [];
for (const radiusToken of radiusTokens) {
if (radiusToken === "full") {
newRadius.push(radiusToken);
}
else if (!(radiusToken in legacyBorderRadiusNameTokenLookup)) {
console.warn(`Possibly invalid radius token found: ${radiusToken}\n`);
newRadius.push(radiusToken);
}
else {
newRadius.push(`${legacyBorderRadiusNameTokenLookup[radiusToken]}`);
}
}
return newRadius.join(" ");
}
/**
* New props in Box do not have bg- or border- prefixes
* This function removes those prefixes from the tokens
*/
function cleanReplacementToken(token, type) {
if (type === "background") {
return token.replace("bg-", "");
}
if (type === "borderColor") {
return token.replace("border-", "");
}
return token;
}
/**
* Adds bg- or border- prefixes to tokens for comparison with existing replacements
*/
function addPrefix(token, type) {
if (type === "background") {
return `bg-${token}`;
}
if (type === "borderColor") {
return `border-${token}`;
}
return token;
}
function predefinedReplacentset() {
const set = new Set();
for (const key in legacy_tokens_1.legacyTokenConfig) {
const config = legacy_tokens_1.legacyTokenConfig[key];
if (config.replacement) {
set.add(config.replacement);
}
}
return set;
}