JDito Upgraders in Modularization
When modularizing a project, developers often need to:
- Rename functions
- Move functions from one library to another (for example, relocating dependency-related functions to a module-specific library)
To streamline this process and avoid manually updating all function calls and corresponding import statements, use JDito upgraders. JDito upgraders are JSON configuration files that map old symbols to their new counterparts.
JDito upgraders only modify call sites and related imports after you have manually moved or renamed the source functions. They do not move or rename functions themselves.
Locate and Run JDito Upgraders
Place all upgrader files for a module in the others folder of the project tree, either directly or in a subfolder named upgraders.
To execute upgraders:
- Right-click the root node of your ADITO Designer project in the project tree.
- Select "Upgrade JDito…".
- Choose a package root, a folder, or a specific upgrader file:
- Selecting a folder executes all upgrader JSON files within it (recursively).
- Selecting a single JSON file executes only that file.
Folder selection processes all .json files recursively, including unrelated files such as package.json or .eslintrc.json. Decide whether to run all upgraders or a specific subset. To ensure upgraders from dependencies are included, select the package root. Running upgraders can take a while.
Create a New Upgrader File
The context menu in others does not provide a "New Upgrader" option. Create upgrader files using any text editor.
- Name the file
<Meaning>_Upgrader.json. The name should clearly describe what it upgrades. - Recommended: Group all upgrader files for a module under
others/upgraders. Create the folder manually if needed.
Upgrader File Structure
An upgrader file is a JSON document with an elements array. Each array item is one upgrade element.
{
"elements": [
{
// configuration for first update element
},
{
// configuration for second update element
}
]
}
You may include one or multiple upgrade elements (even of different types) in a single file.
- Group elements logically: if several changes belong to one atomic upgrade, keep them in the same file.
- Every element requires a
typefield. Other attributes depend on the type and are described below.
JDito upgraders do not automatically remove obsolete imports. After running upgraders, clean up with ESLint autofix:
npx eslint --ext .js --ignore-pattern node_modules/ --fix
Upgrader Types
There are several types of upgraders. Each type has its own set of attributes.
Please read the descriptions of each type to learn how to use them.
STATICFUNCTION_MOVED
Use when a static function remains the same but its owning object/class changes.
Parameters:
base(required): Function name (right part of the call)oldName(required): Old object/class name (left part)newName(required): New object/class name (left part)imports(optional): Map of symbol-to-import-sources for newly required imports
{
"elements": [
{
"type": "STATICFUNCTION_MOVED",
"base": "doStuff",
"oldName": "MyObject",
"newName": "NewClass",
"imports": {
"NewClass": [
"NewClass_lib"
]
}
}
]
}
Example result:
import { MyObject } from "MyLib";
+ import { NewClass } from "NewClass_lib";
- let result = MyObject.doStuff();
+ let result = NewClass.doStuff();
- let resultParams = MyObject.doStuff("foo", 42, true);
+ let resultParams = NewClass.doStuff("foo", 42, true);
The old import remains. Run ESLint to remove unused imports.
STATICFUNCTION_RENAMED
Use when the owning object/class stays the same but the static function name changes.
Parameters:
oldName(required): Old function namenewName(required): New function namebase(recommended): Static object/class name (left part)
Although base is not technically required, the upgrader will not work without it.
{
"elements": [
{
"type": "STATICFUNCTION_RENAMED",
"base": "EventHandler",
"oldName": "doStuff",
"newName": "newExportFunctionName"
}
]
}
Example result:
- let result = EventHandler.doStuff();
+ let result = EventHandler.newExportFunctionName();
- let resultParams = EventHandler.doStuff("foo", 42, true);
+ let resultParams = EventHandler.newExportFunctionName("foo", 42, true);
This upgrader does not update imports. If imports need to change, use IMPORT afterwards.
GLOBALFUNCTION_RENAMED
Use when a top-level exported function is renamed and/or moved to a different import.
Parameters:
oldName(required): Old function nameoldImportName(required): Old import sourcenewName(optional): New function namenewImportName(optional): New import source
{
"elements": [
{
"type": "GLOBALFUNCTION_RENAMED",
"oldName": "oldSelect",
"newName": "newSelect",
"oldImportName": "OldSql_lib",
"newImportName": "NewSql_lib"
}
]
}
Example result:
import { oldSelect } from "OldSql_lib";
+ import { newSelect } from "NewSql_lib";
- let result = oldSelect('foo', 42, true);
+ let result = newSelect('foo', 42, true);
The old import may remain. Clean up with ESLint.
PROPERTY_RENAMED
Use when a named export representing a property changes its export name and/or source, while member access stays the same.
Parameters:
base(required): Member path that follows the property.oldName(required): Old property export nameoldImportName(required): Old import sourcenewName(optional): New property export namenewImportName(optional): New import source
{
"elements": [
{
"type": "PROPERTY_RENAMED",
"base": "FOO.Subelement",
"oldName": "MyProperty",
"oldImportName": "MyAttributes_lib",
"newName": "NewProperty",
"newImportName": "AnotherAttributes_lib"
}
]
}
Example result:
import { MyProperty } from "MyAttributes_lib";
+ import { NewProperty } from "AnotherAttributes_lib";
- let property = MyProperty.FOO.Subelement;
+ let property = NewProperty.FOO.Subelement;
The old import may remain. Clean up with ESLint.
IMPORT
Use when only the import source changes for a given named export.
Parameters:
oldImportName(required): Old import sourcenewImportName(required): New import sourcebase(required): Named export whose import should move
{
"elements": [
{
"type": "IMPORT",
"base": "MyProperty",
"oldImportName": "MyAttributes_lib",
"newImportName": "AnotherAttributes_lib"
}
]
}
Example result:
- import { MyProperty, AnotherProperty } from "MyAttributes_lib";
+ import { AnotherProperty } from "MyAttributes_lib";
+ import { MyProperty } from "AnotherAttributes_lib";
This upgrader rewrites imports without leaving stale entries.
MEMBERFUNCTION_TO_STATICFUNCTION
Use when an instance/member function is extracted into a utility as a static function. The original receiver becomes the first argument.
Parameters:
base(required): New object/class providing the static function (left part)oldName(required): Old member function namenewName(optional): New static function nameimports(optional): Map of symbol-to-import-sources to add
{
"elements": [
{
"type": "MEMBERFUNCTION_TO_STATICFUNCTION",
"oldName": "getMemberFunction",
"newName": "getStaticFunction",
"base": "MyUtilsElement",
"imports": {
"MyUtilsElement": [
"MyUtils_lib"
]
}
}
]
}
Example result:
+ import { MyUtilsElement } from "MyUtils_lib";
- let result = template.getMemberFunction(123, "foo")
+ let result = MyUtilsElement.getStaticFunction(template, 123, "foo")
REGEX
Use when a targeted transformation cannot be expressed with a dedicated upgrader type. Applies a regex-based search/replace and can add imports.
Regex upgraders are powerful and risky. They may cause unintended changes. Test thoroughly on diverse samples and prefer specialized upgraders when possible.
Parameters:
search(required): Regular expression used to match codereplace(optional): Replacement stringimports(optional): Map of symbol-to-import-sources to add
{
"elements": [
{
"type": "REGEX",
"search": "Foo",
"replace": "Bar",
"imports": {
"Bar": [
"Bar_lib"
]
}
}
]
}
Example result:
+ import { Bar } from "Bar_lib";
- let param = Foo.bar;
+ let param = Bar.bar;
- Foo.doStuff(123, "baz", true);
+ Bar.doStuff(123, "baz", true);
- let result = Foo.calc(1, 2);
+ let result = Bar.calc(1, 2);
- let text = "Lorem Foo Ipsum";
+ let text = "Lorem Bar Ipsum";