{"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,QAAQ;CAErC,SAAS;EACP,OAAO,KAAK,qBAAqB;CACnC;CAEA;CAEA;CAEA,YAA6B,CAAC;CAE9B,iBAAgC,CAAC;CAEjC,eAA8B,CAAC;CAE/B,wBAAwB;CAExB;CAEA,YAAsB,QAAqC;EACzD,MAAM,GAAG,SAAS;EAClB,KAAK,gBAAgB,OAAO;EAC5B,KAAK,uBAAuB,OAAO,cAAc;EACjD,IAAI,QAAQ,kBAAkB,QAAQ,cACpC,MAAM,IAAI,MAAM,oDAAoD;EAEtE,KAAK,iBAAiB,QAAQ,kBAAkB,CAAC;EACjD,KAAK,eAAe,QAAQ,gBAAgB,CAAC;EAC7C,KAAK,wBACH,QAAQ,yBAAyB,KAAK;CAC1C;CAEA,aAAa,qBACX,QACsB;EACtB,MAAM,cAAc,IAAI,YAAY,MAAM;EAC1C,IAAI,CAAC,YAAY,cAAc,eAC7B,MAAM,YAAY,cAAc,WAAW;EAE7C,YAAY,YAAY,MAAMC,kBAAAA,uBAC5B,YAAY,aACd;EACA,YAAY,oBAAoB,OAAO,YACrC,OAAO,QAAQ,QAAQ,qBAAqB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,OAC5D,YAAY,UACT,KAAK,UAAoB,MAAM,SAAS,CAAC,CACzC,SAAS,GAAG,CACjB,CACF;EACA,kBAAA,mCACE,YAAY,WACZ,YAAY,cACd;EACA,kBAAA,kCACE,YAAY,WACZ,YAAY,YACd;EACA,OAAO;CACT;CAEA,aAAa,kBACX,QACsB;EACtB,MAAM,EAAE,eAAe,MAAM,OAAO;EACpC,MAAM,aAAa,IAAI,WAAW,OAAO,oBAAoB;EAC7D,OAAO,YAAY,qBAAqB;GACtC,GAAG;GACH,eAAe;EACjB,CAAC;CACH;;;;;;;;;;;CAYA,MAAM,aAAa,cAA+C;EAChE,IAAI,iBACF,KAAK,eAAe,SAAS,IACzB,KAAK,UAAU,QAAQ,iBACrB,KAAK,eAAe,SAAS,aAAa,SAAS,CACrD,IACA,KAAK;EAEX,IAAI,KAAK,aAAa,SAAS,GAC7B,iBAAiB,eAAe,QAC7B,iBAAiB,CAAC,KAAK,aAAa,SAAS,aAAa,SAAS,CACtE;EAGF,IAAI,gBAAgB,aAAa,SAAS,GAAG;GAC3C,kBAAA,gCACE,KAAK,WACL,cACA,0BACF;GACA,iBAAiB,KAAK,UAAU,QAAQ,iBACtC,aAAa,SAAS,aAAa,SAAS,CAC9C;EACF;EAEA,OAAOC,kBAAAA,4BACL,gBACA,KAAK,eACL,KAAK,uBACL,KAAK,iBACP;CACF;;;;;;CAOA,MAAM,IAAI,SAAiB,QAAuB,OAAwB;EAExE,MAAM,MAAM,MAAM,KAAK,cAAc,MAAM,OAAO;EAElD,IAAI,UAAU,OACZ,OAAO,KAAK,UAAU,GAAG;EAG3B,IAAI,KAAK,SAAS,GAChB,OAAO,KAAK,UAAU,IAAI,EAAE;EAG9B,OAAO;CACT;CAEA,YAAmC;EACjC,OAAO;GACL,OAAO;GACP,sBAAsB,KAAK;GAC3B,gBAAgB,KAAK;GACrB,cAAc,KAAK;GACnB,uBAAuB,KAAK;EAC9B;CACF;;CAGA,aAAa,UAAU;EACrB,IAAI;GACF,MAAM,EAAE,eAAe,MAAM,OAAO;GACpC,OAAO,EAAE,WAAW;EACtB,SAAS,GAAG;GACV,QAAQ,MAAM,CAAC;GACf,MAAM,IAAI,MACR,wEACF;EACF;CACF;AACF"}