@itwin/appui-codemod
Version:
Codemod scripts for AppUI.
98 lines (86 loc) • 4.51 kB
text/typescript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import type { API, ASTPath, FileInfo, JSCodeshift, MemberExpression, ObjectExpression, ObjectProperty, Options } from "jscodeshift";
import { ObjectExpressionCollection, useObjectExpression } from "../utils/ObjectExpression";
export default function transformer(file: FileInfo, api: API, options: Options) {
const j = api.jscodeshift;
useObjectExpression(j);
const root = j(file.source);
transformAbstractWidget(j, root.findObjectExpressions("Widget"))
.renameProperty("getWidgetContent", "content", (_path, property) => {
const functionExpression = j(property).find(j.ArrowFunctionExpression);
const element = functionExpression.find(j.JSXElement).nodes()[0];
if (!element)
return;
functionExpression.at(0).replaceWith(element);
});
return root.toSource(options.printOptions);
}
function handleCanFloatProperty(j: JSCodeshift, objectToProperties: Map<ASTPath<ObjectExpression>, ObjectProperty[]>, canFloatProperty: string): Parameters<ObjectExpressionCollection["removeProperty"]>[1] {
return (path, property) => {
let objectProperties = objectToProperties.get(path);
if (!objectProperties) {
objectProperties = [];
objectToProperties.set(path, objectProperties);
}
if (property.type === "ObjectProperty") {
const newProperty = j.objectProperty(j.identifier(canFloatProperty), property.value);
objectProperties.push(newProperty);
}
};
}
export function transformAbstractWidget(j: JSCodeshift, widgets: ObjectExpressionCollection) {
const objectToProperties = new Map<ASTPath<ObjectExpression>, ObjectProperty[]>();
widgets
.removeProperty("onWidgetStateChanged")
.removeProperty("saveTransientState")
.removeProperty("restoreTransientState")
.removeProperty("internalData")
.removeProperty("applicationData")
.renameProperty("isFloatingStateSupported", "canFloat")
.renameProperty("badgeType", "badge")
.renameProperty("allowedPanelTargets", "allowedPanels", (_path, property) => {
const arrayExpression = j(property).find(j.ArrayExpression);
const newElements: MemberExpression[] = [];
arrayExpression.find(j.Literal).forEach((literal) => {
const value = literal.value.value;
switch (value) {
case "left":
case "right":
case "bottom":
case "top": {
const capitalized = value.charAt(0).toUpperCase() + value.slice(1);
newElements.push(j.memberExpression(j.identifier("StagePanelLocation"), j.identifier(capitalized)));
break;
}
}
});
arrayExpression.paths()[0].value.elements = newElements;
// TODO: add `StagePanelLocation` to import declaration.
})
.removeProperty("isFloatingStateWindowResizable", handleCanFloatProperty(j, objectToProperties, "isResizable"))
.removeProperty("floatingContainerId", handleCanFloatProperty(j, objectToProperties, "containerId"))
.removeProperty("defaultFloatingPosition", handleCanFloatProperty(j, objectToProperties, "defaultPosition"))
.removeProperty("defaultFloatingSize", handleCanFloatProperty(j, objectToProperties, "defaultSize"))
.removeProperty("hideWithUiWhenFloating", handleCanFloatProperty(j, objectToProperties, "hideWithUi"));
for (const [objectExpression, properties] of objectToProperties) {
if (properties.length === 0)
continue;
const canFloat = objectExpression.value.properties.find((property) => {
if (property.type === "ObjectProperty" && property.key.type === "Identifier" && property.key.name === "canFloat")
return true;
return false;
}) as ObjectProperty | undefined;
if (!canFloat) {
const newCanFloat = j.objectProperty(j.identifier("canFloat"), j.objectExpression(properties));
objectExpression.value.properties.push(newCanFloat);
continue;
}
if (canFloat.value.type === "BooleanLiteral" && canFloat.value.value === false)
continue;
canFloat.value = j.objectExpression(properties);
}
return widgets;
}