mirror of
https://github.com/outline/outline.git
synced 2026-08-03 13:27:25 +03:00
Remove dead ImportHelper (#13134)
This commit is contained in:
@@ -1,179 +0,0 @@
|
||||
import path from "node:path";
|
||||
import fs from "fs-extra";
|
||||
import { tmpdir } from "node:os";
|
||||
import ImportHelper from "./ImportHelper";
|
||||
|
||||
describe("ImportHelper", () => {
|
||||
describe("toFileTree", () => {
|
||||
let tempDir: string;
|
||||
|
||||
beforeEach(async () => {
|
||||
// Create a unique temporary directory for each test
|
||||
tempDir = await fs.mkdtemp(path.join(tmpdir(), "import-helper-test-"));
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
// Clean up the temporary directory after each test
|
||||
await fs.remove(tempDir);
|
||||
});
|
||||
|
||||
it("should filter out hidden files starting with dot", async () => {
|
||||
// Create test file structure
|
||||
await fs.writeFile(path.join(tempDir, "visible-file.txt"), "content");
|
||||
await fs.writeFile(path.join(tempDir, ".hidden-file.txt"), "content");
|
||||
await fs.writeFile(path.join(tempDir, "another-file.md"), "content");
|
||||
await fs.writeFile(path.join(tempDir, ".DS_Store"), "content");
|
||||
|
||||
const result = await ImportHelper.toFileTree(tempDir);
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.children).toHaveLength(2);
|
||||
|
||||
const childNames = result!.children.map((child) => child.name);
|
||||
expect(childNames).toContain("visible-file.txt");
|
||||
expect(childNames).toContain("another-file.md");
|
||||
expect(childNames).not.toContain(".hidden-file.txt");
|
||||
expect(childNames).not.toContain(".DS_Store");
|
||||
});
|
||||
|
||||
it("should filter out __MACOSX directories", async () => {
|
||||
// Create test directory structure
|
||||
await fs.ensureDir(path.join(tempDir, "normal-folder"));
|
||||
await fs.ensureDir(path.join(tempDir, "__MACOSX"));
|
||||
await fs.writeFile(
|
||||
path.join(tempDir, "normal-folder", "file.txt"),
|
||||
"content"
|
||||
);
|
||||
await fs.writeFile(path.join(tempDir, "__MACOSX", "metadata"), "content");
|
||||
|
||||
const result = await ImportHelper.toFileTree(tempDir);
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.children).toHaveLength(1);
|
||||
expect(result!.children[0].name).toBe("normal-folder");
|
||||
});
|
||||
|
||||
it("should filter hidden files in nested directories", async () => {
|
||||
// Create nested directory structure with hidden files
|
||||
await fs.ensureDir(path.join(tempDir, "folder1", "subfolder"));
|
||||
await fs.writeFile(
|
||||
path.join(tempDir, "folder1", "visible.txt"),
|
||||
"content"
|
||||
);
|
||||
await fs.writeFile(
|
||||
path.join(tempDir, "folder1", ".hidden.txt"),
|
||||
"content"
|
||||
);
|
||||
await fs.writeFile(
|
||||
path.join(tempDir, "folder1", "subfolder", "nested.txt"),
|
||||
"content"
|
||||
);
|
||||
await fs.writeFile(
|
||||
path.join(tempDir, "folder1", "subfolder", ".nested-hidden.txt"),
|
||||
"content"
|
||||
);
|
||||
|
||||
const result = await ImportHelper.toFileTree(tempDir);
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.children).toHaveLength(1);
|
||||
|
||||
const folder1 = result!.children[0];
|
||||
expect(folder1.name).toBe("folder1");
|
||||
expect(folder1.children).toHaveLength(2); // visible.txt and subfolder
|
||||
|
||||
const visibleFiles = folder1.children.filter(
|
||||
(child) => child.name !== "subfolder"
|
||||
);
|
||||
expect(visibleFiles).toHaveLength(1);
|
||||
expect(visibleFiles[0].name).toBe("visible.txt");
|
||||
|
||||
const subfolder = folder1.children.find(
|
||||
(child) => child.name === "subfolder"
|
||||
);
|
||||
expect(subfolder).toBeDefined();
|
||||
expect(subfolder!.children).toHaveLength(1);
|
||||
expect(subfolder!.children[0].name).toBe("nested.txt");
|
||||
});
|
||||
|
||||
it("should handle directories with only hidden files", async () => {
|
||||
// Create directory with only hidden files
|
||||
await fs.ensureDir(path.join(tempDir, "empty-looking-folder"));
|
||||
await fs.writeFile(
|
||||
path.join(tempDir, "empty-looking-folder", ".hidden1"),
|
||||
"content"
|
||||
);
|
||||
await fs.writeFile(
|
||||
path.join(tempDir, "empty-looking-folder", ".hidden2"),
|
||||
"content"
|
||||
);
|
||||
|
||||
const result = await ImportHelper.toFileTree(tempDir);
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.children).toHaveLength(1);
|
||||
|
||||
const folder = result!.children[0];
|
||||
expect(folder.name).toBe("empty-looking-folder");
|
||||
expect(folder.children).toHaveLength(0); // All children are hidden
|
||||
});
|
||||
|
||||
it("should correctly set title from deserialized filename", async () => {
|
||||
// Create files with special characters that would be serialized
|
||||
await fs.writeFile(path.join(tempDir, "normal-file.txt"), "content");
|
||||
|
||||
const result = await ImportHelper.toFileTree(tempDir);
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.children).toHaveLength(1);
|
||||
expect(result!.children[0].name).toBe("normal-file.txt");
|
||||
expect(result!.children[0].title).toBe("normal-file");
|
||||
});
|
||||
|
||||
it("should return null for non-existent paths", async () => {
|
||||
const nonExistentPath = path.join(tempDir, "does-not-exist");
|
||||
const result = await ImportHelper.toFileTree(nonExistentPath);
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it("should handle empty directories", async () => {
|
||||
const result = await ImportHelper.toFileTree(tempDir);
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.children).toHaveLength(0);
|
||||
expect(result!.name).toBe(path.basename(tempDir));
|
||||
});
|
||||
|
||||
it("should handle mixed file types and hidden files", async () => {
|
||||
// Create a complex structure with various file types and hidden files
|
||||
await fs.writeFile(path.join(tempDir, "document.pdf"), "content");
|
||||
await fs.writeFile(path.join(tempDir, "image.jpg"), "content");
|
||||
await fs.writeFile(path.join(tempDir, ".gitignore"), "content");
|
||||
await fs.writeFile(path.join(tempDir, "readme.md"), "content");
|
||||
await fs.ensureDir(path.join(tempDir, ".git"));
|
||||
await fs.ensureDir(path.join(tempDir, "assets"));
|
||||
await fs.writeFile(path.join(tempDir, ".git", "config"), "content");
|
||||
await fs.writeFile(path.join(tempDir, "assets", "style.css"), "content");
|
||||
|
||||
const result = await ImportHelper.toFileTree(tempDir);
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.children).toHaveLength(4); // document.pdf, image.jpg, readme.md, assets
|
||||
|
||||
const childNames = result!.children.map((child) => child.name);
|
||||
expect(childNames).toContain("document.pdf");
|
||||
expect(childNames).toContain("image.jpg");
|
||||
expect(childNames).toContain("readme.md");
|
||||
expect(childNames).toContain("assets");
|
||||
expect(childNames).not.toContain(".gitignore");
|
||||
expect(childNames).not.toContain(".git");
|
||||
|
||||
const assetsFolder = result!.children.find(
|
||||
(child) => child.name === "assets"
|
||||
);
|
||||
expect(assetsFolder).toBeDefined();
|
||||
expect(assetsFolder!.children).toHaveLength(1);
|
||||
expect(assetsFolder!.children[0].name).toBe("style.css");
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,71 +0,0 @@
|
||||
import path from "node:path";
|
||||
import fs from "fs-extra";
|
||||
import { deserializeFilename } from "./fs";
|
||||
|
||||
export type FileTreeNode = {
|
||||
/** The title, extracted from the file name */
|
||||
title: string;
|
||||
/** The file name including extension */
|
||||
name: string;
|
||||
/** Full path to the file within the zip file */
|
||||
path: string;
|
||||
/** Any nested children */
|
||||
children: FileTreeNode[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper for working with directories of files during imports.
|
||||
*/
|
||||
export default class ImportHelper {
|
||||
/**
|
||||
* Collects the files and folders for a directory filePath.
|
||||
*/
|
||||
public static async toFileTree(
|
||||
filePath: string,
|
||||
currentDepth = 0
|
||||
): Promise<FileTreeNode | null> {
|
||||
const name = path.basename(filePath);
|
||||
const title = deserializeFilename(path.parse(path.basename(name)).name);
|
||||
const item = {
|
||||
path: filePath,
|
||||
name,
|
||||
title,
|
||||
children: [] as FileTreeNode[],
|
||||
};
|
||||
let stats;
|
||||
|
||||
// Ignore macOS metadata directories and hidden files
|
||||
if (name === "__MACOSX" || name.startsWith(".")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
stats = await fs.stat(filePath);
|
||||
} catch (_err) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (stats.isFile()) {
|
||||
return item;
|
||||
}
|
||||
|
||||
if (stats.isDirectory()) {
|
||||
const dirData = await fs.readdir(filePath);
|
||||
if (dirData === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
item.children = (
|
||||
await Promise.all(
|
||||
dirData.map((child) =>
|
||||
this.toFileTree(path.join(filePath, child), currentDepth + 1)
|
||||
)
|
||||
)
|
||||
).filter(Boolean) as FileTreeNode[];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user