{"version":3,"sources":["../../../src/tools/python/storage.ts"],"names":["PythonStorage","Serializable","TemporaryStorage","files","list","slice","upload","map","file","id","pythonId","filename","download","filter","every","f","createSnapshot","loadSnapshot","snapshot","Object","assign","LocalPythonStorage","input","constructor","ignoredFiles","Set","init","fs","promises","mkdir","localWorkingDir","recursive","interpreterWorkingDir","readdir","withFileTypes","Promise","all","isFile","has","name","computeHash","path","join","toString","fileList","filesystemFile","find","copyFile","content","readFile","SHA256","shallowCopy"],"mappings":"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","file":"storage.cjs","sourcesContent":["/**\n * Copyright 2025 IBM Corp.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { PathLike } from \"fs\";\nimport fs from \"node:fs\";\nimport { copyFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { Cache } from \"@/cache/decoratorCache.js\";\nimport { Serializable } from \"@/internals/serializable.js\";\nimport { shallowCopy } from \"@/serializer/utils.js\";\nimport { SHA256 } from \"crypto-js\";\n\nexport interface PythonFile {\n  id: string;\n  pythonId: string;\n  filename: string;\n}\n\nexport interface PythonUploadFile {\n  id: string;\n  filename: string;\n}\n\nexport interface PythonDownloadFile {\n  id?: string;\n  filename: string;\n  pythonId: string;\n}\n\nexport abstract class PythonStorage extends Serializable {\n  /**\n   * List all files that code interpreter can use.\n   */\n  abstract list(): Promise<PythonFile[]>;\n\n  /**\n   * Prepare subset of available files to code interpreter.\n   */\n  abstract upload(files: PythonUploadFile[]): Promise<PythonFile[]>;\n\n  /**\n   * Process updated/modified/deleted files from code interpreter response.\n   */\n  abstract download(files: PythonDownloadFile[]): Promise<PythonFile[]>;\n}\n\nexport class TemporaryStorage extends PythonStorage {\n  protected files: PythonFile[] = [];\n\n  async list() {\n    return this.files.slice();\n  }\n\n  async upload(files: PythonUploadFile[]): Promise<PythonFile[]> {\n    return files.map((file) => ({\n      id: file.id,\n      pythonId: file.id,\n      filename: file.filename,\n    }));\n  }\n\n  async download(files: PythonDownloadFile[]) {\n    this.files = [\n      ...this.files.filter((file) => files.every((f) => f.filename !== file.filename)),\n      ...files.map((file) => ({ id: file.pythonId, ...file })),\n    ];\n    return this.files.slice();\n  }\n\n  createSnapshot() {\n    return { files: this.files.slice() };\n  }\n\n  loadSnapshot(snapshot: ReturnType<typeof this.createSnapshot>) {\n    Object.assign(this, snapshot);\n  }\n}\n\ninterface Input {\n  localWorkingDir: PathLike;\n  interpreterWorkingDir: PathLike;\n  ignoredFiles?: Set<string>;\n}\n\nexport class LocalPythonStorage extends PythonStorage {\n  protected readonly input: Required<Input>;\n\n  constructor(input: Input) {\n    super();\n    this.input = {\n      ...input,\n      ignoredFiles: input?.ignoredFiles ?? new Set([\".gitkeep\"]),\n    };\n  }\n\n  @Cache()\n  protected async init() {\n    await fs.promises.mkdir(this.input.localWorkingDir, { recursive: true });\n    await fs.promises.mkdir(this.input.interpreterWorkingDir, { recursive: true });\n  }\n\n  async list(): Promise<PythonFile[]> {\n    await this.init();\n\n    const files = await fs.promises.readdir(this.input.localWorkingDir, {\n      withFileTypes: true,\n      recursive: false,\n    });\n    return Promise.all(\n      files\n        .filter((file) => file.isFile() && !this.input.ignoredFiles.has(file.name))\n        .map(async (file) => {\n          const pythonId = await this.computeHash(\n            path.join(this.input.localWorkingDir.toString(), file.name),\n          );\n\n          return {\n            id: pythonId,\n            filename: file.name,\n            pythonId,\n          };\n        }),\n    );\n  }\n\n  async upload(files: PythonUploadFile[]): Promise<PythonFile[]> {\n    await this.init();\n\n    const fileList = await this.list();\n\n    await Promise.all(\n      files.map((file) => {\n        const filesystemFile = fileList.find((filesystemFile) => filesystemFile.id === file.id)!;\n        return copyFile(\n          path.join(this.input.localWorkingDir.toString(), filesystemFile.filename),\n          path.join(this.input.interpreterWorkingDir.toString(), filesystemFile.id),\n        );\n      }),\n    );\n    return files.map((file) => ({ ...file, pythonId: file.id }));\n  }\n\n  async download(files: PythonDownloadFile[]) {\n    await this.init();\n\n    await Promise.all(\n      files.map((file) =>\n        copyFile(\n          path.join(this.input.interpreterWorkingDir.toString(), file.pythonId),\n          path.join(this.input.localWorkingDir.toString(), file.filename),\n        ),\n      ),\n    );\n    return files.map((file) => ({ ...file, id: file.pythonId }));\n  }\n\n  protected async computeHash(file: PathLike) {\n    const content = await fs.promises.readFile(file);\n    return SHA256(content.toString()).toString();\n  }\n\n  createSnapshot() {\n    return { input: shallowCopy(this.input) };\n  }\n\n  loadSnapshot(snapshot: ReturnType<typeof this.createSnapshot>) {\n    Object.assign(this, snapshot);\n  }\n}\n"]}