Files
bodyshop/server/rr/lib

rr-rome-client

A minimal Node.js wrapper for Reynolds & Reynolds (Rome/RIH) STAR ProcessMessage over SOAP, with WS-Security UsernameToken.

Contents

  • Overview
  • Install
  • Supported Node Version
  • Peer / External Dependencies
  • Quick Start
  • Configuration & Environment Variables
  • Client API Methods
  • RRResult Structure
  • Types & IntelliSense
  • Errors & Validation
  • Retry Strategy
  • Debug / Dump Flags
  • Live Test Runner (scripts/run-live.mjs)
  • Bundling & Upload Helper (scripts/bundle-for-upload.mjs)
  • XML Templates & XSDs
  • Logging
  • Build & Development
  • Design Notes / Non-goals
  • License

Overview

rr-rome-client builds and sends STAR XML payloads (Customer, Service Vehicle, Combined Search, Advisors, Parts, BSM Repair Orders) inside a SOAP envelope using the STAR Transport ProcessMessage operation. It applies a WS-Security UsernameToken header and provides:

  • High-level RRClient methods for each supported Rome operation.
  • JSDoc typedefs for all payloads and response shapes (usable in JS and TS).
  • Structured parsing of response status blocks and operation-specific data.
  • Automatic BODId & CreationDateTime generation, with ability to override.
  • Basic input validation and error classification.
  • Exponential backoff + jitter for retryable transport/vendor lock scenarios.

Install

npm i rr-rome-client

(You may also need peer dependencies; see below.)

Supported Node Version

package.json declares "engines": { "node": ">=22.0.0" }. The build targets modern Node 22 features (native ESM, improved performance). Earlier Node versions are not officially supported/tested.

Peer / External Dependencies

Rollup externalizes runtime libraries (they are listed in dependencies but not bundled). Ensure these are available in your environment: Required:

  • axios HTTP transport
  • fast-xml-parser STAR XML parsing
  • mustache XML templating
  • uuid BODId generation Optional (only if you use env loader helpers or live scripts):
  • dotenv
  • dotenv-expand

Install (versions per package.json):

npm install axios@^1.7.7 fast-xml-parser@^4.5.0 mustache@^4.2.0 uuid@^9.0.1
# Optional env loader
npm install dotenv@^17.2.3 dotenv-expand@^12.0.3

TypeScript users (optional):

npm install -D @types/node

Browser bundling is not officially supported; you would need polyfills for core modules if attempting.

Quick Start

import { RRClient } from 'rr-rome-client';
import { loadEnv } from 'rr-rome-client/src/util/config.js'; // optional helper

// Load routing & credentials from environment variables (see below)
const { baseUrl, username, password, routing } = loadEnv();

const client = new RRClient({ baseUrl, username, password });

// Minimal createRepairOrder example
const result = await client.createRepairOrder({
  customerNo: '12345',
  departmentType: 'S', // DeptType
  vin: '1ABCDEF2GHIJ34567',
  outsdRoNo: 'EXT-RO-99'
}, { routing });

if (result.success) {
  console.log('RO status:', result.data); // {status, date, time, outsdRoNo, dmsRoNo, errorMessage}
} else {
  console.error('Failure:', result.statusBlocks?.transaction);
}

Configuration & Environment Variables

You can manually provide configuration or use the helper loadEnv(env) in src/util/config.js.

Recognized environment variables:

  • RR_BASE_URL SOAP endpoint URL (required)
  • RR_USERNAME WS-Security UsernameToken username (required)
  • RR_PASSWORD WS-Security UsernameToken password (required)
  • RR_DEALER_NUMBER DealerNumber for Destination (required per call)
  • RR_STORE_NUMBER StoreNumber (optional)
  • RR_AREANUMBER AreaNumber (optional)

Example .env:

RR_BASE_URL=https://rome.example.com/soap
RR_USERNAME=integratorUser
RR_PASSWORD=superSecret
RR_DEALER_NUMBER=1234
RR_STORE_NUMBER=01
RR_AREANUMBER=1

loadEnv() returns { baseUrl, username, password, routing: { dealerNumber, storeNumber, areaNumber } }.

Per-call options object shape (CallOptions):

{
  routing: { dealerNumber: '1234', storeNumber?: '01', areaNumber?: '1' },
  envelope?: { bodId?, creationDateTime?, sender?: { component?, task?, referenceId? } }
}

If omitted, RRClient auto-generates bodId (UUID) and creationDateTime when sending.

Client API Methods

Each method returns a Promise<RRResult<T>> where T is operation-specific data (or array). success is true for vendor SUCCESS and NO_MATCH results; FAIL triggers an RRVendorStatusError exception before a RRResult is returned.

All methods require opts.routing.dealerNumber.

combinedSearch(payload: CombinedSearchQuery, opts)

Search customer + service vehicle combinations by exactly one criterion: phone | license | vin | name | nameRecId | stkNo plus optional make, model, year, maxResults (capped at 50). Minimal:

const res = await client.combinedSearch({ kind: 'vin', vin: '12345' }, { routing });
res.data; // Array<CombinedSearchBlock>

Errors: Throws RRValidationError if missing or multiple criteria.

insertCustomer(payload: InsertCustomerPayload, opts)

Insert a customer record. Required: lastName (or customerName). If individual (ibFlag='I' or inferred by presence of firstName), then firstName required.

const res = await client.insertCustomer({ firstName: 'Jane', lastName: 'Doe', phones:[{number:'5551234567'}] }, { routing });
res.data; // { dmsRecKey, status, statusCode }

updateCustomer(payload: UpdateCustomerPayload, opts)

Update existing customer by nameRecId plus required ibFlag. Other fields optional.

const res = await client.updateCustomer({ nameRecId:'998877', ibFlag:'I', lastName:'Doe' }, { routing });

insertServiceVehicle(payload: InsertServiceVehiclePayload, opts)

Insert a service vehicle linked to a customer. Required: vin, vehicleServInfo.customerNo.

const res = await client.insertServiceVehicle({
  vin:'1HGCM82633A004352',
  vehicleServInfo:{ customerNo:'12345' }
}, { routing });
res.data; // { status, statusCode }

getAdvisors(payload: GetAdvisorsParams, opts)

Fetch advisors for a department. Department values normalized: S/P/B or long names.

const res = await client.getAdvisors({ department:'SERVICE' }, { routing });
res.data; // AdvisorRow[]

createRepairOrder(payload: CreateRepairOrderPayload, opts)

Required: customerNo, departmentType, vin, outsdRoNo. Advisor optional. Complex nested labor/parts/misc blocks supported via payload.

const res = await client.createRepairOrder({
  customerNo:'12345', departmentType:'S', vin:'1ABCDEF2GHIJ34567', outsdRoNo:'EXT-RO-99'
}, { routing });
res.data; // { status, date, time, outsdRoNo, dmsRoNo, errorMessage }

updateRepairOrder(payload: UpdateRepairOrderPayload, opts)

Required: finalUpdate ('Y'|'N'), outsdRoNo. May include roNo and nested sections.

const res = await client.updateRepairOrder({ finalUpdate:'N', outsdRoNo:'EXT-RO-99' }, { routing });

getParts(payload: GetPartsParams, opts)

Required: roNumber (internal ERA RO number).

const res = await client.getParts({ roNumber:'938275' }, { routing });
res.data; // PartRow[]

Payload Schema Reference

Comprehensive field-level summary sourced from src/types.js, operation builders, and validation logic. Types reflect accepted JS types (string|number where applicable). Constraints list enumerations, inference rules, and validation notes. Required = must be supplied by caller (or inferred automatically). Optional fields omitted become absent in generated XML.

CombinedSearchQuery

Only one criterion permitted; maxResults capped at 50.

Field Type Required Constraints / Notes
kind 'phone' 'license' 'vin'
phone string|number|{phone:string} Conditionally (if kind==='phone') Value mapped to <Phone Num="..."/>
license string|number|{license:string} Conditionally (kind==='license') Value mapped to <LicenseNum LicNo="..."/>
vin string|number|{vin:string} Conditionally (kind==='vin') Value mapped to <PartVIN Vin="..."/> (partial VIN allowed)
name {fname,lname,mname} or {name} Conditionally (kind==='name') Either FullName triple or LName only; must supply all three for FullName
nameRecId string|number|{custId:string} {nameRecId:string} Conditionally (kind==='nameRecId')
stkNo string|number|{stkNo:string} Conditionally (kind==='stkNo') Emits <StkNo VehId="..."/>
maxResults number No Capped at 50 (default 50) -> MaxRecs attribute
make string No Defaults 'ANY' -> VehData MakePfx
model string|number No Defaults 'ANY' -> VehData Model
year string|number No Defaults 'ANY' -> VehData Year

InsertCustomerPayload

ibFlag inferred as 'I' if firstName present, else 'B'. Business requires lastName / customerName; individual requires firstName + last name.

Field Type Required Constraints / Notes
ibFlag 'I' 'B' Auto / For update must supply
customerType 'R' 'W' 'I'
createdBy string No Optional CreatedBy attribute
customerName string Conditional Alias for lastName when business
lastName string Yes (unless customerName provided) Required base name; sanitized to A-Z0-9 space
firstName string Required when ibFlag='I' Sanitized; required for individuals
midName string No Sanitized
salut string No Sanitized
suffix string No Sanitized
addresses CustomerAddress[] No Each entry requires line1; Type defaults 'P'
phones CustomerPhone[] No Each entry requires number; Type defaults 'H'
emails CustomerEmail[] No First entry used -> <Email MailTo="..."/>
personal.gender 'M' 'F' 'U'
personal.otherName string No Sanitized alnum/space
personal.anniversaryDate string No Included if non-empty
personal.employerName string No Sanitized
personal.employerPhone string No Raw string
personal.occupation string No Sanitized
personal.optOut string No Pass-through
personal.optOutUse string No Pass-through
personal.birthDates[].type 'P' 'S' No
personal.birthDates[].date string Conditional Included only if non-empty
personal.ssns[].type 'P' 'S' No
personal.ssns[].ssn string Conditional Included only if non-empty
personal.driver.type 'P' 'S' No
personal.driver.licenseNumber string Conditional Required to emit DriverInfo
personal.driver.licenseState string No Optional
personal.driver.licenseExpDate string No Optional
personal.children[].name string No Sanitized; optional list
dms.taxExemptNum string No Optional
dms.salesTerritory string No Optional
dms.deliveryRoute string No Optional
dms.salesmanNum string No Optional
dms.lastContactMethod string No Optional
dms.followups[].type string Conditional Must have both type & value
dms.followups[].value string Conditional Must have both type & value

UpdateCustomerPayload

Extends InsertCustomerPayload plus:

Field Type Required Constraints
nameRecId string|number Yes Required identifier
ibFlag 'I' 'B' Yes

InsertServiceVehiclePayload

Field Type Required Constraints / Notes
vin string Yes Must be provided
modelDesc string No Optional attribute
carline string No Optional attribute
extClrDesc string No Optional attribute
intClrDesc string No Optional attribute
trimDesc string No Optional attribute
bodyStyle string No Optional attribute
engineDesc string No Optional attribute
transDesc string No Optional attribute
year string|number No Emits <Year> element if present
odometer string|number No Emits <Odometer>
odometerUnits string No Emits <OdometerUnits>
vehicleDetail.licNo string No Emits <VehicleDetail LicNo="..."/>
vehicleServInfo.customerNo string|number Yes Required; becomes CustomerNo attribute
vehicleServInfo.salesmanNo string|number No Optional element
vehicleServInfo.inServiceDate string|number No Optional element
vehicleServInfo.mileage string|number No Optional element
vehicleServInfo.teamCode string No Optional element
vehicleServInfo.vehExtWarranty.contractNumber string Conditional Included if any warranty field present
vehicleServInfo.vehExtWarranty.expirationDate string Conditional "" excluded
vehicleServInfo.vehExtWarranty.expirationMileage string|number Conditional "" excluded
vehicleServInfo.advisor.contactInfo.nameRecId string|number No Advisor block included only if provided

CreateRepairOrderPayload

Field Type Required Constraints / Notes
customerNo string|number Yes CustNo
departmentType string|number Yes DeptType
vin string Yes Vin
outsdRoNo string|number Yes External RO identifier
advisorNo string|number No AdvNo
tagNo string|number No TagNo
mileageIn string|number No MileageIn
roComment string No <RoCommentInfo RoComment="..."/>
estimate.parts string|number No EstPartsAmt
estimate.labor string|number No EstLaborAmt
estimate.total string|number No EstTotalAmt
tax.payType 'All' 'Cust' 'Intr'
tax.taxCode string No TaxCode
tax.txblGrossAmt string|number No TxblGrossAmt
tax.grossTaxAmt string|number No GrossTaxAmt
rolabor.ops[].opCode string No Optional
rolabor.ops[].jobNo string|number No Optional
rolabor.ops[].custPayTypeFlag string No Freeform (not validated)
rolabor.ops[].warrPayTypeFlag string No Freeform
rolabor.ops[].intrPayTypeFlag string No Freeform
rolabor.ops[].custTxblNtxblFlag 'T' 'N' No
rolabor.ops[].warrTxblNtxblFlag 'T' 'N' No
rolabor.ops[].intrTxblNtxblFlag 'T' 'N' No
rolabor.ops[].vlrCode string No Optional
rolabor.ops[].bill.payType 'All' 'Cust' 'Intr'
rolabor.ops[].bill.jobTotalHrs string|number No Optional
rolabor.ops[].bill.billTime string|number No Optional
rolabor.ops[].bill.billRate string|number No Optional
rolabor.ops[].ccc.cause string No Optional
rolabor.ops[].ccc.complaint string No Optional
rolabor.ops[].ccc.correction string No Optional
rolabor.ops[].amount.payType 'All' 'Cust' 'Intr'
rolabor.ops[].amount.amtType string No Optional
rolabor.ops[].amount.custPrice string|number No Optional
rolabor.ops[].amount.totalAmt string|number No Optional
ropart.jobs[].opCode string No Optional
ropart.jobs[].jobNo string|number No Optional
ropart.jobs[].lines[].partNo string No Optional
ropart.jobs[].lines[].partNoDesc string No Optional
ropart.jobs[].lines[].partQty string|number No Emits QtyOrd
ropart.jobs[].lines[].sale string|number No Sale
ropart.jobs[].lines[].cost string|number No Cost
ropart.jobs[].lines[].addDeleteFlag string No AddDeleteFlag
rogg.ops[].lines[].breakOut string No Optional
rogg.ops[].lines[].itemType 'G' 'P' 'S'
rogg.ops[].lines[].itemDesc string No Optional
rogg.ops[].lines[].custQty string|number No Optional
rogg.ops[].lines[].warrQty string|number No Optional
rogg.ops[].lines[].intrQty string|number No Optional
rogg.ops[].lines[].custPayTypeFlag string No Optional
rogg.ops[].lines[].warrPayTypeFlag string No Optional
rogg.ops[].lines[].intrPayTypeFlag string No Optional
rogg.ops[].lines[].custTxblNtxblFlag 'T' 'N' No
rogg.ops[].lines[].warrTxblNtxblFlag 'T' 'N' No
rogg.ops[].lines[].intrTxblNtxblFlag 'T' 'N' No
rogg.ops[].lines[].amount.payType 'All' 'Cust' 'Intr'
rogg.ops[].lines[].amount.amtType string No Optional
rogg.ops[].lines[].amount.custPrice string|number No Optional
rogg.ops[].lines[].amount.dlrCost string|number No Optional
romisc.ops[].lines[].miscCode string No Optional
romisc.ops[].lines[].custPayTypeFlag string No Optional
romisc.ops[].lines[].warrPayTypeFlag string No Optional
romisc.ops[].lines[].intrPayTypeFlag string No Optional
romisc.ops[].lines[].custTxblNtxblFlag 'T' 'N' No
romisc.ops[].lines[].warrTxblNtxblFlag 'T' 'N' No
romisc.ops[].lines[].intrTxblNtxblFlag 'T' 'N' No
romisc.ops[].lines[].codeAmt string|number No Optional

UpdateRepairOrderPayload

Adds required finalUpdate and supports most Create fields + mileageOut.

Field Type Required Constraints / Notes
finalUpdate 'Y' 'N' Yes
outsdRoNo string|number Yes External RO identifier (validation requires present)
roNo string|number No Optional internal RoNo
mileageOut string|number No MileageOut
(other fields) see CreateRepairOrderPayload Conditional Same validations apply

GetAdvisorsParams

Field Type Required Constraints / Notes
department 'S' 'P' 'B'
advisorNumber string|number No Optional filter
maxResults number Ignored Not in XSD (builder ignores)

GetPartsParams

Field Type Required Constraints / Notes
roNumber string|number Yes Required; becomes <RoInfo RoNumber="..."/>

Common Routing & Envelope Fields

Field Type Required Constraints / Notes
routing.dealerNumber string Yes Required for all requests (Destination)
routing.storeNumber string No Optional Destination StoreNumber
routing.areaNumber string No Optional Destination AreaNumber
envelope.bodId string Auto UUID generated if omitted
envelope.creationDateTime Date|string Auto Uses current time; formatted without milliseconds
envelope.sender.component string No Defaults 'Rome' if omitted
envelope.sender.task string No Op-specific defaults (e.g. 'CU','SV','BSMRO','CVC','RCT')
envelope.sender.referenceId string No Op-specific defaults ('Insert','Update','Query')

AdvisorRow (response convenience)

Field Type Notes
advisorId string|number|undefined AdvisorNumber attribute
firstName string|undefined FirstName attribute
lastName string|undefined LastName attribute
department 'S' 'P'

PartRow (response convenience)

Field Type Notes
partNumber string|undefined PartNumber
partDescription string|undefined PartDescription
quantityOrdered string|number|undefined QuantityOrdered
quantityShipped string|number|undefined QuantityShipped
price string|number|undefined Price
cost string|number|undefined Cost
processedFlag string|undefined ProcessedFlag
addOrDelete string|undefined AddOrDelete

CombinedSearch Response Shapes

Hierarchical breakdown of the parsed array returned under RRResult.data for combinedSearch (each entry is a CombinedSearchBlock). Attribute-centric; absent fields are simply omitted.

CombinedSearchBlock

Field Type Notes
NameContactId CombinedSearchNameContactId Customer name/contact composite
ServVehicle CombinedSearchServVehicle[] Zero or more service vehicle blocks
Message CombinedSearchMessage[] Optional informational messages

NameContactId

Field Type Notes
NameId CombinedSearchNameId Includes identifiers & individual/business name choice
Address Object[] Each has address-related attributes (lines, city, state, zip, etc.)
ContactOptions Object[] Arbitrary contact option attributes as present
Phone Object[] Each phone entry carries attributes like Type, Num, Ext
Email Object[] Each email entry carries attributes (MailTo, etc.)

NameId

Field Type Notes
NameRecId string|number Identifier used for subsequent operations
IBFlag 'I' 'B'
IndName Object Present for individual: attributes like FName, LName, MName
BusName Object Present for business: attributes like Name (business name)

ServVehicle (CombinedSearchServVehicle)

Field Type Notes
Vehicle CombinedSearchVehicle VIN + descriptive attributes
VehicleServInfo CombinedSearchVehicleServInfo Service info attributes & nested warranty/advisor/comments

Vehicle (CombinedSearchVehicle)

Attribute Type Notes
Vin string Vehicle identification number (may be partial in search results)
VehicleMake string Make code / description
VehicleYr string|number Year
MdlNo string Model code
ModelDesc string Model description
Carline string Carline description
ExtClrDesc string Exterior color
IntClrDesc string Interior color
MakeName string Full make name
VehicleDetail.LicNo string License plate (if present)

VehicleServInfo (CombinedSearchVehicleServInfo)

Attribute Type Notes
CustomerNo string|number Linked customer number
SalesmanNo string|number Optional salesman number
InServiceDate string|number Date vehicle placed in service
Mileage string|number Current mileage
TeamCode string Team/department code
VehExtWarranty.ContractNumber string Extended warranty contract number
VehExtWarranty.ExpirationDate string Warranty expiration date
VehExtWarranty.ExpirationMileage string|number Warranty mileage limit
Advisor.ContactInfo.NameRecId string|number Advisor reference (if present)
VehServComments[] string[] Freeform service comments (array of raw text)

Message (CombinedSearchMessage)

Field Type Notes
MessageNo string|number Optional message number (if provided)
Text string Message text content

CustomerResponseData

Returned as result.data for insertCustomer / updateCustomer.

Field Type Notes
dmsRecKey string|undefined DMS record key identifier (if provided in TransStatus)
status string|undefined Vendor status string
statusCode string|undefined Vendor status code

ServiceVehicleResponseData

Returned as result.data for insertServiceVehicle.

Field Type Notes
status string|undefined GenTransStatus Status
statusCode string|undefined GenTransStatus StatusCode

RepairOrderData

Returned as result.data for createRepairOrder / updateRepairOrder (parsed from RoRecordStatus).

Field Type Notes
status string|undefined RoRecordStatus Status
date string|undefined Date attribute/text
time string|undefined Time attribute/text
outsdRoNo string|undefined External RO number (OutsdRoNo)
dmsRoNo string|undefined Internal DMS RO number (DMSRoNo)
errorMessage string|undefined ErrorMessage if provided

RRResult Structure

Each successful call resolves to:

interface RRResult<T> {
  success: boolean; // SUCCESS or NO_MATCH
  data?: T;         // op-specific parsed convenience data
  parsed: any;      // entire parsed STAR payload root
  xml: { request: string; response: string }; // raw SOAP envelopes
  statusBlocks?: { transaction?: {status,statusCode,message}; roRecord?: {status,date,time,outsdRoNo,dmsRoNo,errorMessage} };
  applicationArea?: any; // raw ApplicationArea node
}

Use statusBlocks.transaction for generic status; data for normalized op output.

Convenience data refers to the distilled, operation-specific subset placed on RRResult.data by a dedicated postParse function (e.g., extracting only RoRecordStatus identifiers or customer DMS keys). It is intentionally smaller and flatter than RRResult.parsed, which contains the entire parsed STAR payload tree. Use data for common identifiers/status checks; fall back to parsed when you need full raw XML-derived detail.

Types & IntelliSense

Rich JSDoc typedefs ship with the package.

  • ESM: import { RRClient } from 'rr-rome-client'; optionally import 'rr-rome-client/types' to prompt editor indexing.
  • CJS: const { RRClient } = require('rr-rome-client'); require('rr-rome-client/types');

Selected typedef categories (see src/types.js):

  • Routing / Envelope / CallOptions
  • Customer / Service Vehicle / Repair Order payload blocks
  • Combined Search structures
  • Advisor and Parts row shapes
  • RRResult<T> generic helper

The build also emits a TypeScript declaration bundle (dist/types/index.d.ts) generated via tsconfig.types.json (processing only src/types.js).

Errors & Validation

Three custom error classes (src/errors.js):

  • RRTransportError Non-2xx HTTP status or network failure; meta.status / meta.body may be attached.
  • RRVendorStatusError Vendor FAIL status (non-success & not NO_MATCH). Includes meta.status (raw status object) and full response XML. retryable may be set (currently determined by vendor message lock wording or explicit flag).
  • RRValidationError Input validation failures (missing required fields, invalid enumeration values, etc.).

Enumerated validations (examples):

  • Customer: ibFlag, required firstName if individual, allowed customerType values.
  • Service Vehicle: mandatory vin and vehicleServInfo.customerNo.
  • Repair Orders: required header fields; enumerations for tax pay type (All|Cust|Intr|Warr), taxable flags (T|N), item types (G|P|S|F).

Error Handling Example:

try {
  await client.createRepairOrder(/* ... */);
} catch (e) {
  if (e instanceof RRVendorStatusError) {
    console.error('Vendor fail', e.meta.status);
  } else if (e instanceof RRValidationError) {
    console.error('Bad input', e.message);
  } else if (e instanceof RRTransportError) {
    console.error('HTTP/Network', e.message, e.meta.status);
  } else {
    console.error('Unexpected', e);
  }
}

Retry Strategy

withBackoff(fn, {max, logger}) (used internally) retries on:

  • Transport/network errors (RRTransportError).
  • Vendor status errors indicating record lock/in use (message matching /lock|in use|record.*busy/i) or explicit retryable flag. Backoff: exponential starting at 400ms, capped at 10s, plus up to 250ms jitter. Configure via new RRClient({ retries: { max: 5 }, ... }).

Debug / Dump Flags

Set these environment variables to inspect request/response internals:

  • RR_DEBUG Enables debug logging (defaultLogger.debug).
  • RR_DUMP_ENVELOPE=1 Prints outgoing SOAP envelope.
  • RR_DUMP_XML=1 Prints full response XML.
  • RR_DUMP_STATUS=1 Logs parsed status blocks.
  • RR_DUMP_APPLICATION=1 Logs raw ApplicationArea block.
  • RR_DUMP_DATA=1 Logs result.data (postParse convenience output).

Live Test Runner (scripts/run-live.mjs)

Provides curated integration tests against a live Rome system using Vitest. Loads .env then .env.local (override). Usage:

node scripts/run-live.mjs <test> [flags] [-- ...vitestArgs]

Available tests (see script for full list & flags):

  • combinedSearch VIN or phone search.
  • insertCustomer, updateCustomer Customer record operations (use --write to enable live writes).
  • insertServiceVehicle Add vehicle (requires or discovers customer).
  • getAdvisors Advisor listing by department.
  • createRepairOrder, updateRepairOrder BSM RO operations.
  • getParts Retrieve RO parts lines.
  • all Run all sequentially.

Common flags:

  • --dumpRR_DUMP_ENVELOPE
  • --writeRR_LIVE_WRITES (enables writes)
  • Operation-specific flags map to RR_TEST_* env variables (see script comments for details).
  • Arbitrary env: --set=KEY=VALUE.

Example:

node scripts/run-live.mjs createRepairOrder --write --dump --customerNo=1134485 --vin=1ABCDEF2GHIJ34567 --ro=BSM123

Bundling & Upload Helper (scripts/bundle-for-upload.mjs)

Creates text bundles of project files for transport/support purposes.

  • Includes key directories (src/, test/, schemas/) and specific root files.
  • Excludes large/irrelevant directories (node_modules, dist, etc.).
  • Options: --max-bytes, --pattern=globish, --with-env (include .env caution), --list-only. Generates bundles/bundle-<uuid>-N.txt with file boundary markers.

XML Templates & XSDs

Templates reside in src/templates/templateMap.js using Mustache. Each operation builder renders a STAR root element plus ApplicationArea. XSD files (under schemas/) accompany operations:

  • Customer Insert/Update: rey_RomeCustomerInsertReq.xsd, rey_RomeCustomerUpdateReq.xsd
  • Service Vehicle Insert: rey_RomeServVehicleInsertReq.xsd
  • Combined Search: rey_RomeCustServVehCombReq.xsd
  • Advisors: rey_RomeGetAdvisorsReq.xsd
  • Parts: rey_RomeGetPartsReq.xsd
  • Repair Orders Create/Update: rey_RomeCreateBSMRepairOrderReq.xsd, rey_RomeUpdateBSMRepairOrderReq.xsd Response XSDs also present for repair orders and others.

Builders attach an xsdFilename hint and elementName; no runtime XSD validation is performed (the project does not contain a validation module beyond these references).

Logging

Default logger (src/logger.js): logs to console via info, warn, error; debug gated by RR_DEBUG. Provide a custom logger with matching method names in RRClientConfig:

const logger = { info:()=>{}, warn:()=>{}, error:console.error, debug:()=>{} };
const client = new RRClient({ baseUrl, username, password, logger });

Build & Development

Scripts:

  • npm run build Rollup builds dist/index.cjs & dist/index.mjs, copies JSDoc types (scripts/postbuild-copy-types.mjs), emits .d.ts (via tsc -p tsconfig.types.json).
  • npm test Runs unit tests (vitest with vitest.config.unit.mjs).
  • npm run bundle Invoke bundle creation (see above).
  • npm run live:<op> Convenience commands mapping to scripts/run-live.mjs (e.g. npm run live:getParts).

Rollup configuration (rollup.config.mjs):

  • Externalizes Node core modules and listed dependencies.
  • Applies terser minification (2 passes, hoisting) for compact output.
  • Generates both CJS and ESM entrypoints.

Tree-shaking is enabled (treeshake.moduleSideEffects = false). sideEffects: false in package.json allows downstream bundlers to drop unused exports.

Design Notes / Non-goals

  • WS-Security: Implements only UsernameToken with password type Text or Digest (configurable via wssePasswordType). No nonce or timestamp included.
  • Idempotency: bodId generated per request unless provided; ensureBodAndDates centralizes creation.
  • Parsing: Focused on extracting status and op-specific identifiers; raw parsed STAR tree still accessible via result.parsed.
  • Status Handling: Treats NO_MATCH (codes like 2 or 213) as non-error with success=true so callers can differentiate empty results from failures.
  • Validation: Enforces only practical minimum & enumerations; does not attempt full schema compliance.
  • No automatic fetch transport fallback yet (axios chosen for reliability). You can replace postSoap if providing a compatible function returning raw response text and error semantics.
  • No built-in XSD validator; XSDs present for reference only.