{"version":3,"file":"neo4j_graph.cjs","names":["neo4j"],"sources":["../../src/graphs/neo4j_graph.ts"],"sourcesContent":["import neo4j, {\n  RoutingControl,\n  type Driver as Neo4jDriver,\n  type Record as Neo4jRecord,\n  type Path as Neo4jPath,\n} from \"neo4j-driver\";\nimport { sha256 } from \"@langchain/core/utils/hash\";\nimport { GraphDocument } from \"./document.js\";\n\n// oxlint-disable-next-line typescript/no-explicit-any\ntype Any = any;\n\ninterface Neo4jGraphConfig {\n  url: string;\n  username: string;\n  password: string;\n  database?: string;\n  timeoutMs?: number;\n  enhancedSchema?: boolean;\n}\n\ninterface StructuredSchema {\n  nodeProps: { [key: NodeType[\"labels\"]]: NodeType[\"properties\"] };\n  relProps: { [key: RelType[\"type\"]]: RelType[\"properties\"] };\n  relationships: PathType[];\n  metadata?: {\n    constraint: Record<string, Any>;\n    index: Record<string, Any>;\n  };\n}\n\nexport interface AddGraphDocumentsConfig {\n  baseEntityLabel?: boolean;\n  includeSource?: boolean;\n}\n\nexport type NodeType = {\n  labels: string;\n  properties: { property: string; type: string }[];\n};\n\nexport type RelType = {\n  type: string;\n  properties: { property: string; type: string }[];\n};\n\nexport type PathType = { start: string; type: string; end: string };\n\nexport const BASE_ENTITY_LABEL = \"__Entity__\";\n\nconst DISTINCT_VALUE_LIMIT = 10;\nconst LIST_LIMIT = 128;\nconst EXHAUSTIVE_SEARCH_LIMIT = 10000;\nconst EXCLUDED_LABELS = [\"Bloom_Perspective\", \"Bloom_Scene\"];\nconst EXCLUDED_RELS = [\"Bloom_HAS_SCENE\"];\n\nconst INCLUDE_DOCS_QUERY = `\nMERGE (d:Document {id:$document.metadata.id})\nSET d.text = $document.pageContent\nSET d += $document.metadata\nWITH d\n`;\n\nconst NODE_PROPERTIES_QUERY = `\nCALL apoc.meta.data()\nYIELD label, other, elementType, type, property\nWHERE NOT type = \"RELATIONSHIP\" AND elementType = \"node\"\n  AND NOT label IN $EXCLUDED_LABELS\nWITH label AS nodeLabels, collect({property:property, type:type}) AS properties\nRETURN {labels: nodeLabels, properties: properties} AS output\n`;\n\nconst REL_PROPERTIES_QUERY = `\nCALL apoc.meta.data()\nYIELD label, other, elementType, type, property\nWHERE NOT type = \"RELATIONSHIP\" AND elementType = \"relationship\"\n      AND NOT label in $EXCLUDED_LABELS\nWITH label AS nodeLabels, collect({property:property, type:type}) AS properties\nRETURN {type: nodeLabels, properties: properties} AS output\n`;\n\nconst REL_QUERY = `\nCALL apoc.meta.data()\nYIELD label, other, elementType, type, property\nWHERE type = \"RELATIONSHIP\" AND elementType = \"node\"\nUNWIND other AS other_node\nWITH * WHERE NOT label IN $EXCLUDED_LABELS\n    AND NOT other_node IN $EXCLUDED_LABELS\nRETURN {start: label, type: property, end: toString(other_node)} AS output\n`;\n\nfunction isDistinctMoreThanLimit(\n  distinct_count = 11,\n  limit = DISTINCT_VALUE_LIMIT\n): boolean {\n  return distinct_count !== undefined && distinct_count > limit;\n}\n\nfunction cleanStringValues(text: string) {\n  return text.replaceAll(\"\\n\", \" \").replaceAll(\"\\r\", \" \");\n}\n\nfunction formatSchema(\n  schema: Record<string, Any>,\n  isEnhanced: boolean\n): string {\n  let formattedNodeProps: string[] = [];\n  let formattedRelProps: string[] = [];\n\n  if (isEnhanced) {\n    // Enhanced formatting for nodes\n    for (const [nodeType, properties] of Object.entries(schema.nodeProps)) {\n      formattedNodeProps.push(`- **${nodeType}**`);\n\n      for (const prop of properties as Array<Record<string, Any>>) {\n        let example = \"\";\n\n        if (prop.type === \"STRING\") {\n          if (prop.values.length > 0) {\n            if (isDistinctMoreThanLimit(prop.distinct_count)) {\n              example = `Example: ${cleanStringValues(prop.values[0])}`;\n            } else {\n              example = `Available options: ${prop.values\n                .map(cleanStringValues)\n                .join(\", \")}`;\n            }\n          }\n        } else if (\n          [\"INTEGER\", \"FLOAT\", \"DATE\", \"DATE_TIME\", \"LOCAL_DATE_TIME\"].includes(\n            prop.type\n          )\n        ) {\n          if (prop.min !== undefined) {\n            example = `Min: ${prop.min}, Max: ${prop.max}`;\n          } else {\n            if (prop.values.length > 0) {\n              example = `Example: ${prop.values[0]}`;\n            }\n          }\n        } else if (prop.type === \"LIST\") {\n          if (!prop.min_size || prop.min_size > LIST_LIMIT) {\n            continue;\n          }\n          example = `Min Size: ${prop.min_size}, Max Size: ${prop.max_size}`;\n        }\n\n        formattedNodeProps.push(\n          `  - \\`${prop.property}\\`: ${prop.type} ${example}`\n        );\n      }\n    }\n\n    // Enhanced formatting for relationships\n    for (const [relType, properties] of Object.entries(schema.relProps)) {\n      formattedRelProps.push(`- **${relType}**`);\n\n      for (const prop of properties as Array<Record<string, Any>>) {\n        let example = \"\";\n\n        if (prop.type === \"STRING\") {\n          if (prop.values.length > 0) {\n            if (isDistinctMoreThanLimit(prop.distinct_count)) {\n              example = `Example: ${cleanStringValues(prop.values[0])}`;\n            } else {\n              example = `Available options: ${prop.values\n                .map(cleanStringValues)\n                .join(\", \")}`;\n            }\n          }\n        } else if (\n          [\"INTEGER\", \"FLOAT\", \"DATE\", \"DATE_TIME\", \"LOCAL_DATE_TIME\"].includes(\n            prop.type\n          )\n        ) {\n          if (prop.min) {\n            example = `Min: ${prop.min}, Max: ${prop.max}`;\n          } else {\n            if (prop.values) {\n              example = `Example: ${prop.values[0]}`;\n            }\n          }\n        } else if (prop.type === \"LIST\") {\n          if (prop.min_size > LIST_LIMIT) {\n            continue;\n          }\n          example = `Min Size: ${prop.min_size}, Max Size: ${prop.max_size}`;\n        }\n\n        formattedRelProps.push(\n          `  - \\`${prop.property}\\`: ${prop.type} ${example}`\n        );\n      }\n    }\n  } else {\n    // Format node properties\n    formattedNodeProps = Object.entries(schema.nodeProps).map(\n      ([key, value]: [string, Any]) => {\n        const propsStr = value\n          .map((prop: Record<string, Any>) => `${prop.property}: ${prop.type}`)\n          .join(\", \");\n        return `${key} {${propsStr}}`;\n      }\n    );\n\n    // Format relationship properties\n    formattedRelProps = Object.entries(schema.relProps).map(\n      ([key, value]: [string, Any]) => {\n        const propsStr = value\n          .map((prop: Record<string, Any>) => `${prop.property}: ${prop.type} `)\n          .join(\", \");\n        return `${key} {${propsStr} } `;\n      }\n    );\n  }\n\n  // Format relationships\n  const formattedRels = schema.relationships.map(\n    (el: Record<string, string>) =>\n      `(: ${el.start}) - [: ${el.type}] -> (:${el.end})`\n  );\n\n  return [\n    \"Node properties are the following:\",\n    formattedNodeProps?.join(\", \"),\n    \"Relationship properties are the following:\",\n    formattedRelProps?.join(\", \"),\n    \"The relationships are the following:\",\n    formattedRels?.join(\", \"),\n  ].join(\"\\n\");\n}\n\n/**\n * @security *Security note*: Make sure that the database connection uses credentials\n * that are narrowly-scoped to only include necessary permissions.\n * Failure to do so may result in data corruption or loss, since the calling\n * code may attempt commands that would result in deletion, mutation\n * of data if appropriately prompted or reading sensitive data if such\n * data is present in the database.\n * The best way to guard against such negative outcomes is to (as appropriate)\n * limit the permissions granted to the credentials used with this tool.\n * For example, creating read only users for the database is a good way to\n * ensure that the calling code cannot mutate or delete data.\n *\n * @link See https://js.langchain.com/docs/security for more information.\n */\nexport class Neo4jGraph {\n  private driver: Neo4jDriver;\n\n  private database: string;\n\n  private timeoutMs: number | undefined;\n\n  private enhancedSchema: boolean;\n\n  protected schema = \"\";\n\n  protected structuredSchema: StructuredSchema = {\n    nodeProps: {},\n    relProps: {},\n    relationships: [],\n    metadata: {\n      constraint: {},\n      index: {},\n    },\n  };\n\n  constructor({\n    url,\n    username,\n    password,\n    database = \"neo4j\",\n    timeoutMs,\n    enhancedSchema = false,\n  }: Neo4jGraphConfig) {\n    try {\n      this.driver = neo4j.driver(url, neo4j.auth.basic(username, password));\n      this.database = database;\n      this.timeoutMs = timeoutMs;\n      this.enhancedSchema = enhancedSchema;\n    } catch {\n      throw new Error(\n        \"Could not create a Neo4j driver instance. Please check the connection details.\"\n      );\n    }\n  }\n\n  static async initialize(config: Neo4jGraphConfig): Promise<Neo4jGraph> {\n    const graph = new Neo4jGraph(config);\n\n    await graph.verifyConnectivity();\n\n    try {\n      await graph.refreshSchema();\n    } catch (error: Any) {\n      if (error.code === \"Neo.ClientError.Procedure.ProcedureNotFound\") {\n        throw new Error(\n          \"Could not use APOC procedures. Please ensure the APOC plugin is installed in Neo4j and that 'apoc.meta.data()' is allowed in Neo4j configuration.\"\n        );\n      }\n\n      throw error;\n    } finally {\n      console.log(\"Schema refreshed successfully.\");\n    }\n\n    return graph;\n  }\n\n  getSchema(): string {\n    return this.schema;\n  }\n\n  getStructuredSchema() {\n    return this.structuredSchema;\n  }\n\n  async query<RecordShape extends Record<string, Any> = Record<string, Any>>(\n    query: string,\n    params: Record<string, Any> = {},\n    routing: RoutingControl = neo4j.routing.WRITE\n  ): Promise<RecordShape[]> {\n    const result = await this.driver.executeQuery<RecordShape>(query, params, {\n      database: this.database,\n      routing,\n      transactionConfig: { timeout: this.timeoutMs },\n    });\n    return toObjects<RecordShape>(result.records);\n  }\n\n  async verifyConnectivity() {\n    await this.driver.getServerInfo();\n  }\n\n  async refreshSchema() {\n    // Assuming query method is defined and returns a Promise\n    const nodeProperties = (\n      await this.query<{ output: NodeType }>(NODE_PROPERTIES_QUERY, {\n        EXCLUDED_LABELS: EXCLUDED_LABELS.concat([BASE_ENTITY_LABEL]),\n      })\n    )?.map((el) => el.output);\n\n    const relationshipsProperties = (\n      await this.query<{ output: RelType }>(REL_PROPERTIES_QUERY, {\n        EXCLUDED_LABELS: EXCLUDED_RELS,\n      })\n    )?.map((el) => el.output);\n\n    const relationships: PathType[] = (\n      await this.query<{ output: PathType }>(REL_QUERY, {\n        EXCLUDED_LABELS: EXCLUDED_LABELS.concat([BASE_ENTITY_LABEL]),\n      })\n    )?.map((el) => el.output);\n\n    const constraint = await this.query(\"SHOW CONSTRAINTS\");\n\n    const index = await this.query(\"SHOW INDEXES YIELD *\");\n\n    // Structured schema similar to Python's dictionary comprehension\n    this.structuredSchema = {\n      nodeProps: Object.fromEntries(\n        nodeProperties?.map((el) => [el.labels, el.properties]) || []\n      ),\n      relProps: Object.fromEntries(\n        relationshipsProperties?.map((el) => [el.type, el.properties]) || []\n      ),\n      relationships: relationships || [],\n      metadata: {\n        constraint,\n        index,\n      },\n    };\n\n    if (this.enhancedSchema) {\n      const schemaCounts = await this.query(\n        `CALL apoc.meta.graphSample() YIELD nodes, relationships ` +\n          `RETURN nodes, [rel in relationships | {name: apoc.any.property(rel, 'type'), count: apoc.any.property(rel, 'count')}] AS relationships`\n      );\n      // Update node info\n      for (const node of schemaCounts[0].nodes) {\n        // Skip bloom labels\n        if (EXCLUDED_LABELS.includes(node.name)) {\n          continue;\n        }\n\n        const nodeProps = this.structuredSchema.nodeProps[node.name];\n\n        if (!nodeProps) {\n          // The node has no properties\n          continue;\n        }\n\n        const enhancedCypher = await this.enhancedSchemaCypher(\n          node.name,\n          nodeProps,\n          node.count < EXHAUSTIVE_SEARCH_LIMIT\n        );\n        const enhancedInfoPromise = await this.query(enhancedCypher);\n        const enhancedInfo = enhancedInfoPromise[0].output;\n\n        for (const prop of nodeProps) {\n          if (enhancedInfo[prop.property]) {\n            Object.assign(prop, enhancedInfo[prop.property]);\n          }\n        }\n      }\n\n      // Update rel info\n      for (const rel of schemaCounts[0].relationships) {\n        // Skip bloom labels\n        if (EXCLUDED_RELS.includes(rel.name)) {\n          continue;\n        }\n        const relProps = this.structuredSchema.relProps[rel.name];\n\n        if (!relProps) {\n          // The rel has no properties\n          continue;\n        }\n        const enhancedCypher = await this.enhancedSchemaCypher(\n          rel.name,\n          relProps,\n          rel.count < EXHAUSTIVE_SEARCH_LIMIT,\n          true\n        );\n\n        const enhancedInfoPromise = await this.query(enhancedCypher);\n        const enhancedInfo = enhancedInfoPromise[0].output;\n\n        for (const prop of relProps) {\n          if (prop.property in enhancedInfo) {\n            Object.assign(prop, enhancedInfo[prop.property]);\n          }\n        }\n      }\n    }\n\n    // Combine all formatted elements into a single string\n    this.schema = formatSchema(this.structuredSchema, this.enhancedSchema);\n  }\n\n  async enhancedSchemaCypher(\n    labelOrType: string,\n    properties: { property: string; type: string }[],\n    exhaustive: boolean,\n    isRelationship = false\n  ) {\n    let matchClause = isRelationship\n      ? `MATCH ()-[n:\\`${labelOrType}\\`]->()`\n      : `MATCH (n:\\`${labelOrType}\\`)`;\n\n    const withClauses: string[] = [];\n    const returnClauses: string[] = [];\n    const outputDict: { [key: string]: string } = {};\n\n    if (exhaustive) {\n      for (const prop of properties) {\n        const propName = prop.property;\n        const propType = prop.type;\n\n        if (propType === \"STRING\") {\n          withClauses.push(\n            `collect(distinct substring(n.\\`${propName}\\`, 0, 50)) AS \\`${propName}_values\\``\n          );\n          returnClauses.push(\n            `values: \\`${propName}_values\\`[..${DISTINCT_VALUE_LIMIT}], distinct_count: size(\\`${propName}_values\\`)`\n          );\n        } else if (\n          [\"INTEGER\", \"FLOAT\", \"DATE\", \"DATE_TIME\", \"LOCAL_DATE_TIME\"].includes(\n            propType\n          )\n        ) {\n          withClauses.push(`min(n.\\`${propName}\\`) AS \\`${propName}_min\\``);\n          withClauses.push(`max(n.\\`${propName}\\`) AS \\`${propName}_max\\``);\n          withClauses.push(\n            `count(distinct n.\\`${propName}\\`) AS \\`${propName}_distinct\\``\n          );\n          returnClauses.push(\n            `min: toString(\\`${propName}_min\\`), max: toString(\\`${propName}_max\\`), distinct_count: \\`${propName}_distinct\\``\n          );\n        } else if (propType === \"LIST\") {\n          withClauses.push(\n            `min(size(n.\\`${propName}\\`)) AS \\`${propName}_size_min\\`, max(size(n.\\`${propName}\\`)) AS \\`${propName}_size_max\\``\n          );\n          returnClauses.push(\n            `min_size: \\`${propName}_size_min\\`, max_size: \\`${propName}_size_max\\``\n          );\n        } else if ([\"BOOLEAN\", \"POINT\", \"DURATION\"].includes(propType)) {\n          continue;\n        }\n        outputDict[propName] = `{${returnClauses.pop()}}`;\n      }\n    } else {\n      matchClause += ` WITH n LIMIT 5`;\n\n      for (const prop of properties) {\n        const propName = prop.property;\n        const propType = prop.type;\n\n        const propIndex = this.structuredSchema?.metadata?.index.filter(\n          (el: Any) =>\n            el.label === labelOrType &&\n            el.properties[0] === propName &&\n            el.type === \"RANGE\"\n        );\n\n        if (propType === \"STRING\") {\n          if (\n            propIndex.length > 0 &&\n            propIndex[0].size > 0 &&\n            propIndex[0].distinctValues <= DISTINCT_VALUE_LIMIT\n          ) {\n            const distinctValuesPromise = await this.query(\n              `CALL apoc.schema.properties.distinct('${labelOrType}', '${propName}') YIELD value`\n            );\n            const distinctValues = distinctValuesPromise[0].value;\n            returnClauses.push(\n              `values: ${distinctValues}, distinct_count: ${distinctValues.length}`\n            );\n          } else {\n            withClauses.push(\n              `collect(distinct substring(n.\\`${propName}\\`, 0, 50)) AS \\`${propName}_values\\``\n            );\n            returnClauses.push(`values: ${propName}_values`);\n          }\n        } else if (\n          [\"INTEGER\", \"FLOAT\", \"DATE\", \"DATE_TIME\", \"LOCAL_DATE_TIME\"].includes(\n            propType\n          )\n        ) {\n          if (!propIndex) {\n            withClauses.push(\n              `collect(distinct toString(n.\\`${propName}\\`)) AS \\`${propName}_values\\``\n            );\n            returnClauses.push(`values: ${propName}_values`);\n          } else {\n            withClauses.push(`min(n.\\`${propName}\\`) AS \\`${propName}_min\\``);\n            withClauses.push(`max(n.\\`${propName}\\`) AS \\`${propName}_max\\``);\n            withClauses.push(\n              `count(distinct n.\\`${propName}\\`) AS \\`${propName}_distinct\\``\n            );\n            returnClauses.push(\n              `min: toString(\\`${propName}_min\\`), max: toString(\\`${propName}_max\\`), distinct_count: \\`${propName}_distinct\\``\n            );\n          }\n        } else if (propType === \"LIST\") {\n          withClauses.push(\n            `min(size(n.\\`${propName}\\`)) AS \\`${propName}_size_min\\`, max(size(n.\\`${propName}\\`)) AS \\`${propName}_size_max\\``\n          );\n          returnClauses.push(\n            `min_size: \\`${propName}_size_min\\`, max_size: \\`${propName}_size_max\\``\n          );\n        } else if ([\"BOOLEAN\", \"POINT\", \"DURATION\"].includes(propType)) {\n          continue;\n        }\n\n        outputDict[propName] = `{${returnClauses.pop()}}`;\n      }\n    }\n\n    const withClause = `WITH ${withClauses.join(\", \")}`;\n    const returnClause = `RETURN {${Object.entries(outputDict)\n      .map(([k, v]) => `\\`${k}\\`: ${v}`)\n      .join(\", \")}} AS output`;\n\n    const cypherQuery = [matchClause, withClause, returnClause].join(\"\\n\");\n\n    return cypherQuery;\n  }\n\n  async addGraphDocuments(\n    graphDocuments: GraphDocument[],\n    config: AddGraphDocumentsConfig = {}\n  ): Promise<void> {\n    const { baseEntityLabel } = config;\n\n    if (baseEntityLabel) {\n      const constraintExists =\n        this.structuredSchema?.metadata?.constraint?.some(\n          (el: Any) =>\n            JSON.stringify(el.labelsOrTypes) ===\n              JSON.stringify([BASE_ENTITY_LABEL]) &&\n            JSON.stringify(el.properties) === JSON.stringify([\"id\"])\n        ) ?? false;\n\n      if (!constraintExists) {\n        await this.query(`\n          CREATE CONSTRAINT IF NOT EXISTS FOR (b:${BASE_ENTITY_LABEL})\n          REQUIRE b.id IS UNIQUE;\n        `);\n        await this.refreshSchema();\n      }\n    }\n\n    const nodeImportQuery = getNodeImportQuery(config);\n    const relImportQuery = getRelImportQuery(config);\n\n    for (const document of graphDocuments) {\n      if (!document.source.metadata.id) {\n        document.source.metadata.id = sha256(document.source.pageContent);\n      }\n\n      // Import nodes\n      await this.query(nodeImportQuery, {\n        data: document.nodes.map((el: Any) => ({ ...el })),\n        document: { ...document.source },\n      });\n\n      // Import relationships\n      await this.query(relImportQuery, {\n        data: document.relationships.map((el: Any) => ({\n          source: el.source.id,\n          source_label: el.source.type,\n          target: el.target.id,\n          target_label: el.target.type,\n          type: el.type.replace(/ /g, \"_\").toUpperCase(),\n          properties: el.properties,\n        })),\n      });\n    }\n  }\n\n  async close() {\n    await this.driver.close();\n  }\n}\n\nfunction getNodeImportQuery({\n  baseEntityLabel,\n  includeSource,\n}: AddGraphDocumentsConfig): string {\n  if (baseEntityLabel) {\n    return `\n          ${includeSource ? INCLUDE_DOCS_QUERY : \"\"}\n          UNWIND $data AS row\n              MERGE(source: \\`${BASE_ENTITY_LABEL}\\` {id: row.id})\n          SET source += row.properties\n          ${includeSource ? \"MERGE (d)-[:MENTIONS]->(source)\" : \"\"}\n          WITH source, row\n          CALL apoc.create.addLabels(source, [row.type]) YIELD node\n          RETURN distinct 'done' AS result\n      `;\n  } else {\n    return `\n          ${includeSource ? INCLUDE_DOCS_QUERY : \"\"}\n          UNWIND $data AS row\n          CALL apoc.merge.node([row.type], {id: row.id},\n          row.properties, {}) YIELD node\n          ${includeSource ? \"MERGE (d)-[:MENTIONS]->(node)\" : \"\"}\n          RETURN distinct 'done' AS result\n      `;\n  }\n}\n\nfunction getRelImportQuery({\n  baseEntityLabel,\n}: AddGraphDocumentsConfig): string {\n  if (baseEntityLabel) {\n    return `\n          UNWIND $data AS row\n          MERGE (source:\\`${BASE_ENTITY_LABEL}\\` {id: row.source})\n          MERGE (target:\\`${BASE_ENTITY_LABEL}\\` {id: row.target})\n          WITH source, target, row\n          CALL apoc.merge.relationship(source, row.type,\n          {}, row.properties, target) YIELD rel\n          RETURN distinct 'done'\n      `;\n  } else {\n    return `\n          UNWIND $data AS row\n          CALL apoc.merge.node([row.source_label], {id: row.source},\n          {}, {}) YIELD node as source\n          CALL apoc.merge.node([row.target_label], {id: row.target},\n          {}, {}) YIELD node as target\n          CALL apoc.merge.relationship(source, row.type,\n          {}, row.properties, target) YIELD rel\n          RETURN distinct 'done'\n      `;\n  }\n}\n\nfunction toObjects<\n  RecordShape extends Record<string, Any> = Record<string, Any>,\n>(records: Neo4jRecord<RecordShape>): RecordShape[] {\n  return records.map((record: Any) => {\n    const rObj = record.toObject();\n    const out: Partial<RecordShape> = {};\n    Object.keys(rObj).forEach((key: keyof RecordShape) => {\n      out[key] = itemIntToString(rObj[key]);\n    });\n    return out as RecordShape;\n  });\n}\n\nfunction itemIntToString(item: Any): Any {\n  if (neo4j.isInt(item)) return item.toString();\n  if (Array.isArray(item)) return item.map((ii) => itemIntToString(ii));\n  if ([\"number\", \"string\", \"boolean\"].indexOf(typeof item) !== -1) return item;\n  if (item === null) return item;\n  if (typeof item === \"object\") return objIntToString(item);\n}\n\nfunction objIntToString(obj: Any) {\n  const entry = extractFromNeoObjects(obj);\n  let newObj: Any = null;\n  if (Array.isArray(entry)) {\n    newObj = entry.map((item) => itemIntToString(item));\n  } else if (entry !== null && typeof entry === \"object\") {\n    newObj = {};\n    Object.keys(entry).forEach((key) => {\n      newObj[key] = itemIntToString(entry[key]);\n    });\n  }\n  return newObj;\n}\n\nfunction extractFromNeoObjects(obj: Any) {\n  if (\n    // eslint-disable-next-line\n    obj instanceof (neo4j.types.Node as any) ||\n    // eslint-disable-next-line\n    obj instanceof (neo4j.types.Relationship as any)\n  ) {\n    return obj.properties;\n    // eslint-disable-next-line\n  } else if (obj instanceof (neo4j.types.Path as any)) {\n    // eslint-disable-next-line\n    return [].concat.apply<any[], any[], any[]>([], extractPathForRows(obj));\n  }\n  return obj;\n}\n\nconst extractPathForRows = (path: Neo4jPath) => {\n  let { segments } = path;\n  // Zero length path. No relationship, end === start\n  if (!Array.isArray(path.segments) || path.segments.length < 1) {\n    segments = [{ ...path, end: null } as Any];\n  }\n\n  return segments.map((segment: Any) =>\n    [\n      objIntToString(segment.start),\n      objIntToString(segment.relationship),\n      objIntToString(segment.end),\n    ].filter((part) => part !== null)\n  );\n};\n"],"mappings":"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"}