@synteq/cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (500) hide show
  1. package/bin/run.js +10 -0
  2. package/dist/api/client.d.ts +167 -0
  3. package/dist/api/client.js +367 -0
  4. package/dist/api/client.js.map +1 -0
  5. package/dist/api/errors.d.ts +16 -0
  6. package/dist/api/errors.js +76 -0
  7. package/dist/api/errors.js.map +1 -0
  8. package/dist/api/factory.d.ts +12 -0
  9. package/dist/api/factory.js +18 -0
  10. package/dist/api/factory.js.map +1 -0
  11. package/dist/api/types.d.ts +738 -0
  12. package/dist/api/types.js +2 -0
  13. package/dist/api/types.js.map +1 -0
  14. package/dist/auth/device-flow.d.ts +8 -0
  15. package/dist/auth/device-flow.js +36 -0
  16. package/dist/auth/device-flow.js.map +1 -0
  17. package/dist/auth/keychain.d.ts +3 -0
  18. package/dist/auth/keychain.js +34 -0
  19. package/dist/auth/keychain.js.map +1 -0
  20. package/dist/auth/logout.d.ts +4 -0
  21. package/dist/auth/logout.js +17 -0
  22. package/dist/auth/logout.js.map +1 -0
  23. package/dist/auth/tokens.d.ts +19 -0
  24. package/dist/auth/tokens.js +56 -0
  25. package/dist/auth/tokens.js.map +1 -0
  26. package/dist/base/command.d.ts +17 -0
  27. package/dist/base/command.js +89 -0
  28. package/dist/base/command.js.map +1 -0
  29. package/dist/commands/account/index.d.ts +5 -0
  30. package/dist/commands/account/index.js +9 -0
  31. package/dist/commands/account/index.js.map +1 -0
  32. package/dist/commands/account/show.d.ts +9 -0
  33. package/dist/commands/account/show.js +75 -0
  34. package/dist/commands/account/show.js.map +1 -0
  35. package/dist/commands/api.d.ts +17 -0
  36. package/dist/commands/api.js +144 -0
  37. package/dist/commands/api.js.map +1 -0
  38. package/dist/commands/bare-metal/index.d.ts +4 -0
  39. package/dist/commands/bare-metal/index.js +5 -0
  40. package/dist/commands/bare-metal/index.js.map +1 -0
  41. package/dist/commands/bare-metal/list.d.ts +9 -0
  42. package/dist/commands/bare-metal/list.js +38 -0
  43. package/dist/commands/bare-metal/list.js.map +1 -0
  44. package/dist/commands/bare-metal/order.d.ts +6 -0
  45. package/dist/commands/bare-metal/order.js +27 -0
  46. package/dist/commands/bare-metal/order.js.map +1 -0
  47. package/dist/commands/catalog.d.ts +11 -0
  48. package/dist/commands/catalog.js +115 -0
  49. package/dist/commands/catalog.js.map +1 -0
  50. package/dist/commands/config/index.d.ts +5 -0
  51. package/dist/commands/config/index.js +9 -0
  52. package/dist/commands/config/index.js.map +1 -0
  53. package/dist/commands/config/set-api-url.d.ts +10 -0
  54. package/dist/commands/config/set-api-url.js +43 -0
  55. package/dist/commands/config/set-api-url.js.map +1 -0
  56. package/dist/commands/config/show.d.ts +9 -0
  57. package/dist/commands/config/show.js +75 -0
  58. package/dist/commands/config/show.js.map +1 -0
  59. package/dist/commands/credits/add.d.ts +14 -0
  60. package/dist/commands/credits/add.js +117 -0
  61. package/dist/commands/credits/add.js.map +1 -0
  62. package/dist/commands/credits/index.d.ts +5 -0
  63. package/dist/commands/credits/index.js +9 -0
  64. package/dist/commands/credits/index.js.map +1 -0
  65. package/dist/commands/credits/list.d.ts +6 -0
  66. package/dist/commands/credits/list.js +43 -0
  67. package/dist/commands/credits/list.js.map +1 -0
  68. package/dist/commands/gpu/activity.d.ts +15 -0
  69. package/dist/commands/gpu/activity.js +8 -0
  70. package/dist/commands/gpu/activity.js.map +1 -0
  71. package/dist/commands/gpu/bandwidth.d.ts +14 -0
  72. package/dist/commands/gpu/bandwidth.js +8 -0
  73. package/dist/commands/gpu/bandwidth.js.map +1 -0
  74. package/dist/commands/gpu/boot-order.d.ts +15 -0
  75. package/dist/commands/gpu/boot-order.js +8 -0
  76. package/dist/commands/gpu/boot-order.js.map +1 -0
  77. package/dist/commands/gpu/console.d.ts +14 -0
  78. package/dist/commands/gpu/console.js +8 -0
  79. package/dist/commands/gpu/console.js.map +1 -0
  80. package/dist/commands/gpu/details.d.ts +15 -0
  81. package/dist/commands/gpu/details.js +8 -0
  82. package/dist/commands/gpu/details.js.map +1 -0
  83. package/dist/commands/gpu/index.d.ts +4 -0
  84. package/dist/commands/gpu/index.js +5 -0
  85. package/dist/commands/gpu/index.js.map +1 -0
  86. package/dist/commands/gpu/ip/add.d.ts +18 -0
  87. package/dist/commands/gpu/ip/add.js +8 -0
  88. package/dist/commands/gpu/ip/add.js.map +1 -0
  89. package/dist/commands/gpu/ip/list.d.ts +14 -0
  90. package/dist/commands/gpu/ip/list.js +8 -0
  91. package/dist/commands/gpu/ip/list.js.map +1 -0
  92. package/dist/commands/gpu/list.d.ts +6 -0
  93. package/dist/commands/gpu/list.js +13 -0
  94. package/dist/commands/gpu/list.js.map +1 -0
  95. package/dist/commands/gpu/order.d.ts +6 -0
  96. package/dist/commands/gpu/order.js +13 -0
  97. package/dist/commands/gpu/order.js.map +1 -0
  98. package/dist/commands/gpu/power.d.ts +17 -0
  99. package/dist/commands/gpu/power.js +8 -0
  100. package/dist/commands/gpu/power.js.map +1 -0
  101. package/dist/commands/gpu/reinstall.d.ts +22 -0
  102. package/dist/commands/gpu/reinstall.js +8 -0
  103. package/dist/commands/gpu/reinstall.js.map +1 -0
  104. package/dist/commands/gpu/resize.d.ts +22 -0
  105. package/dist/commands/gpu/resize.js +8 -0
  106. package/dist/commands/gpu/resize.js.map +1 -0
  107. package/dist/commands/gpu/stats.d.ts +14 -0
  108. package/dist/commands/gpu/stats.js +8 -0
  109. package/dist/commands/gpu/stats.js.map +1 -0
  110. package/dist/commands/help.d.ts +9 -0
  111. package/dist/commands/help.js +19 -0
  112. package/dist/commands/help.js.map +1 -0
  113. package/dist/commands/instant-metal/activity.d.ts +15 -0
  114. package/dist/commands/instant-metal/activity.js +8 -0
  115. package/dist/commands/instant-metal/activity.js.map +1 -0
  116. package/dist/commands/instant-metal/bandwidth.d.ts +14 -0
  117. package/dist/commands/instant-metal/bandwidth.js +8 -0
  118. package/dist/commands/instant-metal/bandwidth.js.map +1 -0
  119. package/dist/commands/instant-metal/boot-order.d.ts +15 -0
  120. package/dist/commands/instant-metal/boot-order.js +8 -0
  121. package/dist/commands/instant-metal/boot-order.js.map +1 -0
  122. package/dist/commands/instant-metal/console.d.ts +14 -0
  123. package/dist/commands/instant-metal/console.js +8 -0
  124. package/dist/commands/instant-metal/console.js.map +1 -0
  125. package/dist/commands/instant-metal/details.d.ts +15 -0
  126. package/dist/commands/instant-metal/details.js +8 -0
  127. package/dist/commands/instant-metal/details.js.map +1 -0
  128. package/dist/commands/instant-metal/index.d.ts +4 -0
  129. package/dist/commands/instant-metal/index.js +5 -0
  130. package/dist/commands/instant-metal/index.js.map +1 -0
  131. package/dist/commands/instant-metal/ip/add.d.ts +18 -0
  132. package/dist/commands/instant-metal/ip/add.js +8 -0
  133. package/dist/commands/instant-metal/ip/add.js.map +1 -0
  134. package/dist/commands/instant-metal/ip/list.d.ts +14 -0
  135. package/dist/commands/instant-metal/ip/list.js +8 -0
  136. package/dist/commands/instant-metal/ip/list.js.map +1 -0
  137. package/dist/commands/instant-metal/list.d.ts +6 -0
  138. package/dist/commands/instant-metal/list.js +13 -0
  139. package/dist/commands/instant-metal/list.js.map +1 -0
  140. package/dist/commands/instant-metal/order.d.ts +6 -0
  141. package/dist/commands/instant-metal/order.js +13 -0
  142. package/dist/commands/instant-metal/order.js.map +1 -0
  143. package/dist/commands/instant-metal/power.d.ts +17 -0
  144. package/dist/commands/instant-metal/power.js +8 -0
  145. package/dist/commands/instant-metal/power.js.map +1 -0
  146. package/dist/commands/instant-metal/reinstall.d.ts +22 -0
  147. package/dist/commands/instant-metal/reinstall.js +8 -0
  148. package/dist/commands/instant-metal/reinstall.js.map +1 -0
  149. package/dist/commands/instant-metal/resize.d.ts +22 -0
  150. package/dist/commands/instant-metal/resize.js +8 -0
  151. package/dist/commands/instant-metal/resize.js.map +1 -0
  152. package/dist/commands/instant-metal/stats.d.ts +14 -0
  153. package/dist/commands/instant-metal/stats.js +8 -0
  154. package/dist/commands/instant-metal/stats.js.map +1 -0
  155. package/dist/commands/login.d.ts +10 -0
  156. package/dist/commands/login.js +98 -0
  157. package/dist/commands/login.js.map +1 -0
  158. package/dist/commands/logout.d.ts +6 -0
  159. package/dist/commands/logout.js +20 -0
  160. package/dist/commands/logout.js.map +1 -0
  161. package/dist/commands/order/gpu.d.ts +6 -0
  162. package/dist/commands/order/gpu.js +13 -0
  163. package/dist/commands/order/gpu.js.map +1 -0
  164. package/dist/commands/order/instant-metal.d.ts +7 -0
  165. package/dist/commands/order/instant-metal.js +14 -0
  166. package/dist/commands/order/instant-metal.js.map +1 -0
  167. package/dist/commands/order/storage.d.ts +6 -0
  168. package/dist/commands/order/storage.js +11 -0
  169. package/dist/commands/order/storage.js.map +1 -0
  170. package/dist/commands/order/vps.d.ts +7 -0
  171. package/dist/commands/order/vps.js +14 -0
  172. package/dist/commands/order/vps.js.map +1 -0
  173. package/dist/commands/order.d.ts +6 -0
  174. package/dist/commands/order.js +46 -0
  175. package/dist/commands/order.js.map +1 -0
  176. package/dist/commands/payments/index.d.ts +5 -0
  177. package/dist/commands/payments/index.js +10 -0
  178. package/dist/commands/payments/index.js.map +1 -0
  179. package/dist/commands/payments/methods/add.d.ts +9 -0
  180. package/dist/commands/payments/methods/add.js +30 -0
  181. package/dist/commands/payments/methods/add.js.map +1 -0
  182. package/dist/commands/payments/methods/delete.d.ts +12 -0
  183. package/dist/commands/payments/methods/delete.js +58 -0
  184. package/dist/commands/payments/methods/delete.js.map +1 -0
  185. package/dist/commands/payments/methods/index.d.ts +5 -0
  186. package/dist/commands/payments/methods/index.js +9 -0
  187. package/dist/commands/payments/methods/index.js.map +1 -0
  188. package/dist/commands/payments/methods/list.d.ts +6 -0
  189. package/dist/commands/payments/methods/list.js +33 -0
  190. package/dist/commands/payments/methods/list.js.map +1 -0
  191. package/dist/commands/payments/methods/set-default.d.ts +9 -0
  192. package/dist/commands/payments/methods/set-default.js +31 -0
  193. package/dist/commands/payments/methods/set-default.js.map +1 -0
  194. package/dist/commands/projects/index.d.ts +5 -0
  195. package/dist/commands/projects/index.js +9 -0
  196. package/dist/commands/projects/index.js.map +1 -0
  197. package/dist/commands/projects/list.d.ts +6 -0
  198. package/dist/commands/projects/list.js +31 -0
  199. package/dist/commands/projects/list.js.map +1 -0
  200. package/dist/commands/resources.d.ts +11 -0
  201. package/dist/commands/resources.js +93 -0
  202. package/dist/commands/resources.js.map +1 -0
  203. package/dist/commands/settings/index.d.ts +6 -0
  204. package/dist/commands/settings/index.js +57 -0
  205. package/dist/commands/settings/index.js.map +1 -0
  206. package/dist/commands/settings/render-mode.d.ts +10 -0
  207. package/dist/commands/settings/render-mode.js +76 -0
  208. package/dist/commands/settings/render-mode.js.map +1 -0
  209. package/dist/commands/ssh-key/add.d.ts +11 -0
  210. package/dist/commands/ssh-key/add.js +89 -0
  211. package/dist/commands/ssh-key/add.js.map +1 -0
  212. package/dist/commands/ssh-key/delete.d.ts +12 -0
  213. package/dist/commands/ssh-key/delete.js +43 -0
  214. package/dist/commands/ssh-key/delete.js.map +1 -0
  215. package/dist/commands/ssh-key/list.d.ts +7 -0
  216. package/dist/commands/ssh-key/list.js +47 -0
  217. package/dist/commands/ssh-key/list.js.map +1 -0
  218. package/dist/commands/storage/attach.d.ts +12 -0
  219. package/dist/commands/storage/attach.js +48 -0
  220. package/dist/commands/storage/attach.js.map +1 -0
  221. package/dist/commands/storage/detach.d.ts +12 -0
  222. package/dist/commands/storage/detach.js +60 -0
  223. package/dist/commands/storage/detach.js.map +1 -0
  224. package/dist/commands/storage/list.d.ts +9 -0
  225. package/dist/commands/storage/list.js +41 -0
  226. package/dist/commands/storage/list.js.map +1 -0
  227. package/dist/commands/storage/order.d.ts +16 -0
  228. package/dist/commands/storage/order.js +223 -0
  229. package/dist/commands/storage/order.js.map +1 -0
  230. package/dist/commands/storage/resize.d.ts +16 -0
  231. package/dist/commands/storage/resize.js +129 -0
  232. package/dist/commands/storage/resize.js.map +1 -0
  233. package/dist/commands/team/details.d.ts +9 -0
  234. package/dist/commands/team/details.js +48 -0
  235. package/dist/commands/team/details.js.map +1 -0
  236. package/dist/commands/team/invite.d.ts +14 -0
  237. package/dist/commands/team/invite.js +65 -0
  238. package/dist/commands/team/invite.js.map +1 -0
  239. package/dist/commands/team.d.ts +15 -0
  240. package/dist/commands/team.js +123 -0
  241. package/dist/commands/team.js.map +1 -0
  242. package/dist/commands/tickets/close.d.ts +13 -0
  243. package/dist/commands/tickets/close.js +39 -0
  244. package/dist/commands/tickets/close.js.map +1 -0
  245. package/dist/commands/tickets/create.d.ts +16 -0
  246. package/dist/commands/tickets/create.js +111 -0
  247. package/dist/commands/tickets/create.js.map +1 -0
  248. package/dist/commands/tickets/departments.d.ts +7 -0
  249. package/dist/commands/tickets/departments.js +27 -0
  250. package/dist/commands/tickets/departments.js.map +1 -0
  251. package/dist/commands/tickets/list.d.ts +10 -0
  252. package/dist/commands/tickets/list.js +66 -0
  253. package/dist/commands/tickets/list.js.map +1 -0
  254. package/dist/commands/tickets/open.d.ts +10 -0
  255. package/dist/commands/tickets/open.js +70 -0
  256. package/dist/commands/tickets/open.js.map +1 -0
  257. package/dist/commands/tickets/reply.d.ts +13 -0
  258. package/dist/commands/tickets/reply.js +48 -0
  259. package/dist/commands/tickets/reply.js.map +1 -0
  260. package/dist/commands/transit.d.ts +9 -0
  261. package/dist/commands/transit.js +47 -0
  262. package/dist/commands/transit.js.map +1 -0
  263. package/dist/commands/tui/index.d.ts +7 -0
  264. package/dist/commands/tui/index.js +87 -0
  265. package/dist/commands/tui/index.js.map +1 -0
  266. package/dist/commands/vds/activity.d.ts +15 -0
  267. package/dist/commands/vds/activity.js +8 -0
  268. package/dist/commands/vds/activity.js.map +1 -0
  269. package/dist/commands/vds/bandwidth.d.ts +14 -0
  270. package/dist/commands/vds/bandwidth.js +8 -0
  271. package/dist/commands/vds/bandwidth.js.map +1 -0
  272. package/dist/commands/vds/boot-order.d.ts +15 -0
  273. package/dist/commands/vds/boot-order.js +8 -0
  274. package/dist/commands/vds/boot-order.js.map +1 -0
  275. package/dist/commands/vds/console.d.ts +14 -0
  276. package/dist/commands/vds/console.js +8 -0
  277. package/dist/commands/vds/console.js.map +1 -0
  278. package/dist/commands/vds/details.d.ts +15 -0
  279. package/dist/commands/vds/details.js +8 -0
  280. package/dist/commands/vds/details.js.map +1 -0
  281. package/dist/commands/vds/index.d.ts +4 -0
  282. package/dist/commands/vds/index.js +5 -0
  283. package/dist/commands/vds/index.js.map +1 -0
  284. package/dist/commands/vds/ip/add.d.ts +18 -0
  285. package/dist/commands/vds/ip/add.js +8 -0
  286. package/dist/commands/vds/ip/add.js.map +1 -0
  287. package/dist/commands/vds/ip/list.d.ts +14 -0
  288. package/dist/commands/vds/ip/list.js +8 -0
  289. package/dist/commands/vds/ip/list.js.map +1 -0
  290. package/dist/commands/vds/list.d.ts +6 -0
  291. package/dist/commands/vds/list.js +13 -0
  292. package/dist/commands/vds/list.js.map +1 -0
  293. package/dist/commands/vds/order.d.ts +6 -0
  294. package/dist/commands/vds/order.js +13 -0
  295. package/dist/commands/vds/order.js.map +1 -0
  296. package/dist/commands/vds/power.d.ts +17 -0
  297. package/dist/commands/vds/power.js +8 -0
  298. package/dist/commands/vds/power.js.map +1 -0
  299. package/dist/commands/vds/reinstall.d.ts +22 -0
  300. package/dist/commands/vds/reinstall.js +8 -0
  301. package/dist/commands/vds/reinstall.js.map +1 -0
  302. package/dist/commands/vds/resize.d.ts +22 -0
  303. package/dist/commands/vds/resize.js +8 -0
  304. package/dist/commands/vds/resize.js.map +1 -0
  305. package/dist/commands/vds/stats.d.ts +14 -0
  306. package/dist/commands/vds/stats.js +8 -0
  307. package/dist/commands/vds/stats.js.map +1 -0
  308. package/dist/commands/vps/activity.d.ts +13 -0
  309. package/dist/commands/vps/activity.js +50 -0
  310. package/dist/commands/vps/activity.js.map +1 -0
  311. package/dist/commands/vps/bandwidth.d.ts +9 -0
  312. package/dist/commands/vps/bandwidth.js +91 -0
  313. package/dist/commands/vps/bandwidth.js.map +1 -0
  314. package/dist/commands/vps/boot-order.d.ts +10 -0
  315. package/dist/commands/vps/boot-order.js +51 -0
  316. package/dist/commands/vps/boot-order.js.map +1 -0
  317. package/dist/commands/vps/console.d.ts +15 -0
  318. package/dist/commands/vps/console.js +198 -0
  319. package/dist/commands/vps/console.js.map +1 -0
  320. package/dist/commands/vps/details.d.ts +15 -0
  321. package/dist/commands/vps/details.js +78 -0
  322. package/dist/commands/vps/details.js.map +1 -0
  323. package/dist/commands/vps/ip/add.d.ts +17 -0
  324. package/dist/commands/vps/ip/add.js +212 -0
  325. package/dist/commands/vps/ip/add.js.map +1 -0
  326. package/dist/commands/vps/ip/list.d.ts +9 -0
  327. package/dist/commands/vps/ip/list.js +102 -0
  328. package/dist/commands/vps/ip/list.js.map +1 -0
  329. package/dist/commands/vps/list.d.ts +12 -0
  330. package/dist/commands/vps/list.js +55 -0
  331. package/dist/commands/vps/list.js.map +1 -0
  332. package/dist/commands/vps/order.d.ts +30 -0
  333. package/dist/commands/vps/order.js +497 -0
  334. package/dist/commands/vps/order.js.map +1 -0
  335. package/dist/commands/vps/power.d.ts +15 -0
  336. package/dist/commands/vps/power.js +123 -0
  337. package/dist/commands/vps/power.js.map +1 -0
  338. package/dist/commands/vps/reinstall.d.ts +20 -0
  339. package/dist/commands/vps/reinstall.js +166 -0
  340. package/dist/commands/vps/reinstall.js.map +1 -0
  341. package/dist/commands/vps/resize.d.ts +22 -0
  342. package/dist/commands/vps/resize.js +205 -0
  343. package/dist/commands/vps/resize.js.map +1 -0
  344. package/dist/commands/vps/stats.d.ts +12 -0
  345. package/dist/commands/vps/stats.js +83 -0
  346. package/dist/commands/vps/stats.js.map +1 -0
  347. package/dist/commands/whoami.d.ts +9 -0
  348. package/dist/commands/whoami.js +70 -0
  349. package/dist/commands/whoami.js.map +1 -0
  350. package/dist/config/paths.d.ts +3 -0
  351. package/dist/config/paths.js +17 -0
  352. package/dist/config/paths.js.map +1 -0
  353. package/dist/config/store.d.ts +15 -0
  354. package/dist/config/store.js +38 -0
  355. package/dist/config/store.js.map +1 -0
  356. package/dist/help.d.ts +9 -0
  357. package/dist/help.js +119 -0
  358. package/dist/help.js.map +1 -0
  359. package/dist/tui/App.d.ts +9 -0
  360. package/dist/tui/App.js +93 -0
  361. package/dist/tui/App.js.map +1 -0
  362. package/dist/tui/components/ActionButton.d.ts +9 -0
  363. package/dist/tui/components/ActionButton.js +52 -0
  364. package/dist/tui/components/ActionButton.js.map +1 -0
  365. package/dist/tui/components/AppHeader.d.ts +6 -0
  366. package/dist/tui/components/AppHeader.js +18 -0
  367. package/dist/tui/components/AppHeader.js.map +1 -0
  368. package/dist/tui/components/BackButton.d.ts +6 -0
  369. package/dist/tui/components/BackButton.js +15 -0
  370. package/dist/tui/components/BackButton.js.map +1 -0
  371. package/dist/tui/components/CenteredFrame.d.ts +8 -0
  372. package/dist/tui/components/CenteredFrame.js +14 -0
  373. package/dist/tui/components/CenteredFrame.js.map +1 -0
  374. package/dist/tui/components/Clickable.d.ts +9 -0
  375. package/dist/tui/components/Clickable.js +48 -0
  376. package/dist/tui/components/Clickable.js.map +1 -0
  377. package/dist/tui/components/ConfirmModal.d.ts +8 -0
  378. package/dist/tui/components/ConfirmModal.js +22 -0
  379. package/dist/tui/components/ConfirmModal.js.map +1 -0
  380. package/dist/tui/components/DataTable.d.ts +14 -0
  381. package/dist/tui/components/DataTable.js +26 -0
  382. package/dist/tui/components/DataTable.js.map +1 -0
  383. package/dist/tui/components/InputBar.d.ts +9 -0
  384. package/dist/tui/components/InputBar.js +10 -0
  385. package/dist/tui/components/InputBar.js.map +1 -0
  386. package/dist/tui/components/Menu.d.ts +16 -0
  387. package/dist/tui/components/Menu.js +78 -0
  388. package/dist/tui/components/Menu.js.map +1 -0
  389. package/dist/tui/components/NumberInput.d.ts +13 -0
  390. package/dist/tui/components/NumberInput.js +55 -0
  391. package/dist/tui/components/NumberInput.js.map +1 -0
  392. package/dist/tui/components/Panel.d.ts +13 -0
  393. package/dist/tui/components/Panel.js +11 -0
  394. package/dist/tui/components/Panel.js.map +1 -0
  395. package/dist/tui/components/Sparkline.d.ts +11 -0
  396. package/dist/tui/components/Sparkline.js +40 -0
  397. package/dist/tui/components/Sparkline.js.map +1 -0
  398. package/dist/tui/components/Spinner.d.ts +4 -0
  399. package/dist/tui/components/Spinner.js +11 -0
  400. package/dist/tui/components/Spinner.js.map +1 -0
  401. package/dist/tui/components/StatusBar.d.ts +6 -0
  402. package/dist/tui/components/StatusBar.js +9 -0
  403. package/dist/tui/components/StatusBar.js.map +1 -0
  404. package/dist/tui/components/Tip.d.ts +4 -0
  405. package/dist/tui/components/Tip.js +11 -0
  406. package/dist/tui/components/Tip.js.map +1 -0
  407. package/dist/tui/hooks/useApi.d.ts +12 -0
  408. package/dist/tui/hooks/useApi.js +15 -0
  409. package/dist/tui/hooks/useApi.js.map +1 -0
  410. package/dist/tui/hooks/useHeader.d.ts +18 -0
  411. package/dist/tui/hooks/useHeader.js +65 -0
  412. package/dist/tui/hooks/useHeader.js.map +1 -0
  413. package/dist/tui/hooks/useMouse.d.ts +27 -0
  414. package/dist/tui/hooks/useMouse.js +174 -0
  415. package/dist/tui/hooks/useMouse.js.map +1 -0
  416. package/dist/tui/hooks/useStdinCapture.d.ts +1 -0
  417. package/dist/tui/hooks/useStdinCapture.js +37 -0
  418. package/dist/tui/hooks/useStdinCapture.js.map +1 -0
  419. package/dist/tui/index.d.ts +12 -0
  420. package/dist/tui/index.js +19 -0
  421. package/dist/tui/index.js.map +1 -0
  422. package/dist/tui/router.d.ts +10 -0
  423. package/dist/tui/router.js +9 -0
  424. package/dist/tui/router.js.map +1 -0
  425. package/dist/tui/screens/Account.d.ts +2 -0
  426. package/dist/tui/screens/Account.js +212 -0
  427. package/dist/tui/screens/Account.js.map +1 -0
  428. package/dist/tui/screens/Billing.d.ts +2 -0
  429. package/dist/tui/screens/Billing.js +586 -0
  430. package/dist/tui/screens/Billing.js.map +1 -0
  431. package/dist/tui/screens/Dashboard.d.ts +2 -0
  432. package/dist/tui/screens/Dashboard.js +150 -0
  433. package/dist/tui/screens/Dashboard.js.map +1 -0
  434. package/dist/tui/screens/Order.d.ts +2 -0
  435. package/dist/tui/screens/Order.js +1169 -0
  436. package/dist/tui/screens/Order.js.map +1 -0
  437. package/dist/tui/screens/Resources.d.ts +2 -0
  438. package/dist/tui/screens/Resources.js +720 -0
  439. package/dist/tui/screens/Resources.js.map +1 -0
  440. package/dist/tui/screens/Tickets.d.ts +2 -0
  441. package/dist/tui/screens/Tickets.js +395 -0
  442. package/dist/tui/screens/Tickets.js.map +1 -0
  443. package/dist/tui/theme/colors.d.ts +12 -0
  444. package/dist/tui/theme/colors.js +29 -0
  445. package/dist/tui/theme/colors.js.map +1 -0
  446. package/dist/tui/theme/glyphs.d.ts +5 -0
  447. package/dist/tui/theme/glyphs.js +6 -0
  448. package/dist/tui/theme/glyphs.js.map +1 -0
  449. package/dist/ui/confirm.d.ts +7 -0
  450. package/dist/ui/confirm.js +18 -0
  451. package/dist/ui/confirm.js.map +1 -0
  452. package/dist/ui/glyphs.d.ts +18 -0
  453. package/dist/ui/glyphs.js +47 -0
  454. package/dist/ui/glyphs.js.map +1 -0
  455. package/dist/ui/payment.d.ts +33 -0
  456. package/dist/ui/payment.js +179 -0
  457. package/dist/ui/payment.js.map +1 -0
  458. package/dist/ui/pm-resolve.d.ts +3 -0
  459. package/dist/ui/pm-resolve.js +19 -0
  460. package/dist/ui/pm-resolve.js.map +1 -0
  461. package/dist/ui/portal.d.ts +1 -0
  462. package/dist/ui/portal.js +19 -0
  463. package/dist/ui/portal.js.map +1 -0
  464. package/dist/ui/render-mode.d.ts +10 -0
  465. package/dist/ui/render-mode.js +30 -0
  466. package/dist/ui/render-mode.js.map +1 -0
  467. package/dist/ui/sparkline.d.ts +6 -0
  468. package/dist/ui/sparkline.js +30 -0
  469. package/dist/ui/sparkline.js.map +1 -0
  470. package/dist/ui/spinner.d.ts +1 -0
  471. package/dist/ui/spinner.js +19 -0
  472. package/dist/ui/spinner.js.map +1 -0
  473. package/dist/ui/stats.d.ts +22 -0
  474. package/dist/ui/stats.js +71 -0
  475. package/dist/ui/stats.js.map +1 -0
  476. package/dist/ui/stdin.d.ts +1 -0
  477. package/dist/ui/stdin.js +8 -0
  478. package/dist/ui/stdin.js.map +1 -0
  479. package/dist/ui/table.d.ts +2 -0
  480. package/dist/ui/table.js +48 -0
  481. package/dist/ui/table.js.map +1 -0
  482. package/dist/ui/ticket-resolve.d.ts +2 -0
  483. package/dist/ui/ticket-resolve.js +17 -0
  484. package/dist/ui/ticket-resolve.js.map +1 -0
  485. package/dist/ui/volume-resolve.d.ts +3 -0
  486. package/dist/ui/volume-resolve.js +30 -0
  487. package/dist/ui/volume-resolve.js.map +1 -0
  488. package/dist/ui/vps-detail.d.ts +3 -0
  489. package/dist/ui/vps-detail.js +79 -0
  490. package/dist/ui/vps-detail.js.map +1 -0
  491. package/dist/ui/vps-resolve.d.ts +4 -0
  492. package/dist/ui/vps-resolve.js +24 -0
  493. package/dist/ui/vps-resolve.js.map +1 -0
  494. package/dist/ui/wait.d.ts +31 -0
  495. package/dist/ui/wait.js +66 -0
  496. package/dist/ui/wait.js.map +1 -0
  497. package/dist/ui/wizard.d.ts +33 -0
  498. package/dist/ui/wizard.js +168 -0
  499. package/dist/ui/wizard.js.map +1 -0
  500. package/package.json +142 -0
@@ -0,0 +1,720 @@
1
+ import React, { useEffect, useState, useCallback, useMemo } from "react";
2
+ import { Box, Text, useInput } from "ink";
3
+ import { Panel } from "../components/Panel.js";
4
+ import { Menu } from "../components/Menu.js";
5
+ import { StatusBar } from "../components/StatusBar.js";
6
+ import { Tip } from "../components/Tip.js";
7
+ import { Spinner } from "../components/Spinner.js";
8
+ import { InputBar } from "../components/InputBar.js";
9
+ import { useApi } from "../hooks/useApi.js";
10
+ import { useHeader } from "../hooks/useHeader.js";
11
+ import { useRouter } from "../router.js";
12
+ import { colors, statusColor } from "../theme/colors.js";
13
+ import { glyphs } from "../theme/glyphs.js";
14
+ import { CenteredFrame } from "../components/CenteredFrame.js";
15
+ import { BackButton } from "../components/BackButton.js";
16
+ import { Clickable } from "../components/Clickable.js";
17
+ import { Sparkline } from "../components/Sparkline.js";
18
+ import { ActionButton } from "../components/ActionButton.js";
19
+ import { ConfirmModal } from "../components/ConfirmModal.js";
20
+ const KIND_ITEMS = [
21
+ { value: "all", label: "All" },
22
+ { value: "cloud", label: "Cloud" },
23
+ { value: "gpu", label: "GPU Cloud" },
24
+ { value: "metal", label: "Metal" },
25
+ { value: "storage", label: "Storage" },
26
+ { value: "transit", label: "Transit" },
27
+ ];
28
+ const KIND_TITLE = {
29
+ all: "All Resources",
30
+ cloud: "Cloud",
31
+ gpu: "GPU Cloud",
32
+ metal: "Metal",
33
+ storage: "Storage",
34
+ transit: "Transit",
35
+ };
36
+ function toVpsRow(v) {
37
+ return {
38
+ kind: "vps",
39
+ id: v.id,
40
+ name: v.hostname,
41
+ status: v.status,
42
+ location: v.location?.city ?? v.location?.name ?? "",
43
+ ip: v.ip_addresses?.[0]?.address ?? "",
44
+ raw: v,
45
+ };
46
+ }
47
+ function toMetalRow(b) {
48
+ return {
49
+ kind: "metal",
50
+ id: b.id,
51
+ name: b.hostname ?? b.reference,
52
+ status: b.is_active ? "active" : "inactive",
53
+ location: b.location_city ?? b.location_name ?? "",
54
+ ip: b.primary_ipv4 ?? "",
55
+ raw: b,
56
+ };
57
+ }
58
+ function toStorageRow(s) {
59
+ return {
60
+ kind: "storage",
61
+ id: s.id,
62
+ name: s.name,
63
+ status: s.is_attached ? `attached:${s.status}` : s.status,
64
+ location: s.location_name ?? "",
65
+ ip: s.vps_hostname ?? "",
66
+ raw: s,
67
+ };
68
+ }
69
+ function toTransitRow(t) {
70
+ return {
71
+ kind: "transit",
72
+ id: t.id,
73
+ name: t.service_name,
74
+ status: "active",
75
+ location: "",
76
+ ip: "",
77
+ raw: t,
78
+ };
79
+ }
80
+ export function Resources() {
81
+ const api = useApi();
82
+ const { header } = useHeader();
83
+ const { goBack } = useRouter();
84
+ const [kind, setKind] = useState("all");
85
+ const [rows, setRows] = useState([]);
86
+ const [loading, setLoading] = useState(true);
87
+ const [error, setError] = useState(null);
88
+ const [filter, setFilter] = useState("");
89
+ const [filterMode, setFilterMode] = useState("off");
90
+ const [mode, setMode] = useState("list");
91
+ const [cursor, setCursor] = useState(0);
92
+ const [selected, setSelected] = useState(null);
93
+ const [pane, setPane] = useState("sidebar");
94
+ const load = useCallback(async (k) => {
95
+ setLoading(true);
96
+ setError(null);
97
+ try {
98
+ let next = [];
99
+ switch (k) {
100
+ case "all": {
101
+ const [vps, metal, storage, transit] = await Promise.all([
102
+ api.vps.list().catch(() => []),
103
+ api.baremetal.list().catch(() => []),
104
+ api.storage.list().catch(() => []),
105
+ api.transit.list().catch(() => []),
106
+ ]);
107
+ next = [
108
+ ...vps.map(toVpsRow),
109
+ ...metal.map(toMetalRow),
110
+ ...storage.map(toStorageRow),
111
+ ...transit.map(toTransitRow),
112
+ ];
113
+ break;
114
+ }
115
+ case "cloud": {
116
+ const vps = await api.vps.list();
117
+ next = vps
118
+ .filter((v) => v.plan?.category !== "gpu_cloud")
119
+ .map(toVpsRow);
120
+ break;
121
+ }
122
+ case "gpu": {
123
+ const vps = await api.vps.list();
124
+ next = vps
125
+ .filter((v) => v.plan?.category === "gpu_cloud")
126
+ .map(toVpsRow);
127
+ break;
128
+ }
129
+ case "metal": {
130
+ const metal = await api.baremetal.list();
131
+ next = metal.map(toMetalRow);
132
+ break;
133
+ }
134
+ case "storage": {
135
+ const storage = await api.storage.list();
136
+ next = storage.map(toStorageRow);
137
+ break;
138
+ }
139
+ case "transit": {
140
+ const transit = await api.transit.list();
141
+ next = transit.map(toTransitRow);
142
+ break;
143
+ }
144
+ }
145
+ setRows(next);
146
+ setCursor(0);
147
+ }
148
+ catch (e) {
149
+ setError(e instanceof Error ? e.message : String(e));
150
+ setRows([]);
151
+ }
152
+ finally {
153
+ setLoading(false);
154
+ }
155
+ }, [api]);
156
+ useEffect(() => {
157
+ load(kind);
158
+ }, [kind, load]);
159
+ const visible = useMemo(() => {
160
+ if (!filter.trim())
161
+ return rows;
162
+ const q = filter.trim().toLowerCase();
163
+ return rows.filter((r) => {
164
+ return (r.name.toLowerCase().includes(q) ||
165
+ r.ip.toLowerCase().includes(q) ||
166
+ r.id.toLowerCase().includes(q));
167
+ });
168
+ }, [rows, filter]);
169
+ useEffect(() => {
170
+ if (cursor >= visible.length)
171
+ setCursor(Math.max(0, visible.length - 1));
172
+ }, [visible.length, cursor]);
173
+ const menuFocused = mode === "list" && filterMode !== "editing" && pane === "sidebar";
174
+ const listPaneActive = mode === "list" && filterMode !== "editing" && pane === "list";
175
+ useInput((input, key) => {
176
+ if (key.escape) {
177
+ if (filterMode === "editing") {
178
+ setFilter("");
179
+ setFilterMode("off");
180
+ return;
181
+ }
182
+ if (mode === "detail") {
183
+ setMode("list");
184
+ setSelected(null);
185
+ return;
186
+ }
187
+ if (pane === "list") {
188
+ setPane("sidebar");
189
+ return;
190
+ }
191
+ goBack();
192
+ return;
193
+ }
194
+ if (filterMode !== "editing") {
195
+ if (key.leftArrow || (key.tab && key.shift)) {
196
+ if (mode === "detail") {
197
+ setMode("list");
198
+ setSelected(null);
199
+ setPane("sidebar");
200
+ return;
201
+ }
202
+ if (pane === "list") {
203
+ setPane("sidebar");
204
+ return;
205
+ }
206
+ }
207
+ if ((key.rightArrow || (key.tab && !key.shift)) &&
208
+ mode === "list" &&
209
+ pane === "sidebar") {
210
+ if (visible.length > 0)
211
+ setPane("list");
212
+ return;
213
+ }
214
+ }
215
+ if (mode === "list" && filterMode !== "editing") {
216
+ if (input === "r") {
217
+ load(kind);
218
+ return;
219
+ }
220
+ if (input === "/") {
221
+ setFilterMode("editing");
222
+ return;
223
+ }
224
+ }
225
+ if (!listPaneActive)
226
+ return;
227
+ if (key.upArrow || input === "k") {
228
+ setCursor((c) => Math.max(0, c - 1));
229
+ return;
230
+ }
231
+ if (key.downArrow || input === "j") {
232
+ setCursor((c) => Math.min(visible.length - 1, c + 1));
233
+ return;
234
+ }
235
+ if (key.return) {
236
+ const sel = visible[cursor];
237
+ if (sel) {
238
+ setSelected(sel);
239
+ setMode("detail");
240
+ }
241
+ }
242
+ }, { isActive: true });
243
+ const rows_count = visible.length;
244
+ const totalRows = process.stdout.rows ?? 24;
245
+ const paneHeight = Math.max(10, totalRows - 6);
246
+ return (React.createElement(CenteredFrame, { fullHeight: true, maxWidth: 120 },
247
+ React.createElement(Box, { paddingX: 2, paddingY: 0, height: 2, alignItems: "center" },
248
+ React.createElement(BackButton, { onBack: () => {
249
+ if (filterMode === "editing") {
250
+ setFilter("");
251
+ setFilterMode("off");
252
+ return;
253
+ }
254
+ if (mode === "detail") {
255
+ setMode("list");
256
+ setSelected(null);
257
+ return;
258
+ }
259
+ if (pane === "list") {
260
+ setPane("sidebar");
261
+ return;
262
+ }
263
+ goBack();
264
+ } }),
265
+ React.createElement(Text, { color: colors.dim },
266
+ " · ",
267
+ React.createElement(Text, { color: colors.text }, "Resources"),
268
+ kind !== "all" ? (React.createElement(Text, { color: colors.dim }, ` · ${KIND_TITLE[kind]}`)) : null)),
269
+ React.createElement(Box, { flexGrow: 1, flexDirection: "row", paddingX: 1 },
270
+ React.createElement(Box, { width: 22, marginRight: 1 },
271
+ React.createElement(Panel, { paddingX: 1, paddingY: 1, width: 22, height: paneHeight, borderColor: pane === "sidebar" ? colors.accent : colors.dim },
272
+ React.createElement(Menu, { items: KIND_ITEMS, onSelect: (v) => setKind(v), focused: menuFocused, initialIndex: 0 }))),
273
+ React.createElement(Box, { flexGrow: 1, flexDirection: "column" },
274
+ React.createElement(Panel, { title: mode === "detail" && selected ? selected.name : KIND_TITLE[kind], rightLabel: mode === "list"
275
+ ? `${rows_count} item${rows_count === 1 ? "" : "s"}`
276
+ : selected
277
+ ? selected.kind.toUpperCase()
278
+ : undefined, paddingX: 2, paddingY: 1, height: paneHeight, borderColor: pane === "list" || mode === "detail" ? colors.accent : colors.dim }, mode === "detail" && selected ? (React.createElement(DetailView, { row: selected })) : loading ? (React.createElement(Spinner, { label: `Loading ${KIND_TITLE[kind].toLowerCase()}…` })) : error ? (React.createElement(Text, { color: colors.error },
279
+ "Error: ",
280
+ error)) : visible.length === 0 ? (React.createElement(Text, { color: colors.dim }, rows.length === 0
281
+ ? `No ${KIND_TITLE[kind].toLowerCase()} resources.`
282
+ : `No matches for "${filter}".`)) : (React.createElement(RowList, { rows: visible, cursor: cursor, showKind: kind === "all", onHover: (i) => {
283
+ if (pane !== "list")
284
+ setPane("list");
285
+ setCursor(i);
286
+ }, onPick: (i) => {
287
+ const sel = visible[i];
288
+ if (sel) {
289
+ setSelected(sel);
290
+ setMode("detail");
291
+ }
292
+ } }))),
293
+ filterMode === "editing" ? (React.createElement(Box, { marginTop: 0 },
294
+ React.createElement(InputBar, { value: filter, onChange: setFilter, onSubmit: (v) => {
295
+ setFilter(v);
296
+ setFilterMode(v.trim() ? "applied" : "off");
297
+ }, placeholder: "filter by name / ip / id \u2014 Enter to apply, Esc to clear", focused: true }))) : filterMode === "applied" && filter ? (React.createElement(Box, { paddingX: 2 },
298
+ React.createElement(Text, { color: colors.dim }, `filter: ${filter}`))) : null)),
299
+ React.createElement(Box, { flexDirection: "column" },
300
+ React.createElement(Tip, null, mode === "detail"
301
+ ? "Esc to go back · s/S/r/x/c to power · click any button."
302
+ : filterMode === "editing"
303
+ ? "Enter to apply filter · Esc to clear."
304
+ : pane === "sidebar"
305
+ ? "↑↓ kinds · → or Tab to enter list · / filter · r refresh · Esc back."
306
+ : "↑↓ rows · Enter to open · ← or Esc to sidebar · / filter · r refresh."),
307
+ React.createElement(StatusBar, { left: `${rows_count} row${rows_count === 1 ? "" : "s"}`, right: [
308
+ header.projectName ? `Project: ${header.projectName}` : "",
309
+ header.teamName ? `Team: ${header.teamName}` : "",
310
+ ].filter(Boolean) }))));
311
+ }
312
+ function RowList({ rows, cursor, showKind, onPick, }) {
313
+ const [hover, setHover] = React.useState(null);
314
+ return (React.createElement(Box, { flexDirection: "column", width: "100%" }, rows.map((r, i) => {
315
+ const focused = i === cursor;
316
+ const isHovered = i === hover;
317
+ const cursorGlyph = focused ? `${glyphs.chevronRight} ` : " ";
318
+ const rowBg = isHovered ? colors.selectionBg : undefined;
319
+ return (React.createElement(Clickable, { key: r.id, onHover: (h) => setHover(h ? i : (prev) => (prev === i ? null : prev)), onClick: () => onPick?.(i) },
320
+ React.createElement(Box, { width: "100%", justifyContent: "space-between", backgroundColor: rowBg, paddingX: 1 },
321
+ React.createElement(Box, null,
322
+ React.createElement(Text, { color: focused ? colors.accent : colors.dim, backgroundColor: rowBg }, cursorGlyph),
323
+ showKind ? (React.createElement(Text, { color: colors.dim, backgroundColor: rowBg }, `[${r.kind}] `)) : null,
324
+ React.createElement(Text, { bold: focused, color: focused ? colors.accent : colors.text, backgroundColor: rowBg }, r.name || "(unnamed)"),
325
+ r.ip ? (React.createElement(Text, { color: colors.dim, backgroundColor: rowBg }, ` ${r.ip}`)) : null),
326
+ React.createElement(Box, null,
327
+ React.createElement(Text, { color: statusColor(r.status) ?? colors.dim, backgroundColor: rowBg }, r.status),
328
+ r.location ? (React.createElement(Text, { color: colors.dim, backgroundColor: rowBg }, ` · ${r.location}`)) : null))));
329
+ })));
330
+ }
331
+ function DetailView({ row }) {
332
+ if (row.kind === "vps") {
333
+ return React.createElement(VpsDetailView, { row: row });
334
+ }
335
+ if (row.kind === "storage") {
336
+ return React.createElement(StorageDetailView, { row: row });
337
+ }
338
+ return React.createElement(StaticDetailView, { row: row });
339
+ }
340
+ function StaticDetailView({ row }) {
341
+ const rows = [];
342
+ rows.push(["Id", row.id]);
343
+ rows.push(["Status", row.status]);
344
+ if (row.ip)
345
+ rows.push(["IP / Host", row.ip]);
346
+ if (row.location)
347
+ rows.push(["Location", row.location]);
348
+ if (row.kind === "metal") {
349
+ const b = row.raw;
350
+ if (b.project_name)
351
+ rows.push(["Project", b.project_name]);
352
+ if (b.cpu_cores)
353
+ rows.push(["CPU cores", String(b.cpu_cores)]);
354
+ if (b.ram_gb)
355
+ rows.push(["RAM", `${b.ram_gb} GB`]);
356
+ rows.push(["Reference", b.reference]);
357
+ }
358
+ else if (row.kind === "storage") {
359
+ const s = row.raw;
360
+ if (s.project_name)
361
+ rows.push(["Project", s.project_name]);
362
+ rows.push(["Size", `${s.size_gb} GB`]);
363
+ if (s.disk_slot)
364
+ rows.push(["Slot", s.disk_slot]);
365
+ if (s.vps_hostname)
366
+ rows.push(["Attached to", s.vps_hostname]);
367
+ }
368
+ else if (row.kind === "transit") {
369
+ const t = row.raw;
370
+ if (t.project_name)
371
+ rows.push(["Project", t.project_name]);
372
+ if (t.commit_rate_bps) {
373
+ const mbps = Math.round(t.commit_rate_bps / 1_000_000);
374
+ rows.push(["Commit", `${mbps} Mbps`]);
375
+ }
376
+ if (t.description)
377
+ rows.push(["Description", t.description]);
378
+ }
379
+ return (React.createElement(Box, { flexDirection: "column" }, rows.map(([k, v]) => (React.createElement(Box, { key: k },
380
+ React.createElement(Box, { width: 16 },
381
+ React.createElement(Text, { color: colors.dim }, k)),
382
+ React.createElement(Text, { color: colors.text }, v))))));
383
+ }
384
+ const initialStats = {
385
+ status: "",
386
+ cpu: null,
387
+ memUsed: null,
388
+ memTotal: null,
389
+ diskUsed: null,
390
+ diskTotal: null,
391
+ uptimeSec: null,
392
+ netHistory: [],
393
+ netOutHistory: [],
394
+ };
395
+ const POLL_MS = 5_000;
396
+ function VpsDetailView({ row }) {
397
+ const api = useApi();
398
+ const v = row.raw;
399
+ const [stats, setStats] = useState(initialStats);
400
+ const [actionStatus, setActionStatus] = useState(null);
401
+ useEffect(() => {
402
+ let abort = false;
403
+ const refresh = async () => {
404
+ try {
405
+ const [latest, rrd] = await Promise.all([
406
+ api.vps.stats(row.id, "hour").catch(() => null),
407
+ api.vps.rrd(row.id, "hour").catch(() => null),
408
+ ]);
409
+ if (abort)
410
+ return;
411
+ const point = pickLatestPoint(latest);
412
+ const netHistory = (rrd?.points ?? [])
413
+ .map((p) => (typeof p.netin === "number" ? p.netin : 0));
414
+ const netOutHistory = (rrd?.points ?? [])
415
+ .map((p) => (typeof p.netout === "number" ? p.netout : 0));
416
+ setStats({
417
+ status: point?.status ?? row.status ?? "",
418
+ cpu: numOrNull(point?.cpu),
419
+ memUsed: numOrNull(point?.mem),
420
+ memTotal: numOrNull(point?.maxmem),
421
+ diskUsed: numOrNull(point?.disk),
422
+ diskTotal: numOrNull(point?.maxdisk),
423
+ uptimeSec: numOrNull(point?.uptime),
424
+ netHistory,
425
+ netOutHistory,
426
+ });
427
+ }
428
+ catch { }
429
+ };
430
+ refresh();
431
+ const t = setInterval(refresh, POLL_MS);
432
+ return () => {
433
+ abort = true;
434
+ clearInterval(t);
435
+ };
436
+ }, [api, row.id, row.status]);
437
+ const doPower = useCallback(async (action) => {
438
+ setActionStatus({ label: `Sending ${action}…`, color: colors.warning });
439
+ try {
440
+ if (action === "cycle") {
441
+ await api.vpsControl.powerCycle(row.id);
442
+ }
443
+ else {
444
+ await api.vpsControl.power(row.id, action);
445
+ }
446
+ setActionStatus({ label: `${action} queued.`, color: colors.success });
447
+ setTimeout(() => setActionStatus(null), 3000);
448
+ }
449
+ catch (e) {
450
+ setActionStatus({
451
+ label: `Failed: ${e instanceof Error ? e.message : String(e)}`,
452
+ color: colors.error,
453
+ });
454
+ }
455
+ }, [api, row.id]);
456
+ const [confirmPower, setConfirmPower] = useState(null);
457
+ const requestPower = useCallback((action) => {
458
+ if (action === "start")
459
+ void doPower(action);
460
+ else
461
+ setConfirmPower(action);
462
+ }, [doPower]);
463
+ useInput((input) => {
464
+ if (input === "s")
465
+ requestPower("start");
466
+ else if (input === "S")
467
+ requestPower("shutdown");
468
+ else if (input === "r")
469
+ requestPower("reboot");
470
+ else if (input === "x")
471
+ requestPower("stop");
472
+ else if (input === "c")
473
+ requestPower("cycle");
474
+ });
475
+ if (confirmPower) {
476
+ return (React.createElement(ConfirmModal, { title: `${capitalizeAction(confirmPower)} ${row.name}?`, hint: confirmPower === "stop"
477
+ ? "Hard-stops the VM — like pulling the power cord."
478
+ : confirmPower === "cycle"
479
+ ? "Hard stop, then start — in-memory state is lost."
480
+ : undefined, onConfirm: () => {
481
+ setConfirmPower(null);
482
+ void doPower(confirmPower);
483
+ }, onCancel: () => setConfirmPower(null) }));
484
+ }
485
+ const planLabel = v.plan?.name ?? v.plan?.category ?? "";
486
+ const gpuLine = v.gpu_count && v.gpu_count > 0
487
+ ? `${v.gpu_count}× ${v.gpu_model_name ?? "GPU"}${v.gpu_vram_gb ? ` (${v.gpu_vram_gb} GB)` : ""}`
488
+ : null;
489
+ return (React.createElement(Box, { flexDirection: "column" },
490
+ React.createElement(DetailRow, { label: "Id", value: row.id }),
491
+ React.createElement(DetailRow, { label: "Status", value: React.createElement(Text, { color: statusColor(stats.status || row.status) ?? colors.text }, stats.status || row.status) }),
492
+ row.ip ? React.createElement(DetailRow, { label: "IP / Host", value: row.ip }) : null,
493
+ row.location ? React.createElement(DetailRow, { label: "Location", value: row.location }) : null,
494
+ v.project_name ? React.createElement(DetailRow, { label: "Project", value: v.project_name }) : null,
495
+ planLabel ? React.createElement(DetailRow, { label: "Plan", value: planLabel }) : null,
496
+ gpuLine ? React.createElement(DetailRow, { label: "GPU", value: gpuLine }) : null,
497
+ stats.uptimeSec !== null ? (React.createElement(DetailRow, { label: "Uptime", value: formatUptime(stats.uptimeSec) })) : null,
498
+ React.createElement(Box, { marginTop: 1, flexDirection: "column" },
499
+ React.createElement(Text, { color: colors.dim, bold: true }, "Usage"),
500
+ React.createElement(UsageRow, { label: "CPU", pct: stats.cpu !== null ? stats.cpu * 100 : null, rightText: stats.cpu !== null ? `${(stats.cpu * 100).toFixed(1)}%` : undefined }),
501
+ React.createElement(UsageRow, { label: "RAM", pct: stats.memUsed !== null && stats.memTotal
502
+ ? (stats.memUsed / stats.memTotal) * 100
503
+ : null, rightText: stats.memUsed !== null && stats.memTotal
504
+ ? `${formatBytes(stats.memUsed)} / ${formatBytes(stats.memTotal)}`
505
+ : undefined }),
506
+ React.createElement(UsageRow, { label: "Disk", pct: stats.diskUsed !== null && stats.diskTotal
507
+ ? (stats.diskUsed / stats.diskTotal) * 100
508
+ : null, rightText: stats.diskUsed !== null && stats.diskTotal
509
+ ? `${formatBytes(stats.diskUsed)} / ${formatBytes(stats.diskTotal)}`
510
+ : undefined })),
511
+ React.createElement(Box, { marginTop: 1, flexDirection: "column" },
512
+ React.createElement(Text, { color: colors.dim, bold: true }, "Network (last hour)"),
513
+ React.createElement(Sparkline, { data: stats.netHistory, width: 28, label: "\u2193 in ", color: colors.accent }),
514
+ React.createElement(Sparkline, { data: stats.netOutHistory, width: 28, label: "\u2191 out ", color: colors.accentSoft })),
515
+ React.createElement(Box, { marginTop: 1, flexDirection: "column" },
516
+ React.createElement(Text, { color: colors.dim, bold: true }, "Actions"),
517
+ React.createElement(Box, { marginTop: 0, flexShrink: 0 },
518
+ React.createElement(ActionButton, { keybind: "s", label: "Start", onPress: () => requestPower("start") }),
519
+ React.createElement(Box, { marginLeft: 1 }),
520
+ React.createElement(ActionButton, { keybind: "S", label: "Shutdown", onPress: () => requestPower("shutdown") }),
521
+ React.createElement(Box, { marginLeft: 1 }),
522
+ React.createElement(ActionButton, { keybind: "r", label: "Reboot", onPress: () => requestPower("reboot") })),
523
+ React.createElement(Box, { marginTop: 0, flexShrink: 0 },
524
+ React.createElement(ActionButton, { keybind: "x", label: "Stop", onPress: () => requestPower("stop") }),
525
+ React.createElement(Box, { marginLeft: 1 }),
526
+ React.createElement(ActionButton, { keybind: "c", label: "Cycle", onPress: () => requestPower("cycle") })),
527
+ actionStatus ? (React.createElement(Box, { marginTop: 1 },
528
+ React.createElement(Text, { color: actionStatus.color }, actionStatus.label))) : null)));
529
+ }
530
+ function DetailRow({ label, value, }) {
531
+ return (React.createElement(Box, null,
532
+ React.createElement(Box, { width: 16 },
533
+ React.createElement(Text, { color: colors.dim }, label)),
534
+ typeof value === "string" ? React.createElement(Text, { color: colors.text }, value) : value));
535
+ }
536
+ function UsageRow({ label, pct, rightText, }) {
537
+ const barWidth = 16;
538
+ const filled = pct !== null && Number.isFinite(pct)
539
+ ? Math.min(barWidth, Math.max(0, Math.round((pct / 100) * barWidth)))
540
+ : 0;
541
+ const bar = pct !== null
542
+ ? "█".repeat(filled) + "░".repeat(barWidth - filled)
543
+ : "─".repeat(barWidth);
544
+ return (React.createElement(Box, null,
545
+ React.createElement(Box, { width: 8 },
546
+ React.createElement(Text, { color: colors.dim }, label)),
547
+ React.createElement(Text, { color: pct !== null ? colors.accent : colors.dim }, bar),
548
+ rightText ? React.createElement(Text, { color: colors.dim }, ` ${rightText}`) : null));
549
+ }
550
+ function pickLatestPoint(raw) {
551
+ if (!raw)
552
+ return null;
553
+ if (Array.isArray(raw)) {
554
+ for (let i = raw.length - 1; i >= 0; i--) {
555
+ const p = raw[i];
556
+ if (p && typeof p === "object" && p.cpu !== undefined && p.cpu !== null) {
557
+ return p;
558
+ }
559
+ }
560
+ return raw[raw.length - 1] ?? null;
561
+ }
562
+ return raw;
563
+ }
564
+ function numOrNull(v) {
565
+ return typeof v === "number" && Number.isFinite(v) ? v : null;
566
+ }
567
+ function formatBytes(n) {
568
+ const units = ["B", "KB", "MB", "GB", "TB"];
569
+ let i = 0;
570
+ let x = n;
571
+ while (x >= 1024 && i < units.length - 1) {
572
+ x /= 1024;
573
+ i++;
574
+ }
575
+ return `${x.toFixed(x >= 10 ? 0 : 1)} ${units[i]}`;
576
+ }
577
+ function capitalizeAction(a) {
578
+ return a.charAt(0).toUpperCase() + a.slice(1);
579
+ }
580
+ function formatUptime(sec) {
581
+ const d = Math.floor(sec / 86400);
582
+ const h = Math.floor((sec % 86400) / 3600);
583
+ const m = Math.floor((sec % 3600) / 60);
584
+ const parts = [];
585
+ if (d)
586
+ parts.push(`${d}d`);
587
+ if (h || d)
588
+ parts.push(`${h}h`);
589
+ parts.push(`${m}m`);
590
+ return parts.join(" ");
591
+ }
592
+ function StorageDetailView({ row }) {
593
+ const api = useApi();
594
+ const v = row.raw;
595
+ const [current, setCurrent] = useState(v);
596
+ const isAttached = current.is_attached;
597
+ const [subMode, setSubMode] = useState("idle");
598
+ const [actionStatus, setActionStatus] = useState(null);
599
+ const [vpsCandidates, setVpsCandidates] = useState(null);
600
+ const [vpsLoadError, setVpsLoadError] = useState(null);
601
+ useEffect(() => {
602
+ if (subMode !== "picking" || vpsCandidates !== null)
603
+ return;
604
+ let abort = false;
605
+ (async () => {
606
+ try {
607
+ const list = await api.vps.list(current.project_id);
608
+ if (abort)
609
+ return;
610
+ setVpsCandidates(list);
611
+ }
612
+ catch (e) {
613
+ if (abort)
614
+ return;
615
+ setVpsLoadError(e instanceof Error ? e.message : String(e));
616
+ }
617
+ })();
618
+ return () => {
619
+ abort = true;
620
+ };
621
+ }, [api, subMode, current.project_id, vpsCandidates]);
622
+ const doAttach = useCallback(async (vpsId) => {
623
+ setSubMode("submitting");
624
+ setActionStatus({ label: "Attaching…", color: colors.warning });
625
+ try {
626
+ const result = await api.storage.attach(current.id, vpsId);
627
+ const targetVps = vpsCandidates?.find((x) => x.id === vpsId);
628
+ setCurrent({
629
+ ...current,
630
+ is_attached: true,
631
+ status: "attached",
632
+ vps_id: vpsId,
633
+ vps_hostname: targetVps?.hostname ?? current.vps_hostname,
634
+ disk_slot: result.disk_slot ?? current.disk_slot,
635
+ });
636
+ setActionStatus({ label: `Attached to ${targetVps?.hostname ?? "VPS"}.`, color: colors.success });
637
+ setSubMode("idle");
638
+ setTimeout(() => setActionStatus(null), 3000);
639
+ }
640
+ catch (e) {
641
+ setActionStatus({
642
+ label: `Failed: ${e instanceof Error ? e.message : String(e)}`,
643
+ color: colors.error,
644
+ });
645
+ setSubMode("idle");
646
+ }
647
+ }, [api, current, vpsCandidates]);
648
+ const doDetach = useCallback(async () => {
649
+ setSubMode("submitting");
650
+ setActionStatus({ label: "Detaching…", color: colors.warning });
651
+ try {
652
+ await api.storage.detach(current.id);
653
+ setCurrent({
654
+ ...current,
655
+ is_attached: false,
656
+ status: "available",
657
+ vps_id: null,
658
+ vps_hostname: null,
659
+ disk_slot: null,
660
+ });
661
+ setActionStatus({ label: "Detached.", color: colors.success });
662
+ setSubMode("idle");
663
+ setTimeout(() => setActionStatus(null), 3000);
664
+ }
665
+ catch (e) {
666
+ setActionStatus({
667
+ label: `Failed: ${e instanceof Error ? e.message : String(e)}`,
668
+ color: colors.error,
669
+ });
670
+ setSubMode("idle");
671
+ }
672
+ }, [api, current]);
673
+ useInput((input, key) => {
674
+ if (subMode !== "idle") {
675
+ if (key.escape && subMode === "picking")
676
+ setSubMode("idle");
677
+ return;
678
+ }
679
+ if (input === "a" && !isAttached)
680
+ setSubMode("picking");
681
+ else if (input === "d" && isAttached)
682
+ doDetach();
683
+ });
684
+ return (React.createElement(Box, { flexDirection: "column" },
685
+ React.createElement(DetailRow, { label: "Id", value: current.id }),
686
+ React.createElement(DetailRow, { label: "Status", value: React.createElement(Text, { color: statusColor(current.status) ?? colors.text }, current.status) }),
687
+ React.createElement(DetailRow, { label: "Project", value: current.project_name ?? "—" }),
688
+ current.location_name ? (React.createElement(DetailRow, { label: "Location", value: current.location_name })) : null,
689
+ React.createElement(DetailRow, { label: "Size", value: `${current.size_gb} GB` }),
690
+ current.monthly_price !== null && current.monthly_price !== undefined ? (React.createElement(DetailRow, { label: "Monthly cost", value: `$${current.monthly_price.toFixed(2)}` })) : null,
691
+ isAttached && current.vps_hostname ? (React.createElement(DetailRow, { label: "Attached to", value: current.vps_hostname })) : null,
692
+ isAttached && current.disk_slot ? (React.createElement(DetailRow, { label: "Disk slot", value: current.disk_slot })) : null,
693
+ React.createElement(Box, { marginTop: 1, flexDirection: "column" },
694
+ React.createElement(Text, { color: colors.dim, bold: true }, "Actions"),
695
+ React.createElement(Box, { marginTop: 0 }, isAttached ? (React.createElement(ActionButton, { keybind: "d", label: "Detach", onPress: doDetach })) : (React.createElement(ActionButton, { keybind: "a", label: "Attach to VPS", onPress: () => setSubMode("picking") }))),
696
+ actionStatus ? (React.createElement(Box, { marginTop: 1 },
697
+ React.createElement(Text, { color: actionStatus.color }, actionStatus.label))) : null),
698
+ subMode === "picking" ? (React.createElement(Box, { marginTop: 1, flexDirection: "column" },
699
+ React.createElement(Text, { color: colors.dim, bold: true }, "Pick a VPS to attach to"),
700
+ vpsLoadError ? (React.createElement(Text, { color: colors.error },
701
+ "Failed to load VPS list: ",
702
+ vpsLoadError)) : vpsCandidates === null ? (React.createElement(Spinner, { label: "Loading VPS list\u2026" })) : (() => {
703
+ const filtered = current.location_id
704
+ ? vpsCandidates.filter((vp) => !vp.location_id || vp.location_id === current.location_id)
705
+ : vpsCandidates;
706
+ if (filtered.length === 0) {
707
+ return (React.createElement(Text, { color: colors.dim }, current.location_name
708
+ ? `No VPS instances in ${current.location_name}. Esc to cancel.`
709
+ : "No VPS instances in this project. Esc to cancel."));
710
+ }
711
+ return (React.createElement(Menu, { items: filtered.map((vp) => ({
712
+ value: vp.id,
713
+ label: vp.hostname,
714
+ hint: `${vp.location?.city ?? vp.location?.name ?? ""} · ${vp.status}`,
715
+ })), onSelect: doAttach }));
716
+ })(),
717
+ React.createElement(Box, { marginTop: 1 },
718
+ React.createElement(Text, { color: colors.dim }, "Esc to cancel.")))) : null));
719
+ }
720
+ //# sourceMappingURL=Resources.js.map