Extensions
Add custom OpenAPI extensions (x-*) to generated operations.
The extensions callback lets you add vendor-specific OpenAPI extensions (x-* fields) to each operation in the generated spec.
Basic usage
const doc = generateOpenApiDocument(appRouter, {
// ...
extensions: ({ meta, procedurePath, operationId }) => {
return {
'x-internal': meta.internal === true,
'x-group': procedurePath[0],
};
},
});Callback parameters
| Parameter | Type | Description |
|---|---|---|
meta | OpenApiMeta | The full metadata object from .meta() |
procedurePath | string[] | Procedure path segments (e.g. ['runs', 'create']) |
operationId | string | The generated operation ID (e.g. runs-create) |
Speakeasy SDK generation
A common use case is generating extensions for Speakeasy SDK generation:
extensions: ({ meta, procedurePath }) => {
const ext: Record<string, unknown> = {};
if (meta.openapi?.['x-speakeasy-group']) {
ext['x-speakeasy-group'] = meta.openapi['x-speakeasy-group'];
}
ext['x-speakeasy-name-override'] = procedurePath[procedurePath.length - 1];
return ext;
},This produces SDK methods like client.runs.create() instead of client.runsCreate().
Custom metadata passthrough
Since OpenApiMeta supports an index signature, you can attach custom fields to .meta() and forward them as extensions:
// In your router
t.procedure.meta({
openapi: { method: 'POST', path: '/runs' },
xAccess: [
{ level: 'limited', authType: 'station' },
{ level: 'full', authType: 'user' },
],
});
// In the generator
extensions: ({ meta }) => {
const xAccess = (meta as Record<string, unknown>).xAccess;
return xAccess ? { 'x-access': xAccess } : {};
},Returning undefined
If the callback returns undefined, no extensions are added to that operation.