import { IRecord, IRecordValue } from './interfaces/record'; import { INerScoreRow, INerScoreRecord } from './interfaces/metadata'; import { IRelationType, IRelation } from './interfaces/relation'; import * as parse from './parse/parse'; import axios from 'axios'; import * as axiosT from 'axios'; // xios types import * as shortid from 'shortid'; var Base64 = require('js-base64').Base64; //const saveURI: string = 'http://neo4japi-env.rnpaigpvnp.us-east-2.elasticbeanstalk.com/db/data/transaction/commit'; const saveURI: string = 'http://neo4japi-env.rnpaigpvnp.us-east-2.elasticbeanstalk.com/db/data/transaction/commit'; /* * You need allow in your neo4j config impor csv files and * put '*.csv' file in correct route (depends on your configuration) * * If you are using docker neo4j official image, you must run this comand: * * docker run * -p 7474:7474 * -p 7687:7687 * -p 7473:7473 * -v $HOME/neo4j/data:/data * -v $HOME/neo4j/logs:/logs * -v $HOME/neo4j/import:/var/lib/neo4j/import * -v $HOME/neo4j/conf/:/conf/ * neo4j:latest * * and put inside $HOME/neo4j/import '*.csv' file * * * For allow import of csv files in neo4j using docker image run this comand: * *docker run * --detach * --publish=7474:7474 * --publish=7687:7687 * --volume=$HOME/neo4j/data:/data * --volume=$HOME/neo4j/logs:/logs * --volume=$HOME/neo4j/conf:/conf * neo4j:3.2 dump-config * * and put in file $HOME/neo4j/conf/neo4j.conf dbms.security.allow_csv_import_from_file_urls=true * */ export async function loadCSVIntoDataBase (headers: Array, fileName: string): Promise { let queryString: string = ''; headers.map( (x: string) => { queryString = queryString + x + ': row.' + x + ','; }); queryString = queryString + 'id: toString(rand())'; let cypherQuery = 'USING PERIODIC COMMIT ' + 'LOAD CSV WITH HEADERS FROM "file:///' + fileName + '" AS row ' + 'CREATE (n:Record{' + queryString + '})'; let props: object = {}; let neo4j: axiosT.AxiosResponse = await generateQueryWithProps(props, cypherQuery); let promiseEditRecord: Promise = new Promise( (resolve: (metadata: string) => void , reject: (str: string) => void ) => { if (neo4j.data.errors.length === 0) { resolve('Sucess.'); }else { reject(JSON.stringify((neo4j.data.errors))); } }); return promiseEditRecord; } /* * Edit a node if it isn exist , create new node * arg label , let create an object with specific label by default label is Record */ export async function editRecord (record: IRecord, label?: string): Promise { let props: object = {}; let neo4j: any; if (label === undefined){ label = 'Record' } let cypherQuery = 'merge (n:' + label + ' {id: {id}}) set n = {props} return n'; props['props'] = {}; record.values.map( (x: IRecordValue) => { props['props'][x.key] = x.value; }); props['id'] = record.id; props['props']['id'] = record.id; let statePromise: string = 'Sucess.'; neo4j = await generateQueryWithProps(props, cypherQuery); try { neo4j = neo4j.data.results[0].data.map ((neo4jRecord: any) => parse.neo4jObjectToRecord(neo4jRecord.row[0]) ); neo4j = await neo4j[0]; } catch (e) { statePromise = e; } let promiseEditRecord: Promise = new Promise( (resolve: (metadata: string) => void , reject: (str: string) => void ) => { if (statePromise === 'Sucess.') { resolve(statePromise); }else { reject(statePromise); } }); return promiseEditRecord; } /* * Edit a node if it isn exist , create new node */ export async function editRelationType (newType: IRelationType): Promise { let cypherQuery: string = `MATCH (a:Record)-[r {id:{relationProps}.id}]-(b) SET r = {relationProps}`; let props: object = {}; let neo4j: axiosT.AxiosResponse; props['relationProps'] = {}; props['relationProps']['id'] = newType.id; props['relationProps']['name'] = newType.name; props['relationProps']['reflexive'] = newType.reflexive; props['relationProps']['symmetric'] = newType.symmetric; props['relationProps']['transitive'] = newType.transitive; neo4j = await generateQueryWithProps(props, cypherQuery); let statePromise: string = 'Sucess.'; if (neo4j.data.errors.length === 0) { statePromise = await changeRelationsLabel(newType); }else { statePromise = 'Error in function editRelationType (relationType).' + JSON.stringify(neo4j.data.errors[0]); } let promiseEditRelation: Promise = new Promise( (resolve: (metadata: string) => void , reject: (str: string) => void ) => { if (statePromise === 'Sucess.') { resolve(statePromise); }else { reject(statePromise); } }); return promiseEditRelation; } /* * Get metadata realated with an especific node */ export async function getMetadata(): Promise { let cypherQuery: string = `OPTIONAL MATCH (n:Record)-[w:Metadata]->(r:NerScore) RETURN r,n`; let props: object = {}; let neo4j: axiosT.AxiosResponse; let arrayMetadata: any = {}; neo4j = await generateQueryWithProps(props, cypherQuery); let promiseMetadata: Promise|undefined|string> = new Promise( (resolve: (meta: any) => void , reject: (str: string) => void ) => { try { if (neo4j.data.results[0].data[0].row[0] === null) { arrayMetadata = undefined; }else { neo4j.data.results[0].data.map((neo4jmetadata: any) => { let nerScoreRow: INerScoreRow[] = parse.neo4jMetadataToINerScoreRow(neo4jmetadata.row[0]); let idRecord: string = neo4jmetadata.row[1].id; arrayMetadata[idRecord] = nerScoreRow; }); } resolve(arrayMetadata); } catch (e) { reject(e + ' Error in function getMetadata().'); } }); return promiseMetadata; } /* * Chage label of a relation type */ export async function changeRelationsLabel (newRelation: IRelationType): Promise { let cypherQuery: string = `MATCH (n)-[r {id:{id}}]->(m) CREATE (n)-[r2: ` + newRelation.name + `]->(m) SET r2 = r WITH r DELETE r`; let props: object = {}; let neo4j: axiosT.AxiosResponse; props['id'] = newRelation.id; neo4j = await generateQueryWithProps(props, cypherQuery); let promiseEditRelation: Promise = new Promise( (resolve: (metadata: string) => void , reject: (str: string) => void ) => { if (neo4j.data.errors.length === 0) { resolve('Sucess.'); }else { reject('Error in function changeRelationsLabel().' + JSON.stringify(neo4j.data.errors[0])); } }); return promiseEditRelation; } /* * Delete a node from neo4j database */ export async function deleteRecord (idDeleteRecord: string) { let props: object = {}; let neo4j: any = {}; props['id'] = idDeleteRecord; let cypherQuery: string = `MATCH (s:Record {id:{id}}) DETACH DELETE s`; try { neo4j = await generateQueryWithProps(props, cypherQuery); neo4j = neo4j.data.results[0].data.map ((neo4jRecord: any) => parse.neo4jObjectToRecord(neo4jRecord.row[0])); neo4j = await neo4j[0]; } catch (e) { neo4j = 'error'; } return neo4j; } /* * Take from database number of all results that match with currently filter. */ export async function getCount (filter: string) { let props: object = {}; let neo4j: any = {}; filter = '(?i)' + filter + '.*'; props['filter'] = filter; let cypherQuery: string = 'MATCH (m:Record)' + 'WHERE (any(prop in keys(m) where m[prop] =~ {filter} OR prop =~ {filter}))' + 'RETURN count(m)'; try { neo4j = await generateQueryWithProps(props, cypherQuery); neo4j = neo4j.data.results[0].data[0].row[0]; } catch (e) { neo4j = 'error'; } return neo4j; } /* * Search in neo4j database all Records related with query string * The attrb meta is used to take nodes with metadata or wothout , witout metadata * process is faster. By default is without * Arg label let search for specific label arguments, by default it is Record */ export async function getRecords (fil: string, nPag: number, nEnt: number, meta?: boolean, label?: string): Promise|string> { // Default meta false if (meta === undefined) { meta = false; } // Default label if (label === undefined) { label = 'Record'; } let props: object = {}; let neo4j: axiosT.AxiosResponse; let arrayRecord: Array; let statePromise: Array|string; let cypherQuery: string = `MATCH (m:` + label +`) WHERE (any(prop in keys(m) where m[prop] =~ {filter} OR prop =~ {filter})) RETURN m SKIP {skip} LIMIT {limit};`; // Prepare query fil = '(?i)' + fil + '.*'; props['filter'] = fil; props['limit'] = nEnt > 5 ? nEnt : 5; props['skip'] = (nPag - 1) >= 0 ? (nPag - 1) * nEnt : 0 ; neo4j = await generateQueryWithProps(props, cypherQuery); try { // Handle error in querry if (neo4j.data.errors.length === 0) { let errorParse: boolean = false; arrayRecord = neo4j.data.results[0].data.map ((neo4jObject: any) => { let result: string|IRecord = parse.neo4jObjectToRecord(neo4jObject.row[0]); if (typeof result === 'string') { errorParse = true; } return result; }); //Take info about clusters let infoCluster: string|undefined|object = await getCluster(); if(typeof infoCluster === 'string'){ statePromise = infoCluster }else { //Check if exists clusters if (infoCluster !== undefined){ arrayRecord.forEach( (record: IRecord) => { record.cluster = []; record.cluster.push(infoCluster[record.id]); }) } } if (errorParse) { statePromise = 'Error parse neo4j response to IRecord'; }else if (meta === true) { // get metadata only if meta arg is true let HashMetadata: any = await getMetadata(); if (typeof HashMetadata === 'string') { statePromise = HashMetadata; }else if (HashMetadata !== undefined) { arrayRecord.forEach((record: IRecord) => { let id: string = record.id; record.nerScores = HashMetadata[id]; }); statePromise = arrayRecord; } }else { statePromise = arrayRecord; } }else { statePromise = JSON.stringify(neo4j.data.errors) + ' Error in function getRecords().'; } }catch (e) { statePromise = e + ' Error in function getRecords().'; } // Handle errors let promiseRecords: Promise|string> = new Promise( (resolve: (metadata: Array) => void , reject: (str: string) => void ) => { if (typeof statePromise === 'string') { reject(statePromise); }else { resolve(statePromise); } }); return promiseRecords; } /* * Search in neo4j database all Records with specific id */ export async function getRecordsById (id: string): Promise { let props: object = {}; let neo4j: axiosT.AxiosResponse; let statePromise: IRecord|string; let cypherQuery: string = 'MATCH (s: Record) WHERE s.id = {id} RETURN s'; props['id'] = id; neo4j = await generateQueryWithProps(props, cypherQuery); try { statePromise = parse.neo4jObjectToRecord(neo4j.data.results[0].data[0].row[0]); if (typeof statePromise !== 'string') { let result: string|INerScoreRow[]|undefined = await getNodeMetadata(statePromise.id); // Handle error take matadata if (typeof result === 'string') { statePromise = result; }else { statePromise.nerScores = result; } } }catch (e) { statePromise = e + 'Error in function getRecordById()'; } let promiseRecord: Promise = new Promise( (resolve: (record: IRecord) => void , reject: (str: string) => void ) => { if (typeof statePromise === 'string') { reject(statePromise); }else { resolve(statePromise); } }); return promiseRecord; } /* * Get metadata realated with an especific node * */ export async function getNodeMetadata(idRecord: string): Promise|undefined|string> { let cypherQuery: string = `OPTIONAL MATCH (n:Record{id: {idRecord}})-[w:Metadata]->(r:NerScore) RETURN r`; let props: object = {}; let neo4j: axiosT.AxiosResponse; let arrayMetadata: Array|undefined; props['idRecord'] = idRecord; neo4j = await generateQueryWithProps(props, cypherQuery); let promiseMetadata: Promise|undefined|string> = new Promise( (resolve: (metadata: Array|undefined) => void , reject: (str: string) => void ) => { try { if (neo4j.data.results[0].data[0].row[0] === null) { arrayMetadata = undefined; }else { arrayMetadata = parse.neo4jMetadataToINerScoreRow(neo4j.data.results[0].data[0].row[0]); } resolve(arrayMetadata); } catch (e) { reject(e + ' Error in function getNodeMetadata().'); } }); return promiseMetadata; } /* * Take all relations type that exists in neo4j database */ export async function getRelationsTypes(): Promise|string> { let cypherQuery: string = `MATCH (a)-[r]-(b) RETURN type(r), collect(r)[0] AS oneRel`; let props: object = {}; // Do query let neo4j: axiosT.AxiosResponse = await generateQueryWithProps(props, cypherQuery); let promiseRelationTypes: Promise|string> = new Promise( (resolve: (types: Array) => void , reject: (str: string) => void ) => { try { // Parse data from querry let arrayRelationTypes: Array = neo4j.data.results[0].data.map((neo4jtype: any) => parse.neo4jRelationsTypesToIRelationTypes (neo4jtype.row[1])); resolve(arrayRelationTypes); } catch (e) { reject('Error in function getRelationsTypes().'); } }); return promiseRelationTypes; } /* * Delete relation from database */ export async function getAllrelationsById(idNode: string): Promise|string> { let cypherQuery: string = ''; let props: object = {}; cypherQuery = `OPTIONAL MATCH (a:Record{id: {id}})-[r] ->(b) RETURN r,a,b;`; props['id'] = idNode; // Do query let neo4j: axiosT.AxiosResponse = await generateQueryWithProps(props, cypherQuery); let isResolve: string|undefined = undefined; let arrayRelation: Array = []; try { // Parse data from querry // neo4j.data.results[0] === undefined means this object doesnt exist (on new object) if (neo4j.data.results[0] !== undefined) { for (let neo4jRelation of neo4j.data.results[0].data) { // Check if exists relations if (neo4jRelation.row[0] !== null) { let relation: IRelation|string|undefined = undefined; relation = await parse.neo4jRelationsToIRelation (neo4jRelation); // Handle error if (typeof relation === 'string') { isResolve = relation; }else if (relation !== undefined) { arrayRelation.push(relation); } } } } } catch (e) { isResolve = e + '->' + ' Error in function getAllrelationsById() '; } let promiseRelation: Promise|string> = new Promise( (resolve: (types: Array) => void , reject: (str: string) => void ) => { if (isResolve === undefined) { resolve(arrayRelation); }else { reject(isResolve); } }); return promiseRelation; } /* * Delete relation from database */ export async function deleteAllRelations(idRecord: string): Promise { let cypherQuery: string = ''; let props: object = {}; cypherQuery = `OPTIONAL MATCH (a:Record{id: {idStart}})-[r]->(b) WHERE type(r) <> "Metadata" DELETE r RETURN a;`; props['idStart'] = idRecord; // Do query let neo4j: axiosT.AxiosResponse = await generateQueryWithProps(props, cypherQuery); let promiseRelationTypes: Promise = new Promise( (resolve: (types: string) => void , reject: (str: string) => void ) => { if (neo4j.data.errors.length === 0) { resolve('Sucess.'); }else { reject('Error in function deleteAllRelations(relation).' + JSON.stringify(neo4j.data.errors[0])); } }); return promiseRelationTypes; } /* * Delete relation from database */ export async function deleteRelation(relation: IRelation): Promise { let cypherQuery: string = ''; let props: object = {}; if (relation.start !== undefined && relation.end !== undefined && relation.type !== undefined) { cypherQuery = `OPTIONAL MATCH (a:Record{id: {idStart}})-[r:` + relation.type.name + `] ->(b:Record{id: {idEnd}}) DELETE r RETURN a;`; props['idStart'] = relation.start.id; props['idEnd'] = relation.end.id; } // Do query let neo4j: axiosT.AxiosResponse = await generateQueryWithProps(props, cypherQuery); let promiseRelationTypes: Promise = new Promise( (resolve: (types: string) => void , reject: (str: string) => void ) => { if (neo4j.data.errors.length === 0) { resolve('Sucess.'); }else { reject('Error in function deleteRelation(relation).' + JSON.stringify(neo4j.data.errors[0])); } }); return promiseRelationTypes; } /* * Generate new relations between objects */ export async function editRelation(relation: IRelation): Promise { let cypherQuery: string = ''; let props: object = {}; let neo4j: axiosT.AxiosResponse; if (relation.start !== undefined && relation.end !== undefined && relation.type !== undefined) { cypherQuery = `MATCH (n {id:{idStart}}), (r {id:{idEnd}}) FOREACH (prop in {relationProps}| MERGE (n)-[w:` + relation.type.name + `{ id: prop.idRelation, name: prop.name, reflexive: prop.reflexive, transitive: prop.transitive, symmetric: prop.symmetric}]->(r) ) RETURN n;`; props['idStart'] = relation.start.id; props['idEnd'] = relation.end.id; props['relationProps'] = {}; props['relationProps']['idRelation'] = relation.type.id; props['relationProps']['name'] = relation.type.name; props['relationProps']['reflexive'] = relation.type.reflexive; props['relationProps']['symmetric'] = relation.type.symmetric; props['relationProps']['transitive'] = relation.type.transitive; // Do query neo4j = await generateQueryWithProps(props, cypherQuery); } let promiseRelationTypes: Promise = new Promise( (resolve: (types: string) => void , reject: (str: string) => void ) => { try { if (neo4j.data.errors.length === 0) { resolve('Sucess.'); }else { reject(JSON.stringify(neo4j.data.errors) + 'Error in function editRelation().'); } }catch (e) { reject(e + ' Error in function editRelation().'); } }); return promiseRelationTypes; } /* * Generate one relation of type relationType between all idNodes and idCluster */ export async function clusterRelation (idNodes: Array, relationType: IRelationType, idCluster: string): Promise { let cypherQuery: string = ''; let props: Array = []; let neo4j: axiosT.AxiosResponse; cypherQuery = `MATCH (n), (r {id:{idEnd}}) WHERE n.id IN {ids} FOREACH (prop in {relationProps}| MERGE (n)-[w:` + relationType.name + `{ id: prop.idRelation, name: prop.name, reflexive: prop.reflexive, transitive: prop.transitive, symmetric: prop.symmetric}]->(r) ) RETURN n;`; let chunkArray: Array = []; let promiseState: string = ''; let prop: object = {}; prop['ids'] = idNodes; prop['idEnd'] = idCluster; prop['relationProps'] = {}; prop['relationProps']['idRelation'] = relationType.id; prop['relationProps']['name'] = relationType.name; prop['relationProps']['reflexive'] = relationType.reflexive; prop['relationProps']['symmetric'] = relationType.symmetric; prop['relationProps']['transitive'] = relationType.transitive; props.push(prop) // Do query neo4j = await generateBachQuery(props, cypherQuery); let promiseRelationTypes: Promise = new Promise( (resolve: (types: string) => void , reject: (str: string) => void ) => { if (neo4j.data.errors.length === 0) { resolve('Sucess.'); }else { reject(JSON.stringify(neo4j.data.errors) + 'Error in function editRelationBatch().'); } }); return promiseRelationTypes; } /* * Recive a cypherQuery and props and make a query to API. */ export async function generateQueryWithProps (props: any, cypherQuery: string) { // encode database connection credentials: 'user:pass' const authB64: string = encodeB64('neo4j:neo4js'); const config: object = { headers: { 'Accept': 'application/json; charset=UTF-8', 'Authorization': 'Basic ' + authB64, 'Content-Type': 'application/json' } }; // saveURI = 'http://localhost:7474/db/data/transaction/commit'; // const saveURI: string = 'http://92.222.181.192:7474/db/data/transaction/commit'; let parameters: object = {}; for (let property in props) { if (props.hasOwnProperty(property)) { parameters[property] = props[property]; } } let query: object = {}; query = {statements : [{statement : cypherQuery, parameters : parameters}] }; return await axios.post(saveURI, JSON.stringify(query) , config); } /* * Generate bach query. */ export async function generateBachQuery (props: Array, cypherQuery: string) { // encode database connection credentials: 'user:pass' const authB64: string = encodeB64('neo4j:neo4js'); const config: object = { headers: { 'Accept': 'application/json; charset=UTF-8', 'Authorization': 'Basic ' + authB64, 'Content-Type': 'application/json' } }; // saveURI = 'http://localhost:7474/db/data/transaction/commit'; // const saveURI: string = 'http://localhost:7474/db/data/transaction/commit'; let query: object = {}; query = {statements : []}; props.forEach((prop: any) => { let parameters: object = {}; for (let property in prop) { if (prop.hasOwnProperty(property)) { parameters[property] = prop[property]; } } let subQuery: object = {}; subQuery = {statement : cypherQuery,parameters : parameters} query['statements'].push(subQuery); }) return await axios.post(saveURI, JSON.stringify(query) , config); } /* * Encode the given string with b64 encryption. */ export function encodeB64( str: string ): string { return Base64.encode(str); } /* * Create a node with metadata information and relate it with its node * new node has label NerScore */ export async function createNerScoreNode(idRecord: string, metadata: string): Promise { let props: object = {}; let neo4j: axiosT.AxiosResponse = undefined; let cypherQuery: string = `MATCH (n{id:{id}}) CREATE (r:NerScore{nerScore:{metadata}}) CREATE (n)-[w:Metadata{relationProps}]->(r) RETURN r,w`; props['id'] = idRecord; props['metadata'] = metadata; props['relationProps'] = {}; props['relationProps']['id'] = shortid.generate(); props['relationProps']['name'] = 'Metadata'; props['relationProps']['reflexive'] = false; props['relationProps']['symetric'] = true ; props['relationProps']['transitive'] = false; if (metadata !== undefined) { // Do query neo4j = await generateQueryWithProps(props, cypherQuery); } let promiseRelationTypes: Promise = new Promise( (resolve: (types: string) => void , reject: (str: string) => void ) => { try { if (neo4j === undefined) { resolve('Sucess.'); }else if (neo4j.data.errors.length === 0) { resolve('Sucess.'); }else { reject(JSON.stringify(neo4j.data.errors) + 'Error in function createNerScoreNode().'); } }catch (e) { reject(e + ' Error in function createNerScoreNode().'); } }); return promiseRelationTypes; } /* * Delete all nodes and his relations with label NerScore from database */ export async function deleteNerScore(): Promise { let cypherQuery: string = `MATCH (n:NerScore) DETACH DELETE n`; let props: object = {}; // Do query let neo4j: axiosT.AxiosResponse = await generateQueryWithProps(props, cypherQuery); let promiseRelationTypes: Promise = new Promise( (resolve: (types: string) => void , reject: (str: string) => void ) => { try { if (neo4j.data.errors.length === 0) { resolve('Sucess.'); }else { reject(JSON.stringify(neo4j.data.errors) + 'Error in function deleteNerScore().'); } }catch (e) { reject(e + ' Error in function deleteNerScore().'); } }); return promiseRelationTypes; } /* * Delete all nodes and his relations with label Cluster */ export async function deleteCluster(): Promise { let cypherQuery: string = `MATCH (n:Cluster) DETACH DELETE n`; let props: object = {}; // Do query let neo4j: axiosT.AxiosResponse = await generateQueryWithProps(props, cypherQuery); let promiseRelationTypes: Promise = new Promise( (resolve: (types: string) => void , reject: (str: string) => void ) => { try { if (neo4j.data.errors.length === 0) { resolve('Sucess.'); }else { reject(JSON.stringify(neo4j.data.errors) + 'Error in function deleteCluster().'); } }catch (e) { reject(e + ' Error in function deleteCluster().'); } }); return promiseRelationTypes; } /* * Get info about cluster if exists */ export async function getCluster(): Promise { let cypherQuery: string = `OPTIONAL MATCH (n:Cluster)<-[w:typeof]-(r:Record) RETURN r.id,n.id`; let props: object = {}; let infoClusters: object = {}; // Do query let neo4j: axiosT.AxiosResponse = await generateQueryWithProps(props, cypherQuery); let promiseMetadata: Promise = new Promise( (resolve: (cluster: any) => void , reject: (str: string) => void ) => { try { if (neo4j.data.results[0].data[0].row[0] === null) { infoClusters = undefined; }else { neo4j.data.results[0].data.map((neo4jmetadata: any) => { let cluster: string = neo4jmetadata.row[1]; let idRecord: string = neo4jmetadata.row[0]; infoClusters[idRecord] = cluster; }); } resolve(infoClusters); } catch (e) { reject(e + ' Error in function getMetadata().'); } }); return promiseMetadata; } /* * Edit a node if it isn exist , create new node * arg label , let create an object with specific label by default label is Record */ export async function editRecordBatch (records: Array, label?: string): Promise { let props: Array = []; let neo4j: any; if (label === undefined){ label = 'Record' } let cypherQuery = 'merge (n:' + label + ' {id: {id}}) set n = {props} return n'; let chunkArray: Array = []; let promiseState: string = ''; while(records.length){ props = []; chunkArray = records.splice(0,2500); chunkArray.forEach((record: IRecord) => { let prop: object = {}; prop['props'] = {}; record.values.map( (x: IRecordValue) => { prop['props'][x.key] = x.value; }); prop['id'] = record.id; prop['props']['id'] = record.id; props.push(prop) }) // Do query neo4j = await generateBachQuery(props, cypherQuery); console.log('x relations'); try { if (neo4j.data.errors.length === 0) { promiseState = 'Sucess.'; }else { promiseState = JSON.stringify(neo4j.data.errors) + 'Error in function editRelationBatch().'; records = []; } }catch (e) { promiseState = e + ' Error in function editRelationBatch().'; records = []; } } let promiseRelationTypes: Promise = new Promise( (resolve: (types: string) => void , reject: (str: string) => void ) => { if (promiseState === 'Sucess.') { resolve(promiseState); }else { reject(promiseState); } }); return promiseRelationTypes; }