@zero-transfer/sdk 0.1.0-alpha.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +182 -213
- package/assets/zero-transfer-logo.svg +201 -201
- package/dist/index.cjs +357 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +356 -5
- package/dist/index.d.ts +356 -5
- package/dist/index.mjs +367 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +16 -4
- package/CHANGELOG.md +0 -177
package/dist/index.mjs
CHANGED
|
@@ -2440,6 +2440,74 @@ var FtpFileSystem = class {
|
|
|
2440
2440
|
path: remotePath
|
|
2441
2441
|
};
|
|
2442
2442
|
}
|
|
2443
|
+
async remove(path2, options = {}) {
|
|
2444
|
+
const remotePath = normalizeFtpPath(path2);
|
|
2445
|
+
const response = await this.control.sendCommand(`DELE ${remotePath}`);
|
|
2446
|
+
if (response.completion) return;
|
|
2447
|
+
if (response.code === 550 && options.ignoreMissing) return;
|
|
2448
|
+
assertPathCommandSucceeded(response, "DELE", remotePath, this.control.providerId);
|
|
2449
|
+
}
|
|
2450
|
+
async rename(from, to) {
|
|
2451
|
+
const fromPath = normalizeFtpPath(from);
|
|
2452
|
+
const toPath = normalizeFtpPath(to);
|
|
2453
|
+
const rnfr = await this.control.sendCommand(`RNFR ${fromPath}`);
|
|
2454
|
+
if (!rnfr.intermediate && !rnfr.completion) {
|
|
2455
|
+
assertPathCommandSucceeded(rnfr, "RNFR", fromPath, this.control.providerId);
|
|
2456
|
+
}
|
|
2457
|
+
await expectCompletion(this.control, `RNTO ${toPath}`, toPath);
|
|
2458
|
+
}
|
|
2459
|
+
async mkdir(path2, options = {}) {
|
|
2460
|
+
const remotePath = normalizeFtpPath(path2);
|
|
2461
|
+
if (!options.recursive) {
|
|
2462
|
+
await expectCompletion(this.control, `MKD ${remotePath}`, remotePath);
|
|
2463
|
+
return;
|
|
2464
|
+
}
|
|
2465
|
+
const segments = remotePath.split("/").filter((s) => s.length > 0);
|
|
2466
|
+
let current = "";
|
|
2467
|
+
for (const segment of segments) {
|
|
2468
|
+
current = `${current}/${segment}`;
|
|
2469
|
+
const response = await this.control.sendCommand(`MKD ${current}`);
|
|
2470
|
+
if (response.completion) continue;
|
|
2471
|
+
if (response.code === 550) continue;
|
|
2472
|
+
assertPathCommandSucceeded(response, "MKD", current, this.control.providerId);
|
|
2473
|
+
}
|
|
2474
|
+
}
|
|
2475
|
+
async rmdir(path2, options = {}) {
|
|
2476
|
+
const remotePath = normalizeFtpPath(path2);
|
|
2477
|
+
if (options.recursive) {
|
|
2478
|
+
await this.removeDirectoryRecursive(remotePath);
|
|
2479
|
+
return;
|
|
2480
|
+
}
|
|
2481
|
+
const response = await this.control.sendCommand(`RMD ${remotePath}`);
|
|
2482
|
+
if (response.completion) return;
|
|
2483
|
+
if (response.code === 550 && options.ignoreMissing) return;
|
|
2484
|
+
assertPathCommandSucceeded(response, "RMD", remotePath, this.control.providerId);
|
|
2485
|
+
}
|
|
2486
|
+
async removeDirectoryRecursive(remotePath) {
|
|
2487
|
+
let entries;
|
|
2488
|
+
try {
|
|
2489
|
+
entries = await readDirectoryEntries(this.control, remotePath);
|
|
2490
|
+
} catch (error) {
|
|
2491
|
+
if (error instanceof PathNotFoundError) return;
|
|
2492
|
+
throw error;
|
|
2493
|
+
}
|
|
2494
|
+
for (const entry of entries) {
|
|
2495
|
+
if (entry.name === "." || entry.name === "..") continue;
|
|
2496
|
+
const childPath = entry.path.startsWith("/") ? entry.path : normalizeFtpPath(`${remotePath.replace(/\/+$/, "")}/${entry.name}`);
|
|
2497
|
+
if (entry.type === "directory") {
|
|
2498
|
+
await this.removeDirectoryRecursive(childPath);
|
|
2499
|
+
} else {
|
|
2500
|
+
const del = await this.control.sendCommand(`DELE ${childPath}`);
|
|
2501
|
+
if (!del.completion && del.code !== 550) {
|
|
2502
|
+
assertPathCommandSucceeded(del, "DELE", childPath, this.control.providerId);
|
|
2503
|
+
}
|
|
2504
|
+
}
|
|
2505
|
+
}
|
|
2506
|
+
const response = await this.control.sendCommand(`RMD ${remotePath}`);
|
|
2507
|
+
if (response.completion) return;
|
|
2508
|
+
if (response.code === 550) return;
|
|
2509
|
+
assertPathCommandSucceeded(response, "RMD", remotePath, this.control.providerId);
|
|
2510
|
+
}
|
|
2443
2511
|
};
|
|
2444
2512
|
var FtpControlConnection = class _FtpControlConnection {
|
|
2445
2513
|
/**
|
|
@@ -3473,7 +3541,8 @@ function normalizeFeatureLines(input) {
|
|
|
3473
3541
|
// src/providers/classic/sftp/SftpProvider.ts
|
|
3474
3542
|
import { Buffer as Buffer5 } from "buffer";
|
|
3475
3543
|
import { createHash, createHmac, timingSafeEqual } from "crypto";
|
|
3476
|
-
import
|
|
3544
|
+
import ssh2 from "ssh2";
|
|
3545
|
+
var { Client: SshClientCtor, utils } = ssh2;
|
|
3477
3546
|
var SFTP_PROVIDER_ID = "sftp";
|
|
3478
3547
|
var SFTP_DEFAULT_PORT = 22;
|
|
3479
3548
|
var SFTP_PROVIDER_CAPABILITIES = {
|
|
@@ -3631,9 +3700,104 @@ var SftpFileSystem = class {
|
|
|
3631
3700
|
throw mapSftpError(error, { command: "LSTAT", path: remotePath });
|
|
3632
3701
|
}
|
|
3633
3702
|
}
|
|
3703
|
+
async remove(path2, options = {}) {
|
|
3704
|
+
throwIfAborted2(options.signal, path2, "remove");
|
|
3705
|
+
const remotePath = normalizeSftpPath(path2);
|
|
3706
|
+
try {
|
|
3707
|
+
await sftpUnlink(this.sftp, remotePath);
|
|
3708
|
+
} catch (error) {
|
|
3709
|
+
const mapped = mapSftpError(error, { command: "REMOVE", path: remotePath });
|
|
3710
|
+
if (options.ignoreMissing && mapped instanceof PathNotFoundError) return;
|
|
3711
|
+
throw mapped;
|
|
3712
|
+
}
|
|
3713
|
+
}
|
|
3714
|
+
async rename(from, to, options = {}) {
|
|
3715
|
+
throwIfAborted2(options.signal, from, "rename");
|
|
3716
|
+
const fromPath = normalizeSftpPath(from);
|
|
3717
|
+
const toPath = normalizeSftpPath(to);
|
|
3718
|
+
try {
|
|
3719
|
+
await sftpRename(this.sftp, fromPath, toPath);
|
|
3720
|
+
} catch (error) {
|
|
3721
|
+
throw mapSftpError(error, { command: "RENAME", path: fromPath });
|
|
3722
|
+
}
|
|
3723
|
+
}
|
|
3724
|
+
async mkdir(path2, options = {}) {
|
|
3725
|
+
throwIfAborted2(options.signal, path2, "mkdir");
|
|
3726
|
+
const remotePath = normalizeSftpPath(path2);
|
|
3727
|
+
if (!options.recursive) {
|
|
3728
|
+
try {
|
|
3729
|
+
await sftpMkdir(this.sftp, remotePath);
|
|
3730
|
+
} catch (error) {
|
|
3731
|
+
throw mapSftpError(error, { command: "MKDIR", path: remotePath });
|
|
3732
|
+
}
|
|
3733
|
+
return;
|
|
3734
|
+
}
|
|
3735
|
+
const segments = remotePath.split("/").filter((s) => s.length > 0);
|
|
3736
|
+
let current = "";
|
|
3737
|
+
for (const segment of segments) {
|
|
3738
|
+
current = `${current}/${segment}`;
|
|
3739
|
+
try {
|
|
3740
|
+
await sftpMkdir(this.sftp, current);
|
|
3741
|
+
} catch (error) {
|
|
3742
|
+
try {
|
|
3743
|
+
const stats = await readSftpStats(this.sftp, current);
|
|
3744
|
+
if (stats.isDirectory()) continue;
|
|
3745
|
+
} catch {
|
|
3746
|
+
}
|
|
3747
|
+
throw mapSftpError(error, { command: "MKDIR", path: current });
|
|
3748
|
+
}
|
|
3749
|
+
}
|
|
3750
|
+
}
|
|
3751
|
+
async rmdir(path2, options = {}) {
|
|
3752
|
+
throwIfAborted2(options.signal, path2, "rmdir");
|
|
3753
|
+
const remotePath = normalizeSftpPath(path2);
|
|
3754
|
+
if (options.recursive) {
|
|
3755
|
+
await this.removeDirectoryRecursive(remotePath);
|
|
3756
|
+
return;
|
|
3757
|
+
}
|
|
3758
|
+
try {
|
|
3759
|
+
await sftpRmdir(this.sftp, remotePath);
|
|
3760
|
+
} catch (error) {
|
|
3761
|
+
const mapped = mapSftpError(error, { command: "RMDIR", path: remotePath });
|
|
3762
|
+
if (options.ignoreMissing && mapped instanceof PathNotFoundError) return;
|
|
3763
|
+
throw mapped;
|
|
3764
|
+
}
|
|
3765
|
+
}
|
|
3766
|
+
async removeDirectoryRecursive(remotePath) {
|
|
3767
|
+
let entries;
|
|
3768
|
+
try {
|
|
3769
|
+
entries = await readSftpDirectory(this.sftp, remotePath);
|
|
3770
|
+
} catch (error) {
|
|
3771
|
+
const mapped = mapSftpError(error, { command: "READDIR", path: remotePath });
|
|
3772
|
+
if (mapped instanceof PathNotFoundError) return;
|
|
3773
|
+
throw mapped;
|
|
3774
|
+
}
|
|
3775
|
+
for (const entry of entries) {
|
|
3776
|
+
if (entry.filename === "." || entry.filename === "..") continue;
|
|
3777
|
+
const childPath = `${remotePath.replace(/\/+$/, "")}/${entry.filename}`.replace(/\/+/g, "/");
|
|
3778
|
+
const isDir = entry.attrs.isDirectory();
|
|
3779
|
+
try {
|
|
3780
|
+
if (isDir) {
|
|
3781
|
+
await this.removeDirectoryRecursive(childPath);
|
|
3782
|
+
} else {
|
|
3783
|
+
await sftpUnlink(this.sftp, childPath);
|
|
3784
|
+
}
|
|
3785
|
+
} catch (error) {
|
|
3786
|
+
throw mapSftpError(error, {
|
|
3787
|
+
command: isDir ? "RMDIR" : "REMOVE",
|
|
3788
|
+
path: childPath
|
|
3789
|
+
});
|
|
3790
|
+
}
|
|
3791
|
+
}
|
|
3792
|
+
try {
|
|
3793
|
+
await sftpRmdir(this.sftp, remotePath);
|
|
3794
|
+
} catch (error) {
|
|
3795
|
+
throw mapSftpError(error, { command: "RMDIR", path: remotePath });
|
|
3796
|
+
}
|
|
3797
|
+
}
|
|
3634
3798
|
};
|
|
3635
3799
|
async function connectSshClient(profile, options, username, authentication) {
|
|
3636
|
-
const client = new
|
|
3800
|
+
const client = new SshClientCtor();
|
|
3637
3801
|
let config;
|
|
3638
3802
|
try {
|
|
3639
3803
|
config = await createConnectConfig(profile, options, username, authentication);
|
|
@@ -4022,6 +4186,50 @@ function readSftpStats(sftp, path2) {
|
|
|
4022
4186
|
});
|
|
4023
4187
|
});
|
|
4024
4188
|
}
|
|
4189
|
+
function sftpUnlink(sftp, path2) {
|
|
4190
|
+
return new Promise((resolve, reject) => {
|
|
4191
|
+
sftp.unlink(path2, (error) => {
|
|
4192
|
+
if (error !== void 0 && error !== null) {
|
|
4193
|
+
reject(error);
|
|
4194
|
+
return;
|
|
4195
|
+
}
|
|
4196
|
+
resolve();
|
|
4197
|
+
});
|
|
4198
|
+
});
|
|
4199
|
+
}
|
|
4200
|
+
function sftpRename(sftp, from, to) {
|
|
4201
|
+
return new Promise((resolve, reject) => {
|
|
4202
|
+
sftp.rename(from, to, (error) => {
|
|
4203
|
+
if (error !== void 0 && error !== null) {
|
|
4204
|
+
reject(error);
|
|
4205
|
+
return;
|
|
4206
|
+
}
|
|
4207
|
+
resolve();
|
|
4208
|
+
});
|
|
4209
|
+
});
|
|
4210
|
+
}
|
|
4211
|
+
function sftpMkdir(sftp, path2) {
|
|
4212
|
+
return new Promise((resolve, reject) => {
|
|
4213
|
+
sftp.mkdir(path2, (error) => {
|
|
4214
|
+
if (error !== void 0 && error !== null) {
|
|
4215
|
+
reject(error);
|
|
4216
|
+
return;
|
|
4217
|
+
}
|
|
4218
|
+
resolve();
|
|
4219
|
+
});
|
|
4220
|
+
});
|
|
4221
|
+
}
|
|
4222
|
+
function sftpRmdir(sftp, path2) {
|
|
4223
|
+
return new Promise((resolve, reject) => {
|
|
4224
|
+
sftp.rmdir(path2, (error) => {
|
|
4225
|
+
if (error !== void 0 && error !== null) {
|
|
4226
|
+
reject(error);
|
|
4227
|
+
return;
|
|
4228
|
+
}
|
|
4229
|
+
resolve();
|
|
4230
|
+
});
|
|
4231
|
+
});
|
|
4232
|
+
}
|
|
4025
4233
|
async function* createSftpReadSource(sftp, path2, range, request) {
|
|
4026
4234
|
if (range.length <= 0) {
|
|
4027
4235
|
return;
|
|
@@ -4349,7 +4557,8 @@ function noop() {
|
|
|
4349
4557
|
|
|
4350
4558
|
// src/providers/classic/sftp/jumpHost.ts
|
|
4351
4559
|
import { Buffer as Buffer6 } from "buffer";
|
|
4352
|
-
import
|
|
4560
|
+
import ssh22 from "ssh2";
|
|
4561
|
+
var { Client: SshClientCtor2 } = ssh22;
|
|
4353
4562
|
function createSftpJumpHostSocketFactory(options) {
|
|
4354
4563
|
if (options.bastion === void 0 && options.buildBastion === void 0) {
|
|
4355
4564
|
throw new ConfigurationError({
|
|
@@ -4370,7 +4579,7 @@ function createSftpJumpHostSocketFactory(options) {
|
|
|
4370
4579
|
}
|
|
4371
4580
|
function openJumpHostChannel(options) {
|
|
4372
4581
|
const { bastionConfig, context } = options;
|
|
4373
|
-
const client = options.createClient ? options.createClient() : new
|
|
4582
|
+
const client = options.createClient ? options.createClient() : new SshClientCtor2();
|
|
4374
4583
|
if (context.signal?.aborted === true) {
|
|
4375
4584
|
return Promise.reject(
|
|
4376
4585
|
new AbortError({
|
|
@@ -6730,7 +6939,17 @@ async function collectChunks5(source) {
|
|
|
6730
6939
|
|
|
6731
6940
|
// src/providers/local/LocalProvider.ts
|
|
6732
6941
|
import { createReadStream } from "fs";
|
|
6733
|
-
import {
|
|
6942
|
+
import {
|
|
6943
|
+
lstat,
|
|
6944
|
+
mkdir,
|
|
6945
|
+
open,
|
|
6946
|
+
readdir,
|
|
6947
|
+
readlink,
|
|
6948
|
+
rename,
|
|
6949
|
+
rm,
|
|
6950
|
+
unlink,
|
|
6951
|
+
writeFile
|
|
6952
|
+
} from "fs/promises";
|
|
6734
6953
|
import path from "path";
|
|
6735
6954
|
var LOCAL_PROVIDER_ID = "local";
|
|
6736
6955
|
var LOCAL_PROVIDER_CAPABILITIES = {
|
|
@@ -6856,7 +7075,55 @@ var LocalFileSystem = class {
|
|
|
6856
7075
|
async stat(path2) {
|
|
6857
7076
|
return readLocalEntry(this.rootPath, normalizeLocalProviderPath(path2));
|
|
6858
7077
|
}
|
|
7078
|
+
async remove(remote, options = {}) {
|
|
7079
|
+
const remotePath = normalizeLocalProviderPath(remote);
|
|
7080
|
+
const localPath = resolveLocalPath(this.rootPath, remotePath);
|
|
7081
|
+
try {
|
|
7082
|
+
await unlink(localPath);
|
|
7083
|
+
} catch (error) {
|
|
7084
|
+
if (options.ignoreMissing && isNodeErrno(error, "ENOENT")) return;
|
|
7085
|
+
if (isNodeErrno(error, "ENOENT")) {
|
|
7086
|
+
throw createPathNotFoundError(remotePath, `Local path not found: ${remotePath}`);
|
|
7087
|
+
}
|
|
7088
|
+
throw error;
|
|
7089
|
+
}
|
|
7090
|
+
}
|
|
7091
|
+
async rename(from, to) {
|
|
7092
|
+
const fromRemote = normalizeLocalProviderPath(from);
|
|
7093
|
+
const toRemote = normalizeLocalProviderPath(to);
|
|
7094
|
+
const fromLocal = resolveLocalPath(this.rootPath, fromRemote);
|
|
7095
|
+
const toLocal = resolveLocalPath(this.rootPath, toRemote);
|
|
7096
|
+
try {
|
|
7097
|
+
await rename(fromLocal, toLocal);
|
|
7098
|
+
} catch (error) {
|
|
7099
|
+
if (isNodeErrno(error, "ENOENT")) {
|
|
7100
|
+
throw createPathNotFoundError(fromRemote, `Local path not found: ${fromRemote}`);
|
|
7101
|
+
}
|
|
7102
|
+
throw error;
|
|
7103
|
+
}
|
|
7104
|
+
}
|
|
7105
|
+
async mkdir(remote, options = {}) {
|
|
7106
|
+
const remotePath = normalizeLocalProviderPath(remote);
|
|
7107
|
+
const localPath = resolveLocalPath(this.rootPath, remotePath);
|
|
7108
|
+
await mkdir(localPath, { recursive: options.recursive === true });
|
|
7109
|
+
}
|
|
7110
|
+
async rmdir(remote, options = {}) {
|
|
7111
|
+
const remotePath = normalizeLocalProviderPath(remote);
|
|
7112
|
+
const localPath = resolveLocalPath(this.rootPath, remotePath);
|
|
7113
|
+
try {
|
|
7114
|
+
await rm(localPath, { recursive: options.recursive === true, force: false });
|
|
7115
|
+
} catch (error) {
|
|
7116
|
+
if (isNodeErrno(error, "ENOENT")) {
|
|
7117
|
+
if (options.ignoreMissing) return;
|
|
7118
|
+
throw createPathNotFoundError(remotePath, `Local path not found: ${remotePath}`);
|
|
7119
|
+
}
|
|
7120
|
+
throw error;
|
|
7121
|
+
}
|
|
7122
|
+
}
|
|
6859
7123
|
};
|
|
7124
|
+
function isNodeErrno(error, code) {
|
|
7125
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
7126
|
+
}
|
|
6860
7127
|
function resolveReadRange2(size, range) {
|
|
6861
7128
|
if (range === void 0) {
|
|
6862
7129
|
return { length: size, offset: 0 };
|
|
@@ -7019,6 +7286,11 @@ function normalizeLocalProviderPath(input) {
|
|
|
7019
7286
|
}
|
|
7020
7287
|
function resolveLocalPath(rootPath, remotePath) {
|
|
7021
7288
|
const normalizedRemotePath = normalizeLocalProviderPath(remotePath);
|
|
7289
|
+
const resolvedRootPath = path.resolve(rootPath);
|
|
7290
|
+
const candidateAbsolute = path.resolve(normalizedRemotePath.split("/").join(path.sep));
|
|
7291
|
+
if (candidateAbsolute === resolvedRootPath || candidateAbsolute.startsWith(resolvedRootPath + path.sep)) {
|
|
7292
|
+
return candidateAbsolute;
|
|
7293
|
+
}
|
|
7022
7294
|
const relativePath = normalizedRemotePath === "/" ? "." : normalizedRemotePath.slice(1);
|
|
7023
7295
|
const resolvedPath = path.resolve(rootPath, relativePath.split("/").join(path.sep));
|
|
7024
7296
|
const relativeToRoot = path.relative(rootPath, resolvedPath);
|
|
@@ -7170,6 +7442,96 @@ var MemoryFileSystem = class {
|
|
|
7170
7442
|
() => cloneRemoteStat(this.requireEntry(normalizeMemoryPath(path2)))
|
|
7171
7443
|
);
|
|
7172
7444
|
}
|
|
7445
|
+
remove(path2, options = {}) {
|
|
7446
|
+
return Promise.resolve().then(() => {
|
|
7447
|
+
const normalized = normalizeMemoryPath(path2);
|
|
7448
|
+
const entry = this.state.entries.get(normalized);
|
|
7449
|
+
if (entry === void 0) {
|
|
7450
|
+
if (options.ignoreMissing) return;
|
|
7451
|
+
throw createPathNotFoundError2(normalized, `Memory path not found: ${normalized}`);
|
|
7452
|
+
}
|
|
7453
|
+
if (entry.type === "directory") {
|
|
7454
|
+
throw createPathNotFoundError2(
|
|
7455
|
+
normalized,
|
|
7456
|
+
`Memory path is a directory; use rmdir: ${normalized}`
|
|
7457
|
+
);
|
|
7458
|
+
}
|
|
7459
|
+
this.state.entries.delete(normalized);
|
|
7460
|
+
this.state.content.delete(normalized);
|
|
7461
|
+
});
|
|
7462
|
+
}
|
|
7463
|
+
rename(from, to) {
|
|
7464
|
+
return Promise.resolve().then(() => {
|
|
7465
|
+
const fromPath = normalizeMemoryPath(from);
|
|
7466
|
+
const toPath = normalizeMemoryPath(to);
|
|
7467
|
+
const entry = this.state.entries.get(fromPath);
|
|
7468
|
+
if (entry === void 0) {
|
|
7469
|
+
throw createPathNotFoundError2(fromPath, `Memory path not found: ${fromPath}`);
|
|
7470
|
+
}
|
|
7471
|
+
ensureParentDirectories(this.state.entries, toPath);
|
|
7472
|
+
const moved = { ...entry, path: toPath, name: basenameRemotePath(toPath) };
|
|
7473
|
+
this.state.entries.delete(fromPath);
|
|
7474
|
+
this.state.entries.set(toPath, moved);
|
|
7475
|
+
const content = this.state.content.get(fromPath);
|
|
7476
|
+
if (content !== void 0) {
|
|
7477
|
+
this.state.content.delete(fromPath);
|
|
7478
|
+
this.state.content.set(toPath, content);
|
|
7479
|
+
}
|
|
7480
|
+
});
|
|
7481
|
+
}
|
|
7482
|
+
mkdir(path2, options = {}) {
|
|
7483
|
+
return Promise.resolve().then(() => {
|
|
7484
|
+
const normalized = normalizeMemoryPath(path2);
|
|
7485
|
+
const existing = this.state.entries.get(normalized);
|
|
7486
|
+
if (existing !== void 0) {
|
|
7487
|
+
if (existing.type === "directory" && options.recursive) return;
|
|
7488
|
+
throw createInvalidFixtureError(normalized, `Memory path already exists: ${normalized}`);
|
|
7489
|
+
}
|
|
7490
|
+
if (options.recursive) {
|
|
7491
|
+
ensureParentDirectories(this.state.entries, normalized);
|
|
7492
|
+
} else {
|
|
7493
|
+
const parent = getParentPath2(normalized);
|
|
7494
|
+
if (parent !== void 0 && !this.state.entries.has(parent)) {
|
|
7495
|
+
throw createPathNotFoundError2(parent, `Memory parent not found: ${parent}`);
|
|
7496
|
+
}
|
|
7497
|
+
}
|
|
7498
|
+
this.state.entries.set(normalized, createDirectoryEntry(normalized));
|
|
7499
|
+
});
|
|
7500
|
+
}
|
|
7501
|
+
rmdir(path2, options = {}) {
|
|
7502
|
+
return Promise.resolve().then(() => {
|
|
7503
|
+
const normalized = normalizeMemoryPath(path2);
|
|
7504
|
+
const entry = this.state.entries.get(normalized);
|
|
7505
|
+
if (entry === void 0) {
|
|
7506
|
+
if (options.ignoreMissing) return;
|
|
7507
|
+
throw createPathNotFoundError2(normalized, `Memory path not found: ${normalized}`);
|
|
7508
|
+
}
|
|
7509
|
+
if (entry.type !== "directory") {
|
|
7510
|
+
throw createPathNotFoundError2(normalized, `Memory path is not a directory: ${normalized}`);
|
|
7511
|
+
}
|
|
7512
|
+
const children = [...this.state.entries.values()].filter(
|
|
7513
|
+
(child) => child.path !== normalized && getParentPath2(child.path) === normalized
|
|
7514
|
+
);
|
|
7515
|
+
if (children.length > 0 && !options.recursive) {
|
|
7516
|
+
throw createInvalidFixtureError(normalized, `Memory directory not empty: ${normalized}`);
|
|
7517
|
+
}
|
|
7518
|
+
const stack = [...children];
|
|
7519
|
+
while (stack.length > 0) {
|
|
7520
|
+
const next = stack.pop();
|
|
7521
|
+
if (!next) continue;
|
|
7522
|
+
if (next.type === "directory") {
|
|
7523
|
+
for (const grand of this.state.entries.values()) {
|
|
7524
|
+
if (grand.path !== next.path && getParentPath2(grand.path) === next.path) {
|
|
7525
|
+
stack.push(grand);
|
|
7526
|
+
}
|
|
7527
|
+
}
|
|
7528
|
+
}
|
|
7529
|
+
this.state.entries.delete(next.path);
|
|
7530
|
+
this.state.content.delete(next.path);
|
|
7531
|
+
}
|
|
7532
|
+
this.state.entries.delete(normalized);
|
|
7533
|
+
});
|
|
7534
|
+
}
|
|
7173
7535
|
requireEntry(path2) {
|
|
7174
7536
|
const entry = this.state.entries.get(path2);
|
|
7175
7537
|
if (entry === void 0) {
|