Uh oh!
There was an error while loading. Please reload this page.
feat(sdk): add TypeScript SDK + SDK Docs - #174
Conversation
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:73fc4c0bd0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const requestType: TrackingRequestType = params.containerNumber | ||
| ? 'container' | ||
| : 'bill_of_lading'; | ||
| const requestNumber = params.containerNumber || params.bookingNumber; |
There was a problem hiding this comment.
Use booking_number when tracking by booking
When trackContainer is called with a bookingNumber, it sets requestType to 'bill_of_lading' because only containerNumber is checked. That means booking numbers are submitted as bill of lading tracking requests, which the API will either reject or interpret incorrectly. This only shows up for callers who pass bookingNumber (and no containerNumber), but in that case the SDK will misclassify the request.
Useful? React with 👍 / 👎.
| query: includeParam ? ({ include: includeParam } as any) : undefined, | ||
| }, | ||
| }) | ||
| ); | ||
| return this.formatResult(raw, options?.format); |
There was a problem hiding this comment.
Map getContainer results for mapped/both formats
getContainer always returns the raw JSON:API document because formatResult is called without a mapper. If a caller sets defaultFormat: 'mapped' or passes options.format = 'mapped'/'both', they still receive the raw response, unlike getShipment and list methods which do map. This makes mapped output inconsistent and breaks code that expects Container fields for getContainer only when mapped is requested.
Useful? React with 👍 / 👎.
Summary
Testing
Greptile Overview
Greptile Summary
This PR adds a comprehensive TypeScript SDK for the Terminal49 API along with complete documentation. The SDK provides a typed client wrapper around the JSON:API using
openapi-fetchandopenapi-typescriptfor type safety.Key additions:
sdks/typescript-sdk/src/client.ts) with 1173 lines of well-structured code including retry logic, error handling, and response mappingshipments,containers,trackingRequests,shippingLines).envlocationsImplementation highlights:
ValidationError,NotFoundError,RateLimitError, etc.)raw,mapped,both)The code is production-ready with excellent test coverage, clear documentation, and follows TypeScript best practices.
Confidence Score: 5/5
Important Files Changed
Sequence Diagram
sequenceDiagram participant User participant Terminal49Client participant openapi-fetch participant Terminal49API participant Jsona User->>Terminal49Client: new Terminal49Client({apiToken, apiBaseUrl}) Terminal49Client->>Terminal49Client: normalizeBaseUrl() Terminal49Client->>Terminal49Client: buildFetch() with auth headers Terminal49Client->>openapi-fetch: createClient({baseUrl, fetch}) User->>Terminal49Client: trackingRequests.createFromInfer(number) Terminal49Client->>Terminal49API: POST /tracking_requests/infer_number Terminal49API-->>Terminal49Client: infer result Terminal49Client->>Terminal49Client: normalizeInferNumberType() Terminal49Client->>Terminal49API: POST /tracking_requests Terminal49API-->>Terminal49Client: tracking request created Terminal49Client-->>User: {infer, trackingRequest} User->>Terminal49Client: containers.get(id, includes) Terminal49Client->>openapi-fetch: GET /containers/{id}?include=... openapi-fetch->>Terminal49API: fetch with Authorization header alt Success Terminal49API-->>openapi-fetch: 200 JSON:API response openapi-fetch-->>Terminal49Client: {data, response} Terminal49Client->>Terminal49Client: formatResult() Terminal49Client-->>User: container data else 500 Server Error Terminal49API-->>openapi-fetch: 500 error Terminal49Client->>Terminal49Client: executeWithRetry() - retry with backoff Terminal49Client->>Terminal49API: retry request Terminal49API-->>Terminal49Client: 200 success Terminal49Client-->>User: container data else 404 Not Found Terminal49API-->>openapi-fetch: 404 error Terminal49Client->>Terminal49Client: toError() - create NotFoundError Terminal49Client-->>User: throw NotFoundError end User->>Terminal49Client: shipments.list(filters, {format: 'mapped'}) Terminal49Client->>Terminal49Client: applyPagination() Terminal49Client->>Terminal49API: GET /shipments with filters Terminal49API-->>Terminal49Client: JSON:API response Terminal49Client->>Terminal49Client: mapShipmentList() Terminal49Client->>Terminal49Client: mapListResult() Terminal49Client-->>User: {items, links, meta} User->>Terminal49Client: deserialize(jsonApiDoc) Terminal49Client->>Jsona: jsona.deserialize(doc) Jsona-->>Terminal49Client: plain objects Terminal49Client-->>User: deserialized data