appium-ios-simulator
Version:
iOS Simulator interface for Appium.
163 lines • 6.85 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.NSUserDefaults = void 0;
exports.toXmlArg = toXmlArg;
exports.generateDefaultsCommandArgs = generateDefaultsCommandArgs;
const lodash_1 = __importDefault(require("lodash"));
const xmldom_1 = require("@xmldom/xmldom");
const teen_process_1 = require("teen_process");
const bluebird_1 = __importDefault(require("bluebird"));
const logger_1 = require("./logger");
/**
* Serializes the given value to plist-compatible
* XML representation, which is ready for further usage
* with `defaults` command line tool arguments
*
* @param value The value to be serialized
* @param serialize Whether to serialize the resulting
* XML to string or to return raw HTMLElement instance
* @returns Either string or raw node representation of
* the given value
* @throws {TypeError} If it is not known how to serialize the given value
*/
function toXmlArg(value, serialize = true) {
let xmlDoc = null;
if (lodash_1.default.isPlainObject(value)) {
xmlDoc = new xmldom_1.DOMParser().parseFromString('<dict></dict>', 'text/xml');
for (const [subKey, subValue] of lodash_1.default.toPairs(value)) {
const keyEl = xmlDoc.createElement('key');
const keyTextEl = xmlDoc.createTextNode(subKey);
keyEl.appendChild(keyTextEl);
xmlDoc.documentElement.appendChild(keyEl);
const subValueEl = xmlDoc.importNode(toXmlArg(subValue, false), true);
xmlDoc.documentElement.appendChild(subValueEl);
}
}
else if (lodash_1.default.isArray(value)) {
xmlDoc = new xmldom_1.DOMParser().parseFromString('<array></array>', 'text/xml');
for (const subValue of value) {
const subValueEl = xmlDoc.importNode(toXmlArg(subValue, false), true);
xmlDoc.documentElement.appendChild(subValueEl);
}
}
else if (lodash_1.default.isBoolean(value)) {
xmlDoc = new xmldom_1.DOMParser().parseFromString(value ? '<true/>' : '<false/>', 'text/xml');
}
else if (lodash_1.default.isInteger(value)) {
xmlDoc = new xmldom_1.DOMParser().parseFromString(`<integer>${value}</integer>`, 'text/xml');
}
else if (lodash_1.default.isNumber(value)) {
xmlDoc = new xmldom_1.DOMParser().parseFromString(`<real>${value}</real>`, 'text/xml');
}
else if (lodash_1.default.isString(value)) {
xmlDoc = new xmldom_1.DOMParser().parseFromString(`<string></string>`, 'text/xml');
const valueTextEl = xmlDoc.createTextNode(value);
xmlDoc.documentElement.appendChild(valueTextEl);
}
if (!xmlDoc) {
throw new TypeError(`The defaults value ${JSON.stringify(value)} cannot be written, ` +
`because it is not known how to handle its type`);
}
return serialize
? new xmldom_1.XMLSerializer().serializeToString(xmlDoc.documentElement)
: xmlDoc.documentElement;
}
/**
* Generates command line args for the `defaults`
* command line utility based on the given preference values mapping.
* See https://shadowfile.inode.link/blog/2018/06/advanced-defaults1-usage/
* for more details.
*
* @param valuesMap Preferences mapping
* @param replace Whether to generate arguments that replace
* complex typed values like arrays or dictionaries in the current plist or
* update them (the default settings)
* @returns Each item in the array
* is the `defaults write <plist>` command suffix
*/
function generateDefaultsCommandArgs(valuesMap, replace = false) {
const resultArgs = [];
for (const [key, value] of lodash_1.default.toPairs(valuesMap)) {
try {
if (!replace && lodash_1.default.isPlainObject(value)) {
const dictArgs = [key, '-dict-add'];
for (const [subKey, subValue] of lodash_1.default.toPairs(value)) {
dictArgs.push(subKey, toXmlArg(subValue));
}
resultArgs.push(dictArgs);
}
else if (!replace && lodash_1.default.isArray(value)) {
const arrayArgs = [key, '-array-add'];
for (const subValue of value) {
arrayArgs.push(toXmlArg(subValue));
}
resultArgs.push(arrayArgs);
}
else {
resultArgs.push([key, toXmlArg(value)]);
}
}
catch (e) {
if (e instanceof TypeError) {
logger_1.log.warn(e.message);
}
else {
throw e;
}
}
}
return resultArgs;
}
class NSUserDefaults {
plist;
constructor(plist) {
this.plist = plist;
}
/**
* Reads the content of the given plist file using plutil command line tool
* and serializes it to a JSON representation
*
* @returns The serialized plist content
* @throws {Error} If there was an error during serialization
*/
async asJson() {
try {
const { stdout } = await (0, teen_process_1.exec)('plutil', ['-convert', 'json', '-o', '-', this.plist]);
return JSON.parse(stdout);
}
catch (e) {
throw new Error(`'${this.plist}' cannot be converted to JSON. Original error: ${e.stderr || e.message}`);
}
}
/**
* Updates the content of the given plist file.
* If the plist does not exist yet then it is going to be created.
*
* @param valuesMap Mapping of preference values to update.
* If any of item values are of dictionary type then only the first level dictionary gets
* updated. Everything below this level will be replaced. This is the known limitation
* of the `defaults` command line tool. A workaround for it would be to read the current
* preferences mapping first and merge it with this value.
* @throws {Error} If there was an error while updating the plist
*/
async update(valuesMap) {
if (!lodash_1.default.isPlainObject(valuesMap)) {
throw new TypeError(`plist values must be a map. '${valuesMap}' is given instead`);
}
if (lodash_1.default.isEmpty(valuesMap)) {
return;
}
const commandArgs = generateDefaultsCommandArgs(valuesMap);
try {
await bluebird_1.default.all(commandArgs.map((args) => (0, teen_process_1.exec)('defaults', ['write', this.plist, ...args])));
}
catch (e) {
throw new Error(`Could not write defaults into '${this.plist}'. Original error: ${e.stderr || e.message}`);
}
}
}
exports.NSUserDefaults = NSUserDefaults;
//# sourceMappingURL=defaults-utils.js.map