start adding cli
This commit is contained in:
parent
2d544e9bd3
commit
95d4348560
11
TODO.txt
11
TODO.txt
|
|
@ -18,9 +18,14 @@
|
||||||
|
|
||||||
## cli
|
## cli
|
||||||
|
|
||||||
[ ] `toes --help`
|
[x] `toes --help`
|
||||||
[ ] `toes --version`
|
[x] `toes --version`
|
||||||
[ ] `toes list`
|
[x] `toes list`
|
||||||
|
[x] `toes start <app>`
|
||||||
|
[x] `toes stop <app>`
|
||||||
|
[x] `toes restart <app>`
|
||||||
|
[ ] `toes open <app>`
|
||||||
|
[ ] `toes logs <app>`
|
||||||
[ ] `toes new`
|
[ ] `toes new`
|
||||||
[ ] `toes pull`
|
[ ] `toes pull`
|
||||||
[ ] `toes push`
|
[ ] `toes push`
|
||||||
|
|
|
||||||
3
bun.lock
3
bun.lock
|
|
@ -5,6 +5,7 @@
|
||||||
"": {
|
"": {
|
||||||
"name": "toes",
|
"name": "toes",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"commander": "^14.0.2",
|
||||||
"forge": "git+https://git.nose.space/defunkt/forge",
|
"forge": "git+https://git.nose.space/defunkt/forge",
|
||||||
"hype": "git+https://git.nose.space/defunkt/hype",
|
"hype": "git+https://git.nose.space/defunkt/hype",
|
||||||
},
|
},
|
||||||
|
|
@ -23,6 +24,8 @@
|
||||||
|
|
||||||
"bun-types": ["bun-types@1.3.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-qyschsA03Qz+gou+apt6HNl6HnI+sJJLL4wLDke4iugsE6584CMupOtTY1n+2YC9nGVrEKUlTs99jjRLKgWnjQ=="],
|
"bun-types": ["bun-types@1.3.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-qyschsA03Qz+gou+apt6HNl6HnI+sJJLL4wLDke4iugsE6584CMupOtTY1n+2YC9nGVrEKUlTs99jjRLKgWnjQ=="],
|
||||||
|
|
||||||
|
"commander": ["commander@14.0.2", "", {}, "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ=="],
|
||||||
|
|
||||||
"forge": ["forge@git+https://git.nose.space/defunkt/forge#debfd73ab22c50f66ccc93cb41164c234f78a920", { "peerDependencies": { "typescript": "^5" } }, "debfd73ab22c50f66ccc93cb41164c234f78a920"],
|
"forge": ["forge@git+https://git.nose.space/defunkt/forge#debfd73ab22c50f66ccc93cb41164c234f78a920", { "peerDependencies": { "typescript": "^5" } }, "debfd73ab22c50f66ccc93cb41164c234f78a920"],
|
||||||
|
|
||||||
"hono": ["hono@4.11.7", "", {}, "sha512-l7qMiNee7t82bH3SeyUCt9UF15EVmaBvsppY2zQtrbIhl/yzBTny+YUxsVjSjQ6gaqaeVtZmGocom8TzBlA4Yw=="],
|
"hono": ["hono@4.11.7", "", {}, "sha512-l7qMiNee7t82bH3SeyUCt9UF15EVmaBvsppY2zQtrbIhl/yzBTny+YUxsVjSjQ6gaqaeVtZmGocom8TzBlA4Yw=="],
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,8 @@
|
||||||
"typescript": "^5.9.2"
|
"typescript": "^5.9.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"hype": "git+https://git.nose.space/defunkt/hype",
|
"commander": "^14.0.2",
|
||||||
"forge": "git+https://git.nose.space/defunkt/forge"
|
"forge": "git+https://git.nose.space/defunkt/forge",
|
||||||
|
"hype": "git+https://git.nose.space/defunkt/hype"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
105
src/cli/index.ts
Normal file
105
src/cli/index.ts
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
import { program } from 'commander'
|
||||||
|
import { join } from 'path'
|
||||||
|
import type { App } from '@types'
|
||||||
|
import { APPS_DIR } from '$apps'
|
||||||
|
|
||||||
|
const HOST = `http://localhost:${process.env.PORT ?? 3000}`
|
||||||
|
|
||||||
|
const STATE_ICONS: Record<string, string> = {
|
||||||
|
running: '●',
|
||||||
|
starting: '◎',
|
||||||
|
stopped: '◯',
|
||||||
|
invalid: '◌',
|
||||||
|
}
|
||||||
|
|
||||||
|
async function get<T>(url: string): Promise<T | undefined> {
|
||||||
|
try {
|
||||||
|
const res = await fetch(join(HOST, url))
|
||||||
|
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`)
|
||||||
|
return await res.json()
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function post<T, B = unknown>(url: string, body?: B): Promise<T | undefined> {
|
||||||
|
try {
|
||||||
|
const res = await fetch(join(HOST, url), {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
})
|
||||||
|
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`)
|
||||||
|
return await res.json()
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function listApps() {
|
||||||
|
const apps: App[] | undefined = await get('/api/apps')
|
||||||
|
if (!apps) return
|
||||||
|
|
||||||
|
for (const app of apps) {
|
||||||
|
console.log(`${STATE_ICONS[app.state] ?? '◯'} ${app.name}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const startApp = async (app: string) => {
|
||||||
|
await post(`/api/apps/${app}/start`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const stopApp = async (app: string) => {
|
||||||
|
await post(`/api/apps/${app}/stop`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const restartApp = async (app: string) => {
|
||||||
|
await post(`/api/apps/${app}/restart`)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
program
|
||||||
|
.name('toes')
|
||||||
|
.version('0.0.1', '-v, --version')
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('list')
|
||||||
|
.description('List all apps')
|
||||||
|
.action(listApps)
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('start')
|
||||||
|
.description('Start an app')
|
||||||
|
.argument('<name>', 'app name')
|
||||||
|
.action(startApp)
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('stop')
|
||||||
|
.description('Stop an app')
|
||||||
|
.argument('<name>', 'app name')
|
||||||
|
.action(stopApp)
|
||||||
|
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('restart')
|
||||||
|
.description('Restart an app')
|
||||||
|
.argument('<name>', 'app name')
|
||||||
|
.action(restartApp)
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('new')
|
||||||
|
.description('Create a new app')
|
||||||
|
.argument('<name>', 'app name')
|
||||||
|
.action(name => {
|
||||||
|
// ...
|
||||||
|
})
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('push')
|
||||||
|
.description('Push app to server')
|
||||||
|
.option('-f, --force', 'force overwrite')
|
||||||
|
.action(options => {
|
||||||
|
// ...
|
||||||
|
})
|
||||||
|
|
||||||
|
program.parse()
|
||||||
Loading…
Reference in New Issue
Block a user