@emulates/brevo 0.0.0-stage → 0.1.1

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 ADDED
@@ -0,0 +1,9 @@
1
+ # Changelog — @emulates/brevo
2
+
3
+ ## 0.1.1 (2026-10-06)
4
+
5
+ Initial release.
6
+
7
+ ### Dependencies
8
+
9
+ - `@emulates/sqlite`
package/DISCOVERY.md ADDED
@@ -0,0 +1,55 @@
1
+ # @emulates/brevo discovery
2
+
3
+ This is the installed-package index for coding agents and tooling. All relative links resolve
4
+ inside `node_modules/@emulates/brevo/`; no repository checkout is needed to discover the emulator's
5
+ supported surface or documented behavior.
6
+
7
+ ## Capability and behavior sources
8
+
9
+ | Question | Authoritative file | What it contains |
10
+ | --- | --- | --- |
11
+ | Behaviour and integration | [`README.md`](README.md) | Routes, state transitions, auth, webhooks, controls, presets and deliberate omissions. |
12
+ | Exact capabilities | [`SUPPORT.md`](SUPPORT.md) | Supported, unsupported and parity-covered operations or commands, including reasons for gaps. |
13
+ | Wire contract | [`openapi.yaml`](openapi.yaml) | Machine-readable paths, methods, schemas, responses and parity annotations. |
14
+ | Public API | [`dist/index.d.ts`](dist/index.d.ts) | The installed package's exact TypeScript exports and signatures. |
15
+ | Package metadata | [`package.json`](package.json) | Runtime/entry-point claims, vendor links, parity scope/tier and `emulates.discovery`. |
16
+
17
+ Read these together: the contract/capability matrix says *what* is available, while the README
18
+ defines stateful behavior, lifecycle rules, test controls, and intentional oracle differences.
19
+ If prose and an executable surface disagree, report a parity mismatch instead of adding a
20
+ consumer-side workaround.
21
+
22
+ ## Parity and oracle
23
+
24
+ - Declared parity surface: **Contact identity and CRUD**.
25
+ - Parity tier: **cold** (the repository controls when live checks run).
26
+ - Oracle: **Live vendor API or sandbox**.
27
+ - Repository command: `bun run parity:service -- brevo`.
28
+ - Evidence model: Run from an Emulates checkout; credentials come only from .env.local or GitHub Actions secrets. Missing credentials exit 2.
29
+
30
+ The npm package contains evidence summaries and the exact contract, not credentials or the
31
+ repository-only parity harness. Self-parity/property and acceptance tests run in the Emulates
32
+ repository; live parity is an additional oracle check, not a substitute for the packaged matrix.
33
+
34
+ ## Runtime introspection
35
+
36
+ - `GET /__admin/health`
37
+ - `GET /__admin`
38
+ - `GET /__admin/state`
39
+ - `GET /__admin/requests`
40
+ - `GET /__admin/metrics`
41
+ - `GET /__admin/faults/presets`
42
+ - `GET /__admin/ui`
43
+
44
+ For HTTP services, use `x-emulates-namespace` (or the documented credential/path carrier) so
45
+ parallel tests do not share state. Admin state, journal, metrics and fault-preset endpoints are
46
+ designed for assertions and diagnosis by consuming test suites.
47
+
48
+ ## Report a mismatch or missing capability
49
+
50
+ Follow the [agent reporting contract](https://github.com/crvouga/emulators/blob/main/docs/REPORTING_ISSUES.md). Include package version,
51
+ operation/command, a minimal redacted request, actual emulator result, expected oracle result or vendor
52
+ documentation, and whether the mismatch appears in the matrix. Never include keys, tokens,
53
+ customer data, prompts, PHI, card data, or unredacted recordings.
54
+
55
+ Service key: `brevo`.
package/README.md CHANGED
@@ -1,3 +1,82 @@
1
- # Temporary Holding Version
1
+ # @emulates/brevo
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ > Part of [Emulates](https://github.com/crvouga/emulators): high-fidelity, in-process emulators for APIs and databases.
4
+
5
+ WIP Brevo v3 contact lifecycle, based on the official contact reference. No messages are sent.
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ bun add @emulates/brevo
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```ts
16
+ import { createRuntime } from "@emulates/brevo"
17
+
18
+ const brevo = createRuntime()
19
+ const response = await brevo.fetch(new Request("http://brevo.test/v3/contacts", {
20
+ method: "POST",
21
+ headers: { "content-type": "application/json", "api-key": "mock_brevo_key" },
22
+ body: JSON.stringify({ email: "synthetic@example.invalid", ext_id: "mock-contact", listIds: [1], updateEnabled: false }),
23
+ }))
24
+ console.log(await response.json()) // { id: 1 }
25
+ ```
26
+
27
+ Run `emulates-brevo serve --port 12124` for a separate application process. Replace
28
+ the client's `https://api.brevo.com` origin with `http://localhost:12124`; the consumer must
29
+ make its base URL injectable (the vendor does not define a standard environment variable).
30
+ Use the synthetic `api-key: mock_brevo_key`, or configure `apiKeys` in `createRuntime`.
31
+
32
+ ### Routes
33
+
34
+ - `POST /v3/contacts`: creates a contact with a numeric id (201). Duplicate email or
35
+ external id with `updateEnabled: false` returns 400 `duplicate_parameter` without mutation.
36
+ `updateEnabled: true` updates the existing contact (204).
37
+ - `PUT /v3/contacts/{identifier}?identifierType=ext_id`: updates attributes, including
38
+ `attributes.EMAIL`, without changing the contact's numeric id or existing list memberships
39
+ (204). `listIds` adds memberships; `unlinkListIds` removes them.
40
+ - `DELETE /v3/contacts/{encoded-email}?identifierType=email_id`: deletes that contact (204).
41
+ - `GET /v3/contacts/{identifier}`: reads the contact. Explicit `identifierType` supports
42
+ `email_id`, `contact_id`, and `ext_id`; the default recognizes an email or numeric id.
43
+
44
+ Missing contacts return 404 `document_not_found`. Invalid identifiers, malformed bodies,
45
+ invalid emails and conflicting updates return 400; missing or invalid API keys return 401.
46
+ Errors use `{code, message}`. There are no webhooks for this surface.
47
+
48
+ ### Controls and verification
49
+
50
+ Pass synthetic `contacts` to seed the emulator; reset restores those fixtures. Shared admin
51
+ routes include `/__admin/state/contacts` for inspection/seeding, `/__admin/reset`, Timeline
52
+ checkpoints, `/__admin/clock`, `/__admin/requests` and `/__admin/faults`. Requests are journaled
53
+ as metadata, never contact bodies or API keys. Set `adminPrefix` to relocate this tree.
54
+
55
+ Namespace carriers are `x-emulates-namespace`, `/__admin/ns/{namespace}`, or API keys
56
+ mapped through `PUT /__admin/credentials`. Each namespace has independent contacts and ids.
57
+ Fault presets: `unauthorized`, `rate_limited` (429 with Retry-After), `server_error` (503),
58
+ and `connection_drop`. Generic fault rules also support deterministic latency.
59
+
60
+ Acceptance tests exercise the raw-fetch requests from issue #280, namespace/reset behavior,
61
+ faults and served HTTP. Property tests cover every operation and detect deliberate divergence.
62
+ `bun scripts/parity.ts` needs `BREVO_API_KEY` and safely compares the missing-contact envelope;
63
+ it does not create, update or delete real contacts. Live write parity has not been verified.
64
+
65
+ ### Deliberately not modelled
66
+
67
+ Email/SMS sending, campaigns, lists management, bulk import/export, SMS/WhatsApp identifiers,
68
+ forceMerge, attribute-definition catalogs, contact statistics and account-level quotas.
69
+ Only email and external-id creation are supported. No real customer fixtures or outbound events.
70
+
71
+ ## API
72
+
73
+ - `BrevoAPI`: in-process FetchAPI with `fetch`, `reset`, `contacts` and `counters` collections.
74
+ - `BREVO_NAMESPACE`: service name (`brevo`).
75
+ - `createRuntime`: shared admin, namespace, clock, fault and journal surface; accepts `apiKeys`
76
+ and `contacts` in addition to shared runtime options.
77
+ - `BREVO_PRESETS`: named fault presets.
78
+ - `document`, `operationIds`, `supportedOperationIds`: generated OpenAPI contract metadata.
79
+ - `createServer`, `serveTarget`, `DEFAULT_PORT` from `./server`: Node HTTP server and CLI
80
+ target (default port 12124).
81
+
82
+ Public types include `Contact`, `BrevoAPIOptions`, `OperationId` and `SupportedOperationId`.
package/SUPPORT.md ADDED
@@ -0,0 +1,14 @@
1
+ # Brevo contacts subset — operation support
2
+
3
+ Generated from `openapi.yaml`; do not edit by hand.
4
+
5
+ - operations in spec: **4**
6
+ - supported by the emulator: **4**
7
+ - parity enabled: **4**
8
+
9
+ | operationId | route | emulator | parity | notes |
10
+ | --- | --- | --- | --- | --- |
11
+ | `CreateContact` | `POST /v3/contacts` | ✅ supported | ⚠️ unsafe (opt-in) | |
12
+ | `GetContact` | `GET /v3/contacts/{identifier}` | ✅ supported | ✅ | |
13
+ | `UpdateContact` | `PUT /v3/contacts/{identifier}` | ✅ supported | ⚠️ unsafe (opt-in) | |
14
+ | `DeleteContact` | `DELETE /v3/contacts/{identifier}` | ✅ supported | ⚠️ unsafe (opt-in) | |