{"version":3,"file":"neo4j_graph.cjs","names":["text: string","schema: Record<string, Any>","isEnhanced: boolean","formattedNodeProps: string[]","formattedRelProps: string[]","prop: Record<string, Any>","el: Record<string, string>","neo4j","config: Neo4jGraphConfig","error: Any","query: string","params: Record<string, Any>","routing: RoutingControl","relationships: PathType[]","labelOrType: string","properties: { property: string; type: string }[]","exhaustive: boolean","withClauses: string[]","returnClauses: string[]","outputDict: { [key: string]: string }","el: Any","graphDocuments: GraphDocument[]","config: AddGraphDocumentsConfig","records: Neo4jRecord<RecordShape>","record: Any","out: Partial<RecordShape>","key: keyof RecordShape","item: Any","obj: Any","newObj: Any","path: Neo4jPath","segment: Any"],"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// eslint-disable-next-line @typescript-eslint/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.replace(\"\\n\", \" \").replace(\"\\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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"}