feat(domains): add forge activation methods

LU
17h ago
+268-3

Summary

Adds Forge activation to domains: a forge.enable subresource call plus Forge-aware options on the classic verify and update, matching the folded API surface (the standalone forge verify and update endpoints no longer exist).

  • resend.domains.forge.enable({ id, returnPath? }) → POST /domains/:id/forge. Activates Forge on the domain and returns the full domain response (same shape as GET /domains/:id). When returnPath is omitted, the API picks a label that is free in the domain's DNS. Idempotent on the API side: enabling an already-migrated domain returns its current state.
  • resend.domains.verify(id, { scope: ['forge'] }) → POST /domains/:id/verify. The optional scope (only value 'forge') re-checks just the Forge record, so the records that are already verified are not re-proven. Without scope, the request is byte-identical to before.
  • resend.domains.update({ id, forgeReturnPath }) → PATCH /domains/:id. Moves the Forge return path while the Forge record is still verifying and does not start verification. Once the record verifies, the path locks and the API refuses with 422 return_path_unavailable. Composes with the other update fields.

The domain response types are unchanged: the API carries Forge state in the records array, so callers poll the Forge record status after adding DNS.

Validation

Unit tests cover the forge enable (URL, method, snake_case body mapping, the empty-body enable), the scoped verify body, the forge_return_path mapping on update, request options in the second argument both alone and mixed with scope, and the per-request options coverage spec; the full suite is 799 tests passing. The earlier 13-step end-to-end run against a server with the Forge stack predates the endpoint fold; the flow re-runs against the reshaped API before release.

Notes for reviewers

  • verify keeps its two-argument shape: VerifyDomainsOptions extends RequestOptions, so scope, headers, and signal all ride in the second argument and the implementation destructures them apart (the same merged-options shape as fetch). Every existing call compiles and behaves unchanged, and nothing is deprecated.

Summary by cubic

Adds a forge subresource to domains for managing Forge activation. Bumps the package to 6.39.0.

  • resend.domains.forge.enable({ id, returnPath? }) activates Forge via POST /domains/:id/forge and returns the full domain; re-enabling an already-activated domain is idempotent.
  • resend.domains.update({ id, forgeReturnPath }) moves the Forge return path via the existing PATCH /domains/:id; after the domain verifies, the API returns 422 return_path_unavailable.
  • resend.domains.verify(id, { scope: ['forge'] }) re-checks only the Forge record via POST /domains/:id/verify and returns { object: 'domain', id }; poll domains.get for state. Existing callers that pass request options as the second argument still work.

Domain response types are unchanged; callers track Forge state by polling the Forge record status after adding DNS.

Part of DEV-2471.