{"version":3,"file":"sql_db.cjs","names":["Serializable","getTableAndColumnsName","generateTableInfoFromTables"],"sources":["../src/sql_db.ts"],"sourcesContent":["import type { DataSource as DataSourceT, DataSourceOptions } from \"typeorm\";\nimport { Serializable } from \"@langchain/core/load/serializable\";\nimport {\n  generateTableInfoFromTables,\n  getTableAndColumnsName,\n  SerializedSqlDatabase,\n  SqlDatabaseDataSourceParams,\n  SqlDatabaseOptionsParams,\n  SqlTable,\n  verifyIgnoreTablesExistInDatabase,\n  verifyIncludeTablesExistInDatabase,\n  verifyListTablesExistInDatabase,\n} from \"./util/sql_utils.js\";\n\nexport type { SqlDatabaseDataSourceParams, SqlDatabaseOptionsParams };\n\n/**\n * Class that represents a SQL database in the LangChain framework.\n *\n * @security **Security Notice**\n * This class generates SQL queries for the given database.\n * The SQLDatabase class provides a getTableInfo method that can be used\n * to get column information as well as sample data from the table.\n * To mitigate risk of leaking sensitive data, limit permissions\n * to read and scope to the tables that are needed.\n * Optionally, use the includesTables or ignoreTables class parameters\n * to limit which tables can/cannot be accessed.\n *\n * @link See https://js.langchain.com/docs/security for more information.\n */\nexport class SqlDatabase\n  extends Serializable\n  implements SqlDatabaseOptionsParams, SqlDatabaseDataSourceParams\n{\n  lc_namespace = [\"langchain\", \"sql_db\"];\n\n  toJSON() {\n    return this.toJSONNotImplemented();\n  }\n\n  appDataSourceOptions: DataSourceOptions;\n\n  appDataSource: DataSourceT;\n\n  allTables: Array<SqlTable> = [];\n\n  includesTables: Array<string> = [];\n\n  ignoreTables: Array<string> = [];\n\n  sampleRowsInTableInfo = 3;\n\n  customDescription?: Record<string, string>;\n\n  protected constructor(fields: SqlDatabaseDataSourceParams) {\n    super(...arguments);\n    this.appDataSource = fields.appDataSource;\n    this.appDataSourceOptions = fields.appDataSource.options;\n    if (fields?.includesTables && fields?.ignoreTables) {\n      throw new Error(\"Cannot specify both includeTables and ignoreTables\");\n    }\n    this.includesTables = fields?.includesTables ?? [];\n    this.ignoreTables = fields?.ignoreTables ?? [];\n    this.sampleRowsInTableInfo =\n      fields?.sampleRowsInTableInfo ?? this.sampleRowsInTableInfo;\n  }\n\n  static async fromDataSourceParams(\n    fields: SqlDatabaseDataSourceParams\n  ): Promise<SqlDatabase> {\n    const sqlDatabase = new SqlDatabase(fields);\n    if (!sqlDatabase.appDataSource.isInitialized) {\n      await sqlDatabase.appDataSource.initialize();\n    }\n    sqlDatabase.allTables = await getTableAndColumnsName(\n      sqlDatabase.appDataSource\n    );\n    sqlDatabase.customDescription = Object.fromEntries(\n      Object.entries(fields?.customDescription ?? {}).filter(([key, _]) =>\n        sqlDatabase.allTables\n          .map((table: SqlTable) => table.tableName)\n          .includes(key)\n      )\n    );\n    verifyIncludeTablesExistInDatabase(\n      sqlDatabase.allTables,\n      sqlDatabase.includesTables\n    );\n    verifyIgnoreTablesExistInDatabase(\n      sqlDatabase.allTables,\n      sqlDatabase.ignoreTables\n    );\n    return sqlDatabase;\n  }\n\n  static async fromOptionsParams(\n    fields: SqlDatabaseOptionsParams\n  ): Promise<SqlDatabase> {\n    const { DataSource } = await import(\"typeorm\");\n    const dataSource = new DataSource(fields.appDataSourceOptions);\n    return SqlDatabase.fromDataSourceParams({\n      ...fields,\n      appDataSource: dataSource,\n    });\n  }\n\n  /**\n   * Get information about specified tables.\n   *\n   * Follows best practices as specified in: Rajkumar et al, 2022\n   * (https://arxiv.org/abs/2204.00498)\n   *\n   * If `sample_rows_in_table_info`, the specified number of sample rows will be\n   * appended to each table description. This can increase performance as\n   * demonstrated in the paper.\n   */\n  async getTableInfo(targetTables?: Array<string>): Promise<string> {\n    let selectedTables =\n      this.includesTables.length > 0\n        ? this.allTables.filter((currentTable) =>\n            this.includesTables.includes(currentTable.tableName)\n          )\n        : this.allTables;\n\n    if (this.ignoreTables.length > 0) {\n      selectedTables = selectedTables.filter(\n        (currentTable) => !this.ignoreTables.includes(currentTable.tableName)\n      );\n    }\n\n    if (targetTables && targetTables.length > 0) {\n      verifyListTablesExistInDatabase(\n        this.allTables,\n        targetTables,\n        \"Wrong target table name:\"\n      );\n      selectedTables = this.allTables.filter((currentTable) =>\n        targetTables.includes(currentTable.tableName)\n      );\n    }\n\n    return generateTableInfoFromTables(\n      selectedTables,\n      this.appDataSource,\n      this.sampleRowsInTableInfo,\n      this.customDescription\n    );\n  }\n\n  /**\n   * Execute a SQL command and return a string representing the results.\n   * If the statement returns rows, a string of the results is returned.\n   * If the statement returns no rows, an empty string is returned.\n   */\n  async run(command: string, fetch: \"all\" | \"one\" = \"all\"): Promise<string> {\n    // TODO: Potential security issue here\n    const res = await this.appDataSource.query(command);\n\n    if (fetch === \"all\") {\n      return JSON.stringify(res);\n    }\n\n    if (res?.length > 0) {\n      return JSON.stringify(res[0]);\n    }\n\n    return \"\";\n  }\n\n  serialize(): SerializedSqlDatabase {\n    return {\n      _type: \"sql_database\",\n      appDataSourceOptions: this.appDataSourceOptions,\n      includesTables: this.includesTables,\n      ignoreTables: this.ignoreTables,\n      sampleRowsInTableInfo: this.sampleRowsInTableInfo,\n    };\n  }\n\n  /** @ignore */\n  static async imports() {\n    try {\n      const { DataSource } = await import(\"typeorm\");\n      return { DataSource };\n    } catch (e) {\n      console.error(e);\n      throw new Error(\n        \"Failed to load typeorm. Please install it with eg. `yarn add typeorm`.\"\n      );\n    }\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA8BA,IAAa,cAAb,MAAa,oBACHA,kCAAAA,aAEV;CACE,eAAe,CAAC,aAAa,SAAS;CAEtC,SAAS;AACP,SAAO,KAAK,sBAAsB;;CAGpC;CAEA;CAEA,YAA6B,EAAE;CAE/B,iBAAgC,EAAE;CAElC,eAA8B,EAAE;CAEhC,wBAAwB;CAExB;CAEA,YAAsB,QAAqC;AACzD,QAAM,GAAG,UAAU;AACnB,OAAK,gBAAgB,OAAO;AAC5B,OAAK,uBAAuB,OAAO,cAAc;AACjD,MAAI,QAAQ,kBAAkB,QAAQ,aACpC,OAAM,IAAI,MAAM,qDAAqD;AAEvE,OAAK,iBAAiB,QAAQ,kBAAkB,EAAE;AAClD,OAAK,eAAe,QAAQ,gBAAgB,EAAE;AAC9C,OAAK,wBACH,QAAQ,yBAAyB,KAAK;;CAG1C,aAAa,qBACX,QACsB;EACtB,MAAM,cAAc,IAAI,YAAY,OAAO;AAC3C,MAAI,CAAC,YAAY,cAAc,cAC7B,OAAM,YAAY,cAAc,YAAY;AAE9C,cAAY,YAAY,MAAMC,kBAAAA,uBAC5B,YAAY,cACb;AACD,cAAY,oBAAoB,OAAO,YACrC,OAAO,QAAQ,QAAQ,qBAAqB,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,OAC5D,YAAY,UACT,KAAK,UAAoB,MAAM,UAAU,CACzC,SAAS,IAAI,CACjB,CACF;AACD,oBAAA,mCACE,YAAY,WACZ,YAAY,eACb;AACD,oBAAA,kCACE,YAAY,WACZ,YAAY,aACb;AACD,SAAO;;CAGT,aAAa,kBACX,QACsB;EACtB,MAAM,EAAE,eAAe,MAAM,OAAO;EACpC,MAAM,aAAa,IAAI,WAAW,OAAO,qBAAqB;AAC9D,SAAO,YAAY,qBAAqB;GACtC,GAAG;GACH,eAAe;GAChB,CAAC;;;;;;;;;;;;CAaJ,MAAM,aAAa,cAA+C;EAChE,IAAI,iBACF,KAAK,eAAe,SAAS,IACzB,KAAK,UAAU,QAAQ,iBACrB,KAAK,eAAe,SAAS,aAAa,UAAU,CACrD,GACD,KAAK;AAEX,MAAI,KAAK,aAAa,SAAS,EAC7B,kBAAiB,eAAe,QAC7B,iBAAiB,CAAC,KAAK,aAAa,SAAS,aAAa,UAAU,CACtE;AAGH,MAAI,gBAAgB,aAAa,SAAS,GAAG;AAC3C,qBAAA,gCACE,KAAK,WACL,cACA,2BACD;AACD,oBAAiB,KAAK,UAAU,QAAQ,iBACtC,aAAa,SAAS,aAAa,UAAU,CAC9C;;AAGH,SAAOC,kBAAAA,4BACL,gBACA,KAAK,eACL,KAAK,uBACL,KAAK,kBACN;;;;;;;CAQH,MAAM,IAAI,SAAiB,QAAuB,OAAwB;EAExE,MAAM,MAAM,MAAM,KAAK,cAAc,MAAM,QAAQ;AAEnD,MAAI,UAAU,MACZ,QAAO,KAAK,UAAU,IAAI;AAG5B,MAAI,KAAK,SAAS,EAChB,QAAO,KAAK,UAAU,IAAI,GAAG;AAG/B,SAAO;;CAGT,YAAmC;AACjC,SAAO;GACL,OAAO;GACP,sBAAsB,KAAK;GAC3B,gBAAgB,KAAK;GACrB,cAAc,KAAK;GACnB,uBAAuB,KAAK;GAC7B;;;CAIH,aAAa,UAAU;AACrB,MAAI;GACF,MAAM,EAAE,eAAe,MAAM,OAAO;AACpC,UAAO,EAAE,YAAY;WACd,GAAG;AACV,WAAQ,MAAM,EAAE;AAChB,SAAM,IAAI,MACR,yEACD"}