Skip to content

vantage-sh/vantage-ts

Repository files navigation

@vantage-sh/vantage-client

A fully-typed TypeScript SDK for the Vantage API. Types and client methods are auto-generated from the official OpenAPI specification.

Installation

npm install @vantage-sh/vantage-client

Two Ways to Use

This SDK provides two distinct modes of operation: a high-level resource API for convenience, and a low-level typed request method for full control with complete type safety.

High-Level API

The APIV2Client organizes endpoints by resource with intuitive CRUD methods:

import { APIV2Client } from "@vantage-sh/vantage-client";

const client = new APIV2Client("your-api-token");

// List resources with query parameters
const reports = await client.costReports.list({ page: 1 });

// Get a specific resource by token
const report = await client.costReports.get("rprt_abc123");

// Create a new resource
const folder = await client.folders.create({
  title: "Production Costs",
  workspace_token: "wrkspc_123",
});

// Update a resource
await client.folders.update("fldr_abc123", {
  title: "Updated Title",
});

// Delete a resource
await client.folders.delete("fldr_abc123");

Resources with nested or specialized endpoints expose additional methods:

// Access sub-resources
const costs = await client.costs.getForCostReport("rprt_abc123", {
  start_date: "2024-01-01",
  end_date: "2024-01-31",
});

Low-Level Typed Requests

For full control, use the request method directly with path strings. The SDK provides complete type safety — TypeScript validates that your path exists, your method is supported, and your request/response bodies match the schema:

import { APIV2Client } from "@vantage-sh/vantage-client";

const client = new APIV2Client("your-api-token");

// Path and method are type-checked against the OpenAPI schema
const report = await client.request(
  "/cost_reports/rprt_abc123",
  "GET",
  undefined
);

// TypeScript enforces correct body shape for POST/PUT/PATCH
const newFolder = await client.request("/folders", "POST", {
  title: "My Folder",
  workspace_token: "wrkspc_123",
});

// Query parameters are passed as the body for GET requests
const reports = await client.request("/cost_reports", "GET", {
  page: 1,
});

Path Type Safety

The Path type is a union of all valid API paths. TypeScript will error on invalid paths:

// ✓ Valid path
await client.request("/cost_reports", "GET", { page: 1 });

// ✗ TypeScript error: invalid path
await client.request("/not_a_real_endpoint", "GET", {});

Method Type Safety

The SupportedMethods<P> type ensures only valid HTTP methods for each path:

// ✓ GET is supported on /cost_reports
await client.request("/cost_reports", "GET", { page: 1 });

// ✗ TypeScript error: DELETE not supported on /cost_reports
await client.request("/cost_reports", "DELETE", {});

Request/Response Types

Import types for individual endpoints when needed:

import type {
  GetCostReportResponse,
  CreateFolderRequest,
  CreateFolderResponse,
} from "@vantage-sh/vantage-client";

function displayReport(report: GetCostReportResponse) {
  console.log(report.title);
}

Error Handling

By default, API errors are thrown as VantageAPIError with structured error information:

import { VantageAPIError } from "@vantage-sh/vantage-client";

try {
  await client.costReports.get("invalid_token");
} catch (error) {
  if (error instanceof VantageAPIError) {
    console.log(error.status);     // 404
    console.log(error.statusText); // "Not Found"
    console.log(error.errors);     // ["Resource not found"] or null
  }
}

Never Throw Mode

For Go-style error handling without try/catch, enable never throw mode by passing true as the second argument to the client constructor:

import { APIV2Client, VantageAPIError } from "@vantage-sh/vantage-client";

const client = new APIV2Client("your-api-token", true);

// All methods return [result, null] on success or [null, error] on failure
const [report, error] = await client.costReports.get("rprt_abc123");

if (error) {
  console.log(error.status);  // 404
  console.log(error.errors);  // ["Resource not found"]
  return;
}

// TypeScript knows report is defined here
console.log(report.title);

This pattern works with all client methods, including the low-level request method:

const client = new APIV2Client("your-api-token", true);

const [folders, error] = await client.request("/folders", "GET", { page: 1 });

if (error) {
  // Handle error
  return;
}

// Use folders safely

Utilities

Path Encoding

Use pathEncode to safely encode dynamic path segments:

import { pathEncode } from "@vantage-sh/vantage-client";

const token = pathEncode(userProvidedToken);
const report = await client.request(
  `/cost_reports/${token}`,
  "GET",
  undefined
);

Development

Building

npm run build

This fetches the latest OpenAPI schema from the Vantage API, generates TypeScript types, and compiles the client.

Type Checking

npm run type-check

Multipart Edge Cases

The client automatically detects multipart/form-data routes and handles them appropriately. However, this detection requires a manually-maintained mapping in BaseClient.ts:

const multipartEdgeCases: MultipartEdgeCases = {
  "/exchange_rates/csv": {
    POST: true,
  },
  "/business_metrics/{}/values.csv": {
    PUT: true,
  },
  // ...
};

The MultipartEdgeCases type is derived from the OpenAPI schema. If a new multipart route is added to the API, TypeScript will produce an error until you add the route to this object. Path parameters are represented as {} in the keys.

Type Helpers

The SDK exports several utility types for advanced use:

Type Description
Path Union of all valid API paths
SupportedMethods<P> Valid HTTP methods for a given path
RequestBodyForPathAndMethod<P, M> Request body type for a path/method
ResponseBodyForPathAndMethod<P, M> Response body type for a path/method
NoSlashString Branded type for safely encoded path segments

Publishing

After building locally and confirming the changes in the Vantage API are reflected in the types in this repository, bump the version in package.json, run npm i, and open a PR. CI will take care of publishing the new version with the updates.

Semantic Considerations:

  • patch - Bug fixes
  • minor - New APIs or additions to existing APIs
  • major - Breaking changes

About

A TypeScript client for the Vantage API

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •