Generate an SDK Script Based on an Existing Model
Introduction
To help you to find out how you can write code to alter your model, the SDK ships with a nice reverse engineering tool. Given a fully loaded model unit, you can generate the JavaScript code that would create that very same unit using code. This way, you can build a template model in Studio Pro, then generate the code you would need to write to achieve the same.
For the Impatient
To generate the code for a fully-loaded unit you can use the following code:
import { JavaScriptSerializer } from "mendixmodelsdk";
console.log(JavaScriptSerializer.serializeToJs(someFullyLoadedModelUnit));
Example
Let’s say you want to generate a set of entities in a domain model that looks like this:
First you need to create the two entities in the domain model and commit that to Team Server. Next, you need to write a script like this:
import { JavaScriptSerializer } from "mendixmodelsdk";
import { MendixPlatformClient } from "mendixplatformsdk";
const projectId = "{YOUR_PROJECT_ID}";
const moduleName = "MyFirstModule";
async function main() {
const client = new MendixPlatformClient();
const app = client.getApp(projectId);
const workingCopy = await app.createTemporaryWorkingCopy("main"); // Use 'trunk' for Subversion based apps
const model = await workingCopy.openModel();
const domainModelInterface = model.allDomainModels().filter(dm => dm.containerAsModule.name === moduleName)[0];
const domainModel = await domainModelInterface.load();
console.log(JavaScriptSerializer.serializeToJs(domainModel));
}
main().catch(console.error);
When you execute the script, you will get the following output of your console. You can also pipe the output to a file if the model is more complex:
(function (unit, model) {
/*
* JavaScript code generated by mendixmodelsdk.sdk.extras.JavaScriptSerializer
* from unit with id "{PROJECT_ID}" of type DomainModels$DomainModel
* in working copy "{PROJECT_NAME}"
* on {DATE}.
*/
var noGeneralization1 = domainmodels.NoGeneralization.create(model);
var stringAttributeType1 = domainmodels.StringAttributeType.create(model);
var storedValue1 = domainmodels.StoredValue.create(model);
var address1 = domainmodels.Attribute.create(model);
address1.name = "Address";
address1.type = stringAttributeType1; // Note: for this property a default value is defined.
address1.value = storedValue1; // Note: for this property a default value is defined.
var stringAttributeType2 = domainmodels.StringAttributeType.create(model);
var storedValue2 = domainmodels.StoredValue.create(model);
var phone1 = domainmodels.Attribute.create(model);
phone1.name = "Phone";
phone1.type = stringAttributeType2; // Note: for this property a default value is defined.
phone1.value = storedValue2; // Note: for this property a default value is defined.
var person1 = domainmodels.Entity.create(model);
person1.name = "Person";
person1.location = {"x":150,"y":270};
person1.generalization = noGeneralization1; // Note: for this property a default value is defined.
person1.attributes.push(address1);
person1.attributes.push(phone1);
person1.imageData = "";
var noGeneralization2 = domainmodels.NoGeneralization.create(model);
var stringAttributeType3 = domainmodels.StringAttributeType.create(model);
var storedValue3 = domainmodels.StoredValue.create(model);
var roleName1 = domainmodels.Attribute.create(model);
roleName1.name = "RoleName";
roleName1.type = stringAttributeType3; // Note: for this property a default value is defined.
roleName1.value = storedValue3; // Note: for this property a default value is defined.
var role1 = domainmodels.Entity.create(model);
role1.name = "Role";
role1.location = {"x":340,"y":580};
role1.generalization = noGeneralization2; // Note: for this property a default value is defined.
role1.attributes.push(roleName1);
role1.imageData = "";
var associationDeleteBehavior1 = domainmodels.AssociationDeleteBehavior.create(model);
var person_Role1 = domainmodels.Association.create(model);
person_Role1.name = "Person_Role";
person_Role1.deleteBehavior = associationDeleteBehavior1; // Note: for this property a default value is defined.
person_Role1.parentConnection = {"x":75,"y":100};
person_Role1.childConnection = {"x":30,"y":0};
var domainModel1 = domainmodels.DomainModel.createIn(unit);
domainModel1.entities.push(person1);
domainModel1.entities.push(role1);
domainModel1.associations.push(person_Role1);
person_Role1.parent = person1;
person_Role1.child = role1;
})
If you want to re-create the entities of an existing domain model, you will need to alter the script a little bit. Replace the first line with:
function generate(domainModel1: domainmodels.DomainModel, model: IModel) {
The original code expects a unit as the first argument. The unit is supposed to be the container for the domain model. However, you don’t want to create a new domain model, you are going to re-use an existing domain model instead. Therefore, you need to remove this line:
const domainModel1 = domainmodels.DomainModel.createIn(unit);
Remove the last bracket on the last line so your JavaScript code will look like this:
function generate(domainModel1: domainmodels.DomainModel, model: IModel) {
/*
* JavaScript code generated by mendixmodelsdk.sdk.extras.JavaScriptSerializer
* from unit with id "{PROJECT_ID}" of type DomainModels$DomainModel
* in working copy "{PROJECT_NAME}"
* on {DATE}.
*/
var noGeneralization1 = domainmodels.NoGeneralization.create(model);
.
.
.
.
.
.
person_Role1.parentConnection = { x: 75, y: 100 };
person_Role1.childConnection = { x: 30, y: 0 };
domainModel1.entities.push(person1);
domainModel1.entities.push(role1);
domainModel1.associations.push(person_Role1);
person_Role1.parent = person1;
person_Role1.child = role1;
}
For the next step, you will create a script that make use of the function. The script is written in TypeScript, so it will be able to run a JavaScript code just fine. This script will create a blank app and modify the domain model in the MyFirstModule
module.
import { domainmodels, IModel } from "mendixmodelsdk";
import { MendixPlatformClient } from "mendixplatformsdk";
async function main() {
const client = new MendixPlatformClient();
const app = await client.createNewApp(`NewApp-${Date.now()}`, {
repositoryType: "git"
});
const workingCopy = await app.createTemporaryWorkingCopy("main");
const model = await workingCopy.openModel();
const domainModelInterface = model.allDomainModels().filter(dm => dm.containerAsModule.name === "MyFirstModule")[0];
const domainModel = await domainModelInterface.load();
generate(domainModel, model);
await model.flushChanges();
await workingCopy.commitToRepository("main");
}
main().catch(console.error);
//The generated code
function generate(domainModel1: domainmodels.DomainModel, model: IModel) {
.
.
.
}
Execute the script. You should have a new app with the generated entities.