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.

185 lines (182 loc) 5.38 kB
// 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 };