feat(infra): framework

This commit is contained in:
EYHN
2024-04-17 14:12:29 +08:00
parent ab17a05df3
commit 06fda3b62c
467 changed files with 9996 additions and 8697 deletions

View File

@@ -1,18 +1,9 @@
import type { ExecutionResult } from 'graphql';
import { GraphQLError } from 'graphql';
import { isNil, isObject, merge } from 'lodash-es';
import { nanoid } from 'nanoid';
import type { GraphQLQuery } from './graphql';
import type { Mutations, Queries } from './schema';
import {
generateRandUTF16Chars,
SPAN_ID_BYTES,
TRACE_FLAG,
TRACE_ID_BYTES,
TRACE_VERSION,
traceReporter,
} from './utils';
export type NotArray<T> = T extends Array<unknown> ? never : T;
@@ -166,7 +157,10 @@ function formatRequestBody<Q extends GraphQLQuery>({
return body;
}
export const gqlFetcherFactory = (endpoint: string) => {
export const gqlFetcherFactory = (
endpoint: string,
fetcher: (input: string, init?: RequestInit) => Promise<Response> = fetch
) => {
const gqlFetch = async <Query extends GraphQLQuery>(
options: QueryOptions<Query>
): Promise<QueryResponse<Query>> => {
@@ -180,14 +174,13 @@ export const gqlFetcherFactory = (endpoint: string) => {
if (!isFormData) {
headers['content-type'] = 'application/json';
}
const ret = fetchWithTraceReport(
const ret = fetcher(
endpoint,
merge(options.context, {
method: 'POST',
headers,
body: isFormData ? body : JSON.stringify(body),
}),
{ event: 'GraphQLRequest' }
})
).then(async res => {
if (res.headers.get('content-type')?.startsWith('application/json')) {
const result = (await res.json()) as ExecutionResult;
@@ -205,7 +198,10 @@ export const gqlFetcherFactory = (endpoint: string) => {
}
}
throw new GraphQLError('GraphQL query responds unexpected result');
throw new GraphQLError(
'GraphQL query responds unexpected result, query ' +
options.query.operationName
);
});
return ret;
@@ -213,47 +209,3 @@ export const gqlFetcherFactory = (endpoint: string) => {
return gqlFetch;
};
export const fetchWithTraceReport = async (
input: RequestInfo | URL,
init?: RequestInit & { priority?: 'auto' | 'low' | 'high' }, // https://github.com/microsoft/TypeScript/issues/54472
traceOptions?: { event: string }
): Promise<Response> => {
const startTime = new Date().toISOString();
const spanId = generateRandUTF16Chars(SPAN_ID_BYTES);
const traceId = generateRandUTF16Chars(TRACE_ID_BYTES);
const traceparent = `${TRACE_VERSION}-${traceId}-${spanId}-${TRACE_FLAG}`;
init = init || {};
init.headers = init.headers || new Headers();
const requestId = nanoid();
const event = traceOptions?.event;
if (init.headers instanceof Headers) {
init.headers.append('x-request-id', requestId);
init.headers.append('traceparent', traceparent);
} else {
const headers = init.headers as Record<string, string>;
headers['x-request-id'] = requestId;
headers['traceparent'] = traceparent;
}
if (!traceReporter) {
return fetch(input, init);
}
try {
const response = await fetch(input, init);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
traceReporter!.cacheTrace(traceId, spanId, startTime, {
requestId,
...(event ? { event } : {}),
});
return response;
} catch (err) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
traceReporter!.uploadTrace(traceId, spanId, startTime, {
requestId,
...(event ? { event } : {}),
});
throw err;
}
};