Skip to content

feat(sdk): add TypeScript SDK + SDK Docs - #174

Merged
dodeja merged 11 commits into
mainfrom
codex/sdk-release
Feb 4, 2026
Merged

feat(sdk): add TypeScript SDK + SDK Docs#174
dodeja merged 11 commits into
mainfrom
codex/sdk-release

Conversation

@dodeja

@dodejadodeja commented Feb 4, 2026

Copy link
Copy Markdown
Member

Summary

  • add the TypeScript SDK package (client, tests, scripts, types)
  • add SDK Docs section with landing page, quickstart, and usage guides
  • normalize SDK base URL and improve smoke test env loading
  • ignore local metadata and node_modules

Testing

  • npm --prefix sdks/typescript-sdk test

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-fetch and openapi-typescript for type safety.

Key additions:

  • TypeScript SDK client (sdks/typescript-sdk/src/client.ts) with 1173 lines of well-structured code including retry logic, error handling, and response mapping
  • Comprehensive test coverage with unit tests and smoke tests
  • Complete SDK documentation section with installation, authentication, methods, filtering, pagination, and error handling guides
  • Type-safe API client using generated OpenAPI types
  • JSON:API deserialization support using Jsona library
  • Namespace-based resource organization (shipments, containers, trackingRequests, shippingLines)
  • Improved smoke test environment loading from multiple .env locations
  • Base URL normalization to handle various input formats

Implementation highlights:

  • Error hierarchy with specific error classes (ValidationError, NotFoundError, RateLimitError, etc.)
  • Automatic retry with exponential backoff for 429/5xx errors
  • Flexible response format options (raw, mapped, both)
  • Resource mappers that transform JSON:API responses to simplified domain models
  • Proper authentication header injection
  • Node 18+ with ES2022 modules

The code is production-ready with excellent test coverage, clear documentation, and follows TypeScript best practices.

Confidence Score: 5/5

  • This PR is safe to merge with high confidence
  • The implementation is well-architected with comprehensive test coverage, follows TypeScript best practices, includes proper error handling with retry logic, and provides complete documentation. All files are new additions with no breaking changes to existing code.
  • No files require special attention

Important Files Changed

FilenameOverview
sdks/typescript-sdk/src/client.tsCore SDK client with JSON:API support, retry logic, error handling, and resource mappings
sdks/typescript-sdk/src/index.tsMain export file for SDK public API
sdks/typescript-sdk/package.jsonPackage configuration with dependencies and build scripts
sdks/typescript-sdk/src/client.test.tsComprehensive unit tests covering retry logic, error handling, and response mapping
sdks/typescript-sdk/src/smoke.test.tsIntegration tests with improved env loading from multiple locations
docs/docs.jsonAdded SDK Docs navigation tab with TypeScript SDK documentation structure

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
Loading

@vercel

vercelBot commented Feb 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
apiReadyReadyPreview, CommentFeb 4, 2026 8:52pm

Request Review

@chatgpt-codex-connectorchatgpt-codex-connectorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +236 to +239
const requestType: TrackingRequestType = params.containerNumber
? 'container'
: 'bill_of_lading';
const requestNumber = params.containerNumber || params.bookingNumber;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Comment on lines +223 to +227
query: includeParam ? ({ include: includeParam } as any) : undefined,
},
})
);
return this.formatResult(raw, options?.format);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

@dodeja
dodeja merged commit e49ed54 into mainFeb 4, 2026
5 checks passed
@github-actionsgithub-actionsBot mentioned this pull request Aug 22, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@dodeja