Skip to content

Instantly share code, notes, and snippets.

@bramblex
Created June 11, 2020 12:53
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 bramblex/6c8470e05f392a81ffcc64f983ed9997 to your computer and use it in GitHub Desktop.
Save bramblex/6c8470e05f392a81ffcc64f983ed9997 to your computer and use it in GitHub Desktop.
type CommandFunc = (
target: any,
key: string,
value: any,
commands: Commands,
) => object;
type Commands = {
[key: string]: CommandFunc;
};
const defaultCommands: Commands = {
default: (target, key: string, value: any) => {
return { [key]: value };
},
merge: (target, key, modifier, commands) => {
return { [key]: modifyObject(target[key] || {}, modifier, commands) };
},
delete: () => ({}),
};
function splitKey(rawKey: string): [string, string] {
const [, command, key] = /^\$(\w+)__(\w+)$/.exec(rawKey) || [
'',
'default',
rawKey,
];
return [command, key];
}
export function modifyObject(
target: object,
modifier: object,
commands: Commands = {},
) {
const finalCommands = { ...defaultCommands, ...commands };
const result = { ...target };
for (const [rawKey, value] of Object.entries(modifier)) {
const [command, key] = splitKey(rawKey);
const commandFunc = finalCommands[command];
if (!commandFunc) {
throw new Error(`Unexpected Command: '${command}'`);
}
const patch = commandFunc(target, key, value, finalCommands);
Object.assign(result, patch);
if (!patch.hasOwnProperty(key)) {
delete result[key];
}
}
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment