(path: string, options?: { parents?: boolean; existOk?: boolean })
| 767 | } |
| 768 | |
| 769 | async mkdir(path: string, options?: { parents?: boolean; existOk?: boolean }): Promise<void> { |
| 770 | const resolved = this._resolvePath(path); |
| 771 | const parents = options?.parents ?? false; |
| 772 | const existOk = options?.existOk ?? false; |
| 773 | |
| 774 | if (parents) { |
| 775 | await this._mkdirRecursive(resolved, existOk); |
| 776 | } else { |
| 777 | const exists = await sftpExists(this._sftp, resolved); |
| 778 | if (exists) { |
| 779 | if (!existOk) { |
| 780 | throw new KaosFileExistsError(`${resolved} already exists`); |
| 781 | } |
| 782 | // `existOk` only applies when the conflicting path is itself a |
| 783 | // directory. A regular file sitting at the target path is still |
| 784 | // a conflict — we must not pretend mkdir succeeded. |
| 785 | const st = await sftpStat(this._sftp, resolved); |
| 786 | if (!st.isDirectory()) { |
| 787 | throw new KaosFileExistsError(`${resolved} already exists but is not a directory`); |
| 788 | } |
| 789 | return; |
| 790 | } |
| 791 | await sftpMkdir(this._sftp, resolved); |
| 792 | } |
| 793 | } |
| 794 | |
| 795 | private async _mkdirRecursive(path: string, existOk: boolean): Promise<void> { |
| 796 | // Split path into components and create each level. |
nothing calls this directly
no test coverage detected