@fnndsc/chili 3.2.5

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 (219) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +113 -0
  3. package/dist/chefs/chefs.d.ts +15 -0
  4. package/dist/chefs/chefs.js +195 -0
  5. package/dist/commands/compute/fields.d.ts +6 -0
  6. package/dist/commands/compute/fields.js +13 -0
  7. package/dist/commands/compute/list.d.ts +19 -0
  8. package/dist/commands/compute/list.js +20 -0
  9. package/dist/commands/connect/login.d.ts +16 -0
  10. package/dist/commands/connect/login.js +18 -0
  11. package/dist/commands/connect/logout.d.ts +6 -0
  12. package/dist/commands/connect/logout.js +16 -0
  13. package/dist/commands/feed/comments.d.ts +41 -0
  14. package/dist/commands/feed/comments.js +45 -0
  15. package/dist/commands/feed/create.d.ts +13 -0
  16. package/dist/commands/feed/create.js +40 -0
  17. package/dist/commands/feed/note.d.ts +21 -0
  18. package/dist/commands/feed/note.js +24 -0
  19. package/dist/commands/feeds/delete.d.ts +14 -0
  20. package/dist/commands/feeds/delete.js +34 -0
  21. package/dist/commands/feeds/fields.d.ts +6 -0
  22. package/dist/commands/feeds/fields.js +17 -0
  23. package/dist/commands/feeds/list.d.ts +17 -0
  24. package/dist/commands/feeds/list.js +38 -0
  25. package/dist/commands/feeds/share.d.ts +17 -0
  26. package/dist/commands/feeds/share.js +19 -0
  27. package/dist/commands/file/view.d.ts +8 -0
  28. package/dist/commands/file/view.js +25 -0
  29. package/dist/commands/files/delete.d.ts +16 -0
  30. package/dist/commands/files/delete.js +36 -0
  31. package/dist/commands/files/fields.d.ts +7 -0
  32. package/dist/commands/files/fields.js +18 -0
  33. package/dist/commands/files/list.d.ts +11 -0
  34. package/dist/commands/files/list.js +23 -0
  35. package/dist/commands/fs/cat.d.ts +15 -0
  36. package/dist/commands/fs/cat.js +26 -0
  37. package/dist/commands/fs/cp.d.ts +17 -0
  38. package/dist/commands/fs/cp.js +26 -0
  39. package/dist/commands/fs/create.d.ts +15 -0
  40. package/dist/commands/fs/create.js +83 -0
  41. package/dist/commands/fs/download.d.ts +25 -0
  42. package/dist/commands/fs/download.js +235 -0
  43. package/dist/commands/fs/edit.d.ts +16 -0
  44. package/dist/commands/fs/edit.js +25 -0
  45. package/dist/commands/fs/ls.d.ts +18 -0
  46. package/dist/commands/fs/ls.js +142 -0
  47. package/dist/commands/fs/mkdir.d.ts +8 -0
  48. package/dist/commands/fs/mkdir.js +21 -0
  49. package/dist/commands/fs/mv.d.ts +13 -0
  50. package/dist/commands/fs/mv.js +73 -0
  51. package/dist/commands/fs/rm.d.ts +24 -0
  52. package/dist/commands/fs/rm.js +108 -0
  53. package/dist/commands/fs/touch.d.ts +16 -0
  54. package/dist/commands/fs/touch.js +62 -0
  55. package/dist/commands/fs/upload.d.ts +55 -0
  56. package/dist/commands/fs/upload.js +221 -0
  57. package/dist/commands/groups/fields.d.ts +6 -0
  58. package/dist/commands/groups/fields.js +13 -0
  59. package/dist/commands/groups/list.d.ts +16 -0
  60. package/dist/commands/groups/list.js +26 -0
  61. package/dist/commands/man/doc.d.ts +16 -0
  62. package/dist/commands/man/doc.js +32 -0
  63. package/dist/commands/man/topics.d.ts +6 -0
  64. package/dist/commands/man/topics.js +27 -0
  65. package/dist/commands/pipeline/fields.d.ts +6 -0
  66. package/dist/commands/pipeline/fields.js +13 -0
  67. package/dist/commands/pipeline/run.d.ts +18 -0
  68. package/dist/commands/pipeline/run.js +33 -0
  69. package/dist/commands/plugin/readme.d.ts +14 -0
  70. package/dist/commands/plugin/readme.js +49 -0
  71. package/dist/commands/plugin/run.d.ts +10 -0
  72. package/dist/commands/plugin/run.js +29 -0
  73. package/dist/commands/plugin/search.d.ts +7 -0
  74. package/dist/commands/plugin/search.js +18 -0
  75. package/dist/commands/plugininstances/fields.d.ts +6 -0
  76. package/dist/commands/plugininstances/fields.js +13 -0
  77. package/dist/commands/plugininstances/list.d.ts +16 -0
  78. package/dist/commands/plugininstances/list.js +26 -0
  79. package/dist/commands/pluginmetas/fields.d.ts +6 -0
  80. package/dist/commands/pluginmetas/fields.js +13 -0
  81. package/dist/commands/pluginmetas/list.d.ts +16 -0
  82. package/dist/commands/pluginmetas/list.js +26 -0
  83. package/dist/commands/plugins/add.d.ts +34 -0
  84. package/dist/commands/plugins/add.js +374 -0
  85. package/dist/commands/plugins/delete.d.ts +14 -0
  86. package/dist/commands/plugins/delete.js +34 -0
  87. package/dist/commands/plugins/fields.d.ts +6 -0
  88. package/dist/commands/plugins/fields.js +17 -0
  89. package/dist/commands/plugins/list.d.ts +17 -0
  90. package/dist/commands/plugins/list.js +40 -0
  91. package/dist/commands/plugins/overview.d.ts +6 -0
  92. package/dist/commands/plugins/overview.js +17 -0
  93. package/dist/commands/store/list.d.ts +23 -0
  94. package/dist/commands/store/list.js +48 -0
  95. package/dist/commands/tags/fields.d.ts +6 -0
  96. package/dist/commands/tags/fields.js +13 -0
  97. package/dist/commands/tags/list.d.ts +16 -0
  98. package/dist/commands/tags/list.js +26 -0
  99. package/dist/commands/workflows/fields.d.ts +6 -0
  100. package/dist/commands/workflows/fields.js +13 -0
  101. package/dist/commands/workflows/list.d.ts +16 -0
  102. package/dist/commands/workflows/list.js +26 -0
  103. package/dist/config/colorConfig.d.ts +56 -0
  104. package/dist/config/colorConfig.js +161 -0
  105. package/dist/connect/connectHandler.d.ts +15 -0
  106. package/dist/connect/connectHandler.js +48 -0
  107. package/dist/context/contextCommand.d.ts +13 -0
  108. package/dist/context/contextCommand.js +193 -0
  109. package/dist/controllers/baseController.d.ts +43 -0
  110. package/dist/controllers/baseController.js +67 -0
  111. package/dist/controllers/feedController.d.ts +35 -0
  112. package/dist/controllers/feedController.js +53 -0
  113. package/dist/controllers/fileController.d.ts +56 -0
  114. package/dist/controllers/fileController.js +93 -0
  115. package/dist/controllers/pluginContextController.d.ts +24 -0
  116. package/dist/controllers/pluginContextController.js +49 -0
  117. package/dist/controllers/pluginController.d.ts +70 -0
  118. package/dist/controllers/pluginController.js +98 -0
  119. package/dist/controllers/pluginMetaController.d.ts +41 -0
  120. package/dist/controllers/pluginMetaController.js +52 -0
  121. package/dist/feeds/feedHandler.d.ts +64 -0
  122. package/dist/feeds/feedHandler.js +203 -0
  123. package/dist/filesystem/fileGroupHandler.d.ts +92 -0
  124. package/dist/filesystem/fileGroupHandler.js +318 -0
  125. package/dist/filesystem/filesystemHandler.d.ts +12 -0
  126. package/dist/filesystem/filesystemHandler.js +135 -0
  127. package/dist/filesystem/inodeCommand.d.ts +12 -0
  128. package/dist/filesystem/inodeCommand.js +37 -0
  129. package/dist/handlers/baseGroupHandler.d.ts +103 -0
  130. package/dist/handlers/baseGroupHandler.js +342 -0
  131. package/dist/index.d.ts +7 -0
  132. package/dist/index.js +239 -0
  133. package/dist/lfs/lfs.d.ts +25 -0
  134. package/dist/lfs/lfs.js +74 -0
  135. package/dist/man/man.d.ts +15 -0
  136. package/dist/man/man.js +31 -0
  137. package/dist/man/renderer.d.ts +26 -0
  138. package/dist/man/renderer.js +187 -0
  139. package/dist/models/feed.d.ts +18 -0
  140. package/dist/models/feed.js +8 -0
  141. package/dist/models/listing.d.ts +33 -0
  142. package/dist/models/listing.js +9 -0
  143. package/dist/models/plugin.d.ts +27 -0
  144. package/dist/models/plugin.js +1 -0
  145. package/dist/models/resource.d.ts +39 -0
  146. package/dist/models/resource.js +9 -0
  147. package/dist/pacs/pacsQueryHandler.d.ts +55 -0
  148. package/dist/pacs/pacsQueryHandler.js +196 -0
  149. package/dist/pacs/pacsQueryPayload.d.ts +19 -0
  150. package/dist/pacs/pacsQueryPayload.js +44 -0
  151. package/dist/pacs/pacsResultRender.d.ts +20 -0
  152. package/dist/pacs/pacsResultRender.js +141 -0
  153. package/dist/pacs/pacsRetrieveHandler.d.ts +87 -0
  154. package/dist/pacs/pacsRetrieveHandler.js +272 -0
  155. package/dist/pacs/pacsServerHandler.d.ts +15 -0
  156. package/dist/pacs/pacsServerHandler.js +32 -0
  157. package/dist/path/pathCommand.d.ts +64 -0
  158. package/dist/path/pathCommand.js +805 -0
  159. package/dist/path/pathMapper.d.ts +189 -0
  160. package/dist/path/pathMapper.js +382 -0
  161. package/dist/plugins/pluginGroupHandler.d.ts +42 -0
  162. package/dist/plugins/pluginGroupHandler.js +90 -0
  163. package/dist/plugins/pluginHandler.d.ts +87 -0
  164. package/dist/plugins/pluginHandler.js +303 -0
  165. package/dist/plugins/pluginMetaHandler.d.ts +21 -0
  166. package/dist/plugins/pluginMetaHandler.js +27 -0
  167. package/dist/screen/screen.d.ts +214 -0
  168. package/dist/screen/screen.js +478 -0
  169. package/dist/utils/admin_prompt.d.ts +42 -0
  170. package/dist/utils/admin_prompt.js +105 -0
  171. package/dist/utils/cli.d.ts +67 -0
  172. package/dist/utils/cli.js +112 -0
  173. package/dist/utils/docker.d.ts +74 -0
  174. package/dist/utils/docker.js +155 -0
  175. package/dist/utils/input_format.d.ts +77 -0
  176. package/dist/utils/input_format.js +135 -0
  177. package/dist/utils/sort.d.ts +29 -0
  178. package/dist/utils/sort.js +63 -0
  179. package/dist/utils/ui.d.ts +7 -0
  180. package/dist/utils/ui.js +26 -0
  181. package/dist/utils.d.ts +15 -0
  182. package/dist/utils.js +14 -0
  183. package/dist/views/compute.d.ts +17 -0
  184. package/dist/views/compute.js +40 -0
  185. package/dist/views/connect.d.ts +13 -0
  186. package/dist/views/connect.js +35 -0
  187. package/dist/views/feed.d.ts +44 -0
  188. package/dist/views/feed.js +110 -0
  189. package/dist/views/file.d.ts +25 -0
  190. package/dist/views/file.js +71 -0
  191. package/dist/views/fs.d.ts +51 -0
  192. package/dist/views/fs.js +105 -0
  193. package/dist/views/ls.d.ts +37 -0
  194. package/dist/views/ls.js +190 -0
  195. package/dist/views/plugin.d.ts +28 -0
  196. package/dist/views/plugin.js +71 -0
  197. package/dist/views/pluginParameters.d.ts +17 -0
  198. package/dist/views/pluginParameters.js +79 -0
  199. package/docs/00_intro.adoc +25 -0
  200. package/docs/01_setup.adoc +63 -0
  201. package/docs/02_context.adoc +128 -0
  202. package/docs/03_searchable.adoc +134 -0
  203. package/docs/10_everyday_examples.adoc +9 -0
  204. package/docs/11_upload_data.adoc +146 -0
  205. package/docs/12_create_a_feed.adoc +9 -0
  206. package/docs/13_run_a_plugin.adoc +271 -0
  207. package/docs/20_plugins.adoc +16 -0
  208. package/docs/21_pluginReadme.adoc +123 -0
  209. package/docs/30_filesystem.adoc +93 -0
  210. package/docs/31_fileops.adoc +51 -0
  211. package/docs/32_file_content.adoc +471 -0
  212. package/docs/_architecture.adoc +48 -0
  213. package/docs/_deepContext.adoc +84 -0
  214. package/docs/_roadmap.adoc +42 -0
  215. package/docs/_searchable.adoc +187 -0
  216. package/docs/_state.adoc +68 -0
  217. package/docs/pacs.adoc +101 -0
  218. package/docs/pathMapper.md +246 -0
  219. package/package.json +92 -0
@@ -0,0 +1,135 @@
1
+ /**
2
+ * @file Input Format Detection
3
+ *
4
+ * Utilities for detecting the format of plugin input strings (name, Docker image, or store URL).
5
+ * Used by plugin_add to determine the appropriate registration strategy.
6
+ *
7
+ * @module
8
+ */
9
+ /**
10
+ * Plugin input format types.
11
+ */
12
+ import readline from "readline";
13
+ /**
14
+ * Recognized input formats for plugin add (e.g. docker image, source URL).
15
+ */
16
+ export var PluginInputFormat;
17
+ (function (PluginInputFormat) {
18
+ PluginInputFormat["PLUGIN_NAME"] = "plugin_name";
19
+ PluginInputFormat["DOCKER_IMAGE"] = "docker_image";
20
+ PluginInputFormat["STORE_URL"] = "store_url";
21
+ })(PluginInputFormat || (PluginInputFormat = {}));
22
+ /**
23
+ * Detects the format of a plugin input string.
24
+ *
25
+ * Determines whether the input is:
26
+ * - A store URL (starts with http:// or https://)
27
+ * - A Docker image (contains / or :)
28
+ * - A plugin name (everything else)
29
+ *
30
+ * @param input - The plugin input string to analyze.
31
+ * @returns DetectedFormat object describing the input type.
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * input_detectFormat('pl-dircopy')
36
+ * // { format: 'plugin_name', value: 'pl-dircopy' }
37
+ *
38
+ * input_detectFormat('fnndsc/pl-dircopy:2.1.1')
39
+ * // { format: 'docker_image', value: 'fnndsc/pl-dircopy:2.1.1', pluginName: 'pl-dircopy', version: '2.1.1' }
40
+ *
41
+ * input_detectFormat('https://cube.chrisproject.org/api/v1/plugins/96/')
42
+ * // { format: 'store_url', value: 'https://...' }
43
+ * ```
44
+ */
45
+ export function input_detectFormat(input) {
46
+ const trimmedInput = input.trim();
47
+ // Check if it's a URL (store URL)
48
+ if (trimmedInput.startsWith('http://') || trimmedInput.startsWith('https://')) {
49
+ return {
50
+ format: PluginInputFormat.STORE_URL,
51
+ value: trimmedInput,
52
+ };
53
+ }
54
+ // Check if it's a Docker image (contains / or :)
55
+ if (trimmedInput.includes('/') || trimmedInput.includes(':')) {
56
+ const { name, version } = pluginNameAndVersion_extractFromImage(trimmedInput);
57
+ return {
58
+ format: PluginInputFormat.DOCKER_IMAGE,
59
+ value: trimmedInput,
60
+ pluginName: name,
61
+ version: version
62
+ };
63
+ }
64
+ // Otherwise, it's a plugin name
65
+ // Check if it includes version (e.g. pl-dircopy-v2.1.1)
66
+ if (trimmedInput.includes('-v')) {
67
+ const lastVIndex = trimmedInput.lastIndexOf('-v');
68
+ const name = trimmedInput.substring(0, lastVIndex);
69
+ const version = trimmedInput.substring(lastVIndex + 2); // +2 for '-v'
70
+ return {
71
+ format: PluginInputFormat.PLUGIN_NAME,
72
+ value: name, // Use name without version as value?
73
+ // Or keep original? Usually value is used for search.
74
+ // plugin_add uses detected.value as search term if pluginName is missing.
75
+ // But we supply pluginName now.
76
+ // Let's keep value as trimmedInput to be safe, but provide pluginName/version.
77
+ pluginName: name,
78
+ version: version
79
+ };
80
+ }
81
+ return {
82
+ format: PluginInputFormat.PLUGIN_NAME,
83
+ value: trimmedInput,
84
+ };
85
+ }
86
+ /**
87
+ * Extracts a plugin name and version from a Docker image string.
88
+ *
89
+ * Examples:
90
+ * 'fnndsc/pl-dircopy:2.1.1' -> { name: 'pl-dircopy', version: '2.1.1' }
91
+ * 'fnndsc/pl-dircopy' -> { name: 'pl-dircopy', version: undefined }
92
+ * 'pl-dircopy:latest' -> { name: 'pl-dircopy', version: 'latest' }
93
+ *
94
+ * @param dockerImage - Docker image string.
95
+ * @returns Object containing extracted plugin name and optional version.
96
+ */
97
+ export function pluginNameAndVersion_extractFromImage(dockerImage) {
98
+ // Split by / to get the last part (repository/image)
99
+ const parts = dockerImage.split('/');
100
+ const lastPart = parts[parts.length - 1];
101
+ const nameParts = lastPart.split(':');
102
+ const name = nameParts[0];
103
+ const version = nameParts.length > 1 ? nameParts[1] : undefined;
104
+ return { name, version };
105
+ }
106
+ /**
107
+ * Backward-compatible helper to extract only the plugin name from a Docker image.
108
+ *
109
+ * @param dockerImage - Docker image string.
110
+ * @returns The extracted plugin name.
111
+ */
112
+ export function pluginName_extractFromImage(dockerImage) {
113
+ const { name } = pluginNameAndVersion_extractFromImage(dockerImage);
114
+ return name;
115
+ }
116
+ /**
117
+ * Prompts the user for confirmation. Throws if declined or if prompt cannot be shown (non-TTY) without force.
118
+ *
119
+ * @param message - The confirmation message to display.
120
+ */
121
+ export async function prompt_confirmOrThrow(message) {
122
+ if (!process.stdout.isTTY) {
123
+ throw new Error(`${message} Use --force to skip confirmation.`);
124
+ }
125
+ const rl = readline.createInterface({
126
+ input: process.stdin,
127
+ output: process.stdout,
128
+ });
129
+ const question = (q) => new Promise((resolve) => rl.question(q, resolve));
130
+ const answer = (await question(`${message} `)).trim().toLowerCase();
131
+ rl.close();
132
+ if (answer !== "y" && answer !== "yes") {
133
+ throw new Error("Operation cancelled by user.");
134
+ }
135
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @file Generic sorting utilities for list operations.
3
+ *
4
+ * Provides type-safe sorting functionality that can be applied to any
5
+ * array of objects, supporting multiple sort fields and reverse ordering.
6
+ *
7
+ * @module
8
+ */
9
+ import { SimpleRecord } from "@fnndsc/cumin";
10
+ /**
11
+ * Sorts an array of objects by a specified field.
12
+ *
13
+ * @template T - The type of objects in the array.
14
+ * @param items - Array of objects to sort.
15
+ * @param sortBy - Field name to sort by.
16
+ * @param reverse - Whether to reverse the sort order (default: false).
17
+ * @returns A new sorted array (non-destructive).
18
+ */
19
+ export declare function items_sort<T extends SimpleRecord>(items: T[], sortBy?: string, reverse?: boolean): T[];
20
+ /**
21
+ * Applies sorting to a list result based on CLI options.
22
+ *
23
+ * @template T - The type of objects in the list.
24
+ * @param items - Array of items to potentially sort.
25
+ * @param sortField - Optional field name to sort by.
26
+ * @param reverse - Whether to reverse the sort order.
27
+ * @returns Sorted or original array.
28
+ */
29
+ export declare function list_applySort<T extends SimpleRecord>(items: T[], sortField?: string, reverse?: boolean): T[];
@@ -0,0 +1,63 @@
1
+ /**
2
+ * @file Generic sorting utilities for list operations.
3
+ *
4
+ * Provides type-safe sorting functionality that can be applied to any
5
+ * array of objects, supporting multiple sort fields and reverse ordering.
6
+ *
7
+ * @module
8
+ */
9
+ /**
10
+ * Sorts an array of objects by a specified field.
11
+ *
12
+ * @template T - The type of objects in the array.
13
+ * @param items - Array of objects to sort.
14
+ * @param sortBy - Field name to sort by.
15
+ * @param reverse - Whether to reverse the sort order (default: false).
16
+ * @returns A new sorted array (non-destructive).
17
+ */
18
+ export function items_sort(items, sortBy, reverse = false) {
19
+ if (!sortBy || items.length === 0) {
20
+ return items;
21
+ }
22
+ const sorted = [...items].sort((a, b) => {
23
+ const aVal = a[sortBy];
24
+ const bVal = b[sortBy];
25
+ // Handle undefined/null values
26
+ if (aVal === undefined || aVal === null)
27
+ return 1;
28
+ if (bVal === undefined || bVal === null)
29
+ return -1;
30
+ let comparison = 0;
31
+ // Determine comparison based on type
32
+ if (typeof aVal === 'number' && typeof bVal === 'number') {
33
+ comparison = aVal - bVal;
34
+ }
35
+ else if (typeof aVal === 'string' && typeof bVal === 'string') {
36
+ comparison = aVal.localeCompare(bVal);
37
+ }
38
+ else if (aVal instanceof Date && bVal instanceof Date) {
39
+ comparison = aVal.getTime() - bVal.getTime();
40
+ }
41
+ else {
42
+ // Fallback: convert to string and compare
43
+ comparison = String(aVal).localeCompare(String(bVal));
44
+ }
45
+ return reverse ? -comparison : comparison;
46
+ });
47
+ return sorted;
48
+ }
49
+ /**
50
+ * Applies sorting to a list result based on CLI options.
51
+ *
52
+ * @template T - The type of objects in the list.
53
+ * @param items - Array of items to potentially sort.
54
+ * @param sortField - Optional field name to sort by.
55
+ * @param reverse - Whether to reverse the sort order.
56
+ * @returns Sorted or original array.
57
+ */
58
+ export function list_applySort(items, sortField, reverse) {
59
+ if (!sortField) {
60
+ return items;
61
+ }
62
+ return items_sort(items, sortField, reverse || false);
63
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Prompts the user for a yes/no confirmation.
3
+ *
4
+ * @param question - The question to ask.
5
+ * @returns A Promise resolving to true if the user answers 'y', false otherwise.
6
+ */
7
+ export declare function prompt_confirm(question: string): Promise<boolean>;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @file User Interface Utilities.
3
+ *
4
+ * This module provides helper functions for CLI interactions, such as prompts.
5
+ *
6
+ * @module
7
+ */
8
+ import * as readline from "readline";
9
+ /**
10
+ * Prompts the user for a yes/no confirmation.
11
+ *
12
+ * @param question - The question to ask.
13
+ * @returns A Promise resolving to true if the user answers 'y', false otherwise.
14
+ */
15
+ export async function prompt_confirm(question) {
16
+ const rl = readline.createInterface({
17
+ input: process.stdin,
18
+ output: process.stdout,
19
+ });
20
+ return new Promise((resolve) => {
21
+ rl.question(`${question} (y/N) `, (answer) => {
22
+ rl.close();
23
+ resolve(answer.toLowerCase() === "y");
24
+ });
25
+ });
26
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @file Utils exports for chili
3
+ *
4
+ * This file exports utility functions without triggering the main CLI.
5
+ * Used by other packages like chell to import utilities.
6
+ *
7
+ * @module
8
+ */
9
+ export { logical_toPhysical } from './utils/cli.js';
10
+ export { PathMapper, pathMapper_get } from './path/pathMapper.js';
11
+ export type { CacheStats } from './path/pathMapper.js';
12
+ /**
13
+ * Re-exports connection initialization from cumin to align duplicate package boundaries.
14
+ */
15
+ export { chrisConnection_init } from '@fnndsc/cumin';
package/dist/utils.js ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @file Utils exports for chili
3
+ *
4
+ * This file exports utility functions without triggering the main CLI.
5
+ * Used by other packages like chell to import utilities.
6
+ *
7
+ * @module
8
+ */
9
+ export { logical_toPhysical } from './utils/cli.js';
10
+ export { PathMapper, pathMapper_get } from './path/pathMapper.js';
11
+ /**
12
+ * Re-exports connection initialization from cumin to align duplicate package boundaries.
13
+ */
14
+ export { chrisConnection_init } from '@fnndsc/cumin';
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @file View layer for compute resource commands.
3
+ *
4
+ * @module
5
+ */
6
+ import { ComputeResource } from '@fnndsc/cumin';
7
+ /**
8
+ * Renders a list of compute resources.
9
+ *
10
+ * @param resources - Array of ComputeResource objects.
11
+ * @param options - Output options (table, csv).
12
+ * @returns Formatted string.
13
+ */
14
+ export declare function computeList_render(resources: ComputeResource[], options?: {
15
+ table?: boolean;
16
+ csv?: boolean;
17
+ }): string;
@@ -0,0 +1,40 @@
1
+ import chalk from 'chalk';
2
+ /**
3
+ * Renders a list of compute resources.
4
+ *
5
+ * @param resources - Array of ComputeResource objects.
6
+ * @param options - Output options (table, csv).
7
+ * @returns Formatted string.
8
+ */
9
+ export function computeList_render(resources, options = {}) {
10
+ if (resources.length === 0)
11
+ return chalk.gray('No compute resources found.');
12
+ const fields = ['id', 'name', 'compute_url', 'description'];
13
+ const headers = ['ID', 'NAME', 'URL', 'DESCRIPTION'];
14
+ if (options.csv) {
15
+ const lines = [headers.map((h) => `"${h}"`).join(',')];
16
+ for (const r of resources) {
17
+ lines.push(fields.map((f) => `"${r[f] ?? ''}"`).join(','));
18
+ }
19
+ return lines.join('\n');
20
+ }
21
+ if (options.table) {
22
+ const colWidths = fields.map((f, i) => Math.max(headers[i].length, ...resources.map((r) => String(r[f] ?? '').length)));
23
+ const header = headers.map((h, i) => h.padEnd(colWidths[i])).join(' ');
24
+ const divider = colWidths.map((w) => '─'.repeat(w)).join(' ');
25
+ const rows = resources.map((r) => fields.map((f, i) => String(r[f] ?? '').padEnd(colWidths[i])).join(' '));
26
+ return [chalk.bold(header), chalk.gray(divider), ...rows].join('\n');
27
+ }
28
+ const termWidth = process.stdout.columns || 120;
29
+ const urlWidth = 40;
30
+ const nameWidth = 20;
31
+ const lines = [];
32
+ for (const r of resources) {
33
+ const id = chalk.bold.gray(String(r.id).padStart(4));
34
+ const name = chalk.cyan(String(r.name).padEnd(nameWidth));
35
+ const url = chalk.blue(String(r.compute_url ?? '').substring(0, urlWidth).padEnd(urlWidth));
36
+ const desc = chalk.gray(String(r.description ?? '').substring(0, termWidth - nameWidth - urlWidth - 12));
37
+ lines.push(`${id} ${name} ${url} ${desc}`);
38
+ }
39
+ return lines.join('\n');
40
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Renders the result of a login attempt.
3
+ * @param success - Whether the connection was successful.
4
+ * @param url - The URL connected to.
5
+ * @param user - The user logged in as.
6
+ * @param token - The auth token received (optional, usually not displayed in full).
7
+ */
8
+ export declare function login_render(success: boolean, url: string, user: string, token?: string): string;
9
+ /**
10
+ * Renders the result of a logout attempt.
11
+ * @param success - Whether the logout was successful.
12
+ */
13
+ export declare function logout_render(success: boolean): string;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @file View layer for connection commands.
3
+ *
4
+ * Provides standard output formatting for login/logout operations.
5
+ *
6
+ * @module
7
+ */
8
+ import chalk from 'chalk';
9
+ /**
10
+ * Renders the result of a login attempt.
11
+ * @param success - Whether the connection was successful.
12
+ * @param url - The URL connected to.
13
+ * @param user - The user logged in as.
14
+ * @param token - The auth token received (optional, usually not displayed in full).
15
+ */
16
+ export function login_render(success, url, user, token) {
17
+ if (success) {
18
+ return chalk.green(`Successfully connected to ${url} as ${user}.`);
19
+ }
20
+ else {
21
+ return chalk.red(`Failed to connect to ${url} as ${user}.`);
22
+ }
23
+ }
24
+ /**
25
+ * Renders the result of a logout attempt.
26
+ * @param success - Whether the logout was successful.
27
+ */
28
+ export function logout_render(success) {
29
+ if (success) {
30
+ return chalk.green('Logged out from ChRIS.');
31
+ }
32
+ else {
33
+ return chalk.red('Logout failed.');
34
+ }
35
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @file View layer for Feed commands.
3
+ *
4
+ * Provides output formatting for feed listing and creation.
5
+ *
6
+ * @module
7
+ */
8
+ import { SimpleRecord } from '@fnndsc/cumin';
9
+ import { Feed } from '../models/feed.js';
10
+ import type { FeedNote } from '../commands/feed/note.js';
11
+ import type { FeedComment } from '../commands/feed/comments.js';
12
+ /**
13
+ * Options for rendering output.
14
+ */
15
+ export interface OutputOptions {
16
+ table?: boolean;
17
+ csv?: boolean;
18
+ }
19
+ /**
20
+ * Renders a list of feeds.
21
+ * @param feeds - Array of Feed objects.
22
+ * @param selectedFields - The fields to display, in order.
23
+ * @param options - Output options (e.g., table, csv).
24
+ */
25
+ export declare function feedList_render(feeds: Feed[], selectedFields: string[], options?: OutputOptions): string;
26
+ /**
27
+ * Renders the result of feed creation.
28
+ * @param feedRecord - The created feed record (SimpleRecord).
29
+ */
30
+ export declare function feedCreate_render(feedRecord: SimpleRecord): string;
31
+ /**
32
+ * Renders a feed note.
33
+ *
34
+ * @param note - Note data.
35
+ * @param feedId - Feed ID for context header.
36
+ */
37
+ export declare function feedNote_render(note: FeedNote, feedId: number): string;
38
+ /**
39
+ * Renders a list of feed comments.
40
+ *
41
+ * @param comments - Array of comments.
42
+ * @param feedId - Feed ID for context header.
43
+ */
44
+ export declare function feedComments_render(comments: FeedComment[], feedId: number): string;
@@ -0,0 +1,110 @@
1
+ import chalk from 'chalk';
2
+ import { screen } from '../screen/screen.js';
3
+ /**
4
+ * Renders a list of feeds.
5
+ * @param feeds - Array of Feed objects.
6
+ * @param selectedFields - The fields to display, in order.
7
+ * @param options - Output options (e.g., table, csv).
8
+ */
9
+ export function feedList_render(feeds, selectedFields, options = {}) {
10
+ if (feeds.length === 0)
11
+ return chalk.gray("No feeds found.");
12
+ // Define default fields if none are specified or if the fields are empty
13
+ const effectiveFields = selectedFields.length > 0 ? selectedFields : ['id', 'name', 'creation_date', 'owner_username'];
14
+ const rows = feeds.map(f => {
15
+ return effectiveFields.map(field => {
16
+ const fieldKey = field;
17
+ const rawValue = f[fieldKey];
18
+ let value = rawValue !== undefined && rawValue !== null ? String(rawValue) : '';
19
+ // Apply basic styling for key fields only in non-CSV/non-Table output
20
+ if (!options.csv && !options.table) {
21
+ if (field === 'id')
22
+ return chalk.bold(value);
23
+ if (field === 'name')
24
+ return chalk.cyan(value);
25
+ }
26
+ if (field === 'creation_date' && value.length > 19)
27
+ return value.substring(0, 19); // Truncate ISO string
28
+ return value;
29
+ });
30
+ });
31
+ const headerForDisplay = effectiveFields.map(field => field.toUpperCase());
32
+ if (options.csv) {
33
+ // CSV format
34
+ const csvHeader = headerForDisplay.map(h => `"${h}"`).join(',');
35
+ const csvRows = rows.map(row => row.map(cell => `"${String(cell).split('"').join('""')}"`).join(',')).join('\n'); // Fixed CSV escaping
36
+ return [csvHeader, csvRows].join('\n');
37
+ }
38
+ else if (options.table) {
39
+ const tableDataForScreen = feeds.map(feed => {
40
+ const row = {};
41
+ effectiveFields.forEach(field => {
42
+ const fieldKey = field;
43
+ const val = feed[fieldKey];
44
+ row[field] = val !== undefined && val !== null ? val : '';
45
+ });
46
+ return row;
47
+ });
48
+ // Pass original effectiveFields as head for correct data mapping, headerForDisplay for title
49
+ return screen.table_output(tableDataForScreen, {
50
+ head: effectiveFields,
51
+ title: { title: "Feeds", justification: "center" },
52
+ typeColors: {
53
+ string: "green",
54
+ number: "yellow",
55
+ boolean: "cyan",
56
+ object: "magenta"
57
+ }
58
+ });
59
+ }
60
+ else {
61
+ // Default list format (tab-separated)
62
+ return rows.map(row => row.join('\t')).join('\n');
63
+ }
64
+ }
65
+ /**
66
+ * Renders the result of feed creation.
67
+ * @param feedRecord - The created feed record (SimpleRecord).
68
+ */
69
+ export function feedCreate_render(feedRecord) {
70
+ return chalk.green(`Feed created successfully.\nID: ${feedRecord.id}\nName: ${feedRecord.name}`);
71
+ }
72
+ /**
73
+ * Renders a feed note.
74
+ *
75
+ * @param note - Note data.
76
+ * @param feedId - Feed ID for context header.
77
+ */
78
+ export function feedNote_render(note, feedId) {
79
+ const lines = [
80
+ chalk.bold.cyan(`Note for feed ${feedId}`),
81
+ chalk.gray('─'.repeat(40)),
82
+ ];
83
+ if (note.title)
84
+ lines.push(`${chalk.bold('Title:')} ${note.title}`);
85
+ lines.push(`${chalk.bold('Content:')} ${note.content || chalk.gray('(empty)')}`);
86
+ return lines.join('\n');
87
+ }
88
+ /**
89
+ * Renders a list of feed comments.
90
+ *
91
+ * @param comments - Array of comments.
92
+ * @param feedId - Feed ID for context header.
93
+ */
94
+ export function feedComments_render(comments, feedId) {
95
+ if (comments.length === 0) {
96
+ return chalk.gray(`No comments on feed ${feedId}.`);
97
+ }
98
+ const lines = [
99
+ chalk.bold.cyan(`Comments on feed ${feedId}`) + chalk.gray(` (${comments.length})`),
100
+ chalk.gray('─'.repeat(50)),
101
+ ];
102
+ for (const c of comments) {
103
+ lines.push(`${chalk.bold.gray(String(c.id).padStart(4))} ` +
104
+ `${chalk.cyan(c.owner_username.padEnd(16))} ` +
105
+ `${chalk.bold(c.title || chalk.gray('(no title)'))}`);
106
+ if (c.content)
107
+ lines.push(` ${chalk.white(c.content)}`);
108
+ }
109
+ return lines.join('\n');
110
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Options for rendering output.
3
+ */
4
+ export interface OutputOptions {
5
+ table?: boolean;
6
+ csv?: boolean;
7
+ }
8
+ /**
9
+ * Represents a file resource item.
10
+ */
11
+ export interface FileResource {
12
+ id?: number;
13
+ fname?: string;
14
+ fsize?: number;
15
+ owner_username?: string;
16
+ creation_date?: string;
17
+ [key: string]: string | number | boolean | null | undefined;
18
+ }
19
+ /**
20
+ * Renders a list of files.
21
+ * @param files - Array of file resource objects.
22
+ * @param selectedFields - The fields to display, in order.
23
+ * @param options - Output options (e.g., table, csv).
24
+ */
25
+ export declare function fileList_render(files: FileResource[], selectedFields: string[], options?: OutputOptions): string;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * @file View layer for File commands.
3
+ *
4
+ * Provides output formatting for file listing (files, dirs, links).
5
+ *
6
+ * @module
7
+ */
8
+ import chalk from 'chalk';
9
+ import { screen } from '../screen/screen.js';
10
+ /**
11
+ * Renders a list of files.
12
+ * @param files - Array of file resource objects.
13
+ * @param selectedFields - The fields to display, in order.
14
+ * @param options - Output options (e.g., table, csv).
15
+ */
16
+ export function fileList_render(files, selectedFields, options = {}) {
17
+ if (files.length === 0)
18
+ return chalk.gray("No files found.");
19
+ // Define default fields if none are specified or if the fields are empty
20
+ const effectiveFields = selectedFields.length > 0
21
+ ? selectedFields
22
+ : ['id', 'fname', 'fsize', 'owner_username', 'creation_date'];
23
+ const rows = files.map(f => {
24
+ return effectiveFields.map(field => {
25
+ const rawValue = f[field];
26
+ let value = rawValue !== undefined && rawValue !== null ? String(rawValue) : '';
27
+ // Apply basic styling for key fields only in non-CSV/non-Table output
28
+ if (!options.csv && !options.table) {
29
+ if (field === 'id')
30
+ return chalk.bold(value);
31
+ if (field === 'fname')
32
+ return chalk.cyan(value);
33
+ }
34
+ if (field === 'creation_date' && value.length > 19)
35
+ return value.substring(0, 19);
36
+ return value;
37
+ });
38
+ });
39
+ const headerForDisplay = effectiveFields.map(field => field.toUpperCase());
40
+ if (options.csv) {
41
+ // CSV format
42
+ const csvHeader = headerForDisplay.map(h => `"${h}"`).join(',');
43
+ const csvRows = rows.map(row => row.map(cell => `"${String(cell).split('"').join('""')}"`).join(',')).join('\n');
44
+ return [csvHeader, csvRows].join('\n');
45
+ }
46
+ else if (options.table) {
47
+ // Prepare data for screen.table_output
48
+ const tableDataForScreen = files.map(file => {
49
+ const row = {};
50
+ effectiveFields.forEach(field => {
51
+ const val = file[field];
52
+ row[field] = val !== undefined && val !== null ? val : '';
53
+ });
54
+ return row;
55
+ });
56
+ return screen.table_output(tableDataForScreen, {
57
+ head: effectiveFields,
58
+ title: { title: "Files", justification: "center" },
59
+ typeColors: {
60
+ string: "green",
61
+ number: "yellow",
62
+ boolean: "cyan",
63
+ object: "magenta"
64
+ }
65
+ });
66
+ }
67
+ else {
68
+ // Default list format (no header)
69
+ return rows.map(row => row.join('\t')).join('\n');
70
+ }
71
+ }