Created
July 7, 2021 20:11
-
-
Save jord-goldberg/dd3b62fa061186b8ba6ee11461a138ce to your computer and use it in GitHub Desktop.
create a SCIM patch request body based on diff between Javascript objects.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import isEqual from "lodash/isEqual"; | |
import isObject from "lodash/isObject"; | |
const flattenPaths = (value, path = []) => { | |
if (!isObject(value)) { | |
return { [path.join(".")]: value }; | |
} | |
if (Array.isArray(value)) { | |
return value.reduce((cumulative, item) => { | |
cumulative[`${path.join(".")}[value eq "${item.value}"]`] = item; | |
return cumulative; | |
}, {}); | |
} | |
return Object.keys(value).reduce((cumulative, key) => { | |
return { | |
...cumulative, | |
...flattenPaths(value[key], [...path, key]) | |
}; | |
}, {}); | |
}; | |
const getOperationsMap = (flattenedObject, flattenedBase, op) => { | |
return Object.keys(flattenedObject).reduce((operationsMap, path) => { | |
const value = flattenedObject[path]; | |
if (!isEqual(value, flattenedBase[path])) { | |
const operation = { | |
path, | |
op: flattenedBase[path] == null ? op : "replace" | |
}; | |
if (operation.op !== "remove") { | |
operation.value = value; | |
} | |
const addArrayBeginIndex = | |
operation.op === "add" ? path.indexOf("[") : -1; | |
if (addArrayBeginIndex === -1) { | |
operationsMap[path] = operation; | |
} else { | |
const addPath = path.substring(0, addArrayBeginIndex); | |
if (operationsMap[addPath] == null) { | |
operation.path = addPath; | |
operation.value = [operation.value]; | |
operationsMap[addPath] = operation; | |
} else { | |
operationsMap[addPath].value.push(operation.value); | |
} | |
} | |
} | |
return operationsMap; | |
}, {}); | |
}; | |
export default class ScimPatch { | |
constructor(patched, original = {}) { | |
const flatPatched = flattenPaths(patched); | |
const flatOriginal = flattenPaths(original); | |
const removals = getOperationsMap(flatOriginal, flatPatched, "remove"); | |
const additions = getOperationsMap(flatPatched, flatOriginal, "add"); | |
this.schemas = ["urn:ietf:params:scim:api:messages:2.0:PatchOp"]; | |
this.Operations = Object.values({ ...removals, ...additions }); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment