hypertune
Version:
[Hypertune](https://www.hypertune.com/) is the most flexible platform for feature flags, A/B testing, analytics and app configuration. Built with full end-to-end type-safety, Git-style version control and local, synchronous, in-memory flag evaluation. Opt
192 lines (175 loc) • 3.77 kB
text/typescript
import {
CodegenRequestBody,
CodegenResponseBody,
GraphqlRequestBody,
InitRequestBody,
InitData,
RequestType,
TracedFetch,
sdkVersion,
ObjectValue,
JsLanguage,
InitQuery,
HashData,
} from "../shared";
import { parseHashData } from "../shared/helpers/hashDataEncoding";
import parseInitResponse from "./parseInitResponse";
export async function codegenRequest({
traceId,
token,
branchName,
body,
language,
edgeBaseUrl,
tracedFetch,
}: {
traceId: string;
token: string;
branchName: string | null;
body: Omit<CodegenRequestBody, "sdkType" | "sdkVersion" | "language">;
language: JsLanguage;
edgeBaseUrl: string;
tracedFetch: TracedFetch;
}): Promise<CodegenResponseBody> {
const fullBody: CodegenRequestBody = {
...body,
sdkType: "js",
sdkVersion,
language,
};
const responseString = await edgeRequest({
traceId,
token,
branchName,
edgeBaseUrl,
tracedFetch,
requestType: "codegen",
body: fullBody,
});
const response = JSON.parse(responseString) as CodegenResponseBody;
if (!response.files) {
throw new Error(`[codegenRequest] unexpected response: ${responseString}`);
}
return response;
}
export async function initRequest({
traceId,
token,
query,
variables,
branchName,
edgeBaseUrl,
tracedFetch,
}: {
traceId: string;
token: string;
query: InitQuery;
variables: ObjectValue;
branchName: string | null;
edgeBaseUrl: string;
tracedFetch: TracedFetch;
}): Promise<InitData> {
const body: InitRequestBody = {
query,
variables,
sdkType: "js",
sdkVersion,
};
const responseString = await edgeRequest({
traceId,
token,
branchName,
body,
edgeBaseUrl,
tracedFetch,
requestType: "init",
});
const response = parseInitResponse(responseString);
if (!response.commitId) {
throw new Error(`[initRequest] unexpected response: ${responseString}`);
}
return response;
}
export async function hashRequest({
traceId,
token,
query,
variables,
branchName,
edgeBaseUrl,
tracedFetch,
}: {
traceId: string;
token: string;
query: InitQuery;
variables: ObjectValue;
branchName: string | null;
edgeBaseUrl: string;
tracedFetch: TracedFetch;
}): Promise<HashData> {
const body: InitRequestBody = {
query,
variables,
sdkType: "js",
sdkVersion,
};
const responseString = await edgeRequest({
traceId,
token,
branchName,
body,
edgeBaseUrl,
tracedFetch,
requestType: "hash",
});
const data = parseHashData(responseString);
if (!data) {
throw new Error(`[hashRequest] unexpected response: ${responseString}`);
}
return data;
}
async function edgeRequest({
traceId,
token,
branchName,
requestType,
body,
edgeBaseUrl,
tracedFetch,
}: {
traceId: string;
token: string;
branchName: string | null;
requestType: RequestType;
body: CodegenRequestBody | InitRequestBody;
edgeBaseUrl: string;
tracedFetch: TracedFetch;
}): Promise<string> {
const url = getEdgeRequestUrl({
baseUrl: edgeBaseUrl,
requestType,
token,
branchName,
body,
});
const response = await tracedFetch(traceId, url, {
method: "GET",
headers: { "Cache-Control": "no-store" },
});
return response.text();
}
export function getEdgeRequestUrl({
baseUrl,
requestType,
token,
branchName,
body,
}: {
baseUrl: string;
requestType: RequestType;
token: string;
branchName: string | null;
body: CodegenRequestBody | InitRequestBody | GraphqlRequestBody;
}): string {
return `${baseUrl}/${requestType}?token=${encodeURIComponent(token)}${branchName ? `&branch=${encodeURIComponent(branchName)}` : ""}&body=${encodeURIComponent(JSON.stringify(body))}`;
}