Skip to content

Instantly share code, notes, and snippets.

@FredLackeyOfficial
Last active June 15, 2022 00:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FredLackeyOfficial/c52b3c437af4b7063eecce08e5ce6d5b to your computer and use it in GitHub Desktop.
Save FredLackeyOfficial/c52b3c437af4b7063eecce08e5ce6d5b to your computer and use it in GitHub Desktop.
Merge a simple JSON object with a more complex version to ensure defaults are always included (even if empty).
{
"parentIdentifier": "ROOT",
"name": "",
"protocol": "",
"parameters": {
"port": "",
"read-only": "",
"swap-red-blue": "",
"cursor": "",
"color-depth": "",
"clipboard-encoding": "",
"disable-copy": "",
"disable-paste": "",
"dest-port": "",
"recording-exclude-output": "",
"recording-exclude-mouse": "",
"recording-include-keys": "",
"create-recording-path": "",
"enable-sftp": "",
"sftp-port": "",
"sftp-server-alive-interval": "",
"enable-audio": "",
"security": "",
"disable-auth": "",
"ignore-cert": "",
"gateway-port": "",
"server-layout": "",
"timezone": "",
"console": "",
"width": "",
"height": "",
"dpi": "",
"resize-method": "",
"console-audio": "",
"disable-audio": "",
"enable-audio-input": "",
"enable-printing": "",
"enable-drive": "",
"create-drive-path": "",
"enable-wallpaper": "",
"enable-theming": "",
"enable-font-smoothing": "",
"enable-full-window-drag": "",
"enable-desktop-composition": "",
"enable-menu-animations": "",
"disable-bitmap-caching": "",
"disable-offscreen-caching": "",
"disable-glyph-caching": "",
"preconnection-id": "",
"hostname": "",
"username": "",
"password": "",
"domain": "",
"gateway-hostname": "",
"gateway-username": "",
"gateway-password": "",
"gateway-domain": "",
"initial-program": "",
"client-name": "",
"printer-name": "",
"drive-name": "",
"drive-path": "",
"static-channels": "",
"remote-app": "",
"remote-app-dir": "",
"remote-app-args": "",
"preconnection-blob": "",
"load-balance-info": "",
"recording-path": "",
"recording-name": "",
"sftp-hostname": "",
"sftp-host-key": "",
"sftp-username": "",
"sftp-password": "",
"sftp-private-key": "",
"sftp-passphrase": "",
"sftp-root-directory": "",
"sftp-directory": ""
},
"attributes": {
"max-connections": "",
"max-connections-per-user": "",
"weight": "",
"failover-only": "",
"guacd-port": "",
"guacd-encryption": "",
"guacd-hostname": ""
}
}
const _ = require('cleaner-node');
const { isDefined, isValid: isValidObject } = _.objects;
const { isValid: isValidString } = _.strings;
const EMPTY_OKAY = true;
// #region Strings
const isString = (a, b) => {
if (isValidString(a, EMPTY_OKAY) && isValidString(b, EMPTY_OKAY)) {
return true;
}
if (isValidString(a, EMPTY_OKAY) && !isDefined(b)) {
return true;
}
if (!isDefined(a) && isValidString(b, EMPTY_OKAY)) {
return true;
}
return false;
}
const doString = (a, b) => {
if (isValidString(a) && !isValidString(b)) {
return a;
}
if (!isValidString(a) && isValidString(b)) {
return b;
}
if (!isValidString(a) && !isValidString(b)) {
return '';
}
if (a === b) {
return a;
}
return a;
}
// #endregion
// #region Objects
const isObject = (a, b) => {
if (isValidObject(a) && isValidObject(b)) {
return true;
}
if (isValidObject(a) && !isDefined(b)) {
return true;
}
if (!isDefined(a) && isValidObject(b)) {
return true;
}
return false
}
const doObject = (a, b) => {
if (!isDefined(a)) { return b; }
if (!isDefined(b)) { return a; }
let keys = [];
const aKeys = Object.keys(a).filter(isValidString);
keys.push(...aKeys);
const bKeys = Object.keys(b).filter(isValidString);
keys.push(...bKeys);
keys = _.strings.unique(keys);
keys.sort();
const result = {};
for (let i = 0; i < keys.length; i += 1) {
const key = keys[i];
const aValue = a[key];
const bValue = b[key];
const _isObject = isObject(aValue, bValue);
const _isString = isString(aValue, bValue);
if (_isObject && _isString) {
throw new Error('Multiple types detected.')
}
if (!_isObject && !_isString) {
throw new Error('Unkown type detected.')
}
if (_isObject) {
result[key] = doObject(aValue, bValue);
} else {
result[key] = doString(aValue, bValue);
}
}
return result;
}
// #endregion
const merge = (primary, secondary) => {
const _isObject = isObject(primary, secondary);
const _isString = isString(primary, secondary);
if (_isObject && _isString) {
throw new Error('Multiple types detected.')
}
if (!_isObject && !_isString) {
throw new Error('Unkown type detected.')
}
let result;
if (_isObject) {
result = doObject(primary, secondary);
} else {
result = doString(primary, secondary);
}
return result;
};
module.exports = merge;
{
"parentIdentifier": "ROOT",
"name": "Sample Workstation A",
"protocol": "rdp",
"parameters": {
"enable-full-window-drag": "true",
"hostname": "172.64.16.195",
"password": "Password!",
"security": "rdp",
"port": "3389",
"enable-wallpaper": "true",
"enable-theming": "true",
"enable-font-smoothing": "true",
"username": "CYBERLEARN\\cisaadmin"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment