From 21f3f46f9493c7c41336e1e93f12986276b1336e Mon Sep 17 00:00:00 2001 From: Guillaume Mathieu Date: Fri, 22 Mar 2024 19:07:56 -0700 Subject: [PATCH] fix: resolve Prettier config based on generated file --- __tests__/prettier/prettier.test.ts | 11 ++++++---- .../class-names-to-type-definitions.test.ts | 20 +++++++++++++++++-- lib/core/list-different.ts | 1 + lib/core/write-file.ts | 1 + lib/prettier/index.ts | 5 +++-- .../class-names-to-type-definition.ts | 3 ++- 6 files changed, 32 insertions(+), 9 deletions(-) diff --git a/__tests__/prettier/prettier.test.ts b/__tests__/prettier/prettier.test.ts index 187c778..04c346e 100644 --- a/__tests__/prettier/prettier.test.ts +++ b/__tests__/prettier/prettier.test.ts @@ -1,13 +1,15 @@ +import { join } from "path"; import prettier from "prettier"; import { attemptPrettier } from "../../lib/prettier"; import { classNamesToTypeDefinitions } from "../../lib/typescript"; +const file = join(__dirname, "test.d.ts"); const input = "export type Styles = {'myClass': string;'yourClass': string;}; export type Classes = keyof Styles; declare const styles: Styles; export default styles;"; describe("attemptPrettier", () => { it("should locate and apply prettier.format", async () => { - const output = await attemptPrettier(input); + const output = await attemptPrettier(file, input); expect(prettier.format(input, { parser: "typescript" })).toMatch(output); }); @@ -16,6 +18,7 @@ describe("attemptPrettier", () => { const typeDefinition = await classNamesToTypeDefinitions({ banner: "", classNames: ["nestedAnother", "nestedClass", "someStyles"], + file, exportType: "default", }); @@ -23,7 +26,7 @@ describe("attemptPrettier", () => { throw new Error("failed to collect typeDefinition"); } - const output = await attemptPrettier(typeDefinition); + const output = await attemptPrettier(file, typeDefinition); expect(output).toMatchSnapshot(); }); @@ -37,7 +40,7 @@ describe("attemptPrettier - mock prettier", () => { }); it("should fail to recognize prettier and return input", async () => { - const output = await attemptPrettier(input); + const output = await attemptPrettier(file, input); expect(input).toMatch(output); }); @@ -49,7 +52,7 @@ describe("attemptPrettier - mock resolution check", () => { }); it("should fail to resolve prettier and return input", async () => { - const output = await attemptPrettier(input); + const output = await attemptPrettier(file, input); expect(input).toMatch(output); }); diff --git a/__tests__/typescript/class-names-to-type-definitions.test.ts b/__tests__/typescript/class-names-to-type-definitions.test.ts index 4575ee1..3ef84c4 100644 --- a/__tests__/typescript/class-names-to-type-definitions.test.ts +++ b/__tests__/typescript/class-names-to-type-definitions.test.ts @@ -1,9 +1,11 @@ import os from "os"; -import { classNamesToTypeDefinitions, ExportType } from "../../lib/typescript"; +import { join } from "path"; +import { classNamesToTypeDefinitions } from "../../lib/typescript"; jest.mock("../../lib/prettier/can-resolve", () => ({ canResolvePrettier: () => false, })); +const file = join(__dirname, "test.d.ts"); describe("classNamesToTypeDefinitions (without Prettier)", () => { beforeEach(() => { @@ -16,6 +18,7 @@ describe("classNamesToTypeDefinitions (without Prettier)", () => { banner: "", classNames: ["myClass", "yourClass"], exportType: "named", + file, }); expect(definition).toEqual( @@ -28,6 +31,7 @@ describe("classNamesToTypeDefinitions (without Prettier)", () => { banner: "", classNames: [], exportType: "named", + file, }); expect(definition).toBeNull(); @@ -38,6 +42,7 @@ describe("classNamesToTypeDefinitions (without Prettier)", () => { banner: "", classNames: ["myClass", "if"], exportType: "named", + file, }); expect(definition).toEqual("export declare const myClass: string;\n"); @@ -51,6 +56,7 @@ describe("classNamesToTypeDefinitions (without Prettier)", () => { banner: "", classNames: ["myClass", "invalid-variable"], exportType: "named", + file, }); expect(definition).toEqual("export declare const myClass: string;\n"); @@ -66,6 +72,7 @@ describe("classNamesToTypeDefinitions (without Prettier)", () => { banner: "", classNames: ["myClass", "yourClass"], exportType: "default", + file, }); expect(definition).toEqual( @@ -78,6 +85,7 @@ describe("classNamesToTypeDefinitions (without Prettier)", () => { banner: "", classNames: [], exportType: "default", + file, }); expect(definition).toBeNull(); @@ -89,7 +97,9 @@ describe("classNamesToTypeDefinitions (without Prettier)", () => { const definition = await classNamesToTypeDefinitions({ banner: "", classNames: ["myClass"], - exportType: "invalid" as ExportType, + // @ts-expect-error -- invalid export type + exportType: "invalid", + file, }); expect(definition).toBeNull(); @@ -103,6 +113,7 @@ describe("classNamesToTypeDefinitions (without Prettier)", () => { classNames: ["myClass", "yourClass"], exportType: "default", quoteType: "double", + file, }); expect(definition).toEqual( @@ -116,6 +127,7 @@ describe("classNamesToTypeDefinitions (without Prettier)", () => { classNames: ["myClass", "yourClass"], exportType: "named", quoteType: "double", + file, }); expect(definition).toEqual( @@ -131,6 +143,7 @@ describe("classNamesToTypeDefinitions (without Prettier)", () => { classNames: ["myClass", "yourClass"], exportType: "default", exportTypeName: "Classes", + file, }); expect(definition).toEqual( @@ -144,6 +157,7 @@ describe("classNamesToTypeDefinitions (without Prettier)", () => { classNames: ["myClass", "yourClass"], exportType: "default", exportTypeInterface: "IStyles", + file, }); expect(definition).toEqual( @@ -161,6 +175,7 @@ describe("classNamesToTypeDefinitions (without Prettier)", () => { banner, classNames: ["myClass", "yourClass"], exportType: "default", + file, }); expect(firstLine(definition!)).toBe(banner); @@ -172,6 +187,7 @@ describe("classNamesToTypeDefinitions (without Prettier)", () => { banner, classNames: ["myClass", "yourClass"], exportType: "named", + file, }); expect(firstLine(definition!)).toBe(banner); diff --git a/lib/core/list-different.ts b/lib/core/list-different.ts index dfdc234..dd39baf 100644 --- a/lib/core/list-different.ts +++ b/lib/core/list-different.ts @@ -31,6 +31,7 @@ export const checkFile = async ( const classNames = await fileToClassNames(file, options); const typeDefinition = await classNamesToTypeDefinitions({ classNames: classNames, + file, ...options, }); diff --git a/lib/core/write-file.ts b/lib/core/write-file.ts index c6beb23..7f94f08 100644 --- a/lib/core/write-file.ts +++ b/lib/core/write-file.ts @@ -24,6 +24,7 @@ export const writeFile = async ( const classNames = await fileToClassNames(file, options); const typeDefinition = await classNamesToTypeDefinitions({ classNames, + file, ...options, }); diff --git a/lib/prettier/index.ts b/lib/prettier/index.ts index 9937723..07a50b1 100644 --- a/lib/prettier/index.ts +++ b/lib/prettier/index.ts @@ -20,9 +20,10 @@ const isPrettier = (t: unknown): t is Prettier => * Try to load prettier and config from project to format input, * fall back to input if prettier is not found or failed * + * @param {file} file * @param {string} input */ -export const attemptPrettier = async (input: string) => { +export const attemptPrettier = async (file: string, input: string) => { if (!canResolvePrettier()) { return input; } @@ -35,7 +36,7 @@ export const attemptPrettier = async (input: string) => { } try { - const config = await prettier.resolveConfig(process.cwd(), { + const config = await prettier.resolveConfig(file, { editorconfig: true, }); // try to return formatted output diff --git a/lib/typescript/class-names-to-type-definition.ts b/lib/typescript/class-names-to-type-definition.ts index b8b6cdd..8f674db 100644 --- a/lib/typescript/class-names-to-type-definition.ts +++ b/lib/typescript/class-names-to-type-definition.ts @@ -13,6 +13,7 @@ export const QUOTE_TYPES: QuoteType[] = ["single", "double"]; export interface TypeDefinitionOptions { banner: string; classNames: ClassName[]; + file: string; exportType: ExportType; exportTypeName?: string; exportTypeInterface?: string; @@ -95,7 +96,7 @@ export const classNamesToTypeDefinitions = async ( if (lines.length) { const typeDefinition = lines.join(`${os.EOL}`) + `${os.EOL}`; - return await attemptPrettier(typeDefinition); + return await attemptPrettier(options.file, typeDefinition); } else { return null; }