@crvouga/mockingbird-service-twilio 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog — @crvouga/mockingbird-service-twilio
2
2
 
3
+ ## 3.1.0 (2026-10-08)
4
+
5
+ ### Features
6
+
7
+ - redesign emulator experience ([d6038c2](https://github.com/crvouga/mockingbird/commit/d6038c27eebbaa1751f02bc9305002a5b1304779))
8
+
9
+ ### Dependencies
10
+
11
+ - `@crvouga/mockingbird-service-sqlite`
12
+
3
13
  ## 3.0.0 (2026-10-07)
4
14
 
5
15
  ### ⚠️ Breaking changes
@@ -14,10 +24,6 @@
14
24
  - typecheck the brand gate before builds ([fc36095](https://github.com/crvouga/mockingbird/commit/fc3609514de70ffe3170a5d216fb8a49f9ce7cbb))
15
25
  - format the emulates records query ([8698872](https://github.com/crvouga/mockingbird/commit/8698872509d06002be5a8fcdc85d79f8462320c3))
16
26
 
17
- ### Dependencies
18
-
19
- - `@crvouga/mockingbird-service-sqlite`
20
-
21
27
  ## 2.3.0 (2026-10-04)
22
28
 
23
29
  ### Features
package/DISCOVERY.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # @crvouga/mockingbird-service-twilio discovery
2
2
 
3
3
  This is the installed-package index for coding agents and tooling. All relative links resolve
4
- inside `node_modules/@crvouga/mockingbird-service-twilio/`; no repository checkout is needed to discover the mock's
4
+ inside `node_modules/@crvouga/mockingbird-service-twilio/`; no repository checkout is needed to discover the emulator's
5
5
  supported surface or documented behavior.
6
6
 
7
7
  ## Capability and behavior sources
@@ -48,7 +48,7 @@ designed for assertions and diagnosis by consuming test suites.
48
48
  ## Report a mismatch or missing capability
49
49
 
50
50
  Follow the [agent reporting contract](https://github.com/crvouga/mockingbird/blob/main/docs/REPORTING_ISSUES.md). Include package version,
51
- operation/command, a minimal redacted request, actual mock result, expected oracle result or vendor
51
+ operation/command, a minimal redacted request, actual emulator result, expected oracle result or vendor
52
52
  documentation, and whether the mismatch appears in the matrix. Never include keys, tokens,
53
53
  customer data, prompts, PHI, card data, or unredacted recordings.
54
54
 
package/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # @crvouga/mockingbird-service-twilio
2
2
 
3
- > Familiar calls. Faithful echoes. Part of [Mockingbird](https://github.com/crvouga/mockingbird).
3
+ > Local emulators. Real API contracts. Part of [Mockingbird](https://github.com/crvouga/mockingbird).
4
4
 
5
- Stateful mock of **Twilio** for test suites: Lookup v2 phone validation, Verify v2 phone OTP
6
- (with the real state machine: wrong codes, attempt limits, 10-minute expiry on the mock clock),
5
+ Stateful emulator of **Twilio** for test suites: Lookup v2 phone validation, Verify v2 phone OTP
6
+ (with the real state machine: wrong codes, attempt limits, 10-minute expiry on the emulator clock),
7
7
  Programmable Messaging with an outbox, and call Recordings. It also signs and posts Twilio's
8
8
  inbound SMS and voice webhooks to your app. Every product is served on one port. A suite reads the
9
9
  OTP from the admin plane instead of bypassing verification (`E2E_OTP_BYPASS_*`).
@@ -36,8 +36,8 @@ npx mockingbird-twilio serve --port 8798 \
36
36
  ### Pointing the app at it (G-T1)
37
37
 
38
38
  twilio-node builds a host for each product (`api.twilio.com`, `verify.twilio.com`,
39
- `lookups.twilio.com`). The mock takes that host as the first path segment:
40
- `{mock}/api/2010-04-01/…`, `{mock}/verify/v2/…`, `{mock}/lookups/v2/…`. Pass every
39
+ `lookups.twilio.com`). The emulator takes that host as the first path segment:
40
+ `{emulator}/api/2010-04-01/…`, `{emulator}/verify/v2/…`, `{emulator}/lookups/v2/…`. Pass every
41
41
  `new Twilio(...)` an `httpClient` that rewrites the URL. `twilioMockUrl` does the rewrite:
42
42
 
43
43
  ```js
@@ -64,7 +64,7 @@ const client = new Twilio(
64
64
  )
65
65
  ```
66
66
 
67
- The mock also routes by the `Host` header. A request that reaches it as `lookups.twilio.com`
67
+ The emulator also routes by the `Host` header. A request that reaches it as `lookups.twilio.com`
68
68
  (through a DNS override or a proxy) and has no prefix is served as `/lookups/…`. The recording
69
69
  adapter's raw `fetch` of `https://api.twilio.com/2010-04-01/…` becomes
70
70
  `twilioMockUrl(url, TWILIO_API_BASE_URL)`. `RecordingUrl` in webhooks keeps the canonical
@@ -88,7 +88,7 @@ const { code, sid, status } = (await latest.json()) as { code: string; sid: stri
88
88
  | --- | --- |
89
89
  | `GET /lookups/v2/PhoneNumbers/{PhoneNumber}` | Validates the number the way the live API does (libphonenumber): `valid`, `validation_errors` (`TOO_SHORT`, `TOO_LONG`, `INVALID_BUT_POSSIBLE`, `INVALID_COUNTRY_CODE`, `INVALID_LENGTH`, `NOT_A_NUMBER`), `phone_number`, `national_format`, `calling_country_code`, `country_code`, `url`. Every data package is `null`. A national number with no `CountryCode` must be a valid US number, otherwise the answer is `INVALID_COUNTRY_CODE`. Fictional 555-01xx numbers are valid. |
90
90
  | `POST /verify/v2/Services/{VA}/Verifications` | `To` (valid E.164, or an email for `Channel=email`), `Channel`, optional `CustomCode`. Creates a `VE…` verification with a 6-digit code (or `fixedCode`). Sending again to the same pending verification keeps its sid and code and adds a `send_code_attempts` entry. The 6th send to one number within 10 minutes is 429 `60203`. A bad `To` is 400 `60200`. An unknown service sid (not `VA` + 32 hex) is 404 `20404`. |
91
- | `POST /verify/v2/Services/{VA}/VerificationCheck` | `Code` plus `VerificationSid` or `To`. The right code returns 200 `approved`, `valid: true`. A wrong code returns 200 `pending` and counts an attempt. The 6th check is 429 `60202`. A missing, approved, canceled or expired (10 minutes on the mock clock) verification is 404 `20404`. |
91
+ | `POST /verify/v2/Services/{VA}/VerificationCheck` | `Code` plus `VerificationSid` or `To`. The right code returns 200 `approved`, `valid: true`. A wrong code returns 200 `pending` and counts an attempt. The 6th check is 429 `60202`. A missing, approved, canceled or expired (10 minutes on the emulator clock) verification is 404 `20404`. |
92
92
  | `GET` / `POST /verify/v2/Services/{VA}/Verifications/{VE}` | Fetches a verification, or sets `Status=canceled\|approved` on one. |
93
93
  | `POST /api/2010-04-01/Accounts/{AC}/Messages.json` | `To`, `Body` or `MediaUrl`, and `From` or `MessagingServiceSid`. Returns 201 with an `SM…` sid (`MM…` with media) and RFC 2822 dates. `MessagingServiceSid` alone is status `accepted`, `from: null`, `num_segments: "0"` (a sender is not chosen yet). `From` alone is status `queued`. Both are kept and the status is `queued` (Twilio queues on a specific sender). There is no idempotency key: the same body creates another sid. Errors: 21604 (no To), 21602 (no Body), 21603 (no From), 21211 (invalid To), 21617 (over 1600 characters). The message is recorded in the outbox. |
94
94
  | `GET /api/2010-04-01/Accounts/{AC}/Messages/{SM}.json` | Reads a message back. |
@@ -104,11 +104,11 @@ wrong credential is 401 `20003`. For a wrong token the message matches the live
104
104
 
105
105
  ### Webhooks (S8.4)
106
106
 
107
- The mock signs inbound webhooks with `X-Twilio-Signature`. The signature is base64
107
+ The emulator signs inbound webhooks with `X-Twilio-Signature`. The signature is base64
108
108
  HMAC-SHA1(auth token, public URL + sorted `key+value` params), the same computation as
109
109
  `twilio.validateRequest`. It signs against the **public base URL the app is configured with**
110
110
  (`--public-base-url`, i.e. `TWILIO_VOICE_WEBHOOK_BASE_URL`), not the localhost address it posts
111
- to. Twilio does not retry these webhooks, so the mock sends each one once.
111
+ to. Twilio does not retry these webhooks, so the emulator sends each one once.
112
112
 
113
113
  | Trigger | Posts to | Payload |
114
114
  | --- | --- | --- |
@@ -146,7 +146,7 @@ can also come from the `x-mockingbird-namespace` header or a `/__admin/ns/<name>
146
146
 
147
147
  - Delivery: messages stay `queued`/`accepted`, no status callbacks are sent (our consumer sets no
148
148
  `statusCallback`), and no voice calls, conferences or media streams happen.
149
- - Message collection `DateSent` filters (messages are never sent by the mock).
149
+ - Message collection `DateSent` filters (messages are never sent by the emulator).
150
150
  - Paid Lookup data packages (`Fields=line_type_intelligence`, `caller_name`, …) are always
151
151
  `null`.
152
152
  - Verify channels other than SMS are accepted and recorded, but nothing is delivered. Verify
@@ -154,7 +154,7 @@ can also come from the `x-mockingbird-namespace` header or a `/__admin/ns/<name>
154
154
  `PUT /__admin/verify`.
155
155
  - Accounts: any `AC…` sid is its own account, and the path's `{AccountSid}` is not
156
156
  cross-checked against the credential.
157
- - libphonenumber-js drops "local only" lengths from its metadata. The mock restores them for
157
+ - libphonenumber-js drops "local only" lengths from its metadata. The emulator restores them for
158
158
  NANP (7) and GB (4–6, 8), which is enough for the fictional numbers tests use. Other countries
159
159
  may answer `TOO_SHORT` where Twilio answers `INVALID_BUT_POSSIBLE`.
160
160
 
@@ -162,11 +162,11 @@ can also come from the `x-mockingbird-namespace` header or a `/__admin/ns/<name>
162
162
 
163
163
  | Export | Kind | Description |
164
164
  | --- | --- | --- |
165
- | `TwilioAPI` | class | The in-process mock: `fetch(request)`, `reset()`, `latestVerification(to)`, `resolveLookup(raw, country?)`, `setLookup(e164, override)`, `putRecording(sid, input)`, `outbox()`, `messages()`. Options: `sqlite`, `now`, `namespace`, `verify`, `accounts`. |
166
- | `createRuntime` | function | The mock with the full service contract (health, admin, namespaces, credentials, presets, outbox, webhooks), plus host routing. Options: `app: {url, publicBaseUrl?, authToken, accountSid?, callerId?, messagingServiceSid?}`, `verify`, `accounts`, `retryDelaysMs`, `fetch`, `clock`, `seed`, `adminKey`, `onLog`. The returned runtime also has `inboundSms(input)` and `voiceWebhook(kind, params)`. |
165
+ | `TwilioAPI` | class | The in-process emulator: `fetch(request)`, `reset()`, `latestVerification(to)`, `resolveLookup(raw, country?)`, `setLookup(e164, override)`, `putRecording(sid, input)`, `outbox()`, `messages()`. Options: `sqlite`, `now`, `namespace`, `verify`, `accounts`. |
166
+ | `createRuntime` | function | The emulator with the full service contract (health, admin, namespaces, credentials, presets, outbox, webhooks), plus host routing. Options: `app: {url, publicBaseUrl?, authToken, accountSid?, callerId?, messagingServiceSid?}`, `verify`, `accounts`, `retryDelaysMs`, `fetch`, `clock`, `seed`, `adminKey`, `onLog`. The returned runtime also has `inboundSms(input)` and `voiceWebhook(kind, params)`. |
167
167
  | `TWILIO_PRESETS` | object | Every named fault preset. |
168
168
  | `TWILIO_WEBHOOK_EVENTS` | object | Webhook event type → the app path it posts to. |
169
- | `twilioMockUrl` | function | Rewrites an upstream `https://<product>.twilio.com/…` URL onto a mock base URL (for the G-T1 `httpClient`). |
169
+ | `twilioMockUrl` | function | Rewrites an upstream `https://<product>.twilio.com/…` URL onto an emulator base URL (for the G-T1 `httpClient`). |
170
170
  | `TWILIO_PRODUCTS` | array | The product prefixes served: `api`, `verify`, `lookups`. |
171
171
  | `lookup` | function | Lookup v2 validation of a raw input (optionally in a `CountryCode` region). |
172
172
  | `e164Key` | function | `+` and digits: the key that admin overrides use. |
package/SUPPORT.md CHANGED
@@ -3,10 +3,10 @@
3
3
  Generated from `openapi.yaml`; do not edit by hand.
4
4
 
5
5
  - operations in spec: **11**
6
- - supported by the mock: **11**
6
+ - supported by the emulator: **11**
7
7
  - parity enabled: **11**
8
8
 
9
- | operationId | route | mock | parity | notes |
9
+ | operationId | route | emulator | parity | notes |
10
10
  | --- | --- | --- | --- | --- |
11
11
  | `FetchPhoneNumber` | `GET /lookups/v2/PhoneNumbers/{PhoneNumber}` | ✅ supported | ✅ | |
12
12
  | `CreateVerification` | `POST /verify/v2/Services/{ServiceSid}/Verifications` | ✅ supported | ⚠️ unsafe (opt-in) | |