{"version":3,"file":"airtable.cjs","names":["BaseDocumentLoader","AsyncCaller","Document"],"sources":["../../../src/document_loaders/web/airtable.ts"],"sourcesContent":["/* oxlint-disable typescript/no-explicit-any */\nimport { BaseDocumentLoader } from \"@langchain/core/document_loaders/base\";\nimport { Document } from \"@langchain/core/documents\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport { AsyncCaller } from \"@langchain/core/utils/async_caller\";\n\nexport interface AirtableRequestParams {\n  view?: string;\n  maxRecords?: number;\n  filterByFormula?: string;\n  fields?: string[];\n}\n\nexport interface AirtableLoaderOptions {\n  tableId: string;\n  baseId: string;\n  kwargs?: AirtableRequestParams;\n}\n\ninterface AirtableRecord {\n  id: string;\n  fields: Record<string, any>;\n  createdTime: string;\n}\n\ninterface AirtableResponse {\n  records: AirtableRecord[];\n  offset?: string;\n}\n\nexport class AirtableLoader extends BaseDocumentLoader {\n  private readonly apiToken: string;\n\n  private readonly tableId: string;\n\n  private readonly baseId: string;\n\n  private readonly kwargs: AirtableRequestParams;\n\n  private static readonly BASE_URL = \"https://api.airtable.com/v0\";\n\n  private asyncCaller: AsyncCaller;\n\n  /**\n   * Initializes the AirtableLoader with configuration options.\n   * Retrieves the API token from environment variables and validates it.\n   *\n   * @param tableId - ID of the Airtable table.\n   * @param baseId - ID of the Airtable base.\n   * @param kwargs - Additional query parameters for Airtable requests.\n   * @param config - Loader configuration for retry options.\n   */\n  constructor({ tableId, baseId, kwargs = {} }: AirtableLoaderOptions) {\n    super();\n    this.apiToken = getEnvironmentVariable(\"AIRTABLE_API_TOKEN\") || \"\";\n    this.tableId = tableId;\n    this.baseId = baseId;\n    this.kwargs = kwargs;\n\n    if (!this.apiToken) {\n      throw new Error(\n        \"Missing Airtable API token. Please set AIRTABLE_API_TOKEN environment variable.\"\n      );\n    }\n\n    this.asyncCaller = new AsyncCaller({ maxRetries: 3, maxConcurrency: 5 });\n  }\n\n  /**\n   * Loads documents from Airtable, handling pagination and retries.\n   *\n   * @returns A promise that resolves to an array of Document objects.\n   */\n  public async load(): Promise<Document[]> {\n    const documents: Document[] = [];\n    let offset: string | undefined;\n\n    try {\n      do {\n        const body = this.constructRequestBody(offset);\n        const data = await this.asyncCaller.call(() => this.fetchRecords(body));\n        data.records.forEach((record: AirtableRecord) =>\n          documents.push(this.createDocument(record))\n        );\n        offset = data.offset;\n      } while (offset);\n    } catch (error) {\n      console.error(\"Error loading Airtable records:\", error);\n      throw new Error(\"Failed to load Airtable records\");\n    }\n\n    return documents;\n  }\n\n  /**\n   * Asynchronous generator function for lazily loading documents from Airtable.\n   * This method yields each document individually, enabling memory-efficient\n   * handling of large datasets by fetching records in pages.\n   *\n   * @returns An asynchronous generator yielding Document objects one by one.\n   */\n  public async *loadLazy(): AsyncGenerator<Document> {\n    let offset: string | undefined;\n    try {\n      do {\n        const body = this.constructRequestBody(offset);\n        const data = await this.asyncCaller.call(() => this.fetchRecords(body));\n\n        for (const record of data.records) {\n          yield this.createDocument(record);\n        }\n\n        offset = data.offset;\n      } while (offset);\n    } catch (error) {\n      console.error(\"Error loading Airtable records lazily:\", error);\n      throw new Error(\"Failed to load Airtable records lazily\");\n    }\n  }\n\n  /**\n   * Constructs the request body for an API call.\n   *\n   * @param offset - An optional string representing the offset for pagination.\n   * @returns A record containing the combined properties of `kwargs` and the provided offset.\n   */\n  private constructRequestBody(offset?: string): Record<string, any> {\n    return { ...this.kwargs, offset };\n  }\n\n  /**\n   * Sends the API request to Airtable and handles the response.\n   * Includes a timeout to prevent hanging on unresponsive requests.\n   *\n   * @param body - The request payload to be sent to the Airtable API.\n   * @returns A promise that resolves to an AirtableResponse object.\n   * @throws Will throw an error if the Airtable API request fails.\n   */\n  private async fetchRecords(\n    body: Record<string, any>\n  ): Promise<AirtableResponse> {\n    const url = `${AirtableLoader.BASE_URL}/${this.baseId}/${this.tableId}/listRecords`;\n    try {\n      const response = await fetch(url, {\n        method: \"POST\",\n        headers: {\n          Authorization: `Bearer ${this.apiToken}`,\n          \"Content-Type\": \"application/json\",\n        },\n        body: JSON.stringify(body),\n      });\n\n      if (!response.ok) {\n        throw new Error(\n          `Airtable API request failed with status ${response.status}: ${response.statusText}`\n        );\n      }\n\n      return (await response.json()) as AirtableResponse;\n    } catch (error) {\n      console.error(\"Error during fetch:\", error);\n      throw error;\n    }\n  }\n\n  /**\n   * Converts an Airtable record into a Document object with metadata.\n   *\n   * @param record - An Airtable record to convert.\n   * @returns A Document object with page content and metadata.\n   */\n  private createDocument(record: AirtableRecord): Document {\n    const metadata: Record<string, any> = {\n      source: `${this.baseId}_${this.tableId}`,\n      base_id: this.baseId,\n      table_id: this.tableId,\n      ...(this.kwargs.view && { view: this.kwargs.view }),\n    };\n    return new Document({ pageContent: JSON.stringify(record), metadata });\n  }\n}\n"],"mappings":";;;;;;;;AA8BA,IAAa,iBAAb,MAAa,uBAAuBA,sCAAAA,mBAAmB;CACrD;CAEA;CAEA;CAEA;CAEA,OAAwB,WAAW;CAEnC;;;;;;;;;;CAWA,YAAY,EAAE,SAAS,QAAQ,SAAS,EAAE,IAA2B;AACnE,SAAO;AACP,OAAK,YAAA,GAAA,0BAAA,wBAAkC,qBAAqB,IAAI;AAChE,OAAK,UAAU;AACf,OAAK,SAAS;AACd,OAAK,SAAS;AAEd,MAAI,CAAC,KAAK,SACR,OAAM,IAAI,MACR,kFACD;AAGH,OAAK,cAAc,IAAIC,mCAAAA,YAAY;GAAE,YAAY;GAAG,gBAAgB;GAAG,CAAC;;;;;;;CAQ1E,MAAa,OAA4B;EACvC,MAAM,YAAwB,EAAE;EAChC,IAAI;AAEJ,MAAI;AACF,MAAG;IACD,MAAM,OAAO,KAAK,qBAAqB,OAAO;IAC9C,MAAM,OAAO,MAAM,KAAK,YAAY,WAAW,KAAK,aAAa,KAAK,CAAC;AACvE,SAAK,QAAQ,SAAS,WACpB,UAAU,KAAK,KAAK,eAAe,OAAO,CAAC,CAC5C;AACD,aAAS,KAAK;YACP;WACF,OAAO;AACd,WAAQ,MAAM,mCAAmC,MAAM;AACvD,SAAM,IAAI,MAAM,kCAAkC;;AAGpD,SAAO;;;;;;;;;CAUT,OAAc,WAAqC;EACjD,IAAI;AACJ,MAAI;AACF,MAAG;IACD,MAAM,OAAO,KAAK,qBAAqB,OAAO;IAC9C,MAAM,OAAO,MAAM,KAAK,YAAY,WAAW,KAAK,aAAa,KAAK,CAAC;AAEvE,SAAK,MAAM,UAAU,KAAK,QACxB,OAAM,KAAK,eAAe,OAAO;AAGnC,aAAS,KAAK;YACP;WACF,OAAO;AACd,WAAQ,MAAM,0CAA0C,MAAM;AAC9D,SAAM,IAAI,MAAM,yCAAyC;;;;;;;;;CAU7D,qBAA6B,QAAsC;AACjE,SAAO;GAAE,GAAG,KAAK;GAAQ;GAAQ;;;;;;;;;;CAWnC,MAAc,aACZ,MAC2B;EAC3B,MAAM,MAAM,GAAG,eAAe,SAAS,GAAG,KAAK,OAAO,GAAG,KAAK,QAAQ;AACtE,MAAI;GACF,MAAM,WAAW,MAAM,MAAM,KAAK;IAChC,QAAQ;IACR,SAAS;KACP,eAAe,UAAU,KAAK;KAC9B,gBAAgB;KACjB;IACD,MAAM,KAAK,UAAU,KAAK;IAC3B,CAAC;AAEF,OAAI,CAAC,SAAS,GACZ,OAAM,IAAI,MACR,2CAA2C,SAAS,OAAO,IAAI,SAAS,aACzE;AAGH,UAAQ,MAAM,SAAS,MAAM;WACtB,OAAO;AACd,WAAQ,MAAM,uBAAuB,MAAM;AAC3C,SAAM;;;;;;;;;CAUV,eAAuB,QAAkC;EACvD,MAAM,WAAgC;GACpC,QAAQ,GAAG,KAAK,OAAO,GAAG,KAAK;GAC/B,SAAS,KAAK;GACd,UAAU,KAAK;GACf,GAAI,KAAK,OAAO,QAAQ,EAAE,MAAM,KAAK,OAAO,MAAM;GACnD;AACD,SAAO,IAAIC,0BAAAA,SAAS;GAAE,aAAa,KAAK,UAAU,OAAO;GAAE;GAAU,CAAC"}