fix(client): update request handling and typings for current smartrequest and OpenAPI output

This commit is contained in:
2026-05-07 23:31:22 +00:00
parent e85d725873
commit 46782d925b
15 changed files with 6162 additions and 4884 deletions
+2 -2
View File
@@ -1,8 +1,8 @@
/**
* autocreated commitinfo by @pushrocks/commitinfo
* autocreated commitinfo by @push.rocks/commitinfo
*/
export const commitinfo = {
name: '@apiclient.xyz/hetznercloud',
version: '1.2.0',
version: '1.2.1',
description: 'An unofficial TypeScript API client for the Hetzner Cloud API providing easy methods to manage servers, volumes, and firewalls.'
}
+29 -10
View File
@@ -30,16 +30,35 @@ export class HetznerAccount {
console.log(`Url: ${url}`);
console.log(`Method: ${methodArg}`);
console.log(`Payload: ${JSON.stringify(payloadArg, null, 2)}`);
const response = await plugins.smartrequest.request(url, {
method: methodArg,
headers: {
const request = plugins.smartrequest.SmartRequest.create()
.url(url)
.headers({
Authorization: `Bearer ${this.token}`,
},
requestBody: payloadArg,
keepAlive: false,
});
console.log(response.statusCode);
console.log(response.body);
return response;
})
.options({
keepAlive: false,
});
if (methodArg !== 'GET' && methodArg !== 'DELETE') {
request.json(payloadArg);
}
const response = methodArg === 'POST'
? await request.post()
: methodArg === 'PUT'
? await request.put()
: methodArg === 'PATCH'
? await request.patch()
: methodArg === 'DELETE'
? await request.delete()
: await request.get();
const body = await response.json().catch(() => ({}));
const responseObject = {
statusCode: response.status,
body,
};
console.log(responseObject.statusCode);
console.log(responseObject.body);
return responseObject;
}
}
+5 -5
View File
@@ -10,7 +10,7 @@ export class HetznerFirewall {
optionsArg: {
name: string;
labels?: {[key: string]: string},
rules: types.IFirewall['rules'],
rules: types.TFirewallCreateRequestBody['rules'],
}
) => {
const firewall = new HetznerFirewall(hetznerAccountRefArg);
@@ -26,7 +26,7 @@ export class HetznerFirewall {
createFirewallUrl,
createFirewallPayload
);
firewall.data = (response.body as types.TFirewallCreateResponseBody).firewall;
firewall.data = (response.body as types.TFirewallCreateResponseBody).firewall!;
return firewall;
}
@@ -49,7 +49,7 @@ export class HetznerFirewall {
for (const firewall of firewalls) {
let isMatch = true;
for (const key in labelObject) {
if (firewall.data.labels[key] !== labelObject[key]) {
if ((firewall.data.labels || {})[key] !== labelObject[key]) {
isMatch = false;
}
}
@@ -61,7 +61,7 @@ export class HetznerFirewall {
}
// INSTANCE
public data: types.IFirewall;
public data!: types.IFirewall;
public hetznerAccountRef: HetznerAccount;
constructor(hetznerAccountRefArg: HetznerAccount) {
@@ -71,4 +71,4 @@ export class HetznerFirewall {
public async delete() {
await this.hetznerAccountRef.request('DELETE', `/firewalls/${this.data.id}`, {});
}
}
}
+3 -3
View File
@@ -35,7 +35,7 @@ export class HetznerServer {
createServerUrl,
createServerPayload
);
server.data = (response.body as types.TServerCreateResponseBody).server;
server.data = (response.body as types.TServerCreateResponseBody).server!;
return server;
}
@@ -58,7 +58,7 @@ export class HetznerServer {
for (const server of servers) {
let isMatch = true;
for (const key in labelObject) {
if (server.data.labels[key] !== labelObject[key]) {
if ((server.data.labels || {})[key] !== labelObject[key]) {
isMatch = false;
}
}
@@ -71,7 +71,7 @@ export class HetznerServer {
// INSTANCE
public hetznerAccountRef: HetznerAccount;
public data: types.IServer;
public data!: types.IServer;
constructor(hetznerAccountRefArg: HetznerAccount) {
this.hetznerAccountRef = hetznerAccountRefArg;
+4 -4
View File
@@ -30,7 +30,7 @@ export class HetznerVolume {
createVolumeUrl,
createVolumePayload
);
volume.data = (response.body as types.TVolumeCreateResponseBody).volume;
volume.data = (response.body as types.TVolumeCreateResponseBody).volume!;
return volume;
}
@@ -53,7 +53,7 @@ export class HetznerVolume {
for (const volume of volumes) {
let isMatch = true;
for (const key in labelObject) {
if (volume.data.labels[key] !== labelObject[key]) {
if ((volume.data.labels || {})[key] !== labelObject[key]) {
isMatch = false;
}
}
@@ -64,7 +64,7 @@ export class HetznerVolume {
return results;
}
public data: types.IVolume;
public data!: types.IVolume;
public hetznerAccountRef: HetznerAccount;
constructor(hetznerAccountRefArg: HetznerAccount) {
@@ -74,4 +74,4 @@ export class HetznerVolume {
public delete = async () => {
await this.hetznerAccountRef.request('DELETE', `/volumes/${this.data.id}`, {});
}
}
}
+12 -6
View File
@@ -1,14 +1,20 @@
import * as plugins from './hetznercloud.plugins.js';
import * as hetznerOpenapiSpec from './openapi.spec.js';
type TJsonRequestBody<TPathMethod> = TPathMethod extends { requestBody?: infer TRequestBody }
? NonNullable<TRequestBody> extends { content: { 'application/json': infer TJsonBody } }
? TJsonBody
: never
: never;
// datacenters
export type TDatacenters = hetznerOpenapiSpec.paths['/datacenters']['get']['responses']['200']['content']['application/json'];
// servers
export type IServer = hetznerOpenapiSpec.paths['/servers/{id}']['get']['responses']['200']['content']['application/json']['server'];
export type IServer = NonNullable<hetznerOpenapiSpec.paths['/servers/{id}']['get']['responses']['200']['content']['application/json']['server']>;
export type TServersGetRequestBody = {};
export type TServersGetResponseBody = hetznerOpenapiSpec.paths['/servers']['get']['responses']['200']['content']['application/json'];
export type TServerCreateRequestBody = hetznerOpenapiSpec.paths['/servers']['post']['requestBody']['content']['application/json'];
export type TServerCreateRequestBody = TJsonRequestBody<hetznerOpenapiSpec.paths['/servers']['post']>;
export type TServerCreateResponseBody = hetznerOpenapiSpec.paths['/servers']['post']['responses']['201']['content']['application/json'];
export type TServerDeleteRequestBody = hetznerOpenapiSpec.paths['/servers/{id}']['delete'];
@@ -44,17 +50,17 @@ export type THetznerCloudServerName =
export type THetznerCloudLocationName = 'fsn1' | 'nbg1' | 'hel1' | 'ash' | 'hil';
// volumes
export type IVolume = hetznerOpenapiSpec.paths['/volumes/{id}']['get']['responses']['200']['content']['application/json']['volume'];
export type IVolume = NonNullable<hetznerOpenapiSpec.paths['/volumes/{id}']['get']['responses']['200']['content']['application/json']['volume']>;
export type TVolumeGetRequestBody = {};
export type TVolumeGetResponseBody = hetznerOpenapiSpec.paths['/volumes']['get']['responses']['200']['content']['application/json'];
export type TVolumeCreateRequestBody = hetznerOpenapiSpec.paths['/volumes']['post']['requestBody']['content']['application/json'];
export type TVolumeCreateRequestBody = TJsonRequestBody<hetznerOpenapiSpec.paths['/volumes']['post']>;
export type TVolumeCreateResponseBody = hetznerOpenapiSpec.paths['/volumes']['post']['responses']['201']['content']['application/json'];
export type TVolumeDeleteRequestBody = hetznerOpenapiSpec.paths['/volumes/{id}']['delete'];
// firewalls
export type IFirewall = hetznerOpenapiSpec.paths['/firewalls/{id}']['get']['responses']['200']['content']['application/json']['firewall'];
export type IFirewall = NonNullable<hetznerOpenapiSpec.paths['/firewalls/{id}']['get']['responses']['200']['content']['application/json']['firewall']>;
export type TFirewallsGetRequestBody = {};
export type TFirewallsGetResponseBody = hetznerOpenapiSpec.paths['/firewalls']['get']['responses']['200']['content']['application/json'];
export type TFirewallCreateRequestBody = hetznerOpenapiSpec.paths['/firewalls']['post']['requestBody']['content']['application/json'];
export type TFirewallCreateRequestBody = TJsonRequestBody<hetznerOpenapiSpec.paths['/firewalls']['post']>;
export type TFirewallCreateResponseBody = hetznerOpenapiSpec.paths['/firewalls']['post']['responses']['201']['content']['application/json'];
export type TFirewallDeleteRequestBody = hetznerOpenapiSpec.paths['/firewalls/{id}']['delete'];