UNPKG

stellate

Version:

The CLI you need to work with Stellate from your CLI. See https://docs.stellate.co/docs/cli for the complete documentation.

190 lines (188 loc) 5.83 kB
// 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/apollo-server.ts import { introspectionFromSchema } from "graphql"; var createStellateLoggerPlugin = (options) => { var _a, _b; const sendVariablesAsHash = (_a = options.sendVariablesAsHash) != null ? _a : true; const shouldSyncSchema = (_b = options.schemaSyncing) != null ? _b : true; let stopped = false, timeout; const sendSchema = async (apiSchema) => { if (shouldSyncSchema) { const introspection = introspectionFromSchema(apiSchema); const randomTimeout = Math.random() * 5e3; if (timeout) clearTimeout(timeout); timeout = setTimeout(async () => { timeout = null; if (!stopped) { try { 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); } }; return { async serverWillStart() { return { schemaDidLoadOrUpdate({ apiSchema }) { sendSchema(apiSchema); }, async serverWillStop() { stopped = true; if (timeout) { clearTimeout(timeout); } } }; }, async requestDidStart(requestCtx) { const start = Date.now(); const { request } = requestCtx; const { operationName, variables, http, query } = request; if (!http) return; const { headers, method } = http; if (headers.has("gcdn-request-id")) return; return { async willSendResponse(respContext) { var _a2, _b2; const { response, source } = respContext; if (response.body.kind !== "single") { console.warn( `Stellate does not currently support logging incremental results.` ); return; } const respBody = response.body.singleResult; const queryString = query || source; if (!queryString) return; const graphqlClientName = ((_a2 = request.http) == null ? void 0 : _a2.headers.get("x-graphql-client-name")) || void 0; const graphqlClientVersion = ((_b2 = request.http) == null ? void 0 : _b2.headers.get("x-graphql-client-version")) || void 0; const stellatePayload = extractStellatePayload({ headers, responseHeaders: response.http.headers, operation: queryString, method, sendVariablesAsHash, start, operationName, errors: respContext.errors, response: respBody, variables, hasSetCookie: response.http.headers.has("set-cookie"), graphqlClientName, graphqlClientVersion }); warnFetch(options.fetch); try { await logRequest({ fetch: options.fetch, payload: stellatePayload, token: options.token, serviceName: options.serviceName }); } catch (e) { } } }; } }; }; export { createBlake3Hash, createStellateLoggerPlugin };