@stordata/vsphere-soapify
Version:
A NodeJS abstraction layer for the vSphere SOAP API
93 lines (75 loc) • 2.35 kB
JavaScript
;
module.exports = class Instance {
constructor(client) {
/**
* We manually define the property so that it is not enumerated.
* This avoids JS -> XML pollution because Instance objects get serialized as SOAP requests
*/
Object.defineProperty(this, 'client', { value: client });
}
parse(value, type) {
return this.client.getParser().parse(value, type);
}
toXmlObject() {
const object = {
attributes: {
'xsi:type': this.constructor.name
}
};
for (const [key, value] of Object.entries(this)) {
object[key] = this.xmlValue(value);
}
return object;
}
xmlValue(value) {
if (typeof value === 'object' && 'toXmlObject' in value) {
return value.toXmlObject();
}
if (Array.isArray(value)) {
return value.map(item => this.xmlValue(item));
}
if (value instanceof Date) {
return value.toISOString();
}
return value;
}
fill(source) {
if (source) {
for (const [key, type] of Object.entries(this.constructor.mappings())) {
if (source[key] !== undefined) {
this[key] = this.parse(source[key], type);
}
}
}
}
static mappings() {
return {};
}
/**
* Used to avoid requesting all sub-properties of an object.
* See http://www.doublecloud.org/2010/04/invalid-property-a-trick-with-vsphere-propertycollector/ for a nice explanation
* of why this might happen to you for some entities...
* As a general rule, set this to `true` for inherited Data Objects (i.e.: those that don't directly extend {@link DynamicData})
*
* @returns {Boolean} Whether the library should request this object in full, or ask for all sub-properties
*/
static requestFully() {
return false;
}
static properties(...prefixes) {
return Object.entries(this.mappings()).reduce((properties, [key, value]) => {
if (typeof value === 'string' || /^ArrayOf/.test(value.name) || value.requestFully()) {
properties.push([...prefixes, key].join('.'));
} else {
properties.push(...value.properties(...prefixes, key));
}
return properties;
}, []);
}
static get ArrayOf() {
const parent = this;
return class extends this {
static get name() { return `ArrayOf${parent.name}`; }
};
}
};