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/grpcProject 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
| Option | Type | Default | Description |
|---|---|---|---|
proto | string | (required) | Path to the .proto file |
address | string | (required) | Server host:port ({{KEY}} supported) |
package | string | (required) | Protobuf package (e.g. acme.users.v1) |
service | string | (required) | Service name within the package |
metadata | Record<string, string> | {} | Static call metadata ({{KEY}} supported) |
tls | boolean | false | Use TLS credentials (default: insecure) |
deadlineMs | number | 30000 | Default per-call deadline (ms) |
Contracts & redaction
- The manifest registers a
grpccontract protocol used viacontract.grpc.with("name", { client }). Its case shape differs from HTTP (e.g.target: "Service/Method",request,expect.statusCode) — see the@glubean/grpctypes for the exactGrpcContractSpec. - gRPC traces use the same upload redaction pipeline as other trace events.
Request metadata is stored under trace
metadata, so baseline credential keys such asauthorization,token,api_key, andsecretare masked before upload. - The package also exports
GRPC_REDACTION_SCOPESfor hosts that explicitly compile plugin-provided redaction scopes. The current CLI does not require you to wire this manually for normalglubean run --upload, but custom hosts that callcompileScopes(...)themselves should pass those scopes. - Still keep credentials in
.env.secrets, avoid logging derived credential strings, and useglubean redact --input .glubean/last-run.result.jsonwhen you want to preview exactly what will be masked before sharing or uploading.