Update files

This commit is contained in:
Mohamed Boudra
2026-01-27 13:06:01 +07:00
parent 637967fa14
commit 766585d1cb
10 changed files with 249 additions and 279 deletions
+53 -1
View File
@@ -2,7 +2,7 @@ import { describe, it, expect, beforeEach, afterEach } from "vitest";
import { mkdtempSync, rmSync, writeFileSync, mkdirSync, realpathSync } from "fs";
import { join } from "path";
import { tmpdir } from "os";
import { findProjectIcon, getProjectIcon, ICON_PATTERNS, PRIORITY_DIRS, IGNORED_DIRS } from "./project-icon.js";
import { findProjectIcon, getProjectIcon, ICON_PATTERNS, PRIORITY_DIRS, IGNORED_DIRS, MONOREPO_PACKAGE_DIRS } from "./project-icon.js";
function createTempDir(): string {
return realpathSync(mkdtempSync(join(tmpdir(), "project-icon-test-")));
@@ -55,6 +55,13 @@ describe("findProjectIcon", () => {
});
});
describe("MONOREPO_PACKAGE_DIRS", () => {
it("includes common monorepo package directories", () => {
expect(MONOREPO_PACKAGE_DIRS).toContain("packages");
expect(MONOREPO_PACKAGE_DIRS).toContain("apps");
});
});
it("returns null when no icon is found", async () => {
const result = await findProjectIcon(tempDir);
expect(result).toBeNull();
@@ -175,6 +182,51 @@ describe("findProjectIcon", () => {
// Should return the first one based on pattern order (favicon.ico comes first)
expect(result).toBe(join(tempDir, "favicon.ico"));
});
describe("monorepo package directories", () => {
it("finds icon in packages/*/public directory", async () => {
mkdirSync(join(tempDir, "packages", "app", "public"), { recursive: true });
writeFileSync(join(tempDir, "packages", "app", "public", "favicon.ico"), "icon");
const result = await findProjectIcon(tempDir);
expect(result).toBe(join(tempDir, "packages", "app", "public", "favicon.ico"));
});
it("finds icon in apps/*/public directory", async () => {
mkdirSync(join(tempDir, "apps", "web", "public"), { recursive: true });
writeFileSync(join(tempDir, "apps", "web", "public", "favicon.png"), "icon");
const result = await findProjectIcon(tempDir);
expect(result).toBe(join(tempDir, "apps", "web", "public", "favicon.png"));
});
it("finds icon in packages/* root", async () => {
mkdirSync(join(tempDir, "packages", "ui"), { recursive: true });
writeFileSync(join(tempDir, "packages", "ui", "logo.svg"), "icon");
const result = await findProjectIcon(tempDir);
expect(result).toBe(join(tempDir, "packages", "ui", "logo.svg"));
});
it("prioritizes root priority dirs over monorepo dirs", async () => {
mkdirSync(join(tempDir, "public"), { recursive: true });
mkdirSync(join(tempDir, "packages", "app", "public"), { recursive: true });
writeFileSync(join(tempDir, "public", "favicon.ico"), "root icon");
writeFileSync(join(tempDir, "packages", "app", "public", "favicon.ico"), "package icon");
const result = await findProjectIcon(tempDir);
expect(result).toBe(join(tempDir, "public", "favicon.ico"));
});
it("prioritizes monorepo dirs over root dir (non-priority)", async () => {
mkdirSync(join(tempDir, "packages", "app", "public"), { recursive: true });
writeFileSync(join(tempDir, "logo.png"), "root icon");
writeFileSync(join(tempDir, "packages", "app", "public", "favicon.ico"), "package icon");
const result = await findProjectIcon(tempDir);
expect(result).toBe(join(tempDir, "packages", "app", "public", "favicon.ico"));
});
});
});
describe("getProjectIcon", () => {
+56
View File
@@ -9,6 +9,9 @@ export const ICON_PATTERNS = [
"favicon.ico",
"favicon.png",
"favicon.svg",
"favico.ico",
"favico.png",
"favico.svg",
"icon.png",
"icon.svg",
"app-icon.png",
@@ -24,6 +27,11 @@ export const ICON_PATTERNS = [
*/
export const PRIORITY_DIRS = ["public", "static", "assets", "images", "img"];
/**
* Monorepo package directory patterns to scan (e.g., packages/app, apps/web).
*/
export const MONOREPO_PACKAGE_DIRS = ["packages", "apps"];
/**
* Directories to ignore during search.
*/
@@ -306,6 +314,54 @@ export async function findProjectIcon(
}
}
// Then search monorepo package directories (packages/*, apps/*)
for (const monoDir of MONOREPO_PACKAGE_DIRS) {
const monoPath = join(projectDir, monoDir);
let packageEntries: string[];
try {
packageEntries = await readdir(monoPath);
} catch {
continue;
}
for (const packageName of packageEntries) {
const packagePath = join(monoPath, packageName);
try {
const packageStats = await stat(packagePath);
if (!packageStats.isDirectory()) continue;
} catch {
continue;
}
// Search priority dirs within the package
for (const priorityDir of PRIORITY_DIRS) {
const priorityPath = join(packagePath, priorityDir);
try {
const priorityStats = await stat(priorityPath);
if (priorityStats.isDirectory()) {
const result = await searchDirRecursively(
priorityPath,
ICON_PATTERNS,
ignoredDirsSet,
maxDepth - 1
);
if (result) {
return result;
}
}
} catch {
// Directory doesn't exist, continue
}
}
// Search package root
const found = await findIconInDir(packagePath, ICON_PATTERNS);
if (found) {
return found;
}
}
}
// Then search root and any other non-priority directories
const found = await findDirRecursively(projectDir);
if (found) {