Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.1.0"
".": "0.2.0"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 30
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fhypeman-cfdd18a303e2e6c87d671e6ae3ecdcd1d9642b053c2ef6bc507eee3f55cc6aa8.yml
openapi_spec_hash: 0b038c955d95740ace74103a9c18d5a3
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fhypeman-6e0a4efd150867a61bb7e6d1a9afe5ed0e51cc35ffd79839b9126a4e95e111a5.yml
openapi_spec_hash: 29efc937461cf32fb3ffcf9bff9d70dd
config_hash: f65a6a2bcef49a9f623212f9de6d6f6f
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Changelog

## 0.2.0 (2026-01-07)

Full Changelog: [v0.1.0...v0.2.0](https://github.com/onkernel/hypeman-ts/compare/v0.1.0...v0.2.0)

### Features

* Resource accounting ([57ff511](https://github.com/onkernel/hypeman-ts/commit/57ff511aa73bbc08b67496d7b807418b9342dc87))


### Chores

* break long lines in snippets into multiline ([48ae7b9](https://github.com/onkernel/hypeman-ts/commit/48ae7b93d321533d96fc9e5be246450fb93eb725))

## 0.1.0 (2025-12-23)

Full Changelog: [v0.0.2...v0.1.0](https://github.com/onkernel/hypeman-ts/compare/v0.0.2...v0.1.0)
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright 2025 Hypeman
Copyright 2026 Hypeman

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@onkernel/hypeman",
"version": "0.1.0",
"version": "0.2.0",
"description": "The official TypeScript library for the Hypeman API",
"author": "Hypeman <>",
"types": "dist/index.d.ts",
Expand Down
33 changes: 33 additions & 0 deletions src/resources/instances/instances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@ export interface Instance {
*/
state: 'Created' | 'Running' | 'Paused' | 'Shutdown' | 'Stopped' | 'Standby' | 'Unknown';

/**
* Disk I/O rate limit (human-readable, e.g., "100MB/s")
*/
disk_io_bps?: string;

/**
* Environment variables
*/
Expand Down Expand Up @@ -259,6 +264,16 @@ export namespace Instance {
* Network configuration of the instance
*/
export interface Network {
/**
* Download bandwidth limit (human-readable, e.g., "1Gbps", "125MB/s")
*/
bandwidth_download?: string;

/**
* Upload bandwidth limit (human-readable, e.g., "1Gbps", "125MB/s")
*/
bandwidth_upload?: string;

/**
* Whether instance is attached to the default network
*/
Expand Down Expand Up @@ -387,6 +402,12 @@ export interface InstanceCreateParams {
*/
devices?: Array<string>;

/**
* Disk I/O rate limit (e.g., "100MB/s", "500MB/s"). Defaults to proportional share
* based on CPU allocation if configured.
*/
disk_io_bps?: string;

/**
* Environment variables
*/
Expand Down Expand Up @@ -433,6 +454,18 @@ export namespace InstanceCreateParams {
* Network configuration for the instance
*/
export interface Network {
/**
* Download bandwidth limit (external→VM, e.g., "1Gbps", "125MB/s"). Defaults to
* proportional share based on CPU allocation.
*/
bandwidth_download?: string;

/**
* Upload bandwidth limit (VM→external, e.g., "1Gbps", "125MB/s"). Defaults to
* proportional share based on CPU allocation.
*/
bandwidth_upload?: string;

/**
* Whether to attach instance to the default network
*/
Expand Down
2 changes: 1 addition & 1 deletion src/version.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const VERSION = '0.1.0'; // x-release-please-version
export const VERSION = '0.2.0'; // x-release-please-version
5 changes: 4 additions & 1 deletion tests/api-resources/ingresses.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ describe('resource ingresses', () => {
const responsePromise = client.ingresses.create({
name: 'my-api-ingress',
rules: [
{ match: { hostname: '{instance}.example.com' }, target: { instance: '{instance}', port: 8080 } },
{
match: { hostname: '{instance}.example.com' },
target: { instance: '{instance}', port: 8080 },
},
],
});
const rawResponse = await responsePromise.asResponse();
Expand Down
13 changes: 11 additions & 2 deletions tests/api-resources/instances/instances.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,15 @@ describe('resource instances', () => {
image: 'docker.io/library/alpine:latest',
name: 'my-workload-1',
devices: ['l4-gpu'],
disk_io_bps: '100MB/s',
env: { PORT: '3000', NODE_ENV: 'production' },
hotplug_size: '2GB',
hypervisor: 'cloud-hypervisor',
network: { enabled: true },
network: {
bandwidth_download: '1Gbps',
bandwidth_upload: '1Gbps',
enabled: true,
},
overlay_size: '20GB',
size: '2GB',
vcpus: 2,
Expand Down Expand Up @@ -102,7 +107,11 @@ describe('resource instances', () => {
await expect(
client.instances.logs(
'id',
{ follow: true, source: 'app', tail: 0 },
{
follow: true,
source: 'app',
tail: 0,
},
{ path: '/_stainless_unknown_path' },
),
).rejects.toThrow(Hypeman.NotFoundError);
Expand Down
6 changes: 5 additions & 1 deletion tests/api-resources/volumes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ describe('resource volumes', () => {

// Prism tests are disabled
test.skip('create: required and optional params', async () => {
const response = await client.volumes.create({ name: 'my-data-volume', size_gb: 10, id: 'vol-data-1' });
const response = await client.volumes.create({
name: 'my-data-volume',
size_gb: 10,
id: 'vol-data-1',
});
});

// Prism tests are disabled
Expand Down
66 changes: 55 additions & 11 deletions tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ describe('instantiate client', () => {
error: jest.fn(),
};

const client = new Hypeman({ logger: logger, logLevel: 'debug', apiKey: 'My API Key' });
const client = new Hypeman({
logger: logger,
logLevel: 'debug',
apiKey: 'My API Key',
});

await forceAPIResponseForClient(client);
expect(debugMock).toHaveBeenCalled();
Expand All @@ -107,7 +111,11 @@ describe('instantiate client', () => {
error: jest.fn(),
};

const client = new Hypeman({ logger: logger, logLevel: 'info', apiKey: 'My API Key' });
const client = new Hypeman({
logger: logger,
logLevel: 'info',
apiKey: 'My API Key',
});

await forceAPIResponseForClient(client);
expect(debugMock).not.toHaveBeenCalled();
Expand Down Expand Up @@ -157,7 +165,11 @@ describe('instantiate client', () => {
};

process.env['HYPEMAN_LOG'] = 'debug';
const client = new Hypeman({ logger: logger, logLevel: 'off', apiKey: 'My API Key' });
const client = new Hypeman({
logger: logger,
logLevel: 'off',
apiKey: 'My API Key',
});

await forceAPIResponseForClient(client);
expect(debugMock).not.toHaveBeenCalled();
Expand All @@ -173,7 +185,11 @@ describe('instantiate client', () => {
};

process.env['HYPEMAN_LOG'] = 'not a log level';
const client = new Hypeman({ logger: logger, logLevel: 'debug', apiKey: 'My API Key' });
const client = new Hypeman({
logger: logger,
logLevel: 'debug',
apiKey: 'My API Key',
});
expect(client.logLevel).toBe('debug');
expect(warnMock).not.toHaveBeenCalled();
});
Expand Down Expand Up @@ -267,7 +283,11 @@ describe('instantiate client', () => {
return new Response(JSON.stringify({}), { headers: { 'Content-Type': 'application/json' } });
};

const client = new Hypeman({ baseURL: 'http://localhost:5000/', apiKey: 'My API Key', fetch: testFetch });
const client = new Hypeman({
baseURL: 'http://localhost:5000/',
apiKey: 'My API Key',
fetch: testFetch,
});

await client.patch('/foo');
expect(capturedRequest?.method).toEqual('PATCH');
Expand Down Expand Up @@ -345,7 +365,11 @@ describe('instantiate client', () => {

describe('withOptions', () => {
test('creates a new client with overridden options', async () => {
const client = new Hypeman({ baseURL: 'http://localhost:5000/', maxRetries: 3, apiKey: 'My API Key' });
const client = new Hypeman({
baseURL: 'http://localhost:5000/',
maxRetries: 3,
apiKey: 'My API Key',
});

const newClient = client.withOptions({
maxRetries: 5,
Expand Down Expand Up @@ -385,7 +409,11 @@ describe('instantiate client', () => {
});

test('respects runtime property changes when creating new client', () => {
const client = new Hypeman({ baseURL: 'http://localhost:5000/', timeout: 1000, apiKey: 'My API Key' });
const client = new Hypeman({
baseURL: 'http://localhost:5000/',
timeout: 1000,
apiKey: 'My API Key',
});

// Modify the client properties directly after creation
client.baseURL = 'http://localhost:6000/';
Expand Down Expand Up @@ -531,7 +559,11 @@ describe('retries', () => {
return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } });
};

const client = new Hypeman({ apiKey: 'My API Key', timeout: 10, fetch: testFetch });
const client = new Hypeman({
apiKey: 'My API Key',
timeout: 10,
fetch: testFetch,
});

expect(await client.request({ path: '/foo', method: 'get' })).toEqual({ a: 1 });
expect(count).toEqual(2);
Expand Down Expand Up @@ -561,7 +593,11 @@ describe('retries', () => {
return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } });
};

const client = new Hypeman({ apiKey: 'My API Key', fetch: testFetch, maxRetries: 4 });
const client = new Hypeman({
apiKey: 'My API Key',
fetch: testFetch,
maxRetries: 4,
});

expect(await client.request({ path: '/foo', method: 'get' })).toEqual({ a: 1 });

Expand All @@ -585,7 +621,11 @@ describe('retries', () => {
capturedRequest = init;
return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } });
};
const client = new Hypeman({ apiKey: 'My API Key', fetch: testFetch, maxRetries: 4 });
const client = new Hypeman({
apiKey: 'My API Key',
fetch: testFetch,
maxRetries: 4,
});

expect(
await client.request({
Expand Down Expand Up @@ -647,7 +687,11 @@ describe('retries', () => {
capturedRequest = init;
return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } });
};
const client = new Hypeman({ apiKey: 'My API Key', fetch: testFetch, maxRetries: 4 });
const client = new Hypeman({
apiKey: 'My API Key',
fetch: testFetch,
maxRetries: 4,
});

expect(
await client.request({
Expand Down