ipfsd-ctl
Version:
Spawn IPFS Daemons, Kubo or...
162 lines (128 loc) • 4.74 kB
text/typescript
import { logger } from '@libp2p/logger'
import type { KuboNode, KuboInfo, KuboInitOptions, KuboOptions, KuboStartOptions, KuboStopOptions } from './index.js'
import type { PeerInfo } from '@libp2p/interface'
import type { KuboRPCClient } from 'kubo-rpc-client'
const log = logger('ipfsd-ctl:kubo:client')
export interface KuboClientInit extends KuboOptions {
endpoint: string
id: string
disposable: boolean
repo: string
}
/**
* Node for remote nodes
*/
export default class KuboClient implements KuboNode {
public options: KuboOptions & Required<Pick<KuboOptions, 'rpc'>>
public peerInfo?: PeerInfo
public id: string
public disposable: boolean
public repo: string
private readonly endpoint: string
private _api?: KuboRPCClient
private readonly initArgs?: KuboInitOptions
private readonly startArgs?: KuboStartOptions
private readonly stopArgs?: KuboStopOptions
constructor (options: KuboClientInit) {
if (options.rpc == null) {
throw new Error('Please pass an rpc option')
}
// @ts-expect-error cannot detect rpc is present
this.options = options
this.endpoint = options.endpoint
this.disposable = options.disposable
this.id = options.id
this.repo = options.repo
if (options.init != null && typeof options.init !== 'boolean') {
this.initArgs = options.init
}
if (options.start != null && typeof options.start !== 'boolean') {
this.startArgs = options.start
}
if (options.stop != null) {
this.stopArgs = options.stop
}
}
get api (): KuboRPCClient {
if (this._api == null) {
throw new Error('Not started')
}
return this._api
}
async info (): Promise<KuboInfo> {
log('info %s/info?%s', this.endpoint, new URLSearchParams({ id: this.id }).toString())
const response = await fetch(`${this.endpoint}/info?${new URLSearchParams({ id: this.id })}`, {
method: 'GET'
})
log('info %s/info?%s %d', this.endpoint, new URLSearchParams({ id: this.id }).toString(), response.status)
if (!response.ok) {
throw new Error(`Error getting remote kubo info - ${await response.text()}`)
}
return response.json()
}
async init (args?: KuboInitOptions): Promise<void> {
log('init %s/init?%s', this.endpoint, new URLSearchParams({ id: this.id }).toString())
const response = await fetch(`${this.endpoint}/init?${new URLSearchParams({ id: this.id })}`, {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
...(this.initArgs ?? {}),
...(args ?? {})
})
})
log('init %s/init?%s %d', this.endpoint, new URLSearchParams({ id: this.id }).toString(), response.status)
if (!response.ok) {
throw new Error(`Error initializing remote kubo - ${await response.text()}`)
}
}
async start (args?: KuboStartOptions): Promise<void> {
log('start %s/start?%s', this.endpoint, new URLSearchParams({ id: this.id }).toString())
const response = await fetch(`${this.endpoint}/start?${new URLSearchParams({ id: this.id })}`, {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
...(this.startArgs ?? {}),
...(args ?? {})
})
})
if (!response.ok) {
throw new Error(`Error starting remote kubo - ${await response.text()}`)
}
const info = await response.json()
this._api = this.options.rpc(info.api)
}
async stop (args?: KuboStopOptions): Promise<void> {
log('stop %s/stop?%s', this.endpoint, new URLSearchParams({ id: this.id }).toString())
const response = await fetch(`${this.endpoint}/stop?${new URLSearchParams({ id: this.id })}`, {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
...(this.stopArgs ?? {}),
...(args ?? {})
})
})
log('stop %s/stop?%s %d', this.endpoint, new URLSearchParams({ id: this.id }).toString(), response.status)
if (!response.ok) {
throw new Error(`Error stopping remote kubo - ${await response.text()}`)
}
if (this.disposable) {
await this.cleanup()
}
}
async cleanup (): Promise<void> {
log('cleanup %s/cleanup?%s', this.endpoint, new URLSearchParams({ id: this.id }).toString())
const response = await fetch(`${this.endpoint}/cleanup?${new URLSearchParams({ id: this.id })}`, {
method: 'POST'
})
log('cleanup %s/cleanup?%s %d', this.endpoint, new URLSearchParams({ id: this.id }).toString(), response.status)
if (!response.ok) {
throw new Error(`Error cleaning up remote kubo - ${await response.text()}`)
}
}
}