stellate
Version:
The CLI you need to work with Stellate from your CLI. See https://docs.stellate.co/docs/cli for the complete documentation.
185 lines (182 loc) • 5.38 kB
JavaScript
// src/envelop.ts
import { introspectionFromSchema, print } from "graphql";
import { isAsyncIterable } from "@envelop/core";
// src/server-plugins-shared.ts
function createBlake3Hash(str) {
let val = 0;
const strlen = str.length;
if (strlen === 0) {
return val;
}
for (let i = 0; i < strlen; ++i) {
const code = str.charCodeAt(i);
val = (val << 5) - val + code;
val &= val;
}
return val >>> 0;
}
function extractStellatePayload({
headers,
operation,
method,
start,
operationName,
errors,
response,
variables,
responseHeaders,
sendVariablesAsHash,
hasSetCookie,
graphqlClientName,
graphqlClientVersion
}) {
const forwardedFor = headers.get("x-forwarded-for");
const ips = forwardedFor ? forwardedFor.split(",") : [];
const vary = responseHeaders && responseHeaders.get("vary");
let varyHash = void 0;
if (vary && vary.length) {
const varyHeaders = vary.split(",").map((headerName) => headerName && headerName.trim()).sort();
const variedValues = varyHeaders.map((headerName) => {
const headerValue = headerName && headers.get(headerName);
return headerValue ? `${headerName}:${headerValue}` : void 0;
}).filter(Boolean).join("\n");
varyHash = createBlake3Hash(variedValues);
}
return {
graphqlClientName,
graphqlClientVersion,
operation,
operationName,
variables: sendVariablesAsHash ? void 0 : variables,
variableHash: sendVariablesAsHash ? createBlake3Hash(JSON.stringify(variables || {})) : void 0,
method,
elapsed: Date.now() - start,
ip: ips[0] || headers.get("true-client-ip") || headers.get("x-real-ip") || void 0,
hasSetCookie,
referer: headers.get("referer") || void 0,
userAgent: headers.get("user-agent") || void 0,
statusCode: 200,
errors,
responseSize: JSON.stringify(response).length,
responseHash: createBlake3Hash(JSON.stringify(response)),
varyHash
};
}
function warnFetch(fetch) {
if (typeof fetch !== "function") {
console.warn(
`Stellate logger plugin requires a fetch function to be provided as an option.`
);
return;
}
}
var hostname = process.env.STELLATE_ENDPOINT === "local" || process.env.STELLATE_ENDPOINT === "staging" ? "stellate.dev" : "stellate.sh";
async function logRequest({
fetch: fetchFn,
payload,
token,
serviceName
}) {
return fetchFn(`https://${serviceName}.${hostname}/log`, {
method: "POST",
body: JSON.stringify(payload),
headers: {
"Content-Type": "application/json",
"Stellate-Logging-Token": token
}
});
}
// src/envelop.ts
var FauxHeaders = class {
constructor(init) {
this.headers = Object.keys(init).reduce((acc, key) => {
acc[key.trim().toLowerCase()] = init[key];
return acc;
}, {});
}
get(key) {
return this.headers[key.trim().toLowerCase()];
}
has(key) {
return !!this.headers[key.trim().toLowerCase()];
}
};
var createStellateLoggerPlugin = (options) => {
var _a;
const shouldSyncSchema = (_a = options.schemaSyncing) != null ? _a : true;
let timeout;
return {
onSchemaChange(opts) {
if (shouldSyncSchema) {
const apiSchema = opts.schema;
const randomTimeout = Math.random() * 5e3;
if (timeout) clearTimeout(timeout);
timeout = setTimeout(async () => {
timeout = null;
try {
const introspection = introspectionFromSchema(apiSchema);
options.fetch(`https://${options.serviceName}.${hostname}/schema`, {
method: "POST",
body: JSON.stringify({
schema: introspection
}),
headers: {
"Content-Type": "application/json",
"Stellate-Schema-Token": options.token
}
}).then(() => {
});
} catch (e) {
}
}, randomTimeout);
}
},
onExecute(payload) {
var _a2;
const sendVariablesAsHash = (_a2 = options.sendVariablesAsHash) != null ? _a2 : true;
const start = Date.now();
return {
async onExecuteDone({ result }) {
if (isAsyncIterable(result)) {
console.warn(
`Stellate does not currently support logging incremental results.`
);
return;
}
let { headers } = payload.args.contextValue.request;
const { method } = payload.args.contextValue.request;
if (typeof headers.get !== "function") {
headers = new FauxHeaders(
headers
);
}
if (headers.has("gcdn-request-id")) return;
const stellatePayload = extractStellatePayload({
headers,
operation: print(payload.args.document),
method,
sendVariablesAsHash,
start,
operationName: payload.args.operationName,
errors: result.errors,
response: result
});
warnFetch(options.fetch);
try {
await logRequest({
fetch: options.fetch,
payload: stellatePayload,
token: options.token,
serviceName: options.serviceName
});
} catch (e) {
}
}
};
}
};
};
export {
createBlake3Hash,
createStellateLoggerPlugin
};