Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions automation/utils/bin/rui-generate-package-xml.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#!/usr/bin/env ts-node

import { writeClientPackageXml, ClientPackageXML } from "../src/package-xml-v2";
import { readPropertiesXml, writeClientPackage } from "../src/xml-reader";
import { getWidgetInfo } from "../src/package-info";
import { readPropertiesFile } from "../src/package-xml-v2/properties-xml";
import path from "node:path";
import { existsSync } from "node:fs";

Expand All @@ -29,11 +28,11 @@ async function generatePackageXml(): Promise<void> {
}

// Read properties file and extract widget ID
const propertiesXml = await readPropertiesFile(propertiesFilePath);
const propertiesXml = await readPropertiesXml(propertiesFilePath);
const widgetId = propertiesXml.widget["@_id"];

// Generate ClientPackageXML structure
const clientPackageXml: ClientPackageXML = {
const clientPackageXml = {
name: packageInfo.mxpackage.name,
version: packageInfo.version,
widgetFiles: [packageInfo.mxpackage.name + ".xml"],
Expand All @@ -42,10 +41,10 @@ async function generatePackageXml(): Promise<void> {

// Write the generated package.xml
const packageXmlPath = path.join(srcDir, "package.xml");
await writeClientPackageXml(packageXmlPath, clientPackageXml);
await writeClientPackage(packageXmlPath, clientPackageXml);
}

async function main() {
async function main(): Promise<void> {
try {
await generatePackageXml();
} catch (error) {
Expand Down
2 changes: 1 addition & 1 deletion automation/utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"cross-zip": "^4.0.1",
"enquirer": "^2.4.1",
"execa": "^5.1.1",
"fast-xml-parser": "^4.1.3",
"fast-xml-parser": "^5.2.5",
"glob": "^11.0.3",
"node-fetch": "^2.7.0",
"ora": "^5.4.1",
Expand Down
94 changes: 0 additions & 94 deletions automation/utils/src/package-xml-v2/index.ts

This file was deleted.

21 changes: 0 additions & 21 deletions automation/utils/src/package-xml-v2/properties-xml.ts

This file was deleted.

2 changes: 2 additions & 0 deletions automation/utils/src/xml-reader/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { ClientPackageInfo, readClientPackage, writeClientPackage } from "./package-xml";
export { readPropertiesXml } from "./properties-xml";
56 changes: 56 additions & 0 deletions automation/utils/src/xml-reader/package-xml.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { ClientModulePackageFile } from "./schema";
import { Version, VersionString } from "../version";
import { readFile, writeFile } from "fs/promises";
import { xmlJsonToXmlText, xmlTextToXmlJson } from "./parser";

export interface ClientPackageInfo {
name: string;
version: Version;
widgetFiles: string[];
files: string[];
}

function parseClientPackageXml(xmlJson: ClientModulePackageFile): ClientPackageInfo {
const clientModule = xmlJson?.package?.clientModule ?? {};

const name = clientModule["@_name"] ?? "";
const versionString = clientModule["@_version"] ?? "1.0.0";

return {
name,
version: Version.fromString(versionString as VersionString),
widgetFiles: clientModule.widgetFiles !== "" ? clientModule.widgetFiles?.widgetFile.map(i => i["@_path"]) : [],
files: clientModule.files !== "" ? clientModule.files?.file.map(i => i["@_path"]) : []
};
}

function buildClientPackageXml(clientPackage: ClientPackageInfo): ClientModulePackageFile {
const toXmlArray = (paths: string[]): any => {
return paths.map(path => ({ "@_path": path }));
};
return {
"?xml": {
"@_version": "1.0",
"@_encoding": "utf-8"
},
package: {
clientModule: {
widgetFiles:
clientPackage.widgetFiles.length !== 0 ? { widgetFile: toXmlArray(clientPackage.widgetFiles) } : "",
files: clientPackage.files.length !== 0 ? { file: toXmlArray(clientPackage.files) } : "",
"@_name": clientPackage.name,
"@_version": clientPackage.version.format(),
"@_xmlns": "http://www.mendix.com/clientModule/1.0/"
},
"@_xmlns": "http://www.mendix.com/package/1.0/"
}
};
}

export async function readClientPackage(path: string): Promise<ClientPackageInfo> {
return parseClientPackageXml(ClientModulePackageFile.passthrough().parse(xmlTextToXmlJson(await readFile(path))));
}

export async function writeClientPackage(path: string, data: ClientPackageInfo): Promise<void> {
await writeFile(path, xmlJsonToXmlText(buildClientPackageXml(data)));
}
74 changes: 74 additions & 0 deletions automation/utils/src/xml-reader/parser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { XMLBuilder, XMLParser } from "fast-xml-parser";

const arrayNodes = [
"file",
"widgetFile",
"propertyGroup",
"enumerationValue",
"property",
"systemProperty",
"attributeType",
"translation",
"selectionType",
"actionVariable",
"associationType"
];

const singleNodes = [
"name",
"caption",
"description",
"widget",
"helpUrl",
"enumerationValues",
"returnType",
"attributeTypes",
"studioCategory",
"studioProCategory",
"selectionTypes",
"category",
"translations",
"actionVariables",
"associationTypes",
"icon",
"module",
"projectFile",
"properties"
];

export function xmlTextToXmlJson(xmlText: string | Buffer): unknown {
const parser = new XMLParser({
ignoreAttributes: false,
allowBooleanAttributes: true,
attributeValueProcessor: (attr, val) => {
if (attr === "defaultValue") {
return val;
}
if (val === "true") return true;
if (val === "false") return false;
return val;
},
isArray: (name, _jpath, _isLeafNode, isAttribute) => {
if (isAttribute) return false;
if (arrayNodes.includes(name)) return true;
if (singleNodes.includes(name)) return false;

return false;
}
});

return parser.parse(xmlText);
}

export function xmlJsonToXmlText(xmlObject: any): string {
const builder = new XMLBuilder({
ignoreAttributes: false,
format: true,
indentBy: " ",
suppressEmptyNode: true
});
return builder
.build(xmlObject)
.replaceAll(/(<[^>]*?)\/>/g, "$1 />") // Add space before /> in self-closing tags
.replaceAll(/(<\?[^>]*?)\?>/g, "$1 ?>"); // Add space before ?> in XML declarations
}
Loading
Loading