Cleanups before a major release#1903
Conversation
Replace the plain `string` type on `code` with `WebServiceErrorCode`, an open
`ClientErrorCode | (string & {})` union, mirroring geoip2-node. This offers
autocompletion for the five client-generated codes while still accepting any
code the web service returns. The `ClientErrorCode` and `WebServiceErrorCode`
types are exported from the package.
Client-generated errors are now built through a `clientError()` helper typed
with the closed `ClientErrorCode`, so a typo at a throw site is a compile
error. The server-returned `data.code` path stays open.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Give ArgumentError an optional `cause` option and forward it to the Error constructor, matching WebServiceError and the geoip2-node error classes. This is additive; no current caller passes a cause. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Warning Review limit reached
More reviews will be available in 22 minutes and 56 seconds. Learn how PR review limits work. To continue reviewing without waiting, enable usage-based billing in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (18)
📝 WalkthroughWalkthroughThe PR adds an options-object constructor for ChangesClient API and request-shape updates
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces several refactorings and breaking changes, including updating the WebServiceClient constructor to accept an options object with a custom fetcher, removing the external validator dependency in favor of custom and built-in validation helpers, and ensuring Transaction serialization does not mutate input objects. Feedback on these changes highlights a potential TypeError in the WebServiceClient constructor if null is passed as options, the need to prevent purely numeric top-level domains in the custom isFQDN validation, and a missing object check in camelcaseKeys that could lead to errors when processing primitive values.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/request/transaction.ts (1)
103-111: 🩺 Stability & Availability | 🟠 Major
toString()still mutatesorder.referrerUriin place. Insrc/request/transaction.ts:103-107,sanitizeKeys()only makes a shallow copy, sosanitized.orderis still the caller’sOrderinstance. SincereferrerUriis aURL, converting it to a string overwrites that shared object; rebuildorderbefore serializing it.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/request/transaction.ts` around lines 103 - 111, The Transaction.toString() path still mutates the shared Order object because sanitizeKeys() only shallow-copies and the referrerUri conversion is applied in place. Update the toString() logic in Transaction to rebuild sanitized.order as a new object before serializing, converting referrerUri to a string on that copy instead of assigning back onto the original Order instance. Keep the change localized to Transaction.sanitizeKeys()/toString() so JSON.stringify(snakecaseKeys(...)) operates on fully detached data.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/errors.ts`:
- Around line 4-6: `ArgumentError` in `src/errors.ts` does not expose the
standard library error fields expected by consumers. Update the `ArgumentError`
class so it includes `code`, `error`, and optional `url` properties alongside
`name` and `message`, or relocate this class out of `src/errors.ts` if it should
not follow that contract. Use the existing `ArgumentError` constructor as the
place to initialize and expose these fields consistently.
In `@src/request/transaction.spec.ts`:
- Around line 239-253: The non-mutation coverage in the Transaction
serialization spec only checks Billing, but toString() also rebuilds Shipping
and CreditCard and rewrites Order.referrerUri via sanitizeKeys(). Extend the
existing test in transaction.spec.ts using the Transaction, Billing, Device,
Shipping, CreditCard, and Order symbols so it asserts those caller-owned objects
still retain their original fields and do not gain renamed keys after
serialization.
In `@src/webServiceClient.spec.ts`:
- Around line 34-49: The test helper clientWith currently injects a fetch stub
and bypasses HTTP-layer mocking, which conflicts with the required pattern for
this spec suite. Update the request/response tests in webServiceClient.spec.ts
to use nock for mocking the Client HTTP interactions, and remove or avoid the
fetcher injection path in clientWith so the tests exercise the real HTTP layer
while still asserting captured requests where needed.
In `@src/webServiceClient.ts`:
- Around line 81-92: The options handling in webServiceClient should not
dereference null in the `typeof options === 'object'` branch. Update the
`Client` constructor logic to guard `options != null` before accessing
`options.fetcher`, `options.host`, and `options.timeout`, or explicitly reject
null with a stable library error instead of allowing a raw TypeError. Use the
`Client` constructor and the options-object branch as the fix point.
---
Outside diff comments:
In `@src/request/transaction.ts`:
- Around line 103-111: The Transaction.toString() path still mutates the shared
Order object because sanitizeKeys() only shallow-copies and the referrerUri
conversion is applied in place. Update the toString() logic in Transaction to
rebuild sanitized.order as a new object before serializing, converting
referrerUri to a string on that copy instead of assigning back onto the original
Order instance. Keep the change localized to
Transaction.sanitizeKeys()/toString() so JSON.stringify(snakecaseKeys(...))
operates on fully detached data.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: a3990048-c00c-4c43-b0a9-a3637c796235
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (19)
CHANGELOG.mdREADME.mdpackage.jsonsrc/errors.spec.tssrc/errors.tssrc/index.tssrc/request/email.spec.tssrc/request/email.tssrc/request/order.tssrc/request/transaction.spec.tssrc/request/transaction.tssrc/response/models/factors.tssrc/response/models/insights.tssrc/response/models/score.tssrc/types.tssrc/utils.spec.tssrc/utils.tssrc/webServiceClient.spec.tssrc/webServiceClient.ts
|
Note This is Claude, commenting on Greg's behalf. Thanks for the reviews. Summary of how each finding was handled (the branch was rewritten via autosquash, so the fixes are folded into the relevant commits): Fixed
Intentional (kept)
Won't fix
204 tests pass; lint, build, and prettier are clean. |
Change the WebServiceClient constructor from
`(accountID, licenseKey, timeout?, host?)` to
`(accountID, licenseKey, options?: Options | number)`, matching geoip2-node.
`Options` carries `timeout`, `host`, and a new `fetcher` (a custom `fetch`
implementation, useful for proxies/dispatchers and testing). A bare number is
still accepted as the timeout for backward compatibility, so existing
`new Client(id, key, 3000)` callers are unaffected; only the rare caller that
passed `host` as a fourth positional argument must switch to `{ host }`.
Requests now go through `this.fetcher` rather than the global `fetch`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Transaction.toString() builds a shallow copy via Object.assign({}, this), so
the nested billing/shipping/creditCard objects were still the caller's
instances — and the address2 -> address_2 and was3DSecureSuccessful ->
was_3d_secure_successful renames mutated them in place (a caller's Billing
would lose address2 and gain address_2 after serialization). Rebuild each
renamed object as a fresh object instead, leaving the caller's instances
untouched.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
TransactionProps.customInputs was typed CustomInput[] but the stored field is a Record, and the value was always run through Object.assign to flatten it. Additively widen the input type to `CustomInput[] | Record<string, boolean | number | string>` and handle both: an array is flattened as before, a record is used directly. Existing CustomInput[] callers are unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Match geoip2-node's utility name for cross-library consistency. This is an internal helper (not exported from the package), so the rename has no effect on consumers. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the three `validator` uses with built-ins: * email.ts: reimplement the `isEmail`/`isFQDN` input guards with small regex helpers (covered by the existing email.spec.ts cases, including IDN domains and trailing-dot rejections). * order.ts: the `referrerUri` `isURL` check was effectively validating a value that is already a `URL`; validate with the native `URL` constructor instead, preserving the ArgumentError on invalid input. * transaction.spec.ts: replace the test-only `isJSON` with a local `JSON.parse` helper. Drops `validator` and `@types/validator` from the dependencies. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The WebServiceClient tests now drive requests through an injected `fetcher` that returns canned `Response`s and records the requests made, instead of mocking at the HTTP layer with nock. A dedicated test asserts the request shape (method, path, POST body, auth header) directly; error/status cases return the corresponding `Response`, and the timeout case rejects when the request signal aborts — exercising the real timeout signal deterministically. This removes the `nock` dev dependency (which was on a beta release). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Note This is Claude, commenting on Greg's behalf. Follow-up from a fresh review pass. The changes below are folded into the relevant commits (branch rewritten via autosquash). Addressed
Not changed (with reasons)
206 tests pass; lint, build, and prettier are clean. |
Part of the pre-major-release cleanups tracked in STF-809. This is the
minfraud-api-nodefollow-up to the geoip2-node PR (maxmind/GeoIP2-node#1726),bringing the two libraries in line and doing a few minfraud-specific cleanups.
The guiding principle is gentle breaking changes: most users need to change
nothing, or only make trivial (lint/type-level) adjustments.
Changes (one commit each)
Mirroring geoip2-node:
ClientErrorCodeunion forWebServiceError.code.codeis nowWebServiceErrorCode(ClientErrorCode | (string & {})) instead ofstring, giving autocompletion for the client-generated codes while stillaccepting any server code. Client errors are built through a
clientError()helper typed with the closed
ClientErrorCode, so a typo at a throw site isa compile error. New types are exported.
causeonArgumentError— accepts and forwards an optionalcause,matching
WebServiceError.fetcher. The client constructortakes
(accountID, licenseKey, options?: Options | number). A bare number isstill accepted as the timeout, so only callers passing
hostpositionallychange (to
{ host }).fetcherallows a customfetch(proxy/dispatcher,testing).
minfraud-specific:
Transactionserialization mutating caller objects.toString()shallow-copied the transaction, so the
address2→address_2/was3DSecureSuccessfulrenames mutated the caller'sBilling/Shipping/CreditCardinstances. Each renamed object is now rebuilt fresh.customInputsmay be a plain record, not just aCustomInput[](additive).
Dependencies & tests:
camelizeResponse→camelcaseKeysto match geoip2-node (internal).validatorproduction dependency — reimplement theisEmail/isFQDNinput guards (covered by the existingemail.spec.ts,including IDN domains), validate
referrerUriwith the nativeURLconstructor, and replace the test-only
isJSON.nockwith the injectedfetcherin the web-service tests anddrop the
nockdev dependency.Testing
npm run lint,npm run build, andprettierare clean.validatorandnockare gone frompackage.json.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Breaking Changes
Bug Fixes