UNPKG

@langchain/community

Version:
1 lines 7.67 kB
{"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"}