127 lines
3.7 KiB
JavaScript
127 lines
3.7 KiB
JavaScript
/**
|
|
* @file rr-wsdl.js
|
|
* @description Lightweight service description + utilities for the Rome (R&R) SOAP actions.
|
|
* - Maps actions to SOAPAction headers (from rr-constants)
|
|
* - Maps actions to Mustache template filenames (xml-templates/*.xml)
|
|
* - Provides verification helpers to ensure templates exist
|
|
* - Provides normalized SOAP headers used by the transport
|
|
*/
|
|
|
|
const path = require("path");
|
|
const fs = require("fs/promises");
|
|
const { RR_ACTIONS, RR_SOAP_HEADERS } = require("./rr-constants");
|
|
const mustache = require("mustache");
|
|
|
|
// ---- Action <-> Template wiring ----
|
|
// Keep action names consistent with rr-helpers / rr-lookup / rr-repair-orders / rr-customer
|
|
const ACTION_TEMPLATES = Object.freeze({
|
|
InsertCustomer: "InsertCustomer",
|
|
UpdateCustomer: "UpdateCustomer",
|
|
InsertServiceVehicle: "InsertServiceVehicle",
|
|
CreateRepairOrder: "CreateRepairOrder",
|
|
UpdateRepairOrder: "UpdateRepairOrder",
|
|
GetAdvisors: "GetAdvisors",
|
|
GetParts: "GetParts",
|
|
CombinedSearch: "CombinedSearch"
|
|
});
|
|
|
|
/**
|
|
* Get the SOAPAction string for a known action.
|
|
* Throws if action is unknown.
|
|
*/
|
|
function getSoapAction(action) {
|
|
const entry = RR_ACTIONS[action];
|
|
if (!entry) {
|
|
const known = Object.keys(RR_ACTIONS).join(", ");
|
|
throw new Error(`Unknown RR action "${action}". Known: ${known}`);
|
|
}
|
|
return entry.soapAction;
|
|
}
|
|
|
|
/**
|
|
* Get the template filename (without extension) for a known action.
|
|
* e.g., "CreateRepairOrder" -> "CreateRepairOrder"
|
|
*/
|
|
function getTemplateForAction(action) {
|
|
const tpl = ACTION_TEMPLATES[action];
|
|
if (!tpl) {
|
|
const known = Object.keys(ACTION_TEMPLATES).join(", ");
|
|
throw new Error(`No template mapping for RR action "${action}". Known: ${known}`);
|
|
}
|
|
return tpl;
|
|
}
|
|
|
|
/**
|
|
* Build headers for a SOAP request, including SOAPAction.
|
|
* Consumers: rr-helpers (transport).
|
|
*/
|
|
function buildSoapHeadersForAction(action) {
|
|
return {
|
|
...RR_SOAP_HEADERS,
|
|
SOAPAction: getSoapAction(action)
|
|
};
|
|
}
|
|
|
|
/**
|
|
* List all known actions with their SOAPAction + template.
|
|
* Useful for diagnostics (e.g., /rr/actions route).
|
|
*/
|
|
function listActions() {
|
|
return Object.keys(ACTION_TEMPLATES).map((action) => ({
|
|
action,
|
|
soapAction: getSoapAction(action),
|
|
template: getTemplateForAction(action)
|
|
}));
|
|
}
|
|
|
|
/**
|
|
* Verify that every required template exists in xml-templates/.
|
|
* Returns an array of issues; empty array means all good.
|
|
*/
|
|
async function verifyTemplatesExist() {
|
|
const issues = [];
|
|
const baseDir = path.join(__dirname, "xml-templates");
|
|
|
|
for (const [action, tpl] of Object.entries(ACTION_TEMPLATES)) {
|
|
const filePath = path.join(baseDir, `${tpl}.xml`);
|
|
try {
|
|
const contents = await fs.readFile(filePath, "utf8"); // throws if missing
|
|
try {
|
|
// Parse-only to catch “Unclosed section …” and similar
|
|
mustache.parse(contents);
|
|
} catch (parseErr) {
|
|
issues.push({ action, template: tpl, error: `Mustache parse error: ${parseErr.message}`, filePath });
|
|
}
|
|
} catch {
|
|
issues.push({ action, template: tpl, error: `Missing file: ${filePath}` });
|
|
}
|
|
}
|
|
return issues;
|
|
}
|
|
/**
|
|
* Quick assert that throws if any template is missing.
|
|
* You can call this once during boot and log the result.
|
|
*/
|
|
async function assertTemplates() {
|
|
const issues = await verifyTemplatesExist();
|
|
if (issues.length) {
|
|
const msg =
|
|
"RR xml-templates verification failed:\n" +
|
|
issues.map((i) => ` - ${i.action} -> ${i.template}.xml :: ${i.error}`).join("\n");
|
|
throw new Error(msg);
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
// Maps / helpers
|
|
ACTION_TEMPLATES,
|
|
listActions,
|
|
getSoapAction,
|
|
getTemplateForAction,
|
|
buildSoapHeadersForAction,
|
|
|
|
// Verification
|
|
verifyTemplatesExist,
|
|
assertTemplates
|
|
};
|