@fnndsc/brasa 0.56.2 → 0.56.4

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 (333) hide show
  1. package/dist/buildinfo.json +1 -1
  2. package/dist/builtins/berth/berth.d.ts +11 -0
  3. package/dist/builtins/berth/berth.js +53 -22
  4. package/dist/builtins/berth/berth.js.map +1 -1
  5. package/dist/builtins/berth/berthCube.d.ts +17 -2
  6. package/dist/builtins/berth/berthCube.js +22 -10
  7. package/dist/builtins/berth/berthCube.js.map +1 -1
  8. package/dist/builtins/debug.d.ts +24 -3
  9. package/dist/builtins/debug.js +66 -13
  10. package/dist/builtins/debug.js.map +1 -1
  11. package/dist/builtins/fs/acl.args.d.ts +5 -38
  12. package/dist/builtins/fs/acl.args.js +6 -72
  13. package/dist/builtins/fs/acl.args.js.map +1 -1
  14. package/dist/builtins/fs/acl.d.ts +100 -10
  15. package/dist/builtins/fs/acl.js +222 -68
  16. package/dist/builtins/fs/acl.js.map +1 -1
  17. package/dist/builtins/fs/cat.args.d.ts +14 -15
  18. package/dist/builtins/fs/cat.args.js +13 -40
  19. package/dist/builtins/fs/cat.args.js.map +1 -1
  20. package/dist/builtins/fs/cat.d.ts +40 -3
  21. package/dist/builtins/fs/cat.js +89 -10
  22. package/dist/builtins/fs/cat.js.map +1 -1
  23. package/dist/builtins/fs/cd.d.ts +24 -6
  24. package/dist/builtins/fs/cd.js +71 -18
  25. package/dist/builtins/fs/cd.js.map +1 -1
  26. package/dist/builtins/fs/configWrite.d.ts +24 -8
  27. package/dist/builtins/fs/configWrite.js +77 -36
  28. package/dist/builtins/fs/configWrite.js.map +1 -1
  29. package/dist/builtins/fs/cp.d.ts +39 -4
  30. package/dist/builtins/fs/cp.js +120 -55
  31. package/dist/builtins/fs/cp.js.map +1 -1
  32. package/dist/builtins/fs/download.d.ts +12 -1
  33. package/dist/builtins/fs/download.js +24 -4
  34. package/dist/builtins/fs/download.js.map +1 -1
  35. package/dist/builtins/fs/du.d.ts +59 -33
  36. package/dist/builtins/fs/du.js +111 -79
  37. package/dist/builtins/fs/du.js.map +1 -1
  38. package/dist/builtins/fs/edit.d.ts +19 -4
  39. package/dist/builtins/fs/edit.js +77 -16
  40. package/dist/builtins/fs/edit.js.map +1 -1
  41. package/dist/builtins/fs/find.d.ts +25 -0
  42. package/dist/builtins/fs/find.js +76 -5
  43. package/dist/builtins/fs/find.js.map +1 -1
  44. package/dist/builtins/fs/mkdir.d.ts +28 -18
  45. package/dist/builtins/fs/mkdir.js +95 -66
  46. package/dist/builtins/fs/mkdir.js.map +1 -1
  47. package/dist/builtins/fs/mv.d.ts +34 -4
  48. package/dist/builtins/fs/mv.js +129 -64
  49. package/dist/builtins/fs/mv.js.map +1 -1
  50. package/dist/builtins/fs/pull.args.d.ts +56 -17
  51. package/dist/builtins/fs/pull.args.js +16 -66
  52. package/dist/builtins/fs/pull.args.js.map +1 -1
  53. package/dist/builtins/fs/pull.d.ts +62 -0
  54. package/dist/builtins/fs/pull.js +86 -22
  55. package/dist/builtins/fs/pull.js.map +1 -1
  56. package/dist/builtins/fs/pwd.d.ts +19 -5
  57. package/dist/builtins/fs/pwd.js +62 -8
  58. package/dist/builtins/fs/pwd.js.map +1 -1
  59. package/dist/builtins/fs/rm.d.ts +58 -21
  60. package/dist/builtins/fs/rm.js +99 -82
  61. package/dist/builtins/fs/rm.js.map +1 -1
  62. package/dist/builtins/fs/rmdir.d.ts +29 -11
  63. package/dist/builtins/fs/rmdir.js +87 -36
  64. package/dist/builtins/fs/rmdir.js.map +1 -1
  65. package/dist/builtins/fs/touch.d.ts +44 -9
  66. package/dist/builtins/fs/touch.js +91 -27
  67. package/dist/builtins/fs/touch.js.map +1 -1
  68. package/dist/builtins/fs/transferJobs.d.ts +64 -0
  69. package/dist/builtins/fs/transferJobs.js +98 -0
  70. package/dist/builtins/fs/transferJobs.js.map +1 -0
  71. package/dist/builtins/fs/tree.d.ts +36 -9
  72. package/dist/builtins/fs/tree.js +126 -36
  73. package/dist/builtins/fs/tree.js.map +1 -1
  74. package/dist/builtins/fs/upload.d.ts +35 -3
  75. package/dist/builtins/fs/upload.js +99 -14
  76. package/dist/builtins/fs/upload.js.map +1 -1
  77. package/dist/builtins/fs/xattr.args.d.ts +12 -33
  78. package/dist/builtins/fs/xattr.args.js +17 -95
  79. package/dist/builtins/fs/xattr.args.js.map +1 -1
  80. package/dist/builtins/fs/xattr.d.ts +98 -8
  81. package/dist/builtins/fs/xattr.js +163 -24
  82. package/dist/builtins/fs/xattr.js.map +1 -1
  83. package/dist/builtins/games/bytes.d.ts +201 -5
  84. package/dist/builtins/games/bytes.js +255 -54
  85. package/dist/builtins/games/bytes.js.map +1 -1
  86. package/dist/builtins/games/chimes.d.ts +180 -3
  87. package/dist/builtins/games/chimes.js +203 -26
  88. package/dist/builtins/games/chimes.js.map +1 -1
  89. package/dist/builtins/games/chrislab.d.ts +101 -3
  90. package/dist/builtins/games/chrislab.js +117 -17
  91. package/dist/builtins/games/chrislab.js.map +1 -1
  92. package/dist/builtins/games/cowsay.d.ts +93 -2
  93. package/dist/builtins/games/cowsay.js +90 -31
  94. package/dist/builtins/games/cowsay.js.map +1 -1
  95. package/dist/builtins/games/figlet.d.ts +70 -2
  96. package/dist/builtins/games/figlet.js +83 -6
  97. package/dist/builtins/games/figlet.js.map +1 -1
  98. package/dist/builtins/games/lab.d.ts +104 -5
  99. package/dist/builtins/games/lab.js +144 -6
  100. package/dist/builtins/games/lab.js.map +1 -1
  101. package/dist/builtins/games/lolcat.d.ts +61 -1
  102. package/dist/builtins/games/lolcat.js +59 -24
  103. package/dist/builtins/games/lolcat.js.map +1 -1
  104. package/dist/builtins/games/morse.d.ts +36 -1
  105. package/dist/builtins/games/morse.js +50 -2
  106. package/dist/builtins/games/morse.js.map +1 -1
  107. package/dist/builtins/games/numbers.d.ts +241 -5
  108. package/dist/builtins/games/numbers.js +298 -23
  109. package/dist/builtins/games/numbers.js.map +1 -1
  110. package/dist/builtins/games/play.d.ts +96 -6
  111. package/dist/builtins/games/play.js +137 -6
  112. package/dist/builtins/games/play.js.map +1 -1
  113. package/dist/builtins/games/qr.d.ts +40 -1
  114. package/dist/builtins/games/qr.js +51 -2
  115. package/dist/builtins/games/qr.js.map +1 -1
  116. package/dist/builtins/games/show.d.ts +131 -6
  117. package/dist/builtins/games/show.js +208 -20
  118. package/dist/builtins/games/show.js.map +1 -1
  119. package/dist/builtins/games/sky.d.ts +178 -4
  120. package/dist/builtins/games/sky.js +228 -12
  121. package/dist/builtins/games/sky.js.map +1 -1
  122. package/dist/builtins/games/text.d.ts +258 -7
  123. package/dist/builtins/games/text.js +310 -29
  124. package/dist/builtins/games/text.js.map +1 -1
  125. package/dist/builtins/games/trek.d.ts +67 -3
  126. package/dist/builtins/games/trek.js +63 -10
  127. package/dist/builtins/games/trek.js.map +1 -1
  128. package/dist/builtins/games/wtf.d.ts +58 -1
  129. package/dist/builtins/games/wtf.js +67 -6
  130. package/dist/builtins/games/wtf.js.map +1 -1
  131. package/dist/builtins/help.d.ts +38 -2
  132. package/dist/builtins/help.js +76 -769
  133. package/dist/builtins/help.js.map +1 -1
  134. package/dist/builtins/helpSections.js +4 -1
  135. package/dist/builtins/helpSections.js.map +1 -1
  136. package/dist/builtins/net/connect.d.ts +36 -3
  137. package/dist/builtins/net/connect.js +84 -26
  138. package/dist/builtins/net/connect.js.map +1 -1
  139. package/dist/builtins/net/cubepath.d.ts +49 -5
  140. package/dist/builtins/net/cubepath.js +69 -27
  141. package/dist/builtins/net/cubepath.js.map +1 -1
  142. package/dist/builtins/net/logout.d.ts +13 -4
  143. package/dist/builtins/net/logout.js +49 -3
  144. package/dist/builtins/net/logout.js.map +1 -1
  145. package/dist/builtins/net/netstat.d.ts +29 -4
  146. package/dist/builtins/net/netstat.js +64 -23
  147. package/dist/builtins/net/netstat.js.map +1 -1
  148. package/dist/builtins/net/pacs.d.ts +169 -15
  149. package/dist/builtins/net/pacs.js +92 -33
  150. package/dist/builtins/net/pacs.js.map +1 -1
  151. package/dist/builtins/net/query.args.d.ts +95 -0
  152. package/dist/builtins/net/query.args.js +26 -0
  153. package/dist/builtins/net/query.args.js.map +1 -0
  154. package/dist/builtins/net/query.d.ts +98 -5
  155. package/dist/builtins/net/query.js +89 -83
  156. package/dist/builtins/net/query.js.map +1 -1
  157. package/dist/builtins/net/status.d.ts +5 -3
  158. package/dist/builtins/net/status.js +5 -12
  159. package/dist/builtins/net/status.js.map +1 -1
  160. package/dist/builtins/parametersofplugin.d.ts +82 -3
  161. package/dist/builtins/parametersofplugin.js +79 -23
  162. package/dist/builtins/parametersofplugin.js.map +1 -1
  163. package/dist/builtins/proc.d.ts +210 -3
  164. package/dist/builtins/proc.js +210 -119
  165. package/dist/builtins/proc.js.map +1 -1
  166. package/dist/builtins/res/compute.d.ts +67 -3
  167. package/dist/builtins/res/compute.js +121 -35
  168. package/dist/builtins/res/compute.js.map +1 -1
  169. package/dist/builtins/res/dicom.d.ts +52 -3
  170. package/dist/builtins/res/dicom.js +82 -34
  171. package/dist/builtins/res/dicom.js.map +1 -1
  172. package/dist/builtins/res/expect.d.ts +52 -3
  173. package/dist/builtins/res/expect.js +92 -29
  174. package/dist/builtins/res/expect.js.map +1 -1
  175. package/dist/builtins/res/feed.d.ts +475 -3
  176. package/dist/builtins/res/feed.js +253 -158
  177. package/dist/builtins/res/feed.js.map +1 -1
  178. package/dist/builtins/res/files.d.ts +517 -3
  179. package/dist/builtins/res/files.js +124 -44
  180. package/dist/builtins/res/files.js.map +1 -1
  181. package/dist/builtins/res/gather.d.ts +113 -3
  182. package/dist/builtins/res/gather.js +153 -44
  183. package/dist/builtins/res/gather.js.map +1 -1
  184. package/dist/builtins/res/gather.process.d.ts +27 -19
  185. package/dist/builtins/res/gather.process.js +29 -59
  186. package/dist/builtins/res/gather.process.js.map +1 -1
  187. package/dist/builtins/res/group.d.ts +284 -3
  188. package/dist/builtins/res/group.js +147 -76
  189. package/dist/builtins/res/group.js.map +1 -1
  190. package/dist/builtins/res/image.d.ts +30 -2
  191. package/dist/builtins/res/image.js +62 -10
  192. package/dist/builtins/res/image.js.map +1 -1
  193. package/dist/builtins/res/play.d.ts +71 -9
  194. package/dist/builtins/res/play.js +124 -82
  195. package/dist/builtins/res/play.js.map +1 -1
  196. package/dist/builtins/res/plugininstance.d.ts +307 -2
  197. package/dist/builtins/res/plugininstance.js +122 -50
  198. package/dist/builtins/res/plugininstance.js.map +1 -1
  199. package/dist/builtins/res/pluginmeta.d.ts +244 -2
  200. package/dist/builtins/res/pluginmeta.js +98 -40
  201. package/dist/builtins/res/pluginmeta.js.map +1 -1
  202. package/dist/builtins/res/record.d.ts +37 -3
  203. package/dist/builtins/res/record.js +127 -57
  204. package/dist/builtins/res/record.js.map +1 -1
  205. package/dist/builtins/res/resourceList.d.ts +136 -0
  206. package/dist/builtins/res/resourceList.js +51 -0
  207. package/dist/builtins/res/resourceList.js.map +1 -0
  208. package/dist/builtins/res/tag.d.ts +244 -3
  209. package/dist/builtins/res/tag.js +97 -41
  210. package/dist/builtins/res/tag.js.map +1 -1
  211. package/dist/builtins/res/user.d.ts +122 -3
  212. package/dist/builtins/res/user.js +83 -21
  213. package/dist/builtins/res/user.js.map +1 -1
  214. package/dist/builtins/res/workflow.d.ts +244 -2
  215. package/dist/builtins/res/workflow.js +97 -40
  216. package/dist/builtins/res/workflow.js.map +1 -1
  217. package/dist/builtins/store.d.ts +85 -3
  218. package/dist/builtins/store.js +135 -68
  219. package/dist/builtins/store.js.map +1 -1
  220. package/dist/builtins/sys/apropos.d.ts +80 -5
  221. package/dist/builtins/sys/apropos.js +121 -15
  222. package/dist/builtins/sys/apropos.js.map +1 -1
  223. package/dist/builtins/sys/cal.d.ts +44 -5
  224. package/dist/builtins/sys/cal.js +57 -10
  225. package/dist/builtins/sys/cal.js.map +1 -1
  226. package/dist/builtins/sys/command.d.ts +20 -0
  227. package/dist/builtins/sys/command.js +31 -0
  228. package/dist/builtins/sys/command.js.map +1 -1
  229. package/dist/builtins/sys/context.d.ts +13 -3
  230. package/dist/builtins/sys/context.js +51 -4
  231. package/dist/builtins/sys/context.js.map +1 -1
  232. package/dist/builtins/sys/date.d.ts +56 -5
  233. package/dist/builtins/sys/date.js +63 -9
  234. package/dist/builtins/sys/date.js.map +1 -1
  235. package/dist/builtins/sys/echo.d.ts +63 -2
  236. package/dist/builtins/sys/echo.js +87 -8
  237. package/dist/builtins/sys/echo.js.map +1 -1
  238. package/dist/builtins/sys/fortune.d.ts +27 -2
  239. package/dist/builtins/sys/fortune.js +44 -2
  240. package/dist/builtins/sys/fortune.js.map +1 -1
  241. package/dist/builtins/sys/grep.d.ts +245 -11
  242. package/dist/builtins/sys/grep.js +418 -131
  243. package/dist/builtins/sys/grep.js.map +1 -1
  244. package/dist/builtins/sys/joblets.d.ts +66 -7
  245. package/dist/builtins/sys/joblets.js +101 -14
  246. package/dist/builtins/sys/joblets.js.map +1 -1
  247. package/dist/builtins/sys/motd.d.ts +37 -3
  248. package/dist/builtins/sys/motd.js +49 -8
  249. package/dist/builtins/sys/motd.js.map +1 -1
  250. package/dist/builtins/sys/notes.d.ts +75 -3
  251. package/dist/builtins/sys/notes.js +90 -29
  252. package/dist/builtins/sys/notes.js.map +1 -1
  253. package/dist/builtins/sys/physicalmode.d.ts +24 -3
  254. package/dist/builtins/sys/physicalmode.js +68 -14
  255. package/dist/builtins/sys/physicalmode.js.map +1 -1
  256. package/dist/builtins/sys/tasks.d.ts +74 -5
  257. package/dist/builtins/sys/tasks.js +102 -14
  258. package/dist/builtins/sys/tasks.js.map +1 -1
  259. package/dist/builtins/sys/textFilters.d.ts +673 -41
  260. package/dist/builtins/sys/textFilters.js +718 -263
  261. package/dist/builtins/sys/textFilters.js.map +1 -1
  262. package/dist/builtins/sys/timing.d.ts +24 -3
  263. package/dist/builtins/sys/timing.js +67 -14
  264. package/dist/builtins/sys/timing.js.map +1 -1
  265. package/dist/builtins/sys/variables.d.ts +70 -4
  266. package/dist/builtins/sys/variables.js +103 -31
  267. package/dist/builtins/sys/variables.js.map +1 -1
  268. package/dist/builtins/sys/version.d.ts +27 -2
  269. package/dist/builtins/sys/version.js +48 -3
  270. package/dist/builtins/sys/version.js.map +1 -1
  271. package/dist/builtins/sys/weather.d.ts +92 -15
  272. package/dist/builtins/sys/weather.js +71 -45
  273. package/dist/builtins/sys/weather.js.map +1 -1
  274. package/dist/builtins/sys/whoami.d.ts +38 -18
  275. package/dist/builtins/sys/whoami.js +112 -8
  276. package/dist/builtins/sys/whoami.js.map +1 -1
  277. package/dist/builtins/utils.d.ts +0 -37
  278. package/dist/builtins/utils.js +0 -86
  279. package/dist/builtins/utils.js.map +1 -1
  280. package/dist/chris/chrisCommands.js +58 -152
  281. package/dist/chris/chrisCommands.js.map +1 -1
  282. package/dist/chris/commandFallback.d.ts +12 -0
  283. package/dist/chris/commandFallback.js +47 -0
  284. package/dist/chris/commandFallback.js.map +1 -1
  285. package/dist/chris/filesystem.js +7 -5
  286. package/dist/chris/filesystem.js.map +1 -1
  287. package/dist/chris/help.js +0 -1018
  288. package/dist/chris/help.js.map +1 -1
  289. package/dist/chris/kinds.d.ts +21 -0
  290. package/dist/chris/kinds.js +114 -2
  291. package/dist/chris/kinds.js.map +1 -1
  292. package/dist/chris/mounts.d.ts +4 -4
  293. package/dist/chris/mounts.js +9 -16
  294. package/dist/chris/mounts.js.map +1 -1
  295. package/dist/chris/navigation.d.ts +2 -3
  296. package/dist/chris/navigation.js +6 -20
  297. package/dist/chris/navigation.js.map +1 -1
  298. package/dist/chris/pacsResources.d.ts +259 -0
  299. package/dist/chris/pacsResources.js +168 -0
  300. package/dist/chris/pacsResources.js.map +1 -0
  301. package/dist/core/commandDeclaration.d.ts +97 -7
  302. package/dist/core/commandDeclaration.js +21 -0
  303. package/dist/core/commandDeclaration.js.map +1 -1
  304. package/dist/core/commandParse.js +65 -17
  305. package/dist/core/commandParse.js.map +1 -1
  306. package/dist/core/commandRegistry.d.ts +4 -3
  307. package/dist/core/commandRegistry.js +36 -8
  308. package/dist/core/commandRegistry.js.map +1 -1
  309. package/dist/core/commandSchema.js +5 -2
  310. package/dist/core/commandSchema.js.map +1 -1
  311. package/dist/core/commandUsage.d.ts +15 -0
  312. package/dist/core/commandUsage.js +59 -7
  313. package/dist/core/commandUsage.js.map +1 -1
  314. package/dist/core/coreCommands.js +63 -212
  315. package/dist/core/coreCommands.js.map +1 -1
  316. package/dist/core/paths.d.ts +29 -1
  317. package/dist/core/paths.js +15 -2
  318. package/dist/core/paths.js.map +1 -1
  319. package/dist/core/preprocess.d.ts +3 -4
  320. package/dist/core/preprocess.js +4 -5
  321. package/dist/core/preprocess.js.map +1 -1
  322. package/dist/lib/completer/declared.js +7 -4
  323. package/dist/lib/completer/declared.js.map +1 -1
  324. package/dist/lib/completer/index.js +2 -7
  325. package/dist/lib/completer/index.js.map +1 -1
  326. package/dist/lib/parser.d.ts +0 -8
  327. package/dist/lib/parser.js +0 -11
  328. package/dist/lib/parser.js.map +1 -1
  329. package/dist/lib/vfs/vfs.d.ts +2 -1
  330. package/dist/lib/vfs/vfs.js +5 -4
  331. package/dist/lib/vfs/vfs.js.map +1 -1
  332. package/dist/notes.json +1 -1
  333. package/package.json +5 -5
@@ -1,55 +1,48 @@
1
1
  /**
2
- * @file Builtin files command (and links, dirs).
3
- * Manages file resources.
2
+ * @file `files`, `links` and `dirs`: CUBE's file, link and folder resources
3
+ * as rows (a listing of the records, not of a folder's contents, which `ls`
4
+ * shows), listed, searched, and their fields named.
5
+ *
6
+ * Declared in one record each (`filesCommand`, `linksCommand`,
7
+ * `dirsCommand`), of one grammar: the subcommands, the path a listing is
8
+ * under, and the listing options every resource command reads.
9
+ *
10
+ * Key components:
11
+ * - filesCommand / linksCommand / dirsCommand: the declarations.
12
+ * - builtin_files / builtin_links / builtin_dirs: each run over words already split.
13
+ *
14
+ * @module
4
15
  */
5
16
  import chalk from 'chalk';
6
- import { commandArgs_process, cliOptions_extract } from '../utils.js';
7
17
  import { files_fetchList } from '@fnndsc/chili/commands/files/list.js';
8
18
  import { fileFields_fetch } from '@fnndsc/chili/commands/files/fields.js';
9
19
  import { table_render } from '@fnndsc/chili/screen/screen.js';
10
20
  import { envelope_ok, envelope_error } from '@fnndsc/menu';
11
21
  import { exitCode_set } from '../../core/handlerRun.js';
22
+ import { command_declare } from '../../core/commandDeclaration.js';
23
+ import { declaredCommand_run } from '../../core/commandParse.js';
24
+ import { RESOURCE_LIST_OPTIONS_GRAMMAR, resourceListBag_build } from './resourceList.js';
12
25
  /**
13
- * Generic handler for file group commands (files, links, dirs).
26
+ * Lists one kind of record, under a path when one is given.
14
27
  *
15
- * @param args - command arguments.
16
- * @param assetName - the asset type ('files', 'links', 'dirs').
17
- * @returns An envelope carrying the listing or fields.
28
+ * @param assetName - The kind.
29
+ * @param options - The bag chili's listing reads.
30
+ * @param path - The ChRIS path the records are under, or none.
31
+ * @returns The table, or that there are none, or the error.
18
32
  */
19
- async function builtin_fileGroup(args, assetName) {
20
- const parsed = commandArgs_process(args);
21
- const subcommand = parsed._[0];
22
- if (!subcommand) {
23
- return envelope_ok(`${chalk.red(`Usage: ${assetName} <list|search|inspect> ...`)}\n`);
24
- }
33
+ async function fileGroupList_render(assetName, options, path) {
25
34
  try {
26
- if (subcommand === 'list') {
27
- const path = parsed._[1];
28
- const results = await files_fetchList(cliOptions_extract(parsed), assetName, path);
29
- if (!results) {
30
- return envelope_error('', undefined, `No ${assetName} resources found. Perhaps check your current context?\n`);
31
- }
32
- if (results.tableData.length === 0) {
33
- return envelope_ok(`No ${assetName} found matching the criteria.\n`);
34
- }
35
- return envelope_ok(table_render(results.tableData, results.selectedFields, {
36
- title: { title: assetName, justification: "center" },
37
- pagination: results.totalCount !== undefined ? { shown: results.tableData.length, total: results.totalCount } : undefined,
38
- }));
39
- }
40
- else if (subcommand === 'search') {
41
- const query = parsed._[1] ?? '';
42
- return builtin_fileGroup([...args.filter((a) => a !== subcommand), '--search', query], assetName);
35
+ const results = await files_fetchList(options, assetName, path);
36
+ if (!results) {
37
+ return envelope_error('', undefined, `No ${assetName} resources found. Perhaps check your current context?\n`);
43
38
  }
44
- else if (subcommand === 'inspect' || subcommand === 'fieldslist') {
45
- const fields = await fileFields_fetch(assetName);
46
- if (fields && fields.length > 0) {
47
- return envelope_ok(table_render(fields.map(f => ({ fields: f })), ["fields"]));
48
- }
49
- return envelope_ok(`No resource fields found for ${assetName}.\n`);
39
+ if (results.tableData.length === 0) {
40
+ return envelope_ok(`No ${assetName} found matching the criteria.\n`);
50
41
  }
51
- exitCode_set(1);
52
- return envelope_error(`${chalk.yellow(`Unknown subcommand: ${subcommand}. Usage: ${assetName} <list|search|inspect>`)}\n`);
42
+ return envelope_ok(table_render(results.tableData, results.selectedFields, {
43
+ title: { title: assetName, justification: 'center' },
44
+ pagination: results.totalCount !== undefined ? { shown: results.tableData.length, total: results.totalCount } : undefined,
45
+ }));
53
46
  }
54
47
  catch (e) {
55
48
  const msg = e instanceof Error ? e.message : String(e);
@@ -58,30 +51,117 @@ async function builtin_fileGroup(args, assetName) {
58
51
  }
59
52
  }
60
53
  /**
61
- * Handles files commands.
54
+ * Names the fields one kind of record has.
55
+ *
56
+ * @param assetName - The kind.
57
+ * @returns The fields' table, or that there are none.
58
+ */
59
+ async function fileGroupFields_render(assetName) {
60
+ const fields = await fileFields_fetch(assetName);
61
+ if (fields && fields.length > 0) {
62
+ return envelope_ok(table_render(fields.map((f) => ({ fields: f })), ['fields']));
63
+ }
64
+ return envelope_ok(`No resource fields found for ${assetName}.\n`);
65
+ }
66
+ /** What a `files`, `links` or `dirs` line may hold. */
67
+ const FILE_GROUP_GRAMMAR = {
68
+ subcommands: {
69
+ list: {
70
+ summary: 'List the records, 20 to a page, under a path when one is given',
71
+ operands: [{ name: 'path', kind: 'cfsPath', optional: true, summary: 'The ChRIS path the records are under' }],
72
+ options: { ...RESOURCE_LIST_OPTIONS_GRAMMAR },
73
+ },
74
+ search: {
75
+ summary: 'List the records a filter matches (list --search <term>)',
76
+ operands: [{ name: 'term', kind: 'word', summary: 'The filter, field:value (inspect names the fields)' }],
77
+ options: { ...RESOURCE_LIST_OPTIONS_GRAMMAR },
78
+ },
79
+ inspect: { summary: 'Name the fields a record has' },
80
+ fieldslist: { summary: 'The same as inspect' },
81
+ },
82
+ };
83
+ /**
84
+ * The handler of one kind of record's command.
85
+ *
86
+ * @param assetName - The kind.
87
+ * @returns The handler.
88
+ */
89
+ function fileGroupHandler_make(assetName) {
90
+ return async (args) => {
91
+ switch (args.subcommand) {
92
+ case 'list': return fileGroupList_render(assetName, resourceListBag_build(args.options), args.operands.path);
93
+ case 'search': return fileGroupList_render(assetName, resourceListBag_build(args.options, args.operands.term), undefined);
94
+ case 'inspect':
95
+ case 'fieldslist': return fileGroupFields_render(assetName);
96
+ }
97
+ };
98
+ }
99
+ /**
100
+ * One kind of record's declaration.
101
+ *
102
+ * @param assetName - The kind, which names the command.
103
+ * @param noun - What a record is, for the help.
104
+ * @returns The declaration.
105
+ */
106
+ function fileGroupCommand_make(assetName, noun) {
107
+ return command_declare({
108
+ name: assetName,
109
+ grammar: FILE_GROUP_GRAMMAR,
110
+ help: {
111
+ summary: `CUBE's ${noun} records: list them, search them, name their fields`,
112
+ description: `List CUBE's ${noun} records as rows, under a ChRIS path when one is given, a page at a time or every page, filtered by a field:value search and in the columns asked for; inspect names the fields a record has. These are the records themselves; ls lists a folder's contents.`,
113
+ category: 'Resources',
114
+ examples: [`${assetName} list`, `${assetName} list ~/uploads --fields fname,fsize`, `${assetName} search fname:dicom`, `${assetName} inspect`],
115
+ },
116
+ handler: fileGroupHandler_make(assetName),
117
+ });
118
+ }
119
+ /** `files <list|search|inspect>`: the declaration. */
120
+ export const filesCommand = fileGroupCommand_make('files', 'file');
121
+ /** `links <list|search|inspect>`: the declaration. */
122
+ export const linksCommand = fileGroupCommand_make('links', 'link');
123
+ /** `dirs <list|search|inspect>`: the declaration. */
124
+ export const dirsCommand = fileGroupCommand_make('dirs', 'folder');
125
+ /**
126
+ * `files` over words already split: the declaration's parse and handler.
62
127
  *
63
128
  * @param args - command arguments.
64
129
  * @returns An envelope carrying the files listing or fields.
130
+ *
131
+ * @example
132
+ * ```ts
133
+ * await builtin_files(['list', '/home/chris/uploads']);
134
+ * ```
65
135
  */
66
136
  export async function builtin_files(args) {
67
- return builtin_fileGroup(args, 'files');
137
+ return declaredCommand_run(filesCommand, args);
68
138
  }
69
139
  /**
70
- * Handles links commands.
140
+ * `links` over words already split: the declaration's parse and handler.
71
141
  *
72
142
  * @param args - command arguments.
73
143
  * @returns An envelope carrying the links listing or fields.
144
+ *
145
+ * @example
146
+ * ```ts
147
+ * await builtin_links(['list']);
148
+ * ```
74
149
  */
75
150
  export async function builtin_links(args) {
76
- return builtin_fileGroup(args, 'links');
151
+ return declaredCommand_run(linksCommand, args);
77
152
  }
78
153
  /**
79
- * Handles dirs commands.
154
+ * `dirs` over words already split: the declaration's parse and handler.
80
155
  *
81
156
  * @param args - command arguments.
82
157
  * @returns An envelope carrying the dirs listing or fields.
158
+ *
159
+ * @example
160
+ * ```ts
161
+ * await builtin_dirs(['list']);
162
+ * ```
83
163
  */
84
164
  export async function builtin_dirs(args) {
85
- return builtin_fileGroup(args, 'dirs');
165
+ return declaredCommand_run(dirsCommand, args);
86
166
  }
87
167
  //# sourceMappingURL=files.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"files.js","sourceRoot":"","sources":["../../../src/builtins/res/files.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../../src/builtins/res/files.ts"],"names":[],"mappings":"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"}
@@ -2,9 +2,119 @@ import { CommandEnvelope } from '@fnndsc/menu';
2
2
  import { GATHER_MODEL_KIND } from './gather.kind.js';
3
3
  export { GATHER_MODEL_KIND };
4
4
  /**
5
- * Builtin handler for the `gather` command.
5
+ * `gather [list | add | remove | rm | clear | name | feed | process]`: the declaration.
6
6
  *
7
- * @param args - Parsed command arguments.
8
- * @returns An envelope carrying the cohort, or a usage refusal.
7
+ * @example
8
+ * ```ts
9
+ * commands_register({ declarations: [gatherCommand] }, 'backend');
10
+ * ```
11
+ */
12
+ export declare const gatherCommand: import("../../core/commandDeclaration.js").CommandDeclaration<{
13
+ readonly bare: {
14
+ readonly summary: "Show the cohort (as list)";
15
+ };
16
+ readonly subcommands: {
17
+ readonly list: {
18
+ readonly summary: "Show the cohort";
19
+ };
20
+ readonly add: {
21
+ readonly summary: "Take series, directories or files into it";
22
+ readonly operands: readonly [{
23
+ readonly name: "paths";
24
+ readonly kind: "cfsPath";
25
+ readonly optional: true;
26
+ readonly repeat: true;
27
+ readonly glob: true;
28
+ readonly summary: "Paths, handles (@SER3, @SER1-4) or ${listing}; with none, a listing piped in";
29
+ }];
30
+ };
31
+ readonly remove: {
32
+ readonly summary: "Drop members, by path or by listed index";
33
+ readonly operands: readonly [{
34
+ readonly name: "members";
35
+ readonly kind: "cfsPath";
36
+ readonly optional: true;
37
+ readonly repeat: true;
38
+ readonly glob: true;
39
+ readonly summary: "Paths, handles or listed indices (2, #2); with none, a listing piped in";
40
+ }];
41
+ };
42
+ readonly rm: {
43
+ readonly summary: "As remove";
44
+ readonly operands: readonly [{
45
+ readonly name: "members";
46
+ readonly kind: "cfsPath";
47
+ readonly optional: true;
48
+ readonly repeat: true;
49
+ readonly glob: true;
50
+ readonly summary: "Paths, handles or listed indices (2, #2); with none, a listing piped in";
51
+ }];
52
+ };
53
+ readonly clear: {
54
+ readonly summary: "Empty it, name and feed included";
55
+ };
56
+ readonly name: {
57
+ readonly summary: "Read the cohort's name, or give it one";
58
+ readonly operands: readonly [{
59
+ readonly name: "name";
60
+ readonly kind: "word";
61
+ readonly optional: true;
62
+ readonly repeat: true;
63
+ readonly summary: "The new name; its words are joined";
64
+ }];
65
+ };
66
+ readonly feed: {
67
+ readonly summary: "The cohort's feed, made now if it has none: series still at the PACS are pulled first, then one feed is rooted on every member";
68
+ readonly options: {
69
+ readonly title: {
70
+ readonly long: "title";
71
+ readonly summary: "The feed's title, when one is made (the cohort's name otherwise)";
72
+ readonly value: {
73
+ readonly name: "title";
74
+ readonly kind: "word";
75
+ };
76
+ };
77
+ };
78
+ };
79
+ readonly process: {
80
+ readonly summary: "Run a plugin or pipeline ONCE over the whole cohort, off one feed whose root holds every member";
81
+ readonly operands: readonly [{
82
+ readonly name: "executable";
83
+ readonly kind: "word";
84
+ readonly summary: "The plugin's /bin name or the pipeline's own name";
85
+ }, {
86
+ readonly name: "arguments";
87
+ readonly kind: "word";
88
+ readonly optional: true;
89
+ readonly repeat: true;
90
+ readonly summary: "After --: the run's own arguments";
91
+ }];
92
+ readonly options: {
93
+ readonly title: {
94
+ readonly long: "title";
95
+ readonly summary: "The feed's title, when one is made (the cohort's name otherwise)";
96
+ readonly value: {
97
+ readonly name: "title";
98
+ readonly kind: "word";
99
+ };
100
+ };
101
+ readonly detach: {
102
+ readonly long: "detach";
103
+ readonly summary: "Return at once rather than wait for the run";
104
+ };
105
+ };
106
+ };
107
+ };
108
+ }>;
109
+ /**
110
+ * `gather` over words already split: the declaration's parse and handler.
111
+ *
112
+ * @param args - The words after `gather`.
113
+ * @returns An envelope carrying the cohort, or the refusal of a bad line.
114
+ *
115
+ * @example
116
+ * ```ts
117
+ * await builtin_gather(['add', '~/uploads/brain']);
118
+ * ```
9
119
  */
10
120
  export declare function builtin_gather(args: string[]): Promise<CommandEnvelope>;
@@ -2,6 +2,7 @@
2
2
  * @file Builtin gather command: the session's cohort as a kernel subject.
3
3
  *
4
4
  * Subcommands: list (the default), add, remove, clear, name, feed, process.
5
+ * Declared in one record (`gatherCommand`).
5
6
  *
6
7
  * Gathering was a surface gesture before it was a verb, which meant the set
7
8
  * a session was working on could only be built by pressing on it. As a
@@ -9,6 +10,18 @@
9
10
  * the surface becomes one client of the cohort rather than the only place
10
11
  * it exists.
11
12
  *
13
+ * Key components:
14
+ * - gatherCommand: the declaration.
15
+ * - builtin_gather: the declaration run over words already split.
16
+ *
17
+ * Typical usage:
18
+ * ```ts
19
+ * await builtin_gather(['add', '@SER3']);
20
+ * ```
21
+ *
22
+ * Dependencies: the cohort store; `gather.process.js`, loaded when a feed is
23
+ * made or a run starts.
24
+ *
12
25
  * @module
13
26
  */
14
27
  import { listingIn_take, listingOperands_extract } from '../../core/listing.js';
@@ -16,7 +29,9 @@ import { answerNumbering_derive, handleWords_map, numberedFooter_render } from '
16
29
  import chalk from 'chalk';
17
30
  import path from 'path';
18
31
  import { table_render } from '@fnndsc/chili/screen/screen.js';
19
- import { commandArgs_process, path_resolve } from '../utils.js';
32
+ import { path_resolve } from '../utils.js';
33
+ import { command_declare } from '../../core/commandDeclaration.js';
34
+ import { declaredCommand_run } from '../../core/commandParse.js';
20
35
  import { cohort_read, cohort_write, cohortModel_wrap, cohortFolders_fill, member_key, members_drop, members_merge, pathKind_determine, seriesUID_parse, } from './gather.store.js';
21
36
  import { placeImagery_is, seriesFacts_fill } from './gather.facts.js';
22
37
  import { envelope_ok, envelope_error } from '@fnndsc/menu';
@@ -217,14 +232,14 @@ async function gather_name(operands) {
217
232
  /**
218
233
  * Makes the cohort's feed, or names the one it has.
219
234
  *
220
- * @param words - The words after `gather feed`, raw.
235
+ * @param title - The feed's title as `--title` gave it, or null for the cohort's name.
221
236
  * @returns The cohort, with its feed.
222
237
  */
223
- async function gather_feed(words) {
238
+ async function gather_feed(title) {
224
239
  // Loaded on demand, as `process` is: making a feed carries the pull and
225
240
  // feed machinery, which the cohort's own verbs never need.
226
241
  const { cohortFeed_make } = await import('./gather.process.js');
227
- const made = await cohortFeed_make(words);
242
+ const made = await cohortFeed_make(title);
228
243
  if (typeof made === 'string')
229
244
  return gather_error(`gather feed: ${made}`);
230
245
  const feedId = made.state.feed?.feedId;
@@ -232,53 +247,147 @@ async function gather_feed(words) {
232
247
  const envelope = cohort_render(made.state);
233
248
  return envelope_ok(`${chalk.green(said)}\n${envelope.rendered}`, envelope.model);
234
249
  }
250
+ /** What `add` takes. */
251
+ const ADD_OPERAND = {
252
+ name: 'paths', kind: 'cfsPath', optional: true, repeat: true, glob: true,
253
+ summary: 'Paths, handles (@SER3, @SER1-4) or ${listing}; with none, a listing piped in',
254
+ };
255
+ /** What `remove` and `rm` take. */
256
+ const REMOVE_OPERAND = {
257
+ name: 'members', kind: 'cfsPath', optional: true, repeat: true, glob: true,
258
+ summary: 'Paths, handles or listed indices (2, #2); with none, a listing piped in',
259
+ };
260
+ /** The title of a feed `feed` or `process` makes. */
261
+ const TITLE_OPTION = { long: 'title', summary: "The feed's title, when one is made (the cohort's name otherwise)", value: { name: 'title', kind: 'word' } };
262
+ /** What a `gather` line may hold. */
263
+ const GATHER_GRAMMAR = {
264
+ bare: { summary: 'Show the cohort (as list)' },
265
+ subcommands: {
266
+ list: { summary: 'Show the cohort' },
267
+ add: { summary: 'Take series, directories or files into it', operands: [ADD_OPERAND] },
268
+ remove: { summary: 'Drop members, by path or by listed index', operands: [REMOVE_OPERAND] },
269
+ rm: { summary: 'As remove', operands: [REMOVE_OPERAND] },
270
+ clear: { summary: 'Empty it, name and feed included' },
271
+ name: {
272
+ summary: "Read the cohort's name, or give it one",
273
+ operands: [{ name: 'name', kind: 'word', optional: true, repeat: true, summary: 'The new name; its words are joined' }],
274
+ },
275
+ feed: {
276
+ summary: "The cohort's feed, made now if it has none: series still at the PACS are pulled first, then one feed is rooted on every member",
277
+ options: { title: TITLE_OPTION },
278
+ },
279
+ process: {
280
+ summary: 'Run a plugin or pipeline ONCE over the whole cohort, off one feed whose root holds every member',
281
+ operands: [
282
+ { name: 'executable', kind: 'word', summary: "The plugin's /bin name or the pipeline's own name" },
283
+ { name: 'arguments', kind: 'word', optional: true, repeat: true, summary: "After --: the run's own arguments" },
284
+ ],
285
+ options: {
286
+ title: TITLE_OPTION,
287
+ detach: { long: 'detach', summary: 'Return at once rather than wait for the run' },
288
+ },
289
+ },
290
+ },
291
+ };
235
292
  /**
236
- * Builtin handler for the `gather` command.
293
+ * `gather [list | add | remove | rm | clear | name | feed | process]`: the declaration.
237
294
  *
238
- * @param args - Parsed command arguments.
239
- * @returns An envelope carrying the cohort, or a usage refusal.
295
+ * @example
296
+ * ```ts
297
+ * commands_register({ declarations: [gatherCommand] }, 'backend');
298
+ * ```
240
299
  */
241
- export async function builtin_gather(args) {
242
- const parsed = commandArgs_process(args);
243
- const subcommand = parsed._[0];
244
- const operands = parsed._.slice(1);
245
- try {
246
- if (subcommand === undefined || subcommand === 'list')
247
- return cohort_render(await cohort_read());
248
- if (subcommand === 'add' || subcommand === 'remove' || subcommand === 'rm') {
249
- // With no operands, a listing piped in is the operand list (#1103):
250
- // `query … | gather add`. With neither, the verb says what it needs
251
- // rather than taking the held listing behind the operator's back.
252
- let given = operands;
253
- if (given.length === 0) {
254
- const piped = listingIn_take();
255
- if (piped === null) {
256
- return gather_error(`gather ${subcommand}: what? give paths or handles (@SER3), \${listing}, or pipe a listing in (query … | gather ${subcommand === 'rm' ? 'remove' : subcommand})`);
300
+ export const gatherCommand = command_declare({
301
+ name: 'gather',
302
+ grammar: GATHER_GRAMMAR,
303
+ help: {
304
+ summary: 'Hold the set of things this session is working on',
305
+ description: "Hold the set of things this session is working on: the cohort. add and remove take paths, handles (@SER3, @SER1-4), ${listing}, or a listing piped in with no operands: query … | gather add. With none of these they refuse rather than guess. process runs off the cohort's own feed when it has one, refuses while a series is unpulled, and answers as the bare run would: R=$(gather process …). <executable> is the /bin name or the pipeline's own name: gather process \"FreeSurfer 8.2.0 mri_convert\". A plugin that starts jobs of its own (pl-dymap) finishes once they are submitted; watch them in the feed.",
306
+ category: 'Workflows',
307
+ examples: [
308
+ 'gather',
309
+ 'gather add /net/pacs/queries/qid:3125/Study_1.2.3/Series_4.5.6',
310
+ 'gather add ~/uploads/brain',
311
+ 'gather add @SER3 @SER7',
312
+ 'query PatientID:1234567,Modality:MR | gather add',
313
+ 'gather remove 2',
314
+ 'gather name "sag cohort"',
315
+ 'gather feed',
316
+ 'R=$(gather process pl-dcm2niix-v1.0.2 --title "sag nifti")',
317
+ 'gather process pl-x -- --threshold 0.5',
318
+ ],
319
+ },
320
+ holds: ['cohort'],
321
+ handler: async (args) => {
322
+ try {
323
+ switch (args.subcommand) {
324
+ case null:
325
+ case 'list':
326
+ return cohort_render(await cohort_read());
327
+ case 'add':
328
+ return await gatherMembers_change('add', args.operands.paths);
329
+ case 'remove':
330
+ case 'rm':
331
+ return await gatherMembers_change(args.subcommand, args.operands.members);
332
+ case 'clear':
333
+ return await gather_clear();
334
+ case 'name':
335
+ return await gather_name(args.operands.name);
336
+ case 'feed':
337
+ return await gather_feed(args.options.title ?? null);
338
+ case 'process': {
339
+ // Loaded on demand: running carries the plugin and pipeline
340
+ // machinery, which the cohort's own verbs never need.
341
+ const { gather_process } = await import('./gather.process.js');
342
+ return await gather_process({
343
+ name: args.operands.executable,
344
+ title: args.options.title ?? null,
345
+ detach: args.options.detach,
346
+ forwarded: args.operands.arguments,
347
+ });
257
348
  }
258
- given = listingOperands_extract(piped) ?? [];
259
- if (given.length === 0)
260
- return gather_error(`gather ${subcommand}: the listing piped in has nothing to ${subcommand === 'add' ? 'gather' : 'remove'}.`);
261
349
  }
262
- return subcommand === 'add' ? await gather_add(given) : await gather_remove(given);
263
350
  }
264
- if (subcommand === 'clear')
265
- return await gather_clear();
266
- // Raw words: the run's own arguments follow `--`, and a generic parser
267
- // would read them as gather's options.
268
- // Loaded on demand: running carries the plugin and pipeline machinery,
269
- // which the cohort's own verbs never need.
270
- if (subcommand === 'process') {
271
- const { gather_process } = await import('./gather.process.js');
272
- return await gather_process(args.slice(args.indexOf('process') + 1));
351
+ catch (e) {
352
+ return gather_error(`gather: ${e instanceof Error ? e.message : String(e)}`);
273
353
  }
274
- if (subcommand === 'name')
275
- return await gather_name(operands);
276
- if (subcommand === 'feed')
277
- return await gather_feed(args.slice(args.indexOf('feed') + 1));
278
- }
279
- catch (e) {
280
- return gather_error(`gather: ${e instanceof Error ? e.message : String(e)}`);
354
+ },
355
+ });
356
+ /**
357
+ * `gather` over words already split: the declaration's parse and handler.
358
+ *
359
+ * @param args - The words after `gather`.
360
+ * @returns An envelope carrying the cohort, or the refusal of a bad line.
361
+ *
362
+ * @example
363
+ * ```ts
364
+ * await builtin_gather(['add', '~/uploads/brain']);
365
+ * ```
366
+ */
367
+ export async function builtin_gather(args) {
368
+ return declaredCommand_run(gatherCommand, args);
369
+ }
370
+ /**
371
+ * Adds members to the cohort or drops them. With no operands, a listing
372
+ * piped in is the operand list (#1103): `query … | gather add`. With
373
+ * neither, the verb says what it needs rather than taking the held listing
374
+ * behind the operator's back.
375
+ *
376
+ * @param verb - `add`, `remove` or `rm`.
377
+ * @param operands - The paths, handles or indices given.
378
+ * @returns The cohort after the change, or a refusal.
379
+ */
380
+ async function gatherMembers_change(verb, operands) {
381
+ let given = operands;
382
+ if (given.length === 0) {
383
+ const piped = listingIn_take();
384
+ if (piped === null) {
385
+ return gather_error(`gather ${verb}: what? give paths or handles (@SER3), \${listing}, or pipe a listing in (query … | gather ${verb === 'rm' ? 'remove' : verb})`);
386
+ }
387
+ given = listingOperands_extract(piped) ?? [];
388
+ if (given.length === 0)
389
+ return gather_error(`gather ${verb}: the listing piped in has nothing to ${verb === 'add' ? 'gather' : 'remove'}.`);
281
390
  }
282
- return gather_error(`Unknown subcommand: ${subcommand}. Usage: gather <list|add|remove|clear|name|feed|process>`);
391
+ return verb === 'add' ? await gather_add(given) : await gather_remove(given);
283
392
  }
284
393
  //# sourceMappingURL=gather.js.map