KehittäjätTypeScript SDK
Hostwolf Apps SDK JavaScriptille ja TypeScriptille
@hostwolf/apps-sdk on Hostwolf Apps -rajapinnan virallinen tyypitetty asiakaskirjasto. Sillä julkaiset ja ajat sovelluksiasi koodista: projektit, sovellukset, julkaisut ja lokit, ympäristömuuttujat, hallinnoidut tietokannat, automaattinen skaalaus, taltiot ja paljon muuta.
npm install https://app.hostwolf.net/dl/hostwolf-apps-sdk-0.2.1.tgz
SDK jaetaan osoitteesta app.hostwolf.net eikä npm-rekisteristä. Yllä oleva komento lisää sen package.json-tiedostoosi muodossa "@hostwolf/apps-sdk": "https://app.hostwolf.net/dl/hostwolf-apps-sdk-0.2.1.tgz", ja tuot sen nimellä @hostwolf/apps-sdk. pnpm, yarn ja bun hyväksyvät saman URL-osoitteen. Jokaisella versiolla on oma URL; katso Versiot.
Se toimii Node 18+:ssa, Bunissa ja Denossa, eikä sillä ole ajonaikaisia riippuvuuksia.
Katso myös: REST API -viite · MCP-palvelin · Muutosloki · Hanki API-tunnus
Pikaopas#
Luo API-tunnus konsolissa kohdassa Avaimet ja tunnukset → API-tunnukset, ja sitten:
import { HostwolfApps } from '@hostwolf/apps-sdk';
const hw = new HostwolfApps({ token: process.env.HOSTWOLF_APPS_TOKEN! });
const server = (await hw.servers.purchased()).find((s) => s.kind === 'app' && s.status === 'ready')!;
const { uuid: project } = await hw.projects.create({ name: 'shop' });
const app = await hw.applications.createFromGit({
project_uuid: project,
environment_name: 'production',
server_uuid: server.server_uuid!,
git_repository: 'https://github.com/acme/shop',
git_branch: 'main',
build_pack: 'nixpacks',
ports_exposes: '3000',
});
await hw.applications.setEnvs(app.uuid, { NODE_ENV: 'production' });
const deployment = await hw.deployAndWait(app.uuid);
console.log(deployment.status, await hw.applications.logs(app.uuid, { lines: 20 }));
Resursseihin viitataan niiden uuid:llä. Vastausobjektit käyttävät rajapinnan omia kenttänimiä (snake_case), ja niiden TypeScript-tyypit viedään, esim. Application, Deployment ja ManagedDatabase.
Asetukset#
new HostwolfApps({
token: '12|abc...', // required
baseUrl: 'https://console.app.hostwolf.net', // default
timeoutMs: 30_000, // per request
maxRetries: 2, // 429s, and 502/503/504 on GET
maxRetryWaitMs: 10_000, // longer Retry-After waits fail fast instead
language: 'de', // error messages in en, de, fr, es or fi
fetch: customFetch, // optional
});
Projektit ja ympäristöt#
REST: Projektien päätepisteet
| Metodi | Mitä se tekee |
|---|---|
projects.list() / get(uuid) | Projektit; get sisältää ympäristöt |
projects.create({ name }) | Uusi projekti, jossa on production-ympäristö |
projects.update / delete | Nimeä uudelleen tai poista tyhjä projekti |
projects.environments(uuid) | Projektin ympäristöt |
projects.environment(uuid, 'staging') | Yksi ympäristö (nimen tai uuid:n perusteella) resursseineen |
projects.createEnvironment / updateEnvironment / deleteEnvironment | Hallitse ympäristöjä |
projects.sharedEnvs / environmentSharedEnvs | Muuttujat, jotka jaetaan projektin tai ympäristön kaikille sovelluksille |
Sovellukset#
REST: Sovellusten päätepisteet
| Metodi | Mitä se tekee |
|---|---|
applications.list({ tag }) | Tiimin kaikki sovellukset |
applications.get(uuid) | Yksi sovellus asetuksineen |
applications.createFromGit(input) | Julkisesta repositoriosta (nixpacks, railpack, dockerfile tai static) |
applications.createFromPrivateRepo(input) | Yksityisestä repositoriosta deploy-avaimella (private_key_uuid) |
applications.createFromGithubApp(input) | Yhdistetyn GitHub Appin repositoriosta (github_app_uuid); push-julkaisut toimivat suoraan |
applications.createFromDockerfile(input) | Dockerfile-tekstistä, repositoriota ei tarvita |
applications.createFromImage(input) | Valmiista konttikuvasta, kuten ghcr.io/acme/web |
applications.update(uuid, changes) | Nimi, verkkotunnukset, portit, haara, build- ja käynnistyskomennot, terveystarkistus, rajat |
applications.deploy(uuid, { force }) | Tee build ja käynnistä; palauttaa deployment_uuid:n |
applications.restart / stop | Käynnistä uudelleen ilman uutta buildia, tai pysäytä |
applications.logs(uuid, { lines }) | Kontin viimeisin tuloste (tunnus tarvitsee read:sensitive-oikeuden) |
applications.metrics(uuid, { minutes }) | Suorittimen ja muistin historia |
applications.rollbackImages / rollback(uuid, tag) | Julkaise aiempi konttikuva uudelleen |
applications.delete(uuid, { deleteVolumes }) | Poista sovellus (ja oletuksena sen taltiot) |
Sovellukset toimivat sovelluspalvelimillasi. server_uuid on servers.purchased()-kutsun server_uuid-kenttä (tai servers.list()-kutsun uuid). Jätä domains pois, niin saat generoidun *.app.hostwolf.net-osoitteen.
Ympäristömuuttujat#
| Metodi | Mitä se tekee |
|---|---|
applications.envs(uuid) | Muuttujat; arvot ovat null, ellei tunnuksella ole read:sensitive-oikeutta |
applications.setEnvs(uuid, { KEY: 'value' }) | Luo tai päivitä useita kerralla |
applications.setEnv(uuid, { key, value, is_shown_once }) | Luo tai päivitä yksi |
applications.createEnv / updateEnv | Tiukka luonti (409, jos on jo olemassa) ja päivitys |
applications.deleteEnv(uuid, envUuid) / deleteEnvByKey(uuid, key) | Poista muuttuja |
teams.sharedEnvs() ja vastaavat | Koko tiimin muuttujat, käytetään muodossa {{team.KEY}} |
Käynnissä olevat kontit näkevät muuttuneet muuttujat seuraavan julkaisun jälkeen.
Julkaisut#
REST: Julkaisujen päätepisteet
const { deployment_uuid } = await hw.applications.deploy(app.uuid);
const done = await hw.deployments.wait(deployment_uuid!, {
timeoutMs: 10 * 60_000,
onStatus: (status) => console.log(status), // queued, in_progress, finished
});
wait ja deployAndWait heittävät HostwolfAppsError-virheen koodilla deployment_failed (viestissä lokin viimeiset rivit), deployment_cancelled tai timeout. Anna throwOnFailure: false, jos haluat epäonnistuneen julkaisun takaisin virheen sijaan.
| Metodi | Mitä se tekee |
|---|---|
deployments.running() | Jonossa olevat tai nyt käynnissä olevat julkaisut koko tiimissä |
deployments.get(uuid) | Yksi julkaisu, koontiloki kentässä logs |
parseDeploymentLogs(deployment) | Koontiloki riveinä ({ output, type, timestamp }) |
deployments.forApplication(uuid, { skip, take }) | Sivullinen sovelluksen julkaisuja, uusin ensin |
deployments.allForApplication(uuid) | Asynkroninen iteraattori niiden kaikkien yli |
deployments.deploy({ uuid, tag, force }) | Julkaise useita sovelluksia uuid:n tai tunnisteen perusteella |
deployments.cancel(uuid) | Peru jonossa oleva tai käynnissä oleva julkaisu |
Palvelimet#
| Metodi | Mitä se tekee |
|---|---|
servers.purchased() / purchasedServer(uuid) | Ostamasi sovelluspalvelimet ja VPS:t: koko, kaupunki, tila, hinta ja server_uuid |
servers.list() / get(uuid) | Sovelluspalvelimet, joilla sovelluksia voi ajaa |
servers.resources(uuid) / domains(uuid) | Mitä palvelimella ajetaan, ja sen verkkotunnukset |
servers.metrics(uuid, { minutes }) | Suorittimen ja muistin historia |
servers.destinations(uuid) | Palvelimen Docker-verkot (usean palvelimen käyttöön) |
servers.traffic(uuid, { month }) | Ostetun palvelimen lähtevä liikenne ja sen lasku tähän mennessä (1 Tt kuukaudessa sisältyy) |
servers.teamTraffic({ month }) | Sama tiimin kaikille palvelimille, yhteissummineen |
servers.regions({ size }) | Kaupungit kokokohtaisine kuukausihintoineen ja tieto siitä, mihin automaattinen skaalaus voi lisätä palvelimia |
Palvelimia voi ostaa ja perua vain konsolissa, joten API-tunnus ei voi koskaan ostaa palvelinta.
Usea palvelin#
Aja yhden sovelluksen kopioita usealla sovelluspalvelimellasi. Hostwolf tekee konttikuvan kerran, käynnistää kopion jokaisella palvelimella ja tasaa kuorman niiden välillä.
await hw.applications.addServer(app.uuid, otherServer.server_uuid!);
await hw.deployAndWait(app.uuid);
console.log(await hw.applications.destinations(app.uuid)); // primary + copies
removeDestination(appUuid, destinationUuid) lopettaa kopion ajamisen kyseisellä palvelimella.
Hallinnoidut tietokannat#
PostgreSQL, MySQL/MariaDB ja Redis Hostwolfin tietokantapalvelimilla, erillään sovelluspalvelimistasi, TLS:llä, öisillä varmuuskopioilla muualle ja PostgreSQL:lle ajankohtaan palautuksella.
const plans = await hw.databases.catalog(); // engines, plans, pool sizes, regions, prices
const db = await hw.databases.create({ engine: 'postgres', plan: 'small', region: 'vultr:ams' });
await hw.databases.waitUntilReady(db.uuid);
await hw.databases.attach(db.uuid, app.uuid); // DATABASE_URL (pooled) + DATABASE_DIRECT_URL
await hw.deployAndWait(app.uuid);
Tietokanta laskutetaan tunneittain palvelintilauksellasi siitä hetkestä, kun se luodaan. create lähettää Idempotency-Key-otsakkeen, joten uudelleen yritetty kutsu ei koskaan luo toista tietokantaa; anna oma avaimesi parametrilla { idempotencyKey }.
connection(uuid) palauttaa kaksi URL-osoitetta. url kulkee yhteyspoolerin kautta (PgBouncer portissa 6432, ProxySQL portissa 6033): käytä sitä sovelluksessasi. direct_url yltää suoraan tietokantaan: käytä sitä migraatioihin, LISTEN/NOTIFY-käyttöön, istuntoasetuksiin ja pitkiin transaktioihin. Redisillä on yksi URL.
| Metodi | Mitä se tekee |
|---|---|
databases.list() / get(uuid) | Tietokantasi moottoreineen, paketteineen, alueineen, tiloineen, hintoineen, rajoineen sekä upgrades- ja advice-tietoineen |
databases.connection(uuid) | Poolattu ja suora URL salasanoineen (tunnus tarvitsee oikeuden read:sensitive) |
databases.attach(uuid, appUuid, { envKey, overwrite }) | Tallenna poolattu URL muuttujaan DATABASE_URL ja suora muuttujaan DATABASE_DIRECT_URL (Redis: REDIS_URL). Jos sovelluksella on ne jo eri arvolla, kutsu heittää conflict-virheen, jossa on error.conflicts ja error.suggestedEnvKey; anna envKey tai overwrite: true |
databases.upgrade(uuid, plan, { confirm: true }) | Siirry suurempaan pakettiin listasta upgrades; URL pysyy samana |
databases.setEvictionPolicy(uuid, policy) | Redis: allkeys-lru välimuistille, noeviction jonoille (tulee voimaan heti) |
databases.backup(uuid) | Aloita ylimääräinen varmuuskopio nyt |
databases.delete(uuid) | Poista se ja lopeta laskutus; tuki voi palauttaa sen 7 päivän ajan |
upgrade ilman parametria { confirm: true } ei muuta mitään: se heittää HostwolfAppsError-virheen koodilla confirm_required, ja error.quote sisältää uuden kuukausihinnan, joka näytetään ensin.
Automaattinen skaalaus#
const { policy, blocker, status } = await hw.autoscaling.get(app.uuid);
await hw.autoscaling.enable(app.uuid, { min_copies: 1, max_copies: 4, monthly_cap_usd: 40 });
Automaattinen skaalaus lisää sovelluspalvelimia lähelle kävijöitäsi, kun suoritinkuorma pysyy korkeana, ja poistaa ne, kun se laskee. Lisätyt palvelimet laskutetaan tunneittain normaalihintaan, enintään monthly_cap_usd asti. blocker kertoo, miksi sitä ei vielä voi ottaa käyttöön (esimerkiksi aktiivista palvelintilausta ei ole). Pois jättämäsi kentät säilyttävät arvonsa; disable(uuid) poistaa sen käytöstä. cities listaa alueiden tunnisteet, jotka allowed_cities hyväksyy sovellukselle, sekä tuntihinnan siellä; servers.regions() listaa kaikki kaupungit.
Tallennustaltiot#
Lohkotallennustilaa sovelluspalvelimillesi ja VPS:illesi: 10–1000 Gt, liitettynä palvelimella polkuun /mnt/volume-<id>, laskutus tunneittain. Laskua nostavat kutsut vaativat { confirm: true }; ilman sitä ne eivät muuta mitään ja heittävät koodin confirm_required sekä hinnan kentässä error.quote.
const offer = await hw.volumes.offer(server.uuid, { sizeGb: 50 }); // sizes allowed here and the price
const volume = await hw.volumes.create(server.uuid, { size_gb: 50, autogrow_max_gb: 200 }, { confirm: true });
await hw.volumes.waitFor(volume.id); // mounted in about a minute
await hw.volumes.resize(server.uuid, volume.id, 100, { confirm: true });
| Metodi | Mitä se tekee |
|---|---|
volumes.list(serverUuid) / listAll({ status }) / get(id) | Palvelimen taltiot tai tiimin kaikki taltiot (status: 'detached' irrotetuille) |
volumes.offer(serverUuid, { sizeGb }) | Myydäänkö palvelimen kaupungissa taltioita, koot ja hinta |
volumes.create(serverUuid, { size_gb, backups, autogrow_max_gb }, { confirm }) | Lisää taltio (varmuuskopiot oletuksena käytössä) |
volumes.resize / setBackups / setAutogrow / update | Suurenna (ei koskaan pienennä), ota varmuuskopiot käyttöön tai pois käytöstä, aseta automaattisen kasvun raja |
volumes.detach(serverUuid, id) | Poista liitos ja irrota se; se säilyttää tiedostonsa, ja sitä laskutetaan edelleen |
volumes.attach(id, serverUuid, { confirm }) | Liitä irrotettu taltio palvelimeen samassa kaupungissa |
volumes.backups(id) / backupNow(serverUuid, id) | Palautettavissa olevat varmuuskopiot tai varmuuskopio heti |
volumes.restore(serverUuid, id, backupId, 'same' | 'new', { confirm }) | Palauta itse taltioon tai uuteen taltioon |
volumes.restoreDetached(id, backupId, serverUuid, { confirm }) | Palauta irrotetun taltion varmuuskopio uuteen taltioon |
volumes.delete(id, { confirm: true }) | Poista se ja sen tiedostot |
Kun palvelin poistetaan, sen taltiot irrotetaan ja säilytetään 7 päivää maksutta (kept_until); liitä taltio sillä välin toiseen palvelimeen samassa kaupungissa, tai se poistetaan.
Sovellusten taltiot#
| Metodi | Mitä se tekee |
|---|---|
applications.storages(uuid) | Pysyvät taltiot ja tiedostoliitokset |
applications.createStorage(uuid, { type: 'persistent', name, mount_path }) | Lisää taltio (julkaise uudelleen liittääksesi sen) |
applications.updateStorage / deleteStorage | Muuta tai poista yksi |
applications.setVolumeBackup(uuid, storageUuid, { frequency: 'daily' }) | Varmuuskopioi taltio aikataulun mukaan |
applications.runVolumeBackup / deleteVolumeBackup | Varmuuskopioi nyt tai poista aikataulu |
Tiimit#
| Metodi | Mitä se tekee |
|---|---|
teams.current() / members() | Tunnuksen tiimi ja sen jäsenet |
teams.update({ name }) | Nimeä tiimi uudelleen |
teams.auditEvents({ page }) / allAuditEvents() | Tiimin tarkastusloki (ylläpitäjät ja omistajat) |
Sivutus#
Rajapinnan sivuttamille listoille on kaksi tapaa: yksi metodi palauttaa yhden sivun, ja all…-metodi palauttaa asynkronisen iteraattorin jokaisen kohteen yli. collect muuttaa iteraattorin taulukoksi:
import { collect } from '@hostwolf/apps-sdk';
const deployments = await collect(hw.deployments.allForApplication(app.uuid), 100);
for await (const event of hw.teams.allAuditEvents({ action: 'deploy' })) console.log(event.description);
Virheet#
REST: Virhemuoto ja tilakoodit
Epäonnistuneet kutsut heittävät HostwolfAppsError-virheen.
import { HostwolfAppsError } from '@hostwolf/apps-sdk';
try {
await hw.applications.createFromDockerfile({ project_uuid, server_uuid, dockerfile });
} catch (e) {
if (e instanceof HostwolfAppsError && e.isValidation) console.log(e.errors); // { field: ['message'] }
else throw e;
}
Sillä on nämä ominaisuudet:
status: HTTP-tila, tai 0 verkkovirheissä, aikakatkaisuissa ja epäonnistuneissa julkaisuissa.code: lyhyt koodi, kutenvalidation_failed,unauthenticated,forbidden,not_found,rate_limited,confirm_required,deployment_failedtaitimeout.quote:confirm_required-virheen yhteydessä rajapinnan ilmoittama hinta (näytä se ja kutsu sitten uudelleen parametrilla{ confirm: true }).retryAfter: 429-vastauksessa sekunnit, joiden jälkeen kutsu sallitaan taas. Lyhyet odotukset yritetään uudelleen puolestasi; pidemmät epäonnistuvat heti, ja tämä kenttä on asetettu.message: luettava kuvaus, kenttävirheet mukaan lukien.errors: 422-vastauksen kenttävirheet muodossa{ field: ['message'] }.body: vastauksen sisältö. 403-virheessä asiasta, jonka Hostwolf tekee puolestasi (kuten palvelinten lisääminen), on mukanadocs-linkki.- Pikaliput:
isNotFound,isRateLimited,isValidation,isUnauthorizedjaisConfirmRequired.
Raa'at pyynnöt#
Jos päätepisteelle ei vielä ole kääremetodia, kutsu sitä suoraan:
await hw.http.get(`/applications/${uuid}/scheduled-tasks`);
await hw.http.post(`/applications/${uuid}/scheduled-tasks`, { name: 'cleanup', command: 'npm run cleanup', frequency: '0 3 * * *' });
Polut ovat suhteessa osoitteeseen /api/v1. Kaikki päätepisteet löydät API-viitteestä.
Versiot#
| Tiedosto | Käyttö |
|---|---|
https://app.hostwolf.net/dl/hostwolf-apps-sdk- | Kiinteä versio. Käytä tätä package.json-tiedostossa. |
https://app.hostwolf.net/dl/hostwolf-apps-sdk.tgz | Aina uusin versio. Paketinhallinnat välimuistittavat URL-osoitteen mukaan, joten suosi versioituja osoitteita. |
https://app.hostwolf.net/dl/index.json | Nykyiset versiot SHA-256- ja npm-eheystarkisteineen. |
Päivitä asentamalla uudempi versioitu URL.
Lisenssi#
MIT