mirror of
https://github.com/graphql-hive/console
synced 2026-04-21 14:37:17 +00:00
159 lines
3.9 KiB
TypeScript
159 lines
3.9 KiB
TypeScript
import asyncRetry from 'async-retry';
|
|
import Docker from 'dockerode';
|
|
import { humanId } from 'human-id';
|
|
|
|
let docker: Docker | null = null;
|
|
|
|
function getDockerConnection() {
|
|
if (!docker) {
|
|
docker = new Docker();
|
|
}
|
|
|
|
return docker;
|
|
}
|
|
|
|
const LOCAL_SERVICES = {
|
|
server: 3001,
|
|
clickhouse: 8123,
|
|
emails: 6260,
|
|
composition_federation_2: 3069,
|
|
usage: 4001,
|
|
schema: 6500,
|
|
external_composition: 3012,
|
|
mock_server: 3042,
|
|
'otel-collector': 4318,
|
|
workflows: 3014,
|
|
} as const;
|
|
|
|
export type KnownServices = keyof typeof LOCAL_SERVICES;
|
|
|
|
export function getCDNPort() {
|
|
if (process.env.RUN_AGAINST_LOCAL_SERVICES === '1') {
|
|
return 9000;
|
|
}
|
|
|
|
return 8083;
|
|
}
|
|
|
|
export function getAppBaseUrl() {
|
|
if (process.env.RUN_AGAINST_LOCAL_SERVICES === '1') {
|
|
return 'localhost:3000';
|
|
}
|
|
|
|
return 'localhost:8080';
|
|
}
|
|
|
|
export async function getServiceHost(
|
|
serviceName: KnownServices,
|
|
servicePort: number,
|
|
localhost = true,
|
|
): Promise<string> {
|
|
if (process.env.RUN_AGAINST_LOCAL_SERVICES === '1') {
|
|
return `localhost:${LOCAL_SERVICES[serviceName]}`;
|
|
}
|
|
|
|
const actualHost = localhost ? 'localhost' : serviceName;
|
|
const docker = getDockerConnection();
|
|
const containers = await docker.listContainers({
|
|
filters: JSON.stringify({
|
|
label: [`com.docker.compose.service=${serviceName}`],
|
|
}),
|
|
});
|
|
|
|
if (containers.length === 0) {
|
|
throw new Error(`Failed to locate Docker container for service "${serviceName}"!`);
|
|
}
|
|
|
|
const container = containers[0];
|
|
const ports = container.Ports || [];
|
|
|
|
if (ports.length === 0) {
|
|
throw new Error(
|
|
`Container "${container.Id}" for service "${serviceName}" does not expose any ports!`,
|
|
);
|
|
}
|
|
|
|
const publicPort = ports.find(p => p.PublicPort === servicePort);
|
|
const privatePort = ports.find(p => p.PrivatePort === servicePort);
|
|
|
|
if (!publicPort && !privatePort) {
|
|
throw new Error(
|
|
`Container "${container.Id}" for service "${serviceName}" does not expose port "${servicePort}"!`,
|
|
);
|
|
}
|
|
|
|
if (publicPort) {
|
|
return `${actualHost}:${publicPort.PublicPort}`;
|
|
}
|
|
|
|
if (privatePort) {
|
|
console.warn(
|
|
`Container "${container.Id}" (service: "${serviceName}") expose port "${servicePort}" as "${privatePort.PublicPort}", please consider to update your setup!`,
|
|
);
|
|
|
|
return `${actualHost}:${privatePort.PublicPort}`;
|
|
}
|
|
|
|
return `${actualHost}:${servicePort}`;
|
|
}
|
|
|
|
export function generateUnique() {
|
|
return humanId({
|
|
separator: '',
|
|
adjectiveCount: 1,
|
|
addAdverb: true,
|
|
capitalize: false,
|
|
});
|
|
}
|
|
|
|
export function assertNonNull<T>(
|
|
value: T | null,
|
|
message = 'Expected non-null value.',
|
|
): asserts value is T {
|
|
if (value === null) {
|
|
throw new Error(message);
|
|
}
|
|
}
|
|
|
|
export function assertNonNullish<T>(
|
|
value: T | null | undefined,
|
|
message = 'Expected non-null value.',
|
|
): asserts value is T {
|
|
if (value === null) {
|
|
throw new Error(message);
|
|
}
|
|
}
|
|
|
|
export async function pollForEmailVerificationLink(input: string | { email: string; now: number }) {
|
|
const email = typeof input === 'string' ? input : input.email;
|
|
const now = new Date(typeof input === 'string' ? Date.now() - 10_000 : input.now).toISOString();
|
|
const url = new URL('http://localhost:3014/_history');
|
|
url.searchParams.set('after', now);
|
|
|
|
return await asyncRetry(
|
|
async () => {
|
|
const emails = await fetch(url.toString())
|
|
.then(res => res.json())
|
|
.then(emails =>
|
|
emails.filter((e: any) => e.to === email && e.subject === 'Verify your email'),
|
|
);
|
|
|
|
if (emails.length === 0) {
|
|
throw new Error('Could not find email');
|
|
}
|
|
|
|
// take the latest one
|
|
const result = emails[emails.length - 1];
|
|
|
|
const urlMatch = result.body.match(/href=\"(http:\/\/[^\s"]+)/);
|
|
if (!urlMatch) throw new Error('No URL found in email');
|
|
|
|
return new URL(urlMatch[1]);
|
|
},
|
|
{
|
|
retries: 10,
|
|
minTimeout: 1000,
|
|
maxTimeout: 10000,
|
|
},
|
|
);
|
|
}
|