Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
50 lines
1.5 KiB
TypeScript
50 lines
1.5 KiB
TypeScript
import type { SftpBookmark } from "../../../domain/models";
|
|
|
|
const ROOT_PATH_RE = /^[A-Za-z]:[\\/]?$/;
|
|
|
|
export function getSftpBookmarkLabel(path: string): string {
|
|
const trimmed = path.trim();
|
|
if (trimmed === "/" || ROOT_PATH_RE.test(trimmed)) return trimmed;
|
|
return trimmed.split(/[\\/]/).filter(Boolean).pop() || trimmed;
|
|
}
|
|
|
|
export function createSftpBookmark(
|
|
path: string,
|
|
options: { global?: boolean; idPrefix?: string } = {},
|
|
): SftpBookmark {
|
|
const global = options.global === true;
|
|
const idPrefix = options.idPrefix ?? (global ? "gbm" : "bm");
|
|
return {
|
|
id: `${idPrefix}-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
path,
|
|
label: getSftpBookmarkLabel(path),
|
|
...(global ? { global: true } : {}),
|
|
};
|
|
}
|
|
|
|
export function moveSftpBookmark<T extends { id: string }>(
|
|
bookmarks: T[],
|
|
fromId: string,
|
|
toId: string,
|
|
): T[] {
|
|
const from = bookmarks.findIndex((bookmark) => bookmark.id === fromId);
|
|
const to = bookmarks.findIndex((bookmark) => bookmark.id === toId);
|
|
if (from < 0 || to < 0 || from === to) return bookmarks;
|
|
const next = bookmarks.slice();
|
|
const [item] = next.splice(from, 1);
|
|
next.splice(to, 0, item);
|
|
return next;
|
|
}
|
|
|
|
export function renameSftpBookmark<T extends { id: string; label: string }>(
|
|
bookmarks: T[],
|
|
id: string,
|
|
label: string,
|
|
): T[] {
|
|
const nextLabel = label.trim();
|
|
if (!nextLabel) return bookmarks;
|
|
return bookmarks.map((bookmark) => (
|
|
bookmark.id === id ? { ...bookmark, label: nextLabel } : bookmark
|
|
));
|
|
}
|