Skip to Content

gRPC Plugin (@glubean/grpc)

@glubean/grpc is a first-party gRPC client plugin for Glubean.

Status: Experimental (pre-1.0). API may evolve. This page covers setup and the configure-mode client; see the package types for the full contract and matcher surface.

Install

npm install @glubean/grpc

Project setup — install the plugin manifest

@glubean/grpc ships a plugin manifest (registers the grpc contract protocol and the toHaveGrpc* matchers) and a client factory. Install the manifest once from glubean.setup.ts at the project root:

// glubean.setup.ts import { installPlugin } from "@glubean/sdk"; import grpcPlugin from "@glubean/grpc"; await installPlugin(grpcPlugin);

A top-level import "@glubean/grpc" no longer auto-registers these globals.

Quick start (configure plugin mode)

import { test, configure } from "@glubean/sdk"; import { grpc } from "@glubean/grpc"; const { billing } = configure({ plugins: { billing: grpc({ proto: "./protos/billing.proto", address: "{{BILLING_ADDR}}", package: "acme.billing.v1", service: "BillingService", metadata: { authorization: "Bearer {{API_TOKEN}}" }, }), }, }); export const createInvoice = test("create-invoice", async (ctx) => { const res = await billing.call("CreateInvoice", { customer_id: "cus_123", amount_cents: 1200, }); ctx.expect(res.status.code).toBe(0); // 0 = OK });

{{template}} placeholders in address/metadata resolve from vars + secrets at run time. call<T>(method, request, options?) returns { message, status: { code, details }, responseMetadata, duration }.

Contract protocol

Use contract.grpc.with(...) when an RPC is a durable API promise that should run as a check and project into Specifications.

import { configure, contract } from "@glubean/sdk"; import { grpc } from "@glubean/grpc"; const { billing } = configure({ plugins: { billing: grpc({ proto: "./protos/billing.proto", address: "{{BILLING_ADDR}}", package: "acme.billing.v1", service: "BillingService", metadata: { authorization: "Bearer {{API_TOKEN}}" }, }), }, }); const billingGrpc = contract.grpc.with("billingGrpc", { client: billing, tags: ["billing"], }); export const invoiceRpc = billingGrpc("create-invoice-rpc", { target: "BillingService/CreateInvoice", cases: { ok: { description: "valid invoice request creates an invoice", request: { customer_id: "cus_123", amount_cents: 1200, }, expect: { statusCode: 0, message: { customer_id: "cus_123" }, }, }, }, });

Matchers

toHaveGrpcStatus(code), toHaveGrpcOk(), toHaveGrpcMetadata(key, value?).

Options

OptionTypeDefaultDescription
protostring(required)Path to the .proto file
addressstring(required)Server host:port ({{KEY}} supported)
packagestring(required)Protobuf package (e.g. acme.users.v1)
servicestring(required)Service name within the package
metadataRecord<string, string>{}Static call metadata ({{KEY}} supported)
tlsbooleanfalseUse TLS credentials (default: insecure)
deadlineMsnumber30000Default per-call deadline (ms)

Contracts & redaction

  • The manifest registers a grpc contract protocol used via contract.grpc.with("name", { client }). Its case shape differs from HTTP (e.g. target: "Service/Method", request, expect.statusCode) — see the @glubean/grpc types for the exact GrpcContractSpec.
  • gRPC traces use the same upload redaction pipeline as other trace events. Request metadata is stored under trace metadata, so baseline credential keys such as authorization, token, api_key, and secret are masked before upload.
  • The package also exports GRPC_REDACTION_SCOPES for hosts that explicitly compile plugin-provided redaction scopes. The current CLI does not require you to wire this manually for normal glubean run --upload, but custom hosts that call compileScopes(...) themselves should pass those scopes.
  • Still keep credentials in .env.secrets, avoid logging derived credential strings, and use glubean redact --input .glubean/last-run.result.json when you want to preview exactly what will be masked before sharing or uploading.

Next

Last updated on