mirror of
https://github.com/graphql-hive/console
synced 2026-05-13 12:19:03 +00:00
183 lines
5 KiB
TypeScript
183 lines
5 KiB
TypeScript
import { randomUUID } from 'node:crypto';
|
|
import { writeFile } from 'node:fs/promises';
|
|
import { tmpdir } from 'node:os';
|
|
import { join, resolve } from 'node:path';
|
|
import 'jest-expect-message';
|
|
import { execaCommand } from '@esm2cjs/execa';
|
|
import { fetchLatestSchema, fetchLatestValidSchema } from './flow';
|
|
import { getServiceHost } from './utils';
|
|
|
|
const binPath = resolve(__dirname, '../../packages/libraries/cli/bin/run');
|
|
const cliDir = resolve(__dirname, '../../packages/libraries/cli');
|
|
|
|
async function generateTmpFile(content: string, extension: string) {
|
|
const dir = tmpdir();
|
|
const fileName = randomUUID();
|
|
const filepath = join(dir, `${fileName}.${extension}`);
|
|
|
|
await writeFile(filepath, content, 'utf-8');
|
|
|
|
return filepath;
|
|
}
|
|
|
|
export async function createCLI(token: string) {
|
|
let publishCount = 0;
|
|
|
|
async function publish({
|
|
sdl,
|
|
serviceName,
|
|
serviceUrl,
|
|
metadata,
|
|
expect: expectedStatus,
|
|
force,
|
|
acceptBreakingChanges,
|
|
}: {
|
|
sdl: string;
|
|
commit?: string;
|
|
serviceName?: string;
|
|
serviceUrl?: string;
|
|
metadata?: string;
|
|
force?: boolean;
|
|
acceptBreakingChanges?: boolean;
|
|
expect: 'latest' | 'latest-composable' | 'ignored' | 'rejected';
|
|
}) {
|
|
const publishName = ` #${++publishCount}`;
|
|
const commit = randomUUID();
|
|
|
|
const cmd = schemaPublish([
|
|
'--token',
|
|
token,
|
|
'--author',
|
|
'Kamil',
|
|
'--commit',
|
|
commit,
|
|
...(serviceName ? ['--service', serviceName] : []),
|
|
...(serviceUrl ? ['--url', serviceUrl] : []),
|
|
...(metadata ? ['--metadata', metadata] : []),
|
|
...(force ? ['--force'] : []),
|
|
...(acceptBreakingChanges ? ['--experimental_acceptBreakingChanges'] : []),
|
|
await generateTmpFile(sdl, 'graphql'),
|
|
]);
|
|
|
|
const expectedCommit = expect.objectContaining({
|
|
commit,
|
|
});
|
|
|
|
if (expectedStatus === 'rejected') {
|
|
await expect(cmd).rejects.toThrow();
|
|
const latestSchemaResult = await fetchLatestSchema(token).then(r =>
|
|
r.expectNoGraphQLErrors(),
|
|
);
|
|
const latestSchemaCommit = latestSchemaResult.latestVersion?.commit;
|
|
|
|
expect(
|
|
latestSchemaCommit,
|
|
`${publishName} was expected to be rejected but was published`,
|
|
).not.toEqual(expectedCommit);
|
|
|
|
return;
|
|
}
|
|
|
|
// throw if the command fails
|
|
try {
|
|
await cmd;
|
|
} catch (error) {
|
|
throw new Error(`${publishName} failed: ${String(error)}`);
|
|
}
|
|
|
|
const latestSchemaResult = await fetchLatestSchema(token).then(r => r.expectNoGraphQLErrors());
|
|
const latestSchemaCommit = latestSchemaResult.latestVersion?.commit;
|
|
|
|
if (expectedStatus === 'ignored') {
|
|
// Check if the schema was ignored
|
|
expect(
|
|
latestSchemaCommit,
|
|
`${publishName} was expected to be ignored but it was published`,
|
|
).not.toEqual(expectedCommit);
|
|
return;
|
|
}
|
|
// Check if the schema was published
|
|
expect(latestSchemaCommit, `${publishName} was expected to be published`).toEqual(
|
|
expectedCommit,
|
|
);
|
|
|
|
const latestComposableSchemaResult = await fetchLatestValidSchema(token).then(r =>
|
|
r.expectNoGraphQLErrors(),
|
|
);
|
|
|
|
const latestComposableSchemaCommit = latestComposableSchemaResult.latestValidVersion?.commit;
|
|
|
|
// Check if the schema was published as composable or non-composable
|
|
if (expectedStatus === 'latest') {
|
|
// schema is not available to the gateway
|
|
expect(
|
|
latestComposableSchemaCommit,
|
|
`${publishName} was expected to be published but not as composable`,
|
|
).not.toEqual(expectedCommit);
|
|
} else {
|
|
// schema is available to the gateway
|
|
expect(
|
|
latestComposableSchemaCommit,
|
|
`${publishName} was expected to be published as composable`,
|
|
).toEqual(expectedCommit);
|
|
}
|
|
}
|
|
|
|
async function check({
|
|
sdl,
|
|
serviceName,
|
|
expect: expectedStatus,
|
|
}: {
|
|
sdl: string;
|
|
serviceName?: string;
|
|
expect: 'approved' | 'rejected';
|
|
}) {
|
|
const cmd = schemaCheck([
|
|
'--token',
|
|
token,
|
|
...(serviceName ? ['--service', serviceName] : []),
|
|
await generateTmpFile(sdl, 'graphql'),
|
|
]);
|
|
|
|
if (expectedStatus === 'rejected') {
|
|
await expect(cmd).rejects.toThrow();
|
|
return cmd.catch(reason => Promise.resolve(reason.message));
|
|
}
|
|
return cmd;
|
|
}
|
|
|
|
return {
|
|
publish,
|
|
check,
|
|
};
|
|
}
|
|
|
|
async function exec(cmd: string) {
|
|
const outout = await execaCommand(`${binPath} ${cmd}`, {
|
|
shell: true,
|
|
env: {
|
|
OCLIF_CLI_CUSTOM_PATH: cliDir,
|
|
},
|
|
});
|
|
|
|
if (outout.failed) {
|
|
throw new Error(outout.stderr);
|
|
}
|
|
|
|
return outout.stdout;
|
|
}
|
|
|
|
export async function schemaPublish(args: string[]) {
|
|
const registryAddress = await getServiceHost('server', 8082);
|
|
return await exec(
|
|
['schema:publish', `--registry`, `http://${registryAddress}/graphql`, ...args].join(' '),
|
|
);
|
|
}
|
|
|
|
export async function schemaCheck(args: string[]) {
|
|
const registryAddress = await getServiceHost('server', 8082);
|
|
|
|
return await exec(
|
|
['schema:check', `--registry`, `http://${registryAddress}/graphql`, ...args].join(' '),
|
|
);
|
|
}
|