@graphql-mesh/compose-cli
Version:
86 lines (85 loc) • 3.45 kB
JavaScript
import 'tsx/cjs'; // support importing typescript configs
import 'dotenv/config'; // inject dotenv options to process.env
// eslint-disable-next-line import/no-nodejs-modules
import { promises as fsPromises } from 'fs';
// eslint-disable-next-line import/no-nodejs-modules
import { isAbsolute, join, resolve } from 'path';
import { parse } from 'graphql';
import { Command, Option } from '@commander-js/extra-typings';
import { DefaultLogger } from '@graphql-mesh/utils';
import { printSchemaWithDirectives } from '@graphql-tools/utils';
import { getComposedSchemaFromConfig } from './getComposedSchemaFromConfig.js';
let program = new Command()
.addOption(new Option('-c, --config-path <path>', 'path to the configuration file')
.env('CONFIG_PATH')
.default('mesh.config.ts'))
.option('-o, --output <path>', 'path to the output file');
export async function run({ log: rootLog = new DefaultLogger(), productName = 'Mesh Compose', productDescription = 'compose a GraphQL federated schema from any API service(s)', binName = 'mesh-compose', version, }) {
program = program.name(binName).description(productDescription);
if (version)
program = program.version(version);
if (process.env.NODE_ENV === 'test')
program = program.allowUnknownOption();
const opts = program.parse().opts();
const log = rootLog.child(`🕸️ ${productName}`);
const configPath = isAbsolute(opts.configPath)
? opts.configPath
: resolve(process.cwd(), opts.configPath);
log.info(`Checking configuration at ${configPath}`);
const importedConfig = await import(configPath).catch(err => {
if (err.code === 'ERR_MODULE_NOT_FOUND') {
return {}; // no config is ok
}
log.error('Loading configuration failed!');
throw err;
});
if (importedConfig.composeConfig) {
log.info('Loaded configuration');
}
else {
throw new Error(`No configuration found at ${configPath}`);
}
const config = {
...importedConfig?.composeConfig,
...opts,
};
log.info('Composing');
const fusiongraphSchema = await getComposedSchemaFromConfig(config, log);
const fusiongraph = printSchemaWithDirectives(fusiongraphSchema);
let output = config.output;
if (!output) {
if (typeof process === 'object') {
process.stdout.write(fusiongraph + '\n');
}
else {
console.log(fusiongraph);
}
log.info('Done!');
return;
}
log.info(`Writing schema to ${output}`);
output = isAbsolute(output) ? output : join(process.cwd(), output);
let writtenData;
if (output.endsWith('.json')) {
writtenData = JSON.stringify(parse(fusiongraph, { noLocation: true }), null, 2);
}
else if (output.endsWith('.graphql') ||
output.endsWith('.gql') ||
output.endsWith('.graphqls') ||
output.endsWith('.gqls')) {
writtenData = fusiongraph;
}
else if (output.endsWith('.ts') ||
output.endsWith('.cts') ||
output.endsWith('.mts') ||
output.endsWith('.js') ||
output.endsWith('.cjs') ||
output.endsWith('.mjs')) {
writtenData = `export default ${JSON.stringify(fusiongraph)}`;
}
else {
throw new Error(`Unsupported file extension for ${output}`);
}
await fsPromises.writeFile(output, writtenData, 'utf8');
log.info('Done!');
}