import Node from 'type/node';
import SystemId from 'system/enum/id';
import ChangeNode from 'type/node/change';
import FieldValue from 'type/field-value';
import ChangeStatus from 'enum/change-status';
import KeyGenerator from 'utility/key-generator';
import buildNodeUrl from 'utility/build-node-url';
import getNodeParameters from 'utility/get-node-parameters';
import Operation, { OperationInput } from 'operation';
interface Input extends OperationInput {
readonly node: Node;
readonly field: string;
readonly old_value: FieldValue;
readonly new_value: FieldValue;
}
class ChangeFieldOperation extends Operation {
protected async performInternal(): Promise {
await this.addChangeNode();
return this.performFieldChange();
}
private async addChangeNode(): Promise {
const change_node = this.buildChangeNode();
const repository = this.getRepository();
await repository.storeNode(change_node);
const node = this.getNode();
const parameters = getNodeParameters(node.url);
const old_value = node.changes;
const new_value = [...old_value, change_node.url];
// TODO: Use enum for 'changes' below
await repository.setField(parameters, 'changes', old_value, new_value);
}
private performFieldChange(): Promise {
const node = this.getNode();
const field_key = this.getFieldKey();
const parameters = getNodeParameters(node.url);
const repository = this.getRepository();
const old_value = this.getOldValue();
const new_value = this.getNewValue();
return repository.setField(parameters, field_key, old_value, new_value);
}
private buildChangeNode(): ChangeNode {
const url = this.getChangeUrl();
const type_url = this.getChangeTypeUrl();
const hostname = this.getHostname();
const status = ChangeStatus.APPROVED;
const field = this.getFieldKey();
const old_value = this.getOldValue();
const new_value = this.getNewValue();
const creator = `${hostname}/account/anonymous`;
const approver = `${hostname}/account/system`;
const changes: string[] = [];
const permissions: string[] = [];
const created_at = Date.now();
const updated_at = created_at;
return {
url,
type: type_url,
status,
field,
old_value,
new_value,
approver,
creator,
created_at,
updated_at,
changes,
permissions
};
}
private getChangeUrl(): string {
const hostname = this.getHostname();
const type_id = SystemId.CHANGE_TYPE;
const id = KeyGenerator.id();
return buildNodeUrl(hostname, {
type_id,
id
});
}
private getChangeTypeUrl(): string {
const hostname = this.getHostname();
const type_id = SystemId.GENERIC_TYPE;
const id = SystemId.CHANGE_TYPE;
return buildNodeUrl(hostname, {
type_id,
id
});
}
private getNode(): Node {
const input = this.getInput();
return input.node;
}
private getFieldKey(): string {
const input = this.getInput();
return input.field;
}
private getOldValue(): FieldValue {
const input = this.getInput();
return input.old_value;
}
private getNewValue(): FieldValue {
const input = this.getInput();
return input.new_value;
}
}
export default ChangeFieldOperation;