import TypeNode from 'type/type-node'; import SystemId from 'system/enum/id'; import DraftField from 'type/draft-field'; import buildNodeUrl from 'utility/build-node-url'; import FetchNodeOperation from 'operation/fetch-node'; import AddValueToListOperation from 'operation/add-value-to-list'; import Operation, { OperationInput } from 'operation'; interface Input extends OperationInput { readonly id: string; readonly fields: DraftField[]; } class CreateTypeOperation extends Operation { protected async performInternal(): Promise { const node = await this.buildNode(); const repository = this.getRepository(); const persisted_node = await repository.storeNode(node); const type_node = persisted_node as TypeNode; await this.addInstanceToGenericType(type_node); return type_node; } private async buildNode(): Promise { const type_node = this.getTypeNode(); const permissions = this.buildPermissions(); let node = { ...type_node, permissions }; const draft_fields = this.getDraftFields(); draft_fields.forEach((draft_field) => { const { key, value } = draft_field; node = { ...node, [key]: value }; }); return node; } private async addInstanceToGenericType(type_node: TypeNode): Promise { const generic_type = await this.fetchGenericType(); const repository = this.getRepository(); const account = this.getAccount(); const input = { node: generic_type, field_key: 'instances', value: type_node.url, repository, account }; const operation = new AddValueToListOperation(input); await operation.perform(); } private getTypeNode(): TypeNode { const url = this.getUrl(); const type_url = this.getTypeUrl(); const creator = this.getAccountUrl(); const changes: string[] = []; const permissions: string[] = []; const instances: string[] = []; const child_types: string[] = []; const parent_type = this.getParentTypeUrl(); const created_at = Date.now(); const updated_at = created_at; return { url, type: type_url, creator, created_at, updated_at, changes, permissions, instances, child_types, parent_type }; } private async fetchGenericType(): Promise { const repository = this.getRepository(); const account = this.getAccount(); const operation = new FetchNodeOperation({ type_id: SystemId.GENERIC_TYPE, id: SystemId.GENERIC_TYPE, repository, account }); const node = await operation.perform(); return node as TypeNode; } private buildPermissions(): string[] { const hostname = this.getHostname(); const everyone_read_url = buildNodeUrl(hostname, { type_id: SystemId.PERMISSION_TYPE, id: SystemId.EVERYONE_READ_PERMISSION }); return [everyone_read_url]; } private getUrl(): string { const hostname = this.getHostname(); const id = this.getId(); return buildNodeUrl(hostname, { type_id: SystemId.GENERIC_TYPE, id }); } private getTypeUrl(): string { const hostname = this.getHostname(); return buildNodeUrl(hostname, { type_id: SystemId.GENERIC_TYPE, id: SystemId.GENERIC_TYPE }); } private getId(): string { const input = this.getInput(); return input.id; } private getDraftFields(): DraftField[] { const input = this.getInput(); return input.fields; } private getAccountUrl(): string { const account = this.getAccount(); return account.url; } private getParentTypeUrl(): string { const hostname = this.getHostname(); return buildNodeUrl(hostname, { type_id: SystemId.GENERIC_TYPE, id: SystemId.GENERIC_TYPE }); } } export default CreateTypeOperation;