Skip to content
Open
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
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
4 changes: 3 additions & 1 deletion graphql/codegen/src/cli/commands/generate-orm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export interface GenerateOrmOptions {
output?: string;
/** Authorization header */
authorization?: string;
/** Additional HTTP headers for endpoint requests */
headers?: Record<string, string>;
/** Verbose output */
verbose?: boolean;
/** Dry run - don't write files */
Expand Down Expand Up @@ -173,7 +175,7 @@ async function generateOrmForTarget(
endpoint: config.endpoint || undefined,
schema: config.schema || undefined,
authorization: options.authorization || config.headers['Authorization'],
headers: config.headers,
headers: { ...config.headers, ...options.headers },
});

// 2. Run the codegen pipeline
Expand Down
4 changes: 3 additions & 1 deletion graphql/codegen/src/cli/commands/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ export interface GenerateOptions {
output?: string;
/** Authorization header */
authorization?: string;
/** Additional HTTP headers for endpoint requests */
headers?: Record<string, string>;
/** Verbose output */
verbose?: boolean;
/** Dry run - don't write files */
Expand Down Expand Up @@ -174,7 +176,7 @@ async function generateForTarget(
endpoint: config.endpoint || undefined,
schema: config.schema || undefined,
authorization: options.authorization || config.headers['Authorization'],
headers: config.headers,
headers: { ...config.headers, ...options.headers },
});

// 2. Run the codegen pipeline
Expand Down
80 changes: 63 additions & 17 deletions packages/cli/src/commands/codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,54 @@ import {
generateCommand,
type GenerateTargetResult,
} from '@constructive-io/graphql-codegen/cli/commands/generate';
import {
generateOrmCommand,
type GenerateOrmTargetResult,
} from '@constructive-io/graphql-codegen/cli/commands/generate-orm';
import { findConfigFile } from '@constructive-io/graphql-codegen/cli/commands/init';
import {
ConstructiveOptions,
getEnvOptions,
} from '@constructive-io/graphql-env';

function parseHeaders(headerArg: string | string[] | undefined): Record<string, string> {
const headerList = Array.isArray(headerArg) ? headerArg : headerArg ? [headerArg] : [];
const headers: Record<string, string> = {};
for (const h of headerList) {
const idx = typeof h === 'string' ? h.indexOf(':') : -1;
if (idx <= 0) continue;
const name = h.slice(0, idx).trim();
const value = h.slice(idx + 1).trim();
if (!name) continue;
headers[name] = value;
}
return headers;
}

const usage = `
Constructive GraphQL Codegen:

cnc codegen [OPTIONS]

Options:
--help, -h Show this help message
--mode <type> Generation mode: "hooks" (default) or "orm"
--config <path> Path to graphql-codegen config file
--target <name> Target name in config file
--endpoint <url> GraphQL endpoint URL
--auth <token> Authorization header value (e.g., "Bearer 123")
--out <dir> Output directory (default: graphql/codegen/dist)
--header "Name: Value" Optional HTTP header; repeat to add multiple
--out <dir> Output directory
--dry-run Preview without writing files
-v, --verbose Verbose output

--database <name> Database override for DB mode (defaults to PGDATABASE)
--schemas <list> Comma-separated schemas (required for DB mode)

Examples:
cnc codegen --endpoint https://api.example.com/graphql
cnc codegen --mode orm --endpoint https://api.example.com/graphql
cnc codegen --mode hooks --schemas public --database mydb
`;

export default async (
Expand All @@ -41,6 +66,7 @@ export default async (
process.exit(0);
}

const mode = (argv.mode as string) || 'hooks';
const endpointArg = (argv.endpoint as string) || '';
const outputArg = argv.out as string | undefined;
const outDir = outputArg || 'codegen';
Expand All @@ -49,6 +75,11 @@ export default async (
const target = (argv.target as string) || '';
const dryRun = !!(argv['dry-run'] || argv.dryRun);
const verbose = !!(argv.verbose || argv.v);

if (mode !== 'hooks' && mode !== 'orm') {
console.error(`Error: Invalid mode "${mode}". Must be "hooks" or "orm".`);
process.exit(1);
}
const resolvedConfigPath = configPath || findConfigFile() || '';
const hasConfigFile = Boolean(resolvedConfigPath);
const outputForGenerate = outputArg || !hasConfigFile ? outDir : undefined;
Expand All @@ -59,24 +90,39 @@ export default async (
: getEnvOptions();
const schemasArg = (argv.schemas as string) || '';

const headers = parseHeaders(argv.header as string | string[] | undefined);

const runGenerate = async ({
endpoint,
schema,
}: {
endpoint?: string;
schema?: string;
}) => {
const result = await generateCommand({
config: configPath || undefined,
target: target || undefined,
endpoint,
schema,
output: outputForGenerate,
authorization: auth || undefined,
verbose,
dryRun,
});
const targetResults: GenerateTargetResult[] = result.targets ?? [];
const result = mode === 'orm'
? await generateOrmCommand({
config: configPath || undefined,
target: target || undefined,
endpoint,
schema,
output: outputForGenerate,
authorization: auth || undefined,
headers,
verbose,
dryRun,
})
: await generateCommand({
config: configPath || undefined,
target: target || undefined,
endpoint,
schema,
output: outputForGenerate,
authorization: auth || undefined,
headers,
verbose,
dryRun,
});
const targetResults: (GenerateTargetResult | GenerateOrmTargetResult)[] = result.targets ?? [];
const hasNamedTargets =
targetResults.length > 0 &&
(targetResults.length > 1 || targetResults[0]?.name !== 'default');
Expand All @@ -89,14 +135,14 @@ export default async (

if (target.tables?.length) {
console.log(' Tables:');
target.tables.forEach((table) => console.log(` - ${table}`));
(target.tables as any).forEach((table: any) => console.log(` - ${table}`));
}
if (target.filesWritten?.length) {
console.log(' Files written:');
target.filesWritten.forEach((file) => console.log(` - ${file}`));
(target.filesWritten as any).forEach((file: any) => console.log(` - ${file}`));
}
if (!target.success && target.errors?.length) {
target.errors.forEach((error) => console.error(` - ${error}`));
(target.errors as any).forEach((error: any) => console.error(` - ${error}`));
}
});

Expand All @@ -109,12 +155,12 @@ export default async (
if (!result.success) {
console.error(result.message);
if (result.errors?.length)
result.errors.forEach((e) => console.error(' -', e));
(result.errors as any).forEach((e: any) => console.error(' -', e));
process.exit(1);
}
console.log(result.message);
if (result.filesWritten?.length) {
result.filesWritten.forEach((f) => console.log(f));
(result.filesWritten as any).forEach((f: any) => console.log(f));
}
};

Expand Down