diff --git a/packages/core-eslint/rules/_usecase-name.js b/packages/core-eslint/rules/_usecase-name.js new file mode 100644 index 0000000..c8299b8 --- /dev/null +++ b/packages/core-eslint/rules/_usecase-name.js @@ -0,0 +1,17 @@ +/** + * Derive the manifest use-case key from a use-case file path. + * + * Convention: `packages//src/application/use-cases/.use-case.ts` + * → manifest.useCases. + * + * Returns null for non-use-case files. + */ +export function useCaseNameFromFile(filepath) { + if (!filepath.endsWith(".use-case.ts")) return null; + if (!filepath.includes("/application/use-cases/") && !filepath.includes("\\application\\use-cases\\")) { + return null; + } + const base = filepath.split(/[\\/]/).pop(); + const slug = base.replace(/\.use-case\.ts$/, ""); + return slug.split("-").map((part, i) => i === 0 ? part : part[0].toUpperCase() + part.slice(1)).join(""); +} diff --git a/packages/core-eslint/rules/_usecase-name.test.js b/packages/core-eslint/rules/_usecase-name.test.js new file mode 100644 index 0000000..3cfcc63 --- /dev/null +++ b/packages/core-eslint/rules/_usecase-name.test.js @@ -0,0 +1,19 @@ +import { describe, it, expect } from "vitest"; +import { useCaseNameFromFile } from "./_usecase-name.js"; + +describe("useCaseNameFromFile", () => { + it("converts kebab-case slug to camelCase", () => { + expect(useCaseNameFromFile("/repo/packages/auth/src/application/use-cases/sign-in.use-case.ts")).toBe("signIn"); + expect(useCaseNameFromFile("/repo/packages/auth/src/application/use-cases/sign-up.use-case.ts")).toBe("signUp"); + expect(useCaseNameFromFile("/repo/packages/blog/src/application/use-cases/get-article-by-slug.use-case.ts")).toBe("getArticleBySlug"); + }); + + it("handles single-word slugs", () => { + expect(useCaseNameFromFile("/repo/packages/x/src/application/use-cases/login.use-case.ts")).toBe("login"); + }); + + it("returns null for non-use-case files", () => { + expect(useCaseNameFromFile("/repo/packages/auth/src/index.ts")).toBeNull(); + expect(useCaseNameFromFile("/repo/packages/auth/src/feature.manifest.ts")).toBeNull(); + }); +});