@zero-transfer/sdk 0.1.1 → 0.1.3
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/dist/index.cjs +345 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +47 -1
- package/dist/index.d.ts +47 -1
- package/dist/index.mjs +356 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
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
|
/**
|
|
@@ -3793,6 +3861,101 @@ var SftpFileSystem = class {
|
|
|
3793
3861
|
throw mapSftpError(error, { command: "LSTAT", path: remotePath });
|
|
3794
3862
|
}
|
|
3795
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
|
+
}
|
|
3796
3959
|
};
|
|
3797
3960
|
async function connectSshClient(profile, options, username, authentication) {
|
|
3798
3961
|
const client = new SshClientCtor();
|
|
@@ -4184,6 +4347,50 @@ function readSftpStats(sftp, path2) {
|
|
|
4184
4347
|
});
|
|
4185
4348
|
});
|
|
4186
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
|
+
}
|
|
4187
4394
|
async function* createSftpReadSource(sftp, path2, range, request) {
|
|
4188
4395
|
if (range.length <= 0) {
|
|
4189
4396
|
return;
|
|
@@ -7019,7 +7226,55 @@ var LocalFileSystem = class {
|
|
|
7019
7226
|
async stat(path2) {
|
|
7020
7227
|
return readLocalEntry(this.rootPath, normalizeLocalProviderPath(path2));
|
|
7021
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
|
+
}
|
|
7022
7274
|
};
|
|
7275
|
+
function isNodeErrno(error, code) {
|
|
7276
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
7277
|
+
}
|
|
7023
7278
|
function resolveReadRange2(size, range) {
|
|
7024
7279
|
if (range === void 0) {
|
|
7025
7280
|
return { length: size, offset: 0 };
|
|
@@ -7338,6 +7593,96 @@ var MemoryFileSystem = class {
|
|
|
7338
7593
|
() => cloneRemoteStat(this.requireEntry(normalizeMemoryPath(path2)))
|
|
7339
7594
|
);
|
|
7340
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
|
+
}
|
|
7341
7686
|
requireEntry(path2) {
|
|
7342
7687
|
const entry = this.state.entries.get(path2);
|
|
7343
7688
|
if (entry === void 0) {
|