{"version":3,"file":"directory.cjs","names":["BaseDocumentLoader"],"sources":["../../../src/document_loaders/fs/directory.ts"],"sourcesContent":["import type { extname as ExtnameT, resolve as ResolveT } from \"node:path\";\nimport type { readdir as ReaddirT } from \"node:fs/promises\";\nimport { Document } from \"@langchain/core/documents\";\nimport { getEnv } from \"@langchain/core/utils/env\";\nimport { BaseDocumentLoader } from \"@langchain/core/document_loaders/base\";\n\n// TypeScript enums are not tree-shakeable, so doing this instead\n// See https://bargsten.org/jsts/enums/\nexport const UnknownHandling = {\n  Ignore: \"ignore\",\n  Warn: \"warn\",\n  Error: \"error\",\n} as const;\n/**\n * An enumeration of possible handling strategies for unknown file types.\n */\nexport type UnknownHandling =\n  (typeof UnknownHandling)[keyof typeof UnknownHandling];\n\n/**\n * A mapping of file extensions to loader functions. Each loader function\n * takes a file path as a parameter and returns a `BaseDocumentLoader`\n * instance.\n */\nexport interface LoadersMapping {\n  [extension: string]: (filePath: string) => BaseDocumentLoader;\n}\n\n/**\n * A document loader that loads documents from a directory. It extends the\n * `BaseDocumentLoader` class and implements the `load()` method.\n * @example\n * ```typescript\n *\n * const directoryLoader = new DirectoryLoader(\n *   \"src/document_loaders/example_data/\",\n *   {\n *     \".pdf\": (path: string) => new PDFLoader(path),\n *   },\n * );\n *\n * const docs = await directoryLoader.load();\n * console.log({ docs });\n *\n * ```\n */\nexport class DirectoryLoader extends BaseDocumentLoader {\n  constructor(\n    public directoryPath: string,\n    public loaders: LoadersMapping,\n    public recursive: boolean = true,\n    public unknown: UnknownHandling = UnknownHandling.Warn\n  ) {\n    super();\n\n    if (Object.keys(loaders).length === 0) {\n      throw new Error(\"Must provide at least one loader\");\n    }\n    for (const extension in loaders) {\n      if (Object.hasOwn(loaders, extension)) {\n        if (extension[0] !== \".\") {\n          throw new Error(`Extension must start with a dot: ${extension}`);\n        }\n      }\n    }\n  }\n\n  /**\n   * Loads the documents from the directory. If a file is a directory and\n   * `recursive` is `true`, it recursively loads documents from the\n   * subdirectory. If a file is a file, it checks if there is a\n   * corresponding loader function for the file extension in the `loaders`\n   * mapping. If there is, it loads the documents. If there is no\n   * corresponding loader function and `unknown` is set to `Warn`, it logs a\n   * warning message. If `unknown` is set to `Error`, it throws an error.\n   * @returns A promise that resolves to an array of loaded documents.\n   */\n  public async load(): Promise<Document[]> {\n    const { readdir, extname, resolve } = await DirectoryLoader.imports();\n    const files = await readdir(this.directoryPath, { withFileTypes: true });\n\n    const documents: Document[] = [];\n\n    for (const file of files) {\n      const fullPath = resolve(this.directoryPath, file.name);\n      if (file.isDirectory()) {\n        if (this.recursive) {\n          const loader = new DirectoryLoader(\n            fullPath,\n            this.loaders,\n            this.recursive,\n            this.unknown\n          );\n          documents.push(...(await loader.load()));\n        }\n      } else {\n        // I'm aware some things won't be files,\n        // but they will be caught by the \"unknown\" handling below.\n        const loaderFactory = this.loaders[extname(file.name)];\n        if (loaderFactory) {\n          const loader = loaderFactory(fullPath);\n          documents.push(...(await loader.load()));\n        } else {\n          switch (this.unknown) {\n            case UnknownHandling.Ignore:\n              break;\n            case UnknownHandling.Warn:\n              console.warn(`Unknown file type: ${file.name}`);\n              break;\n            case UnknownHandling.Error:\n              throw new Error(`Unknown file type: ${file.name}`);\n            default:\n              throw new Error(`Unknown unknown handling: ${this.unknown}`);\n          }\n        }\n      }\n    }\n\n    return documents;\n  }\n\n  /**\n   * Imports the necessary functions from the `node:path` and\n   * `node:fs/promises` modules. It is used to dynamically import the\n   * functions when needed. If the import fails, it throws an error\n   * indicating that the modules failed to load.\n   * @returns A promise that resolves to an object containing the imported functions.\n   */\n  static async imports(): Promise<{\n    readdir: typeof ReaddirT;\n    extname: typeof ExtnameT;\n    resolve: typeof ResolveT;\n  }> {\n    try {\n      const { extname, resolve } = await import(\"node:path\");\n      const { readdir } = await import(\"node:fs/promises\");\n      return { readdir, extname, resolve };\n    } catch (e) {\n      console.error(e);\n      throw new Error(\n        `Failed to load fs/promises. DirectoryLoader available only on environment 'node'. It appears you are running environment '${getEnv()}'. See https://<link to docs> for alternatives.`\n      );\n    }\n  }\n}\n"],"mappings":";;;;;;;;;AAQA,MAAa,kBAAkB;CAC7B,QAAQ;CACR,MAAM;CACN,OAAO;CACR;;;;;;;;;;;;;;;;;;;AAkCD,IAAa,kBAAb,MAAa,wBAAwBA,sCAAAA,mBAAmB;CACtD,YACE,eACA,SACA,YAA4B,MAC5B,UAAkC,gBAAgB,MAClD;AACA,SAAO;AALA,OAAA,gBAAA;AACA,OAAA,UAAA;AACA,OAAA,YAAA;AACA,OAAA,UAAA;AAIP,MAAI,OAAO,KAAK,QAAQ,CAAC,WAAW,EAClC,OAAM,IAAI,MAAM,mCAAmC;AAErD,OAAK,MAAM,aAAa,QACtB,KAAI,OAAO,OAAO,SAAS,UAAU;OAC/B,UAAU,OAAO,IACnB,OAAM,IAAI,MAAM,oCAAoC,YAAY;;;;;;;;;;;;;CAgBxE,MAAa,OAA4B;EACvC,MAAM,EAAE,SAAS,SAAS,YAAY,MAAM,gBAAgB,SAAS;EACrE,MAAM,QAAQ,MAAM,QAAQ,KAAK,eAAe,EAAE,eAAe,MAAM,CAAC;EAExE,MAAM,YAAwB,EAAE;AAEhC,OAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,WAAW,QAAQ,KAAK,eAAe,KAAK,KAAK;AACvD,OAAI,KAAK,aAAa;QAChB,KAAK,WAAW;KAClB,MAAM,SAAS,IAAI,gBACjB,UACA,KAAK,SACL,KAAK,WACL,KAAK,QACN;AACD,eAAU,KAAK,GAAI,MAAM,OAAO,MAAM,CAAE;;UAErC;IAGL,MAAM,gBAAgB,KAAK,QAAQ,QAAQ,KAAK,KAAK;AACrD,QAAI,eAAe;KACjB,MAAM,SAAS,cAAc,SAAS;AACtC,eAAU,KAAK,GAAI,MAAM,OAAO,MAAM,CAAE;UAExC,SAAQ,KAAK,SAAb;KACE,KAAK,gBAAgB,OACnB;KACF,KAAK,gBAAgB;AACnB,cAAQ,KAAK,sBAAsB,KAAK,OAAO;AAC/C;KACF,KAAK,gBAAgB,MACnB,OAAM,IAAI,MAAM,sBAAsB,KAAK,OAAO;KACpD,QACE,OAAM,IAAI,MAAM,6BAA6B,KAAK,UAAU;;;;AAMtE,SAAO;;;;;;;;;CAUT,aAAa,UAIV;AACD,MAAI;GACF,MAAM,EAAE,SAAS,YAAY,MAAM,OAAO;GAC1C,MAAM,EAAE,YAAY,MAAM,OAAO;AACjC,UAAO;IAAE;IAAS;IAAS;IAAS;WAC7B,GAAG;AACV,WAAQ,MAAM,EAAE;AAChB,SAAM,IAAI,MACR,8HAAA,GAAA,0BAAA,SAAqI,CAAC,iDACvI"}