From 9bac73a046faf4b8f2c45ececbc4a9afdf507cb3 Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Tue, 20 Jan 2026 04:48:08 +0000 Subject: [PATCH 1/2] Replace oxfmt with prettier for code formatting - Replace oxfmt dependency with prettier in graphql-codegen package - Add bundled prettier config with sensible defaults (singleQuote, trailingComma, tabWidth, semi) - Update formatOutput function to use prettier with bundled config - Update npm scripts (fmt, fmt:check) to use prettier - Add minimal test for formatOutput function - Update SPEC.md documentation --- graphql/codegen/SPEC.md | 2 +- graphql/codegen/package.json | 6 +- .../__tests__/codegen/format-output.test.ts | 37 ++++++++ .../src/cli/commands/codegen-prettier.json | 7 ++ graphql/codegen/src/cli/commands/generate.ts | 26 +++--- pnpm-lock.yaml | 86 +------------------ 6 files changed, 66 insertions(+), 98 deletions(-) create mode 100644 graphql/codegen/src/__tests__/codegen/format-output.test.ts create mode 100644 graphql/codegen/src/cli/commands/codegen-prettier.json diff --git a/graphql/codegen/SPEC.md b/graphql/codegen/SPEC.md index 31e1a8315..64f6296b0 100644 --- a/graphql/codegen/SPEC.md +++ b/graphql/codegen/SPEC.md @@ -59,7 +59,7 @@ GraphQL Schema (endpoint or .graphql file) │ ▼ ┌─────────────────────────────────────┐ -│ Output Formatting (oxfmt) │ +│ Output Formatting (prettier) │ └─────────────────────────────────────┘ ``` diff --git a/graphql/codegen/package.json b/graphql/codegen/package.json index a472ae899..6810308b3 100644 --- a/graphql/codegen/package.json +++ b/graphql/codegen/package.json @@ -39,8 +39,8 @@ "build:dev": "makage build --dev", "dev": "ts-node ./src/index.ts", "lint": "eslint . --fix", - "fmt": "oxfmt", - "fmt:check": "oxfmt --check", + "fmt": "prettier --write .", + "fmt:check": "prettier --check .", "test": "jest --passWithNoTests", "test:watch": "jest --watch", "example:codegen:sdk": "tsx src/cli/index.ts generate --config examples/multi-target.config.ts", @@ -62,7 +62,7 @@ "inflekt": "^0.2.0", "inquirerer": "^4.4.0", "jiti": "^2.6.1", - "oxfmt": "^0.13.0" + "prettier": "^3.7.4" }, "peerDependencies": { "@tanstack/react-query": "^5.0.0", diff --git a/graphql/codegen/src/__tests__/codegen/format-output.test.ts b/graphql/codegen/src/__tests__/codegen/format-output.test.ts new file mode 100644 index 000000000..91a822bf4 --- /dev/null +++ b/graphql/codegen/src/__tests__/codegen/format-output.test.ts @@ -0,0 +1,37 @@ +/** + * Test for formatOutput function + * Verifies that prettier formats generated code correctly + */ +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import * as os from 'node:os'; +import { formatOutput } from '../../cli/commands/generate'; + +describe('formatOutput', () => { + let tempDir: string; + + beforeEach(() => { + tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'codegen-format-test-')); + }); + + afterEach(() => { + fs.rmSync(tempDir, { recursive: true, force: true }); + }); + + it('formats TypeScript files with bundled config', () => { + // Write unformatted code (double quotes, missing semicolons) + const unformatted = `const x = "hello" +const obj = {a: 1,b: 2} +`; + fs.writeFileSync(path.join(tempDir, 'test.ts'), unformatted); + + const result = formatOutput(tempDir); + + expect(result.success).toBe(true); + + // Verify formatting applied (single quotes, semicolons added) + const formatted = fs.readFileSync(path.join(tempDir, 'test.ts'), 'utf-8'); + expect(formatted).toContain("'hello'"); + expect(formatted).toContain(';'); + }); +}); diff --git a/graphql/codegen/src/cli/commands/codegen-prettier.json b/graphql/codegen/src/cli/commands/codegen-prettier.json new file mode 100644 index 000000000..323c2c530 --- /dev/null +++ b/graphql/codegen/src/cli/commands/codegen-prettier.json @@ -0,0 +1,7 @@ +{ + "singleQuote": true, + "trailingComma": "all", + "tabWidth": 2, + "useTabs": false, + "semi": true +} diff --git a/graphql/codegen/src/cli/commands/generate.ts b/graphql/codegen/src/cli/commands/generate.ts index 4f36710b0..39ea4276c 100644 --- a/graphql/codegen/src/cli/commands/generate.ts +++ b/graphql/codegen/src/cli/commands/generate.ts @@ -512,7 +512,7 @@ export async function writeGeneratedFiles( process.stdout.write('\r' + ' '.repeat(40) + '\r'); } - // Format all generated files with oxfmt + // Format all generated files with prettier if (errors.length === 0) { if (showProgress) { console.log('Formatting generated files...'); @@ -531,28 +531,32 @@ export async function writeGeneratedFiles( } /** - * Format generated files using oxfmt - * Runs oxfmt on the output directory after all files are written + * Format generated files using prettier + * Runs prettier on the output directory after all files are written + * Uses bundled config with sensible defaults (singleQuote, trailingComma, etc.) */ export function formatOutput(outputDir: string): { success: boolean; error?: string } { // Resolve to absolute path for reliable execution const absoluteOutputDir = path.resolve(outputDir); try { - // Find oxfmt binary from this package's node_modules/.bin - // oxfmt is a dependency of @constructive-io/graphql-codegen - const oxfmtPkgPath = require.resolve('oxfmt/package.json'); - const oxfmtDir = path.dirname(oxfmtPkgPath); - const oxfmtBin = path.join(oxfmtDir, 'bin', 'oxfmt'); + // Find prettier binary from this package's node_modules/.bin + // prettier is a dependency of @constructive-io/graphql-codegen + const prettierPkgPath = require.resolve('prettier/package.json'); + const prettierDir = path.dirname(prettierPkgPath); + const prettierBin = path.join(prettierDir, 'bin', 'prettier.cjs'); - execSync(`"${oxfmtBin}" "${absoluteOutputDir}"`, { + // Use bundled config with sensible defaults + const configPath = path.join(__dirname, 'codegen-prettier.json'); + + execSync(`"${prettierBin}" --write --config "${configPath}" "${absoluteOutputDir}"`, { stdio: 'pipe', encoding: 'utf-8', }); return { success: true }; } catch (err) { - // oxfmt may fail if files have syntax errors or if not installed - const message = err instanceof Error ? err.message : 'Unknown error'; + // prettier may fail if files have syntax errors or if not installed + const message = err instanceof Error ? err.message : String(err); return { success: false, error: message }; } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4c3d3d51a..c0c975a4d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -748,9 +748,9 @@ importers: jiti: specifier: ^2.6.1 version: 2.6.1 - oxfmt: - specifier: ^0.13.0 - version: 0.13.0 + prettier: + specifier: ^3.7.4 + version: 3.7.4 devDependencies: '@tanstack/react-query': specifier: ^5.90.16 @@ -3410,46 +3410,6 @@ packages: '@one-ini/wasm@0.1.1': resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} - '@oxfmt/darwin-arm64@0.13.0': - resolution: {integrity: sha512-WJKGJp9t8lMG3Vmsyz77qj4GIp2Z/z5KkS4Mpbn7nfiVZLVNdxf9k85vHnuGtBZcuxIAjJIRDgitePFPD+timA==} - cpu: [arm64] - os: [darwin] - - '@oxfmt/darwin-x64@0.13.0': - resolution: {integrity: sha512-b9r+uOrnsFIl8DEimw5G69/aXbY5XURzFz0j6Hr8GiAZIrp2GlMLz0B8zhylAXh882GalZGxtcVbLZt5SSe2jw==} - cpu: [x64] - os: [darwin] - - '@oxfmt/linux-arm64-gnu@0.13.0': - resolution: {integrity: sha512-v9+rE/d38wBRli0iYvhgGWlgSAgFBJnnK6kefwQ6POu6n6y/tGiQXjWIyvkBqpQhxxavGnk3z3WXP+DAJSC2eA==} - cpu: [arm64] - os: [linux] - - '@oxfmt/linux-arm64-musl@0.13.0': - resolution: {integrity: sha512-g9A8dOoM/XwToz70aq8XodQZMWwWWPjuTUCI9cxkB1uvpQe4JN6VcHRLMY6Ft1LLh4MIARqq3mCbuXwMVseKiA==} - cpu: [arm64] - os: [linux] - - '@oxfmt/linux-x64-gnu@0.13.0': - resolution: {integrity: sha512-CbMEtJ+0mVWnBHOF+Fx8CYApAs3Iywmo6E+buokXEli98167R2eJ/g7dqNiU6R8hBiO0n4KyoT4KaeYhmQp7KA==} - cpu: [x64] - os: [linux] - - '@oxfmt/linux-x64-musl@0.13.0': - resolution: {integrity: sha512-KqE6qmwLqxbC2I1t65JNqbu87qL4my3Bi1nsmwXzJBW/xFAVNS4OgZnKQwOpW9dDXw8Ng/IoBO24GgOOECkd/w==} - cpu: [x64] - os: [linux] - - '@oxfmt/win32-arm64@0.13.0': - resolution: {integrity: sha512-jVvlnkgdKHT/l13zIG9511KoVwCKGAvQ4CUtiwiP4Nv4K1F586dV4IcOawcRnKpw9KHTV/Q0E8jB5m3tnz2yeQ==} - cpu: [arm64] - os: [win32] - - '@oxfmt/win32-x64@0.13.0': - resolution: {integrity: sha512-HgC7Efv1Eqv8Ag/3LP2WjSvzIFHsxBLBaYOgMhvq4WhZMM3xG9zsb/1A3/pVqdPhvw+Kh62WaYm1WQM9J4l0lQ==} - cpu: [x64] - os: [win32] - '@paralleldrive/cuid2@2.3.1': resolution: {integrity: sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==} @@ -7362,11 +7322,6 @@ packages: resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} engines: {node: '>=10'} - oxfmt@0.13.0: - resolution: {integrity: sha512-WhWYL1nRxevnezPK3GsGlZ2uPnO+rPlJ1U44TEfET+UwDPhKDVFyqlblduAgu3PFwTMgY/GRbaZwlWugvpfbWQ==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - p-finally@1.0.0: resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} engines: {node: '>=4'} @@ -10795,30 +10750,6 @@ snapshots: '@one-ini/wasm@0.1.1': {} - '@oxfmt/darwin-arm64@0.13.0': - optional: true - - '@oxfmt/darwin-x64@0.13.0': - optional: true - - '@oxfmt/linux-arm64-gnu@0.13.0': - optional: true - - '@oxfmt/linux-arm64-musl@0.13.0': - optional: true - - '@oxfmt/linux-x64-gnu@0.13.0': - optional: true - - '@oxfmt/linux-x64-musl@0.13.0': - optional: true - - '@oxfmt/win32-arm64@0.13.0': - optional: true - - '@oxfmt/win32-x64@0.13.0': - optional: true - '@paralleldrive/cuid2@2.3.1': dependencies: '@noble/hashes': 1.8.0 @@ -15890,17 +15821,6 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 - oxfmt@0.13.0: - optionalDependencies: - '@oxfmt/darwin-arm64': 0.13.0 - '@oxfmt/darwin-x64': 0.13.0 - '@oxfmt/linux-arm64-gnu': 0.13.0 - '@oxfmt/linux-arm64-musl': 0.13.0 - '@oxfmt/linux-x64-gnu': 0.13.0 - '@oxfmt/linux-x64-musl': 0.13.0 - '@oxfmt/win32-arm64': 0.13.0 - '@oxfmt/win32-x64': 0.13.0 - p-finally@1.0.0: {} p-limit@1.3.0: From 6ac3c3efd972574381e9319a59b189c208aa1647 Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Tue, 20 Jan 2026 08:10:18 +0000 Subject: [PATCH 2/2] Update Jest snapshot headers to new jestjs.io URL --- .../codegen/__snapshots__/client-generator.test.ts.snap | 2 +- .../codegen/__snapshots__/input-types-generator.test.ts.snap | 2 +- .../codegen/__snapshots__/model-generator.test.ts.snap | 2 +- .../codegen/__snapshots__/query-keys-factory.test.ts.snap | 2 +- .../codegen/__snapshots__/react-query-hooks.test.ts.snap | 2 +- .../codegen/__snapshots__/schema-types-generator.test.ts.snap | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/graphql/codegen/src/__tests__/codegen/__snapshots__/client-generator.test.ts.snap b/graphql/codegen/src/__tests__/codegen/__snapshots__/client-generator.test.ts.snap index 2581ad40f..e9a299087 100644 --- a/graphql/codegen/src/__tests__/codegen/__snapshots__/client-generator.test.ts.snap +++ b/graphql/codegen/src/__tests__/codegen/__snapshots__/client-generator.test.ts.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`client-generator generateCreateClientFile generates createClient factory with models 1`] = ` "/** diff --git a/graphql/codegen/src/__tests__/codegen/__snapshots__/input-types-generator.test.ts.snap b/graphql/codegen/src/__tests__/codegen/__snapshots__/input-types-generator.test.ts.snap index 9fa5733d5..523156dd3 100644 --- a/graphql/codegen/src/__tests__/codegen/__snapshots__/input-types-generator.test.ts.snap +++ b/graphql/codegen/src/__tests__/codegen/__snapshots__/input-types-generator.test.ts.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`generateInputTypesFile generates complete types file for multiple tables with relations 1`] = ` "/** diff --git a/graphql/codegen/src/__tests__/codegen/__snapshots__/model-generator.test.ts.snap b/graphql/codegen/src/__tests__/codegen/__snapshots__/model-generator.test.ts.snap index db345a4e2..dc51d712f 100644 --- a/graphql/codegen/src/__tests__/codegen/__snapshots__/model-generator.test.ts.snap +++ b/graphql/codegen/src/__tests__/codegen/__snapshots__/model-generator.test.ts.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`model-generator generates model with all CRUD methods 1`] = ` "/** diff --git a/graphql/codegen/src/__tests__/codegen/__snapshots__/query-keys-factory.test.ts.snap b/graphql/codegen/src/__tests__/codegen/__snapshots__/query-keys-factory.test.ts.snap index 9d6e45077..6bf8d8eb1 100644 --- a/graphql/codegen/src/__tests__/codegen/__snapshots__/query-keys-factory.test.ts.snap +++ b/graphql/codegen/src/__tests__/codegen/__snapshots__/query-keys-factory.test.ts.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`generateInvalidationFile generates invalidation helpers for a single table without relationships 1`] = ` "/** diff --git a/graphql/codegen/src/__tests__/codegen/__snapshots__/react-query-hooks.test.ts.snap b/graphql/codegen/src/__tests__/codegen/__snapshots__/react-query-hooks.test.ts.snap index 1fa921534..1c246200e 100644 --- a/graphql/codegen/src/__tests__/codegen/__snapshots__/react-query-hooks.test.ts.snap +++ b/graphql/codegen/src/__tests__/codegen/__snapshots__/react-query-hooks.test.ts.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`Barrel File Generators generateCustomMutationsBarrel generates custom mutations barrel 1`] = ` "/** diff --git a/graphql/codegen/src/__tests__/codegen/__snapshots__/schema-types-generator.test.ts.snap b/graphql/codegen/src/__tests__/codegen/__snapshots__/schema-types-generator.test.ts.snap index f3111ec74..e7d4d48d2 100644 --- a/graphql/codegen/src/__tests__/codegen/__snapshots__/schema-types-generator.test.ts.snap +++ b/graphql/codegen/src/__tests__/codegen/__snapshots__/schema-types-generator.test.ts.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`schema-types-generator generates enum types as string unions 1`] = ` "/**