@forgezero/providers
v0.1.26
Published
Service registry with priority, health and fallback. Bring your own credential and config sources.
Maintainers
Readme
Service providers
Send through whichever provider is up. Priority and failover, reordered live.
Package overview
Anyone calling somebody else's API who needs the failure classified rather than guessed. Provider capabilities stay independent from application-owned services, which attach named methods by priority with health tracking. Supported runtimes: bun, node, workers, deno. Package root: @forgezero/providers. Consumer documentation is curated with each module's explicit public flag; the complete internal/export inventory remains in the typed SSOT and declaration files.
bun add @forgezero/providersForgeZero package family
The five packages are installation boundaries. Choose a package by who installs it; choose a subpath by the capability used in that file.
| package | short description | runtimes | documentation | |---|---|---|---| | @forgezero/vault | Scoped secret access with Agent, API-key and systemd-credential sources. | bun, node, workers, deno | Open | | @forgezero/access | Typed route, principal, factor, RBAC and request-pipeline contracts. | bun, node, workers, deno | Open | | @forgezero/providers | Typed external providers with priority, health and classified fallback. | bun, node, workers, deno | Open | | @forgezero/runtime | Portable runtime primitives for queries, jobs, events, schemas and finance. | bun, node | Open | | @forgezero/agent | Operator CLI and managed-node agent for bootstrap, deploy and lifecycle. | bun, node | Open |
@forgezero/providers supported imports and commands
These are supported consumer entry points, not every internal module shipped for ForgeZero managed installation. Each row links to its task-oriented usage.
| public entry | short description | runtime | details |
|---|---|---|---|
| @forgezero/providers | The registry: priority, health, and a terminal-versus-retryable verdict per failure. | portable | Reference + usage |
| @forgezero/providers/email | JetEmail (send, sendBatch), SMTP (send only), and the typed email service contract; SMTP transport is injected. | portable | Reference + usage |
| @forgezero/providers/database | ArangoDB in the registry for credential rotation and health — with failover off by default. | portable | Reference + usage |
| @forgezero/providers/http | Outbound HTTP with a per-host weight budget reserved before the call and settled from the response. | portable | Reference + usage |
| @forgezero/providers/pool | Which outbound address a request leaves by, sticky per key, over the same budget as everything else. | portable | Reference + usage |
| @forgezero/providers/storage | S3-compatible object storage, SigV4 signed with Web Crypto and no vendor SDK. | portable | Reference + usage |
| @forgezero/providers/translation | Google AI Studio translation with strict batch alignment and classified quota failures. | portable | Reference + usage |
| @forgezero/providers/realtime | Cloudflare KV node-directory and Durable Object fan-out clients for project-defined realtime services. | portable | Reference + usage |
| @forgezero/providers/git | Versioned Git Connect contracts for accounts, repositories, branches, webhooks and short-lived clone credentials; GitHub, GitLab and private forges attach without changing the service. | portable | Reference + usage |
| @forgezero/providers/billing | Versioned hosted-payment contracts for Stripe, PayPal and Razorpay; only opaque provider references cross the boundary. | portable | Reference + usage |
Commands
bun add @forgezero/providers @forgezero/vault — Install provider/service routing and the optional ForgeZero Vault credential adapter. bun test — Run the consumer project tests containing provider failure and fallback cases.
bun add @forgezero/providers @forgezero/vault
bun test@forgezero/providers
The registry: priority, health, and a terminal-versus-retryable verdict per failure. This is a supported entry point. Import only the named values used by the adjacent task example; the declaration file remains the complete API reference.
import {
ProviderError,
} from '@forgezero/providers';@forgezero/providers — Extend with a custom provider and service
Public consumers define provider capabilities and application services independently, then attach them with the same ordered-array API.
import {
createService,
defineService,
defineSingleMethodProvider,
serviceMethod,
} from '@forgezero/providers';
import {
createVault,
} from '@forgezero/vault';
import {
vaultCredentials,
} from '@forgezero/vault/providers';
type Notice = { text: string };
type Receipt = { id: string };
const vault = createVault({ project: 'my-project', environment: 'production' });
const postmark = defineSingleMethodProvider({
id: 'postmark', label: 'Postmark', method: 'deliver',
async invoke(context, notice: Notice): Promise<Receipt> {
const response = await fetch('https://api.postmarkapp.com/email', {
method: 'POST', signal: context.signal,
headers: { 'x-postmark-server-token': await context.secret('apiKey') },
body: JSON.stringify(notice)
});
if (!response.ok) throw new Error(`Postmark returned ${response.status}`);
return { id: response.headers.get('x-message-id') ?? crypto.randomUUID() };
},
classify: () => 'retryable'
});
const notifications = defineService({
key: 'notifications', methods: { deliver: serviceMethod<Notice, Receipt>() }
});
const service = createService(notifications, {
deliver: [{ provider: postmark, method: 'deliver', credentials: vaultCredentials(vault, 'postmark'), priority: 1 }]
});@forgezero/providers — Vault first, systemd credential fallback
Bootstrap tries the scoped Vault entry first and the identically named systemd credential second. If neither exists, the provider call fails.
import {
chainScopedCredentials,
scopeCredentials,
} from '@forgezero/providers';
import {
createVault,
systemdCredentials,
} from '@forgezero/vault';
import {
vaultCredentials,
} from '@forgezero/vault/providers';
const vault = createVault({ project: 'my-project', environment: 'production' });
const credentials = chainScopedCredentials(
vaultCredentials(vault, 'jetemail'),
scopeCredentials(systemdCredentials({
nameFor: (reference, field) => `${reference}-${field}`
}), 'jetemail')
);@forgezero/providers/email
JetEmail (send, sendBatch), SMTP (send only), and the typed email service contract; SMTP transport is injected. This is a supported entry point. Import only the named values used by the adjacent task example; the declaration file remains the complete API reference.
import {
emailProviders,
} from '@forgezero/providers/email';@forgezero/providers/email — Email with ordered provider fallback
The service owns send/sendBatch. Ordered entries select exact provider method versions; SMTP is never presented as batch-capable.
import {
createService,
type EmailMessage,
} from '@forgezero/providers';
import {
emailService,
jetemail,
smtp,
type SmtpTransport,
} from '@forgezero/providers/email';
import {
createVault,
} from '@forgezero/vault';
import {
vaultCredentials,
} from '@forgezero/vault/providers';
// Adapt Nodemailer, Bun, or an HTTP SMTP relay once at the host boundary.
declare const transport: SmtpTransport;
const vault = createVault({ project: 'my-project', environment: 'production' });
const email = createService(emailService, {
send: [
{ provider: jetemail, method: 'send', credentials: vaultCredentials(vault, 'jetemail'), config: { from: '[email protected]' }, priority: 1 },
{ provider: smtp, method: 'send', credentials: vaultCredentials(vault, 'smtp'), config: { host: 'smtp.example.com', port: 587, from: '[email protected]', transport }, priority: 2 }
],
sendBatch: [
{ provider: jetemail, method: 'sendBatch', credentials: vaultCredentials(vault, 'jetemail'), config: { from: '[email protected]' }, priority: 1 }
]
});
const message: EmailMessage = { to: '[email protected]', subject: 'Hello', text: 'Sent by ForgeZero' };
const outcome = await email.call('send', message);
if (!outcome.ok) throw outcome.error;
console.log(outcome.result, outcome.attempts);@forgezero/providers/database
ArangoDB in the registry for credential rotation and health — with failover off by default. This is a supported entry point. Import only the named values used by the adjacent task example; the declaration file remains the complete API reference.
import {
ARANGO_COMMUNITY_VERSION,
} from '@forgezero/providers/database';@forgezero/providers/database — Use this entry point
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
import {
ARANGO_COMMUNITY_VERSION,
} from '@forgezero/providers/database';
export const selectedCapability = ARANGO_COMMUNITY_VERSION;@forgezero/providers/http
Outbound HTTP with a per-host weight budget reserved before the call and settled from the response. This is a supported entry point. Import only the named values used by the adjacent task example; the declaration file remains the complete API reference.
import {
BudgetExhausted,
} from '@forgezero/providers/http';@forgezero/providers/http — Use this entry point
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
import {
BudgetExhausted,
} from '@forgezero/providers/http';
export const selectedCapability = BudgetExhausted;@forgezero/providers/pool
Which outbound address a request leaves by, sticky per key, over the same budget as everything else. This is a supported entry point. Import only the named values used by the adjacent task example; the declaration file remains the complete API reference.
import {
PoolEmpty,
} from '@forgezero/providers/pool';@forgezero/providers/pool — Use this entry point
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
import {
PoolEmpty,
} from '@forgezero/providers/pool';
export const selectedCapability = PoolEmpty;@forgezero/providers/storage
S3-compatible object storage, SigV4 signed with Web Crypto and no vendor SDK. This is a supported entry point. Import only the named values used by the adjacent task example; the declaration file remains the complete API reference.
import {
MAX_SINGLE_PUT_BYTES,
} from '@forgezero/providers/storage';@forgezero/providers/storage — Use this entry point
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
import {
MAX_SINGLE_PUT_BYTES,
} from '@forgezero/providers/storage';
export const selectedCapability = MAX_SINGLE_PUT_BYTES;@forgezero/providers/translation
Google AI Studio translation with strict batch alignment and classified quota failures. This is a supported entry point. Import only the named values used by the adjacent task example; the declaration file remains the complete API reference.
import {
TranslationError,
} from '@forgezero/providers/translation';@forgezero/providers/translation — Use this entry point
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
import {
TranslationError,
} from '@forgezero/providers/translation';
export const selectedCapability = TranslationError;@forgezero/providers/realtime
Cloudflare KV node-directory and Durable Object fan-out clients for project-defined realtime services. This is a supported entry point. Import only the named values used by the adjacent task example; the declaration file remains the complete API reference.
import {
RealtimeProviderError,
} from '@forgezero/providers/realtime';@forgezero/providers/realtime — Use this entry point
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
import {
RealtimeProviderError,
} from '@forgezero/providers/realtime';
export const selectedCapability = RealtimeProviderError;@forgezero/providers/git
Versioned Git Connect contracts for accounts, repositories, branches, webhooks and short-lived clone credentials; GitHub, GitLab and private forges attach without changing the service. This is a supported entry point. Import only the named values used by the adjacent task example; the declaration file remains the complete API reference.
import {
defineGitHubProvider,
} from '@forgezero/providers/git';@forgezero/providers/git — Use this entry point
This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
import {
defineGitHubProvider,
} from '@forgezero/providers/git';
export const selectedCapability = defineGitHubProvider;@forgezero/providers/billing
Versioned hosted-payment contracts for Stripe, PayPal and Razorpay; only opaque provider references cross the boundary. This is a supported entry point. Import only the named values used by the adjacent task example; the declaration file remains the complete API reference.
import {
PAYMENT_PROVIDER_KEYS,
} from '@forgezero/providers/billing';@forgezero/providers/billing — Bind a reviewed payment-provider API version
ForgeZero receives only hosted setup URLs and opaque provider references. The concrete HTTP driver and its Vault-backed credentials remain at the host boundary.
import {
paymentProviderAdapter,
type PaymentProviderDriver,
} from '@forgezero/providers/billing';
declare const stripeDriver: PaymentProviderDriver;
const stripe = paymentProviderAdapter({
key: 'stripe:v1',
providerApiVersion: '2026-08',
driver: stripeDriver
});
const setup = await stripe.createHostedSetup({
tenantKey: 'tenant_123',
returnUrl: 'https://app.example.com/billing/return',
cancelUrl: 'https://app.example.com/billing',
idempotencyKey: crypto.randomUUID()
});
location.assign(setup.hostedUrl);Built-in provider capabilities
A provider owns versioned capabilities; it does not own a service. A service method attaches an exact provider, method and version in an ordered array. Current, legacy and deprecated branches can coexist; retired branches never run.
github
- beginUserAuthorization
- completeUserAuthorization
- readVerifiedIdentity
- refreshUserGrant
- revokeUserGrant
- beginInstallation
- completeInstallation
- listInstallations
- listRepositories
- listBranches
- mintCloneCredential
- verifyWebhook
- disconnectInstallation
jetemail
- send
- sendBatch
smtp
- send
arangodb
- query
http
- request
s3
- request
google-ai-studio
- translateGitHub App (github)
Import: @forgezero/providers/git. Each method below is a provider capability that a service attaches by exact version. The OAuth Server projection verifies an email and revokes the temporary user grant before ForgeZero creates its own session. The Git Connect projection mints repository-scoped installation credentials on demand and never persists them. GitLab or a private forge can implement the same Git Connect service without changing pipelines or Agents.
importPath: '@forgezero/providers/git'
providerId: 'github'
methods:
- beginUserAuthorization
- completeUserAuthorization
- readVerifiedIdentity
- refreshUserGrant
- revokeUserGrant
- beginInstallation
- completeInstallation
- listInstallations
- listRepositories
- listBranches
- mintCloneCredential
- verifyWebhook
- disconnectInstallation
credentials:
- clientSecret
- privateKey
- webhookSecret
config:
- clientId
- appId
- slugJetEmail (jetemail)
Import: @forgezero/providers/email. Each method below is a provider capability that a service attaches by exact version. A 401 is RETRYABLE at the loop level — that key is bad, the next provider's may not be. Treating any 4xx as fatal is what loses the fallback.
importPath: '@forgezero/providers/email'
providerId: 'jetemail'
methods:
- send
- sendBatch
credentials:
- apiKey
config:
- eu
- fromSMTP (smtp)
Import: @forgezero/providers/email. Each method below is a provider capability that a service attaches by exact version. Any number of named relays, each with its own priority slot. Also the bootstrap path: the vault opens after a ceremony, and the ceremony needs mail.
importPath: '@forgezero/providers/email'
providerId: 'smtp'
methods:
- send
credentials:
- user
- password
config:
- host
- port
- secure
- from
- transportArangoDB (arangodb)
Import: @forgezero/providers/database. Each method below is a provider capability that a service attaches by exact version. Failover is OFF by default. Writing to a different database because the first was slow is data loss with extra steps; this is here for credential rotation and health.
importPath: '@forgezero/providers/database'
providerId: 'arangodb'
methods:
- query
credentials:
- password
config:
- url
- urls
- readPreferredUrls
- readPreferredFallback
- clusterId
- database
- usernameHTTP (http)
Import: @forgezero/providers/http. Each method below is a provider capability that a service attaches by exact version. 418 and 429 back off rather than falling through. 418 is a venue saying "you ignored a 429 and are now banned", and hammering makes the ban longer.
importPath: '@forgezero/providers/http'
providerId: 'http'
methods:
- request
credentials:
- apiKey
- apiSecret
config:
- baseUrl
- limit
- windowMs
- headroomS3-compatible storage (s3)
Import: @forgezero/providers/storage. Each method below is a provider capability that a service attaches by exact version. A 403 is retryable because on S3 it usually means this key lacks a permission, not that the key is invalid. Works against AWS, R2, MinIO, Garage and Backblaze — path-style addressing by default, because that is what everything except AWS expects.
importPath: '@forgezero/providers/storage'
providerId: 's3'
methods:
- request
credentials:
- accessKeyId
- secretAccessKey
- sessionToken
config:
- endpoint
- region
- bucket
- addressingGoogle AI Studio (google-ai-studio)
Import: @forgezero/providers/translation. Each method below is a provider capability that a service attaches by exact version. Machine translation for a tenant that wants it — ForgeZero translates nothing at runtime. Chosen as the first adapter because the free tier needs no billing account, so the feature can be tried without a procurement conversation. A 429 is a BACKOFF rather than a failure: on the free tier it is expected traffic, and treating it as terminal abandons a catalogue most of the way through. A short answer is terminal, because one translation missing from a batch shifts every later string onto the wrong source and nothing about the result looks broken afterwards.
importPath: '@forgezero/providers/translation'
providerId: 'google-ai-studio'
methods:
- translate
credentials:
- apiKey
config:
- modelFull rendered documentation: https://www.forgezero.net/docs/providers
