Files
Xen-Orchestra-xen-orchestra…/@xen-orchestra/vmware-explorer/soap/normalize.mjs
Florent BEAUCHAMP 3bf50c38ee fix(vmware-explorer): fixes omnibus (#10363)
This branch is a reliability overhaul of the ESXi/vSphere source side of V2V, plus a scope reduction of the package. The SOAP plumbing is rewritten:

    VimClient wraps @vates/node-vsphere-soap in a promise API with one emitter per call (no more cross-talk between concurrent calls, no listener leak) and a pTimeout;
    vim25 faults are now parsed (_parseFault.mjs) so callers get a real fault type instead of task execution failed;
    the library no longer throws from async callbacks (which killed xo-server) and its beforeExit logout hook is per-client instead of removeAllListeners.
    Request specs are built in explicit schema order (soap/specs.mjs) with xsi:type, and property values are normalized (soap/normalize.mjs) so search() and the new #retrieveProperty share one shape.
    search() now paginates, cancels the retrieval and destroys the container view.
    Datastore HTTP downloads get session-cookie reuse, retry with jittered backoff, a headers-only timeout, and range-honouring validation.
    Task waiting polls with backoff and per-operation timeouts (6 h for snapshot consolidation).
    nbdkit servers are memoized by a key that includes the export options, the readiness wait races the process death instead of sleeping 2 s
    the password file is 0600 and unlinked
    the thumbprint is read over TLS in-process instead of two openssl spawns.
    The old VHD-over-datastore readers (VhdEsxi*, Datastore*, openDeltaVmdkAsVhd) are deleted, hence the majo, rleaving the vddk/NBD path with a COWD grain-directory parser as data-map fallback.
    ~1.7k lines of unit tests are added.
2026-09-11 17:36:38 +02:00

41 lines
1.2 KiB
JavaScript

/**
* The SOAP library returns a single element as the element itself, and a repeated one as an array.
*
* @param {unknown} value
* @returns {Array<unknown>} - an empty array when the element is absent
*/
export function asArray(value) {
if (value === undefined || value === null) {
return []
}
return Array.isArray(value) ? value : [value]
}
/**
* Unwraps a value returned by the SOAP library.
*
* A value carrying attributes is wrapped: a scalar becomes `{ $value, attributes }` and a complex
* type gets an extra `attributes` property. Both are noise for the callers, which only care about
* the value itself.
*
* The normalization is intentionally shallow: the library only wraps the elements which do carry
* attributes, so nested scalars are already plain values.
*
* @param {unknown} value
* @returns {unknown}
*/
export function normalizeSoapValue(value) {
if (value === null || typeof value !== 'object') {
return value
}
// a falsy scalar ( '', 0, false ) is still a value
if ('$value' in value) {
return value.$value
}
if ('attributes' in value) {
const { attributes, ...rest } = value
return rest
}
return value
}