Skip to content

UI/dashboard #9

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

Merged
merged 12 commits into from
Jun 2, 2025
Merged
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
**/.DS_Store
**/dist
**/yarn-error.log
lerna-debug.log
lerna-debug.log
.aiccontent
2 changes: 1 addition & 1 deletion packages/kubernetesjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@
"test:deploy": "ts-node scripts/deploy.ts"
},
"devDependencies": {
"schema-sdk": "^0.7.0"
"schema-sdk": "^0.11.3"
}
}
26 changes: 21 additions & 5 deletions packages/kubernetesjs/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { URLSearchParams } from 'url';

interface RequestOptions<Params> {
hostname?: string;
path: string;
Expand All @@ -15,6 +13,7 @@ export interface APIClientOptions {
}

export interface APIClientRequestHeaders {
[key: string]: string | number | string[] | undefined;
accept?: string | string[] | undefined;
'accept-charset'?: string | string[] | undefined;
'accept-encoding'?: string | string[] | undefined;
Expand Down Expand Up @@ -110,11 +109,28 @@ export class APIClient {
}

private buildFullPath(endpoint: string, query?: { [key: string]: any }): string {
const url = new URL(endpoint, this.baseUrl);
// If baseUrl is a relative proxy path (e.g. '/api/k8s'), build manually
if (this.baseUrl.startsWith('/')) {
// Remove any trailing slash from baseUrl, ensure endpoint starts with '/'
const base = this.baseUrl.replace(/\/$/, '')
let url = `${base}${endpoint}`
if (query) {
// Build query params as a simple record so URLSearchParams can accept it
const record: Record<string, string> = {}
Object.keys(query).forEach(key => {
record[key] = String(query[key])
})
const params = new URLSearchParams(record).toString()
if (params) url += `?${params}`
}
return url
}
// Otherwise, treat baseUrl as an absolute URL
const url = new URL(endpoint, this.baseUrl)
if (query) {
Object.keys(query).forEach(key => url.searchParams.append(key, query[key]));
Object.keys(query).forEach(key => url.searchParams.append(key, query[key]))
}
return url.toString();
return url.toString()
}

private async request<Resp>(options: RequestOptions<any>): Promise<Resp> {
Expand Down
94 changes: 94 additions & 0 deletions packages/react/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# KubernetesJS

<p align="center" width="100%">
<img src="https://github.com/hyperweb-io/interweb-utils/assets/545047/89c743c4-be88-409f-9a77-4b02cd7fe9a4" width="80">
<br/>
TypeScript Client for Kubernetes
<br />
<a href="https://github.com/hyperweb-io/kubernetesjs/actions/workflows/ci.yml">
<img height="20" src="https://github.com/hyperweb-io/kubernetesjs/actions/workflows/ci.yml/badge.svg"/>
</a>
<a href="https://github.com/hyperweb-io/kubernetesjs/blob/main/LICENSE">
<img height="20" src="https://img.shields.io/badge/license-MIT-blue.svg"/>
</a>
</p>


KubernetesJS is a **fully-typed**, zero-dependency TypeScript library designed to simplify interactions with Kubernetes APIs. With comprehensive TypeScript support, it provides a strongly-typed interface that makes managing Kubernetes resources clear and predictable, ideal for TypeScript developers looking to integrate Kubernetes management into their applications.

## Features

- **🔒 Fully Typed**: Complete TypeScript definitions for all functions and models for an enhanced development experience.
- **🚀 Zero Dependencies**: Works out of the box without the need for additional installations.
- **📡 Full Kubernetes API Coverage**: Supports all Kubernetes API endpoints with detailed TypeScript types.
- **🌐 Cross-Platform**: Works with both Node.js and browser environments.

## Installation

To install KubernetesJS, you can use npm or yarn:

```bash
npm install kubernetesjs
# or
yarn add kubernetesjs

```

## Example

```js
import { KubernetesClient } from "kubernetesjs";

const client = new KubernetesClient({
restEndpoint: 'http://127.0.0.1:8001'
});

const result = await client.listCoreV1NamespacedPod({
path: { namespace: 'default' }
});

if (result.items && result.items.length) {
result.items.forEach(item => {
console.log('NODE:', item.spec.nodeName);

const initContainers = item.status.initContainerStatuses?.map(ic => ({
image: ic.image,
name: ic.name,
ready: ic.ready,
state: ic.state
}));

const containers = item.status.containerStatuses?.map(c => ({
image: c.image,
name: c.name,
ready: c.ready,
state: c.state
}));

console.log({ containers });
console.log({ initContainers });
});
}
```

## Related

Checkout these related projects:

* [`schema-typescript`](https://github.com/hyperweb-io/schema-typescript/tree/main/packages/schema-typescript)
Provides robust tools for handling JSON schemas and converting them to TypeScript interfaces with ease and efficiency.
* [`@schema-typescript/cli`](https://github.com/hyperweb-io/schema-typescript/tree/main/packages/cli)
CLI is the command line utility for `schema-typescript`.
* [`schema-sdk`](https://github.com/hyperweb-io/schema-typescript/tree/main/packages/schema-sdk)
Provides robust tools for handling OpenAPI schemas and converting them to TypeScript clients with ease and efficiency.
* [`starship`](https://github.com/hyperweb-io/starship) Unified Testing and Development for the Interchain.

## Credits

🛠 Built by Hyperweb — if you like our tools, please checkout and contribute to [our github ⚛️](https://github.com/hyperweb-io)

## Disclaimer

AS DESCRIBED IN THE LICENSES, THE SOFTWARE IS PROVIDED “AS IS”, AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND.

No developer or entity involved in creating this software will be liable for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of the code, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.
18 changes: 18 additions & 0 deletions packages/react/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
transform: {
"^.+\\.tsx?$": [
"ts-jest",
{
babelConfig: false,
tsconfig: "tsconfig.json",
},
],
},
transformIgnorePatterns: [`/node_modules/*`],
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
modulePathIgnorePatterns: ["dist/*"]
};
62 changes: 62 additions & 0 deletions packages/react/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"name": "@kubernetesjs/react",
"version": "0.6.0",
"author": "Dan Lynch <[email protected]>",
"description": "Fully Typed Kubernetes React Hooks",
"keywords": [
"kubernetes",
"k8s",
"typescript",
"api",
"client",
"sdk",
"container",
"orchestration",
"devops",
"cloud-native",
"openapi",
"swagger"
],
"main": "index.js",
"module": "esm/index.js",
"types": "index.d.ts",
"homepage": "https://github.com/hyperweb-io/kubernetesjs",
"license": "SEE LICENSE IN LICENSE",
"publishConfig": {
"access": "public",
"directory": "dist"
},
"repository": {
"type": "git",
"url": "https://github.com/hyperweb-io/kubernetesjs"
},
"bugs": {
"url": "https://github.com/hyperweb-io/kubernetesjs/issues"
},
"scripts": {
"copy": "copyfiles -f ../../LICENSE README.md package.json dist",
"clean": "rimraf dist/**",
"prepare": "npm run build",
"build": "npm run clean; tsc; tsc -p tsconfig.esm.json; npm run copy",
"build:dev": "npm run clean; tsc --declarationMap; tsc -p tsconfig.esm.json; npm run copy",
"lint": "eslint . --fix",
"dev": "ts-node ./test/test.ts",
"deploy": "ts-node ./test/deployment.ts",
"codegen": "ts-node ./scripts/codegen.ts",
"test": "jest",
"test:watch": "jest --watch",
"test:teardown": "ts-node scripts/teardown.ts",
"test:list": "ts-node scripts/list.ts",
"test:deploy": "ts-node scripts/deploy.ts"
},
"dependencies": {
"react": "^18.2.0",
"@tanstack/react-query": "^5.56.1",
"kubernetesjs": "^0.6.0"
},
"devDependencies": {
"@types/react": "^18.2.77",
"schema-sdk": "^0.11.3",
"react": "^18.2.0"
}
}
82 changes: 82 additions & 0 deletions packages/react/scripts/codegen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { writeFileSync } from 'fs';
import { getDefaultSchemaSDKOptions, generateOpenApiClient, generateReactQueryHooks, generateContext} from 'schema-sdk';
import schema from './swagger.json';

const options = getDefaultSchemaSDKOptions({
includePropertyComments: true,
clientName: 'KubernetesClient',
includeSwaggerUrl: true,
exclude: [
'*.v1beta1.*',
'*.v2beta1.*',
'io.k8s.api.events.v1.EventSeries',
'io.k8s.api.events.v1.Event',
'io.k8s.api.flowcontrol*',
],
});
const openApiOptions = {
...options,
npmApiClient: './client',
operationNamingStrategy: {
aliases: {
listCoreV1PodForAllNamespaces: 'getPods',
},
renameMap: {
listCoreV1PodForAllNamespaces: 'listPods',
},
},
paths: {
exclude: ['*flowschema*', '*v1beta1*', '*v2beta1*'],
excludeRequests: ['head', 'options'],
excludeTags: [
'storage_v1beta1',
'*v1beta1',
'*v2beta1',
'*v1beta1*',
'*v2beta1*',
],
},
includeTypeComments: true,
includeMethodComments: true,
mergedParams: false,
namingStrategy: {
useLastSegment: true,
renameMap: {
'io.k8s.api.discovery.v1.EndpointPort': 'DiscoveryEndpointPort',
'io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.ServiceReference':
'ApiExtServiceReference',
'io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.WebhookClientConfig':
'ApiExtWebhookClientConfig',
'io.k8s.api.admissionregistration.v1.ServiceReference':
'AdmissionServiceReference',
},
},
};

// const code = generateOpenApiClient(
// openApiOptions,
// schema as any
// );
// writeFileSync(
// __dirname + '/../src/index.ts',
// code
// );

const contextCode = generateContext(
'Kubernetes',
'kubernetesjs'
);
writeFileSync(__dirname + '/../src/context.tsx', contextCode);

const reactQueryHooks = generateReactQueryHooks(
{...openApiOptions,
hooks: {
enabled: true,
contextHookName: 'useKubernetes',
contextImportPath: './context',
typesImportPath: 'kubernetesjs',
}
},
schema as any
);
writeFileSync(__dirname + '/../src/index.ts', reactQueryHooks);
Loading