mxdocgen
Version:
A small tool that mimics the documentation generation capabilities offered in Mendix Studio Pro, but with greater flexibility. It uses the Mendix Model SDK to extract information from a Mendix model, which is then fed into a set of templates to generate
299 lines • 15.8 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __spreadArrays = (this && this.__spreadArrays) || function () {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
var mendixmodelsdk_1 = require("mendixmodelsdk");
var uuid_1 = __importDefault(require("uuid"));
var datatypes_1 = require("../sdk/datatypes");
var documenttypes_1 = require("../sdk/documenttypes");
var attributetypes_1 = require("../sdk/attributetypes");
var associations_1 = require("../sdk/associations");
var MicroflowParameterObject = mendixmodelsdk_1.microflows.MicroflowParameterObject;
var Microflow = mendixmodelsdk_1.microflows.Microflow;
var Generalization = mendixmodelsdk_1.domainmodels.Generalization;
var AssociationOwner = mendixmodelsdk_1.domainmodels.AssociationOwner;
var DefaultProcessor = /** @class */ (function () {
function DefaultProcessor(moduleFilter, documentFilter) {
this.moduleFilter = moduleFilter;
this.documentFilter = documentFilter;
}
DefaultProcessor.prototype.process = function (model) {
return __awaiter(this, void 0, void 0, function () {
var _a;
var _this = this;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_a = {
Name: "Documentation"
};
return [4 /*yield*/, Promise.all(Array.from(this.modules(model))
.sort(function (a, b) { return a.name.localeCompare(b.name); })
.map(function (module) { return _this.processModule(module); }))];
case 1: return [2 /*return*/, (_a.Modules = _b.sent(),
_a)];
}
});
});
};
DefaultProcessor.prototype.processModule = function (module) {
return __awaiter(this, void 0, void 0, function () {
var documents, _a, _b;
var _this = this;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
documents = Array.from(this.documents(module));
_a = {
ID: uuid_1["default"](),
Name: module.name
};
return [4 /*yield*/, this.processDomainModel(module.domainModel)];
case 1:
_a.DomainModel = _c.sent(),
_a.HasMicroflows = documents.find(documenttypes_1.isMicroflow) !== undefined;
_b = {
ID: uuid_1["default"](),
TypeName: documenttypes_1.typeName(Microflow)
};
return [4 /*yield*/, Promise.all(documents
.filter(documenttypes_1.isMicroflow)
.sort(function (a, b) { return a.name.localeCompare(b.name); })
.map(function (microflow) { return _this.processMicroflow(microflow); }))];
case 2: return [2 /*return*/, (_a.Microflows = (_b.Microflows = _c.sent(),
_b),
_a)];
}
});
});
};
DefaultProcessor.prototype.processDomainModel = function (domainModel) {
return __awaiter(this, void 0, void 0, function () {
var loadedDomainModel, entities, _a;
var _this = this;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, domainModel.load()];
case 1:
loadedDomainModel = _b.sent();
entities = loadedDomainModel.entities
.slice()
.sort(function (a, b) { return a.name.localeCompare(b.name); });
_a = {
ID: loadedDomainModel.id,
Documentation: loadedDomainModel.documentation,
HasEntities: entities.length > 0
};
return [4 /*yield*/, Promise.all(entities.map(function (entity) { return _this.processEntity(entity, loadedDomainModel); }))];
case 2: return [2 /*return*/, (_a.Entities = _b.sent(),
_a)];
}
});
});
};
DefaultProcessor.prototype.processEntity = function (entity, domainModel) {
return __awaiter(this, void 0, void 0, function () {
var loadedEntity, attributes, associations, _a;
var _this = this;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, entity.load()];
case 1:
loadedEntity = _b.sent();
attributes = loadedEntity.attributes
.slice()
.sort(function (a, b) { return a.name.localeCompare(b.name); });
associations = domainModel.associations
.filter(function (association) {
return association.parent === entity ||
(association.child === entity && association.owner === AssociationOwner.Both);
})
.sort(function (a, b) { return a.name.localeCompare(b.name); });
_a = {
ID: loadedEntity.id,
Name: loadedEntity.name,
Documentation: loadedEntity.documentation,
Generalization: loadedEntity.generalization instanceof Generalization
? loadedEntity.generalization.generalizationQualifiedName
: undefined,
HasAttributes: attributes.length > 0
};
return [4 /*yield*/, Promise.all(attributes.map(function (attribute) { return _this.processAttribute(attribute); }))];
case 2:
_a.Attributes = _b.sent(),
_a.HasAssociations = associations.length > 0;
return [4 /*yield*/, Promise.all(associations.map(function (association) { return _this.processAssociation(association, loadedEntity); }))];
case 3: return [2 /*return*/, (_a.Associations = _b.sent(),
_a)];
}
});
});
};
DefaultProcessor.prototype.processAttribute = function (attribute) {
var _a;
return __awaiter(this, void 0, void 0, function () {
var loadedAttribute;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, attribute.load()];
case 1:
loadedAttribute = _b.sent();
return [2 /*return*/, {
Name: loadedAttribute.name,
Documentation: loadedAttribute.documentation,
Type: attributetypes_1.humanReadableAttributeType(loadedAttribute.type),
DefaultValue: (_a = loadedAttribute.value) === null || _a === void 0 ? void 0 : _a.defaultValue
}];
}
});
});
};
DefaultProcessor.prototype.processAssociation = function (association, entity) {
return __awaiter(this, void 0, void 0, function () {
var loadedAssociation;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, association.load()];
case 1:
loadedAssociation = _a.sent();
return [2 /*return*/, {
Name: loadedAssociation.name,
Documentation: loadedAssociation.documentation,
Multiplicity: associations_1.multiplicity(loadedAssociation),
OtherSide: loadedAssociation.parent === entity
? loadedAssociation.child.qualifiedName
: loadedAssociation.parent.qualifiedName
}];
}
});
});
};
DefaultProcessor.prototype.processMicroflow = function (microflow) {
return __awaiter(this, void 0, void 0, function () {
var loadedMicroflow, microflowParameterObjects;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, microflow.load()];
case 1:
loadedMicroflow = _a.sent();
microflowParameterObjects = loadedMicroflow.objectCollection.objects
.filter(function (microflowObject) {
return microflowObject.structureTypeName === MicroflowParameterObject.structureTypeName;
})
.map(function (microflowObject) { return microflowObject; })
.sort(function (a, b) { return a.name.localeCompare(b.name); });
return [2 /*return*/, {
ID: uuid_1["default"](),
Name: microflow.name,
Documentation: loadedMicroflow.documentation,
TypeName: documenttypes_1.documentTypeName(loadedMicroflow),
LowerTypeName: documenttypes_1.documentLowerTypeName(loadedMicroflow),
HasParameters: microflowParameterObjects.length > 0,
Parameters: microflowParameterObjects.map(function (microflowParameter) { return ({
Name: microflowParameter.name,
Type: datatypes_1.humanReadableDataType(microflowParameter.variableType),
Documentation: microflowParameter.documentation
}); }),
ReturnType: datatypes_1.humanReadableDataType(microflow.microflowReturnType),
"Return type": datatypes_1.humanReadableDataType(microflow.microflowReturnType)
}];
}
});
});
};
DefaultProcessor.prototype.modules = function (model) {
var _i, _a, module_1;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_i = 0, _a = model.allModules();
_b.label = 1;
case 1:
if (!(_i < _a.length)) return [3 /*break*/, 4];
module_1 = _a[_i];
if (!(!this.moduleFilter || this.moduleFilter(module_1))) return [3 /*break*/, 3];
return [4 /*yield*/, module_1];
case 2:
_b.sent();
_b.label = 3;
case 3:
_i++;
return [3 /*break*/, 1];
case 4: return [2 /*return*/];
}
});
};
DefaultProcessor.prototype.documents = function (module) {
var _i, _a, document_1;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_i = 0, _a = this.listDocuments(module);
_b.label = 1;
case 1:
if (!(_i < _a.length)) return [3 /*break*/, 4];
document_1 = _a[_i];
if (!(!this.documentFilter || this.documentFilter(document_1))) return [3 /*break*/, 3];
return [4 /*yield*/, document_1];
case 2:
_b.sent();
_b.label = 3;
case 3:
_i++;
return [3 /*break*/, 1];
case 4: return [2 /*return*/];
}
});
};
DefaultProcessor.prototype.listDocuments = function (folderBase) {
var _this = this;
return __spreadArrays(folderBase.documents, folderBase.folders.flatMap(function (folder) { return _this.listDocuments(folder); }));
};
return DefaultProcessor;
}());
exports.DefaultProcessor = DefaultProcessor;
//# sourceMappingURL=defaultprocessor.js.map