Move docs/ package mirror into document-navigator plugin
Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
# @suaveplan/sms-providers - Universal SMS provider implementations for @suaveplan/sms. Real HTTP clients for Twilio (Basic auth + form-encoded + X-Twilio-Signature HMAC-SHA1), Vonage (HMAC-SHA256 webhook), MessageBird (AccessKey + JWT HS256 webhook), Plivo (Basic auth + X-Plivo-Signature-V3 HMAC-SHA256), and AWS SNS (inline SigV4 + RSA-SHA1 SNS notification verifier). Ships ProviderRegistry, httpRequest over injectable FetchLike, composeAbortSignal, SMS_PROVIDERS_CODES + SmsProvidersError, per-provider mapStatus, parseInbound, parseOptOutKeyword, and five OTel instruments. No provider SDK deps; every HTTP call flows through an injectable FetchLike seam.
|
||||
|
||||
> Real provider clients for `@suaveplan/sms` — Twilio, Vonage, MessageBird, Plivo, AWS SNS. Universal (Bun, Node, browsers, Workers, Deno) over an injectable `FetchLike` seam; no provider SDKs in the dep tree.
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
## Documentation tree
|
||||
|
||||
- [aws-sns](./src/aws-sns/aws-sns.md) — Real AWS SNS SMS provider implementing `SmsProvider` from `@suaveplan/sms`. POSTs `Action=Publish` form bodies to the r…
|
||||
- [aws-sns](./src/aws-sns/aws-sns.md) — Real AWS SNS SMS provider implementing `SmsProvider` from `@suaveplan/sms`. POSTs `Action=Publish` form bodies to the r…
|
||||
- [sigv4](./src/aws-sns/sigv4.md) — Inline AWS Signature V4 signer used by `AwsSnsProvider`. Replaces the `@aws-sdk/signature-v4` dependency tree (15+ MB)…
|
||||
- [crypto](./src/crypto/default-hmac.md) — Owns the package's default `HmacSign` implementation (routed through `globalThis.crypto.subtle`) and the small set of u…
|
||||
- [default-hmac](./src/crypto/default-hmac.md) — Owns the package's default `HmacSign` implementation (routed through `globalThis.crypto.subtle`) and the small set of u…
|
||||
- [error-codes](./src/error-codes/error-codes.md) — Defines the stable, namespaced error-code registry `SMS_PROVIDERS_CODES` and the `SmsProvidersError` discriminated subc…
|
||||
- [error-codes](./src/error-codes/error-codes.md) — Defines the stable, namespaced error-code registry `SMS_PROVIDERS_CODES` and the `SmsProvidersError` discriminated subc…
|
||||
- [http](./src/http/http.md) — Universal HTTP helper that every concrete provider client routes through. Wraps an injectable `FetchLike` seam, se…
|
||||
- [http](./src/http/http.md) — Universal HTTP helper that every concrete provider client routes through. Wraps an injectable `FetchLike` seam, se…
|
||||
- [keywords](./src/keywords/keywords.md) — Universal classifier mapping an inbound SMS body to the canonical `OptOutAction` enum used by `@suaveplan/sms`'s `OptOu…
|
||||
- [keywords](./src/keywords/keywords.md) — Universal classifier mapping an inbound SMS body to the canonical `OptOutAction` enum used by `@suaveplan/sms`'s `OptOu…
|
||||
- [messagebird](./src/messagebird/messagebird.md) — Real MessageBird SMS provider implementing `SmsProvider` from `@suaveplan/sms`. POSTs to `/messages` with `Authorizatio…
|
||||
- [messagebird](./src/messagebird/messagebird.md) — Real MessageBird SMS provider implementing `SmsProvider` from `@suaveplan/sms`. POSTs to `/messages` with `Authorizatio…
|
||||
- [otel](./src/otel/otel.md) — Owns the package's OpenTelemetry instrument set. Five instruments cover the public-surface operations every provider cl…
|
||||
- [otel](./src/otel/otel.md) — Owns the package's OpenTelemetry instrument set. Five instruments cover the public-surface operations every provider cl…
|
||||
- [plivo](./src/plivo/plivo.md) — Real Plivo SMS provider implementing `SmsProvider` from `@suaveplan/sms`. POSTs to `/v1/Account/{AuthId}/Message/` auth…
|
||||
- [plivo](./src/plivo/plivo.md) — Real Plivo SMS provider implementing `SmsProvider` from `@suaveplan/sms`. POSTs to `/v1/Account/{AuthId}/Message/` auth…
|
||||
- [registry](./src/registry/registry.md) — `ProviderRegistry` is a process-local, synchronous index of `SmsProvider` instances keyed by `provider.name`. Sibling p…
|
||||
- [registry](./src/registry/registry.md) — `ProviderRegistry` is a process-local, synchronous index of `SmsProvider` instances keyed by `provider.name`. Sibling p…
|
||||
- [twilio](./src/twilio/twilio.md) — Real Twilio SMS provider implementing the `SmsProvider` contract from `@suaveplan/sms`. Issues authenticated, form-enco…
|
||||
- [twilio](./src/twilio/twilio.md) — Real Twilio SMS provider implementing the `SmsProvider` contract from `@suaveplan/sms`. Issues authenticated, form-enco…
|
||||
- [types](./src/types/provider.md) — Defines the shared structural types every concrete provider class consumes: `FetchLike` (the injectable HTTP seam), `Hm…
|
||||
- [provider](./src/types/provider.md) — Defines the shared structural types every concrete provider class consumes: `FetchLike` (the injectable HTTP seam), `Hm…
|
||||
- [vonage](./src/vonage/vonage.md) — Real Vonage (formerly Nexmo) SMS provider implementing `SmsProvider` from `@suaveplan/sms`. POSTs to `/sms/json` with `…
|
||||
- [vonage](./src/vonage/vonage.md) — Real Vonage (formerly Nexmo) SMS provider implementing `SmsProvider` from `@suaveplan/sms`. POSTs to `/sms/json` with `…
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Highlights
|
||||
|
||||
- **Five real provider clients**, every one implementing the `SmsProvider` contract from `@suaveplan/sms`:
|
||||
- `TwilioProvider` — `POST /Messages.json`, HTTP Basic auth, MMS `MediaUrl[]`, X-Twilio-Signature HMAC-SHA1 webhook verifier.
|
||||
- `VonageProvider` — `POST /sms/json`, body auth, auto `type=unicode`, HMAC-SHA256 webhook verifier.
|
||||
- `MessageBirdProvider` — `AccessKey` auth, JSON body, JWT HS256 webhook verifier with `iat`/`exp`/`nbf` enforcement + optional `payload_hash` binding.
|
||||
- `PlivoProvider` — Basic auth, JSON body, X-Plivo-Signature-V3 HMAC-SHA256 verifier.
|
||||
- `AwsSnsProvider` — inline AWS SigV4-signed `Action=Publish`, RSA-SHA1 SNS notification verifier with injectable callback.
|
||||
- **`ProviderRegistry`** indexes provider instances by name; strict register/lookup, frozen `list()` snapshot.
|
||||
- **`SmsProvidersError`** discriminated subclass of `SuaveplanError` with eight namespaced codes (`SMS_PROVIDERS.HTTP_ERROR`, `TIMEOUT`, `PARSE_ERROR`, `CONFIG_MISSING`, `SIGNATURE_INVALID`, `INVALID_NUMBER`, `PROVIDER_NOT_REGISTERED`, `PROVIDER_ALREADY_REGISTERED`).
|
||||
- **`parseOptOutKeyword`** universal CTIA/TCPA opt-in/opt-out/help keyword classifier.
|
||||
- **Five OTel instruments** — `send_total`, `webhook_total`, `signature_failures_total`, `send_duration_ms`, `webhook_verify_duration_ms`.
|
||||
- **Real `node:http` round-trip tests** per provider — no mocks; tests bind a server on a random port and inject a `FetchLike` pointing at it.
|
||||
|
||||
## Quick start
|
||||
|
||||
```ts
|
||||
import {
|
||||
AwsSnsProvider,
|
||||
MessageBirdProvider,
|
||||
PlivoProvider,
|
||||
ProviderRegistry,
|
||||
TwilioProvider,
|
||||
VonageProvider,
|
||||
} from "@suaveplan/sms-providers";
|
||||
|
||||
const registry = new ProviderRegistry();
|
||||
registry.register(new TwilioProvider({ accountSid: "AC…", authToken: "…" }));
|
||||
registry.register(new VonageProvider({ apiKey: "k", apiSecret: "s" }));
|
||||
registry.register(new MessageBirdProvider({ accessKey: "K" }));
|
||||
registry.register(new PlivoProvider({ authId: "A", authToken: "T" }));
|
||||
registry.register(
|
||||
new AwsSnsProvider({
|
||||
region: "us-east-1",
|
||||
accessKeyId: "AKIA…",
|
||||
secretAccessKey: "…",
|
||||
})
|
||||
);
|
||||
|
||||
const twilio = registry.get("twilio");
|
||||
const report = await twilio.send({
|
||||
to: "+15551234567",
|
||||
from: "+15550000000",
|
||||
body: "Hello",
|
||||
});
|
||||
console.log(report.messageId, report.status);
|
||||
```
|
||||
|
||||
## Webhook verification
|
||||
|
||||
Every provider exposes a signature verifier matching its documented scheme:
|
||||
|
||||
```ts
|
||||
// Twilio HMAC-SHA1 over url + sorted form
|
||||
await twilio.verifyWebhookSignature(callbackUrl, params, signature);
|
||||
|
||||
// Vonage HMAC-SHA256 hex over sorted &key=value (excluding sig)
|
||||
await vonage.verifyWebhookSignature(params, sigHex, signatureSecret);
|
||||
|
||||
// MessageBird JWT HS256 with iat/exp/nbf window + payload_hash binding
|
||||
await mb.verifyWebhookSignature(jwt, signingKey, { nowMs, bodyHashHex });
|
||||
|
||||
// Plivo HMAC-SHA256 base64 over url + nonce + sorted key=value,...
|
||||
await plivo.verifyWebhookSignature(url, nonce, params, signature);
|
||||
|
||||
// AWS SNS RSA-SHA1 — pass an injectable verifier callback
|
||||
await sns.verifyNotification(payload, async (pem, msg, sigB64) => {
|
||||
/* createVerify("RSA-SHA1")…verify(...) */
|
||||
return true;
|
||||
});
|
||||
```
|
||||
|
||||
## Tier
|
||||
|
||||
`src/` ships zero `node:*` / `bun:*` / platform imports. Every HTTP call routes through an injectable `FetchLike`; every HMAC routes through an injectable `HmacSign` (defaulting to `globalThis.crypto.subtle`). Tests use real `node:http` + `node:crypto` from under `tests/setup/` and inside `*.test.ts` files only.
|
||||
|
||||
## Pre-publish gate
|
||||
|
||||
```bash
|
||||
bunx turbo lint typecheck test build --filter=@suaveplan/sms-providers
|
||||
bunx turbo test:coverage --filter=@suaveplan/sms-providers # 100/100/100/100
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user