@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.cjs
CHANGED
|
@@ -2601,6 +2601,74 @@ var FtpFileSystem = class {
|
|
|
2601
2601
|
path: remotePath
|
|
2602
2602
|
};
|
|
2603
2603
|
}
|
|
2604
|
+
async remove(path2, options = {}) {
|
|
2605
|
+
const remotePath = normalizeFtpPath(path2);
|
|
2606
|
+
const response = await this.control.sendCommand(`DELE ${remotePath}`);
|
|
2607
|
+
if (response.completion) return;
|
|
2608
|
+
if (response.code === 550 && options.ignoreMissing) return;
|
|
2609
|
+
assertPathCommandSucceeded(response, "DELE", remotePath, this.control.providerId);
|
|
2610
|
+
}
|
|
2611
|
+
async rename(from, to) {
|
|
2612
|
+
const fromPath = normalizeFtpPath(from);
|
|
2613
|
+
const toPath = normalizeFtpPath(to);
|
|
2614
|
+
const rnfr = await this.control.sendCommand(`RNFR ${fromPath}`);
|
|
2615
|
+
if (!rnfr.intermediate && !rnfr.completion) {
|
|
2616
|
+
assertPathCommandSucceeded(rnfr, "RNFR", fromPath, this.control.providerId);
|
|
2617
|
+
}
|
|
2618
|
+
await expectCompletion(this.control, `RNTO ${toPath}`, toPath);
|
|
2619
|
+
}
|
|
2620
|
+
async mkdir(path2, options = {}) {
|
|
2621
|
+
const remotePath = normalizeFtpPath(path2);
|
|
2622
|
+
if (!options.recursive) {
|
|
2623
|
+
await expectCompletion(this.control, `MKD ${remotePath}`, remotePath);
|
|
2624
|
+
return;
|
|
2625
|
+
}
|
|
2626
|
+
const segments = remotePath.split("/").filter((s) => s.length > 0);
|
|
2627
|
+
let current = "";
|
|
2628
|
+
for (const segment of segments) {
|
|
2629
|
+
current = `${current}/${segment}`;
|
|
2630
|
+
const response = await this.control.sendCommand(`MKD ${current}`);
|
|
2631
|
+
if (response.completion) continue;
|
|
2632
|
+
if (response.code === 550) continue;
|
|
2633
|
+
assertPathCommandSucceeded(response, "MKD", current, this.control.providerId);
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
async rmdir(path2, options = {}) {
|
|
2637
|
+
const remotePath = normalizeFtpPath(path2);
|
|
2638
|
+
if (options.recursive) {
|
|
2639
|
+
await this.removeDirectoryRecursive(remotePath);
|
|
2640
|
+
return;
|
|
2641
|
+
}
|
|
2642
|
+
const response = await this.control.sendCommand(`RMD ${remotePath}`);
|
|
2643
|
+
if (response.completion) return;
|
|
2644
|
+
if (response.code === 550 && options.ignoreMissing) return;
|
|
2645
|
+
assertPathCommandSucceeded(response, "RMD", remotePath, this.control.providerId);
|
|
2646
|
+
}
|
|
2647
|
+
async removeDirectoryRecursive(remotePath) {
|
|
2648
|
+
let entries;
|
|
2649
|
+
try {
|
|
2650
|
+
entries = await readDirectoryEntries(this.control, remotePath);
|
|
2651
|
+
} catch (error) {
|
|
2652
|
+
if (error instanceof PathNotFoundError) return;
|
|
2653
|
+
throw error;
|
|
2654
|
+
}
|
|
2655
|
+
for (const entry of entries) {
|
|
2656
|
+
if (entry.name === "." || entry.name === "..") continue;
|
|
2657
|
+
const childPath = entry.path.startsWith("/") ? entry.path : normalizeFtpPath(`${remotePath.replace(/\/+$/, "")}/${entry.name}`);
|
|
2658
|
+
if (entry.type === "directory") {
|
|
2659
|
+
await this.removeDirectoryRecursive(childPath);
|
|
2660
|
+
} else {
|
|
2661
|
+
const del = await this.control.sendCommand(`DELE ${childPath}`);
|
|
2662
|
+
if (!del.completion && del.code !== 550) {
|
|
2663
|
+
assertPathCommandSucceeded(del, "DELE", childPath, this.control.providerId);
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
}
|
|
2667
|
+
const response = await this.control.sendCommand(`RMD ${remotePath}`);
|
|
2668
|
+
if (response.completion) return;
|
|
2669
|
+
if (response.code === 550) return;
|
|
2670
|
+
assertPathCommandSucceeded(response, "RMD", remotePath, this.control.providerId);
|
|
2671
|
+
}
|
|
2604
2672
|
};
|
|
2605
2673
|
var FtpControlConnection = class _FtpControlConnection {
|
|
2606
2674
|
/**
|
|
@@ -3634,7 +3702,8 @@ function normalizeFeatureLines(input) {
|
|
|
3634
3702
|
// src/providers/classic/sftp/SftpProvider.ts
|
|
3635
3703
|
var import_node_buffer4 = require("buffer");
|
|
3636
3704
|
var import_node_crypto = require("crypto");
|
|
3637
|
-
var import_ssh2 = require("ssh2");
|
|
3705
|
+
var import_ssh2 = __toESM(require("ssh2"));
|
|
3706
|
+
var { Client: SshClientCtor, utils } = import_ssh2.default;
|
|
3638
3707
|
var SFTP_PROVIDER_ID = "sftp";
|
|
3639
3708
|
var SFTP_DEFAULT_PORT = 22;
|
|
3640
3709
|
var SFTP_PROVIDER_CAPABILITIES = {
|
|
@@ -3792,9 +3861,104 @@ var SftpFileSystem = class {
|
|
|
3792
3861
|
throw mapSftpError(error, { command: "LSTAT", path: remotePath });
|
|
3793
3862
|
}
|
|
3794
3863
|
}
|
|
3864
|
+
async remove(path2, options = {}) {
|
|
3865
|
+
throwIfAborted2(options.signal, path2, "remove");
|
|
3866
|
+
const remotePath = normalizeSftpPath(path2);
|
|
3867
|
+
try {
|
|
3868
|
+
await sftpUnlink(this.sftp, remotePath);
|
|
3869
|
+
} catch (error) {
|
|
3870
|
+
const mapped = mapSftpError(error, { command: "REMOVE", path: remotePath });
|
|
3871
|
+
if (options.ignoreMissing && mapped instanceof PathNotFoundError) return;
|
|
3872
|
+
throw mapped;
|
|
3873
|
+
}
|
|
3874
|
+
}
|
|
3875
|
+
async rename(from, to, options = {}) {
|
|
3876
|
+
throwIfAborted2(options.signal, from, "rename");
|
|
3877
|
+
const fromPath = normalizeSftpPath(from);
|
|
3878
|
+
const toPath = normalizeSftpPath(to);
|
|
3879
|
+
try {
|
|
3880
|
+
await sftpRename(this.sftp, fromPath, toPath);
|
|
3881
|
+
} catch (error) {
|
|
3882
|
+
throw mapSftpError(error, { command: "RENAME", path: fromPath });
|
|
3883
|
+
}
|
|
3884
|
+
}
|
|
3885
|
+
async mkdir(path2, options = {}) {
|
|
3886
|
+
throwIfAborted2(options.signal, path2, "mkdir");
|
|
3887
|
+
const remotePath = normalizeSftpPath(path2);
|
|
3888
|
+
if (!options.recursive) {
|
|
3889
|
+
try {
|
|
3890
|
+
await sftpMkdir(this.sftp, remotePath);
|
|
3891
|
+
} catch (error) {
|
|
3892
|
+
throw mapSftpError(error, { command: "MKDIR", path: remotePath });
|
|
3893
|
+
}
|
|
3894
|
+
return;
|
|
3895
|
+
}
|
|
3896
|
+
const segments = remotePath.split("/").filter((s) => s.length > 0);
|
|
3897
|
+
let current = "";
|
|
3898
|
+
for (const segment of segments) {
|
|
3899
|
+
current = `${current}/${segment}`;
|
|
3900
|
+
try {
|
|
3901
|
+
await sftpMkdir(this.sftp, current);
|
|
3902
|
+
} catch (error) {
|
|
3903
|
+
try {
|
|
3904
|
+
const stats = await readSftpStats(this.sftp, current);
|
|
3905
|
+
if (stats.isDirectory()) continue;
|
|
3906
|
+
} catch {
|
|
3907
|
+
}
|
|
3908
|
+
throw mapSftpError(error, { command: "MKDIR", path: current });
|
|
3909
|
+
}
|
|
3910
|
+
}
|
|
3911
|
+
}
|
|
3912
|
+
async rmdir(path2, options = {}) {
|
|
3913
|
+
throwIfAborted2(options.signal, path2, "rmdir");
|
|
3914
|
+
const remotePath = normalizeSftpPath(path2);
|
|
3915
|
+
if (options.recursive) {
|
|
3916
|
+
await this.removeDirectoryRecursive(remotePath);
|
|
3917
|
+
return;
|
|
3918
|
+
}
|
|
3919
|
+
try {
|
|
3920
|
+
await sftpRmdir(this.sftp, remotePath);
|
|
3921
|
+
} catch (error) {
|
|
3922
|
+
const mapped = mapSftpError(error, { command: "RMDIR", path: remotePath });
|
|
3923
|
+
if (options.ignoreMissing && mapped instanceof PathNotFoundError) return;
|
|
3924
|
+
throw mapped;
|
|
3925
|
+
}
|
|
3926
|
+
}
|
|
3927
|
+
async removeDirectoryRecursive(remotePath) {
|
|
3928
|
+
let entries;
|
|
3929
|
+
try {
|
|
3930
|
+
entries = await readSftpDirectory(this.sftp, remotePath);
|
|
3931
|
+
} catch (error) {
|
|
3932
|
+
const mapped = mapSftpError(error, { command: "READDIR", path: remotePath });
|
|
3933
|
+
if (mapped instanceof PathNotFoundError) return;
|
|
3934
|
+
throw mapped;
|
|
3935
|
+
}
|
|
3936
|
+
for (const entry of entries) {
|
|
3937
|
+
if (entry.filename === "." || entry.filename === "..") continue;
|
|
3938
|
+
const childPath = `${remotePath.replace(/\/+$/, "")}/${entry.filename}`.replace(/\/+/g, "/");
|
|
3939
|
+
const isDir = entry.attrs.isDirectory();
|
|
3940
|
+
try {
|
|
3941
|
+
if (isDir) {
|
|
3942
|
+
await this.removeDirectoryRecursive(childPath);
|
|
3943
|
+
} else {
|
|
3944
|
+
await sftpUnlink(this.sftp, childPath);
|
|
3945
|
+
}
|
|
3946
|
+
} catch (error) {
|
|
3947
|
+
throw mapSftpError(error, {
|
|
3948
|
+
command: isDir ? "RMDIR" : "REMOVE",
|
|
3949
|
+
path: childPath
|
|
3950
|
+
});
|
|
3951
|
+
}
|
|
3952
|
+
}
|
|
3953
|
+
try {
|
|
3954
|
+
await sftpRmdir(this.sftp, remotePath);
|
|
3955
|
+
} catch (error) {
|
|
3956
|
+
throw mapSftpError(error, { command: "RMDIR", path: remotePath });
|
|
3957
|
+
}
|
|
3958
|
+
}
|
|
3795
3959
|
};
|
|
3796
3960
|
async function connectSshClient(profile, options, username, authentication) {
|
|
3797
|
-
const client = new
|
|
3961
|
+
const client = new SshClientCtor();
|
|
3798
3962
|
let config;
|
|
3799
3963
|
try {
|
|
3800
3964
|
config = await createConnectConfig(profile, options, username, authentication);
|
|
@@ -3993,7 +4157,7 @@ function parseKnownHostsLine(line, lineNumber) {
|
|
|
3993
4157
|
};
|
|
3994
4158
|
}
|
|
3995
4159
|
function parseKnownHostPublicKey(value, lineNumber) {
|
|
3996
|
-
const parsed =
|
|
4160
|
+
const parsed = utils.parseKey(value);
|
|
3997
4161
|
if (parsed instanceof Error) {
|
|
3998
4162
|
throw createKnownHostsConfigurationError(lineNumber, parsed.message);
|
|
3999
4163
|
}
|
|
@@ -4183,6 +4347,50 @@ function readSftpStats(sftp, path2) {
|
|
|
4183
4347
|
});
|
|
4184
4348
|
});
|
|
4185
4349
|
}
|
|
4350
|
+
function sftpUnlink(sftp, path2) {
|
|
4351
|
+
return new Promise((resolve, reject) => {
|
|
4352
|
+
sftp.unlink(path2, (error) => {
|
|
4353
|
+
if (error !== void 0 && error !== null) {
|
|
4354
|
+
reject(error);
|
|
4355
|
+
return;
|
|
4356
|
+
}
|
|
4357
|
+
resolve();
|
|
4358
|
+
});
|
|
4359
|
+
});
|
|
4360
|
+
}
|
|
4361
|
+
function sftpRename(sftp, from, to) {
|
|
4362
|
+
return new Promise((resolve, reject) => {
|
|
4363
|
+
sftp.rename(from, to, (error) => {
|
|
4364
|
+
if (error !== void 0 && error !== null) {
|
|
4365
|
+
reject(error);
|
|
4366
|
+
return;
|
|
4367
|
+
}
|
|
4368
|
+
resolve();
|
|
4369
|
+
});
|
|
4370
|
+
});
|
|
4371
|
+
}
|
|
4372
|
+
function sftpMkdir(sftp, path2) {
|
|
4373
|
+
return new Promise((resolve, reject) => {
|
|
4374
|
+
sftp.mkdir(path2, (error) => {
|
|
4375
|
+
if (error !== void 0 && error !== null) {
|
|
4376
|
+
reject(error);
|
|
4377
|
+
return;
|
|
4378
|
+
}
|
|
4379
|
+
resolve();
|
|
4380
|
+
});
|
|
4381
|
+
});
|
|
4382
|
+
}
|
|
4383
|
+
function sftpRmdir(sftp, path2) {
|
|
4384
|
+
return new Promise((resolve, reject) => {
|
|
4385
|
+
sftp.rmdir(path2, (error) => {
|
|
4386
|
+
if (error !== void 0 && error !== null) {
|
|
4387
|
+
reject(error);
|
|
4388
|
+
return;
|
|
4389
|
+
}
|
|
4390
|
+
resolve();
|
|
4391
|
+
});
|
|
4392
|
+
});
|
|
4393
|
+
}
|
|
4186
4394
|
async function* createSftpReadSource(sftp, path2, range, request) {
|
|
4187
4395
|
if (range.length <= 0) {
|
|
4188
4396
|
return;
|
|
@@ -4510,7 +4718,8 @@ function noop() {
|
|
|
4510
4718
|
|
|
4511
4719
|
// src/providers/classic/sftp/jumpHost.ts
|
|
4512
4720
|
var import_node_buffer5 = require("buffer");
|
|
4513
|
-
var import_ssh22 = require("ssh2");
|
|
4721
|
+
var import_ssh22 = __toESM(require("ssh2"));
|
|
4722
|
+
var { Client: SshClientCtor2 } = import_ssh22.default;
|
|
4514
4723
|
function createSftpJumpHostSocketFactory(options) {
|
|
4515
4724
|
if (options.bastion === void 0 && options.buildBastion === void 0) {
|
|
4516
4725
|
throw new ConfigurationError({
|
|
@@ -4531,7 +4740,7 @@ function createSftpJumpHostSocketFactory(options) {
|
|
|
4531
4740
|
}
|
|
4532
4741
|
function openJumpHostChannel(options) {
|
|
4533
4742
|
const { bastionConfig, context } = options;
|
|
4534
|
-
const client = options.createClient ? options.createClient() : new
|
|
4743
|
+
const client = options.createClient ? options.createClient() : new SshClientCtor2();
|
|
4535
4744
|
if (context.signal?.aborted === true) {
|
|
4536
4745
|
return Promise.reject(
|
|
4537
4746
|
new AbortError({
|
|
@@ -7017,7 +7226,55 @@ var LocalFileSystem = class {
|
|
|
7017
7226
|
async stat(path2) {
|
|
7018
7227
|
return readLocalEntry(this.rootPath, normalizeLocalProviderPath(path2));
|
|
7019
7228
|
}
|
|
7229
|
+
async remove(remote, options = {}) {
|
|
7230
|
+
const remotePath = normalizeLocalProviderPath(remote);
|
|
7231
|
+
const localPath = resolveLocalPath(this.rootPath, remotePath);
|
|
7232
|
+
try {
|
|
7233
|
+
await (0, import_promises2.unlink)(localPath);
|
|
7234
|
+
} catch (error) {
|
|
7235
|
+
if (options.ignoreMissing && isNodeErrno(error, "ENOENT")) return;
|
|
7236
|
+
if (isNodeErrno(error, "ENOENT")) {
|
|
7237
|
+
throw createPathNotFoundError(remotePath, `Local path not found: ${remotePath}`);
|
|
7238
|
+
}
|
|
7239
|
+
throw error;
|
|
7240
|
+
}
|
|
7241
|
+
}
|
|
7242
|
+
async rename(from, to) {
|
|
7243
|
+
const fromRemote = normalizeLocalProviderPath(from);
|
|
7244
|
+
const toRemote = normalizeLocalProviderPath(to);
|
|
7245
|
+
const fromLocal = resolveLocalPath(this.rootPath, fromRemote);
|
|
7246
|
+
const toLocal = resolveLocalPath(this.rootPath, toRemote);
|
|
7247
|
+
try {
|
|
7248
|
+
await (0, import_promises2.rename)(fromLocal, toLocal);
|
|
7249
|
+
} catch (error) {
|
|
7250
|
+
if (isNodeErrno(error, "ENOENT")) {
|
|
7251
|
+
throw createPathNotFoundError(fromRemote, `Local path not found: ${fromRemote}`);
|
|
7252
|
+
}
|
|
7253
|
+
throw error;
|
|
7254
|
+
}
|
|
7255
|
+
}
|
|
7256
|
+
async mkdir(remote, options = {}) {
|
|
7257
|
+
const remotePath = normalizeLocalProviderPath(remote);
|
|
7258
|
+
const localPath = resolveLocalPath(this.rootPath, remotePath);
|
|
7259
|
+
await (0, import_promises2.mkdir)(localPath, { recursive: options.recursive === true });
|
|
7260
|
+
}
|
|
7261
|
+
async rmdir(remote, options = {}) {
|
|
7262
|
+
const remotePath = normalizeLocalProviderPath(remote);
|
|
7263
|
+
const localPath = resolveLocalPath(this.rootPath, remotePath);
|
|
7264
|
+
try {
|
|
7265
|
+
await (0, import_promises2.rm)(localPath, { recursive: options.recursive === true, force: false });
|
|
7266
|
+
} catch (error) {
|
|
7267
|
+
if (isNodeErrno(error, "ENOENT")) {
|
|
7268
|
+
if (options.ignoreMissing) return;
|
|
7269
|
+
throw createPathNotFoundError(remotePath, `Local path not found: ${remotePath}`);
|
|
7270
|
+
}
|
|
7271
|
+
throw error;
|
|
7272
|
+
}
|
|
7273
|
+
}
|
|
7020
7274
|
};
|
|
7275
|
+
function isNodeErrno(error, code) {
|
|
7276
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
7277
|
+
}
|
|
7021
7278
|
function resolveReadRange2(size, range) {
|
|
7022
7279
|
if (range === void 0) {
|
|
7023
7280
|
return { length: size, offset: 0 };
|
|
@@ -7180,6 +7437,11 @@ function normalizeLocalProviderPath(input) {
|
|
|
7180
7437
|
}
|
|
7181
7438
|
function resolveLocalPath(rootPath, remotePath) {
|
|
7182
7439
|
const normalizedRemotePath = normalizeLocalProviderPath(remotePath);
|
|
7440
|
+
const resolvedRootPath = import_node_path2.default.resolve(rootPath);
|
|
7441
|
+
const candidateAbsolute = import_node_path2.default.resolve(normalizedRemotePath.split("/").join(import_node_path2.default.sep));
|
|
7442
|
+
if (candidateAbsolute === resolvedRootPath || candidateAbsolute.startsWith(resolvedRootPath + import_node_path2.default.sep)) {
|
|
7443
|
+
return candidateAbsolute;
|
|
7444
|
+
}
|
|
7183
7445
|
const relativePath = normalizedRemotePath === "/" ? "." : normalizedRemotePath.slice(1);
|
|
7184
7446
|
const resolvedPath = import_node_path2.default.resolve(rootPath, relativePath.split("/").join(import_node_path2.default.sep));
|
|
7185
7447
|
const relativeToRoot = import_node_path2.default.relative(rootPath, resolvedPath);
|
|
@@ -7331,6 +7593,96 @@ var MemoryFileSystem = class {
|
|
|
7331
7593
|
() => cloneRemoteStat(this.requireEntry(normalizeMemoryPath(path2)))
|
|
7332
7594
|
);
|
|
7333
7595
|
}
|
|
7596
|
+
remove(path2, options = {}) {
|
|
7597
|
+
return Promise.resolve().then(() => {
|
|
7598
|
+
const normalized = normalizeMemoryPath(path2);
|
|
7599
|
+
const entry = this.state.entries.get(normalized);
|
|
7600
|
+
if (entry === void 0) {
|
|
7601
|
+
if (options.ignoreMissing) return;
|
|
7602
|
+
throw createPathNotFoundError2(normalized, `Memory path not found: ${normalized}`);
|
|
7603
|
+
}
|
|
7604
|
+
if (entry.type === "directory") {
|
|
7605
|
+
throw createPathNotFoundError2(
|
|
7606
|
+
normalized,
|
|
7607
|
+
`Memory path is a directory; use rmdir: ${normalized}`
|
|
7608
|
+
);
|
|
7609
|
+
}
|
|
7610
|
+
this.state.entries.delete(normalized);
|
|
7611
|
+
this.state.content.delete(normalized);
|
|
7612
|
+
});
|
|
7613
|
+
}
|
|
7614
|
+
rename(from, to) {
|
|
7615
|
+
return Promise.resolve().then(() => {
|
|
7616
|
+
const fromPath = normalizeMemoryPath(from);
|
|
7617
|
+
const toPath = normalizeMemoryPath(to);
|
|
7618
|
+
const entry = this.state.entries.get(fromPath);
|
|
7619
|
+
if (entry === void 0) {
|
|
7620
|
+
throw createPathNotFoundError2(fromPath, `Memory path not found: ${fromPath}`);
|
|
7621
|
+
}
|
|
7622
|
+
ensureParentDirectories(this.state.entries, toPath);
|
|
7623
|
+
const moved = { ...entry, path: toPath, name: basenameRemotePath(toPath) };
|
|
7624
|
+
this.state.entries.delete(fromPath);
|
|
7625
|
+
this.state.entries.set(toPath, moved);
|
|
7626
|
+
const content = this.state.content.get(fromPath);
|
|
7627
|
+
if (content !== void 0) {
|
|
7628
|
+
this.state.content.delete(fromPath);
|
|
7629
|
+
this.state.content.set(toPath, content);
|
|
7630
|
+
}
|
|
7631
|
+
});
|
|
7632
|
+
}
|
|
7633
|
+
mkdir(path2, options = {}) {
|
|
7634
|
+
return Promise.resolve().then(() => {
|
|
7635
|
+
const normalized = normalizeMemoryPath(path2);
|
|
7636
|
+
const existing = this.state.entries.get(normalized);
|
|
7637
|
+
if (existing !== void 0) {
|
|
7638
|
+
if (existing.type === "directory" && options.recursive) return;
|
|
7639
|
+
throw createInvalidFixtureError(normalized, `Memory path already exists: ${normalized}`);
|
|
7640
|
+
}
|
|
7641
|
+
if (options.recursive) {
|
|
7642
|
+
ensureParentDirectories(this.state.entries, normalized);
|
|
7643
|
+
} else {
|
|
7644
|
+
const parent = getParentPath2(normalized);
|
|
7645
|
+
if (parent !== void 0 && !this.state.entries.has(parent)) {
|
|
7646
|
+
throw createPathNotFoundError2(parent, `Memory parent not found: ${parent}`);
|
|
7647
|
+
}
|
|
7648
|
+
}
|
|
7649
|
+
this.state.entries.set(normalized, createDirectoryEntry(normalized));
|
|
7650
|
+
});
|
|
7651
|
+
}
|
|
7652
|
+
rmdir(path2, options = {}) {
|
|
7653
|
+
return Promise.resolve().then(() => {
|
|
7654
|
+
const normalized = normalizeMemoryPath(path2);
|
|
7655
|
+
const entry = this.state.entries.get(normalized);
|
|
7656
|
+
if (entry === void 0) {
|
|
7657
|
+
if (options.ignoreMissing) return;
|
|
7658
|
+
throw createPathNotFoundError2(normalized, `Memory path not found: ${normalized}`);
|
|
7659
|
+
}
|
|
7660
|
+
if (entry.type !== "directory") {
|
|
7661
|
+
throw createPathNotFoundError2(normalized, `Memory path is not a directory: ${normalized}`);
|
|
7662
|
+
}
|
|
7663
|
+
const children = [...this.state.entries.values()].filter(
|
|
7664
|
+
(child) => child.path !== normalized && getParentPath2(child.path) === normalized
|
|
7665
|
+
);
|
|
7666
|
+
if (children.length > 0 && !options.recursive) {
|
|
7667
|
+
throw createInvalidFixtureError(normalized, `Memory directory not empty: ${normalized}`);
|
|
7668
|
+
}
|
|
7669
|
+
const stack = [...children];
|
|
7670
|
+
while (stack.length > 0) {
|
|
7671
|
+
const next = stack.pop();
|
|
7672
|
+
if (!next) continue;
|
|
7673
|
+
if (next.type === "directory") {
|
|
7674
|
+
for (const grand of this.state.entries.values()) {
|
|
7675
|
+
if (grand.path !== next.path && getParentPath2(grand.path) === next.path) {
|
|
7676
|
+
stack.push(grand);
|
|
7677
|
+
}
|
|
7678
|
+
}
|
|
7679
|
+
}
|
|
7680
|
+
this.state.entries.delete(next.path);
|
|
7681
|
+
this.state.content.delete(next.path);
|
|
7682
|
+
}
|
|
7683
|
+
this.state.entries.delete(normalized);
|
|
7684
|
+
});
|
|
7685
|
+
}
|
|
7334
7686
|
requireEntry(path2) {
|
|
7335
7687
|
const entry = this.state.entries.get(path2);
|
|
7336
7688
|
if (entry === void 0) {
|