-
Notifications
You must be signed in to change notification settings - Fork 1
docs: add TypeScript SDK reference section #284
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| --- | ||
| title: Error handling | ||
| description: How to catch and inspect errors thrown by the Kosli TypeScript SDK. | ||
| --- | ||
|
|
||
| All HTTP errors from the SDK are instances of `KosliError` or one of its subclasses. Network-level failures throw one of the client error classes listed below. | ||
|
|
||
| ## KosliError | ||
|
|
||
| `KosliError` is the base class for any non-2xx HTTP response. It exposes: | ||
|
|
||
| | Property | Type | Description | | ||
| |----------|------|-------------| | ||
| | `message` | `string` | Error message | | ||
| | `statusCode` | `number` | HTTP status code (e.g. `404`, `403`) | | ||
| | `headers` | `Headers` | Response headers | | ||
| | `body` | `string` | Raw response body (may be empty) | | ||
| | `rawResponse` | `Response` | The full HTTP response object | | ||
| | `data$` | varies | Structured error data for specific error types (see below) | | ||
|
|
||
| ## HTTP error classes | ||
|
|
||
| These named subclasses cover the most common API errors: | ||
|
|
||
| | Class | Status | Description | | ||
| |-------|--------|-------------| | ||
| | `BadRequestError` | `400` | Invalid request | | ||
| | `UnauthorizedError` | `401` | Permission denied or not authenticated | | ||
| | `NotFoundError` | `404` | Resource not found | | ||
| | `RateLimitedError` | `429` | Rate limit exceeded | | ||
|
|
||
| ```typescript | ||
| import { Kosli } from "@kosli/sdk"; | ||
| import * as errors from "@kosli/sdk/models/errors"; | ||
|
|
||
| const kosli = new Kosli({ | ||
| httpBearer: process.env["KOSLI_API_KEY"] ?? "", | ||
| }); | ||
|
|
||
| try { | ||
| const trail = await kosli.trails.get({}, { | ||
| org: "my-org", | ||
| flowName: "my-flow", | ||
| trailName: "my-trail", | ||
| }); | ||
| } catch (error) { | ||
| if (error instanceof errors.NotFoundError) { | ||
| console.error("Trail not found"); | ||
| } else if (error instanceof errors.UnauthorizedError) { | ||
| console.error("Access denied:", error.data$.message); | ||
| } else if (error instanceof errors.RateLimitedError) { | ||
| console.error("Rate limit hit - back off and retry"); | ||
| } else if (error instanceof errors.KosliError) { | ||
| console.error(`HTTP ${error.statusCode}: ${error.message}`); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Network errors | ||
|
|
||
| These errors are thrown when the request cannot be completed at the transport level: | ||
|
|
||
| | Class | Description | | ||
| |-------|-------------| | ||
| | `ConnectionError` | The HTTP client could not reach the server | | ||
| | `RequestTimeoutError` | The request was aborted by an `AbortSignal` timeout | | ||
| | `RequestAbortedError` | The request was cancelled by the caller | | ||
| | `InvalidRequestError` | The request could not be constructed (invalid input) | | ||
| | `UnexpectedClientError` | An unrecognised error occurred in the HTTP client | | ||
|
|
||
| Network errors do not have a `statusCode` - handle them separately from `KosliError`: | ||
|
|
||
| ```typescript | ||
| import * as errors from "@kosli/sdk/models/errors"; | ||
|
|
||
| try { | ||
| const result = await kosli.trails.list({}, { org: "my-org", flowName: "my-flow" }); | ||
| } catch (error) { | ||
| if (error instanceof errors.ConnectionError) { | ||
| console.error("Could not connect to Kosli - check your network"); | ||
| } else if (error instanceof errors.RequestTimeoutError) { | ||
| console.error("Request timed out"); | ||
| } else if (error instanceof errors.KosliError) { | ||
| console.error(`API error ${error.statusCode}: ${error.message}`); | ||
| } else { | ||
| throw error; | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Other errors | ||
|
|
||
| A small number of operations can throw additional error types for specific conditions: | ||
|
|
||
| | Class | Status | Description | | ||
| |-------|--------|-------------| | ||
| | `ConflictResponseModelError` | `409` | Conflict (e.g. resource already exists) | | ||
| | `RequestEntityTooLargeResponseModelError` | `413` | Request body too large | | ||
| | `ResponseValidationError` | - | Response from server did not match the expected schema; inspect `error.rawValue` or call `error.pretty()` | | ||
|
|
||
| Check the method's documentation to see which errors apply to a specific operation. | ||
|
Comment on lines
+93
to
+101
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Improvement: These additional error types aren't shown in the
Comment on lines
+93
to
+101
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Improvement: The "Other errors" table introduces three additional error classes (
|
||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,182 @@ | ||||||||||
| --- | ||||||||||
| title: Overview | ||||||||||
| description: Use the Kosli TypeScript SDK to interact with the Kosli API from Node.js, Bun, Deno, and browser environments. | ||||||||||
| --- | ||||||||||
|
|
||||||||||
| <Warning> | ||||||||||
| **Early access.** The TypeScript SDK is an unsupported work in progress and may change or be removed without notice. It is provided for evaluation only - do not use it in production. | ||||||||||
| </Warning> | ||||||||||
|
|
||||||||||
| The `@kosli/sdk` package provides a type-safe TypeScript client for the Kosli API. It supports Node.js, Bun, Deno, and all modern browsers. | ||||||||||
|
|
||||||||||
| ## Installation | ||||||||||
|
|
||||||||||
| Install using your preferred package manager: | ||||||||||
|
|
||||||||||
| <CodeGroup> | ||||||||||
| ```bash npm | ||||||||||
| npm add @kosli/sdk | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ```bash pnpm | ||||||||||
| pnpm add @kosli/sdk | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ```bash bun | ||||||||||
| bun add @kosli/sdk | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ```bash yarn | ||||||||||
| yarn add @kosli/sdk | ||||||||||
| ``` | ||||||||||
| </CodeGroup> | ||||||||||
|
|
||||||||||
| <Note> | ||||||||||
| The package is published as an ES Module (ESM) only. CommonJS projects must use dynamic import: | ||||||||||
|
|
||||||||||
| ```typescript | ||||||||||
| const { Kosli } = await import("@kosli/sdk"); | ||||||||||
| ``` | ||||||||||
| </Note> | ||||||||||
|
|
||||||||||
| ## Quick start | ||||||||||
|
|
||||||||||
| ```typescript | ||||||||||
| import { Kosli } from "@kosli/sdk"; | ||||||||||
|
|
||||||||||
| const kosli = new Kosli({ | ||||||||||
| httpBearer: process.env["KOSLI_API_KEY"] ?? "", | ||||||||||
| }); | ||||||||||
|
|
||||||||||
| const trails = await kosli.trails.list({}, { | ||||||||||
| org: "my-org", | ||||||||||
| flowName: "my-flow", | ||||||||||
| }); | ||||||||||
|
|
||||||||||
| console.log(trails); | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ## Authentication | ||||||||||
|
|
||||||||||
| Set your API key when constructing the client. This applies it to all requests: | ||||||||||
|
|
||||||||||
| ```typescript | ||||||||||
| import { Kosli } from "@kosli/sdk"; | ||||||||||
|
|
||||||||||
| const kosli = new Kosli({ | ||||||||||
| httpBearer: process.env["KOSLI_API_KEY"] ?? "", | ||||||||||
| }); | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| Some operations accept the API key at the call site instead. Use this when you need per-request credentials: | ||||||||||
|
|
||||||||||
| ```typescript | ||||||||||
| const result = await kosli.trails.list( | ||||||||||
| { httpBearer: process.env["KOSLI_API_KEY"] ?? "" }, // security | ||||||||||
| { org: "my-org", flowName: "my-flow" }, // request params | ||||||||||
| ); | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| See [personal API keys](/user/personal_api_keys) and [service accounts](/administration/authentication/service_accounts) for how to create API keys. | ||||||||||
|
|
||||||||||
| ## Server selection | ||||||||||
|
|
||||||||||
| By default the SDK targets the EU region. Pass `server: "us"` to use the US region: | ||||||||||
|
|
||||||||||
| ```typescript | ||||||||||
| const kosli = new Kosli({ | ||||||||||
| httpBearer: process.env["KOSLI_API_KEY"] ?? "", | ||||||||||
| server: "us", | ||||||||||
| }); | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| | Name | URL | Region | | ||||||||||
| |------|-----|--------| | ||||||||||
| | `"eu"` | `https://app.kosli.com/api/v2` | EU (default) | | ||||||||||
| | `"us"` | `https://app.us.kosli.com/api/v2` | US | | ||||||||||
|
|
||||||||||
| To point at a custom URL (e.g. a proxy or local instance), use `serverURL` instead: | ||||||||||
|
|
||||||||||
| ```typescript | ||||||||||
| const kosli = new Kosli({ | ||||||||||
| httpBearer: process.env["KOSLI_API_KEY"] ?? "", | ||||||||||
| serverURL: "https://app.kosli.com/api/v2", | ||||||||||
| }); | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ## Available resources | ||||||||||
|
|
||||||||||
| The client exposes the following resource groups: | ||||||||||
|
|
||||||||||
| | Resource | Description | | ||||||||||
| |----------|-------------| | ||||||||||
| | `kosli.actions` | Environment and flow actions | | ||||||||||
| | `kosli.allowlists` | Artifact allowlists | | ||||||||||
| | `kosli.approvals` | Approvals | | ||||||||||
| | `kosli.artifacts` | Artifact reporting and lookup | | ||||||||||
| | `kosli.attestations` | Attestations (custom, JUnit, Jira, Snyk, Sonar, pull request) | | ||||||||||
| | `kosli.builds` | Builds | | ||||||||||
| | `kosli.customAttestationTypes` | Custom attestation type management | | ||||||||||
| | `kosli.deployments` | Deployments | | ||||||||||
| | `kosli.environments` | Environment management and reporting | | ||||||||||
| | `kosli.flows` | Flow management | | ||||||||||
| | `kosli.organizations` | Organization settings and notifications | | ||||||||||
| | `kosli.policies` | Policy management | | ||||||||||
| | `kosli.repos` | Repository live artifact lookup | | ||||||||||
| | `kosli.schemas` | Policy and template schemas | | ||||||||||
| | `kosli.search` | Artifact search by SHA or fingerprint | | ||||||||||
| | `kosli.serviceAccounts` | Service account API key management | | ||||||||||
| | `kosli.snapshots` | Environment snapshots | | ||||||||||
| | `kosli.tags` | Tag management | | ||||||||||
| | `kosli.trails` | Trail management | | ||||||||||
| | `kosli.user` | User settings | | ||||||||||
|
|
||||||||||
| ## Standalone functions | ||||||||||
|
|
||||||||||
| All methods are also available as individually importable functions, which allows bundlers to tree-shake unused code: | ||||||||||
|
|
||||||||||
| ```typescript | ||||||||||
| import { KosliCore } from "@kosli/sdk/core.js"; | ||||||||||
| import { trailsList } from "@kosli/sdk/funcs/trails-list.js"; | ||||||||||
|
|
||||||||||
| const kosli = new KosliCore({ | ||||||||||
| httpBearer: process.env["KOSLI_API_KEY"] ?? "", | ||||||||||
| }); | ||||||||||
|
|
||||||||||
| const result = await trailsList(kosli, {}, { | ||||||||||
| org: "my-org", | ||||||||||
| flowName: "my-flow", | ||||||||||
| }); | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ## Supported runtimes | ||||||||||
|
|
||||||||||
| The SDK requires ECMAScript 2020 or later and the Web Fetch API. Supported environments: | ||||||||||
|
|
||||||||||
| - **Browsers**: Chrome, Safari, Edge, Firefox (evergreen) | ||||||||||
| - **Node.js**: active and maintenance LTS releases (v18, v20+) | ||||||||||
| - **Bun**: v1 and above | ||||||||||
| - **Deno**: v1.39+ | ||||||||||
|
|
||||||||||
| For TypeScript projects, add `"lib": ["es2020", "dom", "dom.iterable"]` to your `tsconfig.json` to get full type support for async iterables, streams, and fetch-related APIs. | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: This reads as though users should set
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: The current phrasing ("add
Suggested change
|
||||||||||
|
|
||||||||||
| ## Debugging | ||||||||||
|
|
||||||||||
| Pass a logger to emit debug output for all requests and responses: | ||||||||||
|
|
||||||||||
| ```typescript | ||||||||||
| const kosli = new Kosli({ | ||||||||||
| httpBearer: process.env["KOSLI_API_KEY"] ?? "", | ||||||||||
| debugLogger: console, | ||||||||||
| }); | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| Alternatively, set the environment variable `KOSLI_DEBUG=true`. | ||||||||||
|
|
||||||||||
| <Warning> | ||||||||||
| Debug logging prints headers including your API key in plain text. Use it only during local development. | ||||||||||
| </Warning> | ||||||||||
|
|
||||||||||
| ## Package | ||||||||||
|
|
||||||||||
| The SDK is published on npm as [`@kosli/sdk`](https://www.npmjs.com/package/@kosli/sdk). | ||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: The
"js"icon is a reasonable choice, but Font Awesome also has a"node-js"and a more specific TypeScript-related icon ("code"). Since this is a TypeScript SDK specifically, consider whether"js"best represents it — or if the broader"code"icon would be less misleading for TS-first users. Minor point, current choice works fine.