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
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
90 changes: 72 additions & 18 deletions packages/cli/src/commands/codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ 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,
Expand All @@ -20,16 +24,23 @@ Constructive GraphQL Codegen:

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 @@ -42,6 +53,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 @@ -50,6 +62,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 @@ -60,24 +77,50 @@ export default async (
: getEnvOptions();
const schemasArg = (argv.schemas as string) || '';

// Parse repeatable --header args into a headers object
const headerArg = argv.header as string | string[] | undefined
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
}

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 @@ -90,14 +133,20 @@ export default async (

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

Expand All @@ -109,13 +158,18 @@ export default async (

if (!result.success) {
console.error(result.message);
if (result.errors?.length)
result.errors.forEach((e) => console.error(' -', e));
if (result.errors?.length) {
for (const e of result.errors) {
console.error(' -', e);
}
}
process.exit(1);
}
console.log(result.message);
if (result.filesWritten?.length) {
result.filesWritten.forEach((f) => console.log(f));
for (const f of result.filesWritten) {
console.log(f);
}
}
};

Expand Down