Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion graphql/codegen/SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ GraphQL Schema (endpoint or .graphql file)
┌─────────────────────────────────────┐
│ Output Formatting (oxfmt)
│ Output Formatting (prettier)
└─────────────────────────────────────┘
```

Expand Down
6 changes: 3 additions & 3 deletions graphql/codegen/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -62,7 +62,7 @@
"inflekt": "^0.3.0",
"inquirerer": "^4.4.0",
"jiti": "^2.6.1",
"oxfmt": "^0.13.0"
"prettier": "^3.7.4"
},
"peerDependencies": {
"@tanstack/react-query": "^5.0.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -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`] = `
"/**
Expand Down
Original file line number Diff line number Diff line change
@@ -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`] = `
"/**
Expand Down
Original file line number Diff line number Diff line change
@@ -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`] = `
"/**
Expand Down
Original file line number Diff line number Diff line change
@@ -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`] = `
"/**
Expand Down
Original file line number Diff line number Diff line change
@@ -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`] = `
"/**
Expand Down
Original file line number Diff line number Diff line change
@@ -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`] = `
"/**
Expand Down
37 changes: 37 additions & 0 deletions graphql/codegen/src/__tests__/codegen/format-output.test.ts
Original file line number Diff line number Diff line change
@@ -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(';');
});
});
7 changes: 7 additions & 0 deletions graphql/codegen/src/cli/commands/codegen-prettier.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"singleQuote": true,
"trailingComma": "all",
"tabWidth": 2,
"useTabs": false,
"semi": true
}
26 changes: 15 additions & 11 deletions graphql/codegen/src/cli/commands/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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...');
Expand All @@ -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 };
}
}
Loading