@fnndsc/chili 3.2.5 → 3.4.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.
- package/README.md +18 -11
- package/dist/commands/fs/download.d.ts +19 -4
- package/dist/commands/fs/download.js +71 -62
- package/dist/commands/fs/upload.d.ts +20 -4
- package/dist/commands/fs/upload.js +42 -31
- package/dist/commands/man/doc.js +1 -1
- package/dist/commands/plugin/readme.js +3 -0
- package/dist/filesystem/fileGroupHandler.d.ts +0 -5
- package/dist/filesystem/fileGroupHandler.js +2 -19
- package/dist/handlers/baseGroupHandler.d.ts +10 -8
- package/dist/handlers/baseGroupHandler.js +28 -23
- package/dist/index.d.ts +6 -1
- package/dist/index.js +13 -179
- package/dist/man/renderer.d.ts +1 -1
- package/dist/man/renderer.js +6 -8
- package/dist/path/pathCommand.js +6 -3
- package/dist/plugins/pluginGroupHandler.d.ts +18 -0
- package/dist/plugins/pluginGroupHandler.js +40 -1
- package/dist/run.d.ts +24 -0
- package/dist/run.js +192 -0
- package/dist/screen/screen.d.ts +13 -0
- package/dist/screen/screen.js +44 -0
- package/dist/utils/resourceData.d.ts +16 -0
- package/dist/utils/resourceData.js +23 -0
- package/dist/views/pluginParameters.d.ts +10 -0
- package/dist/views/pluginParameters.js +24 -17
- package/docs/pacs.adoc +3 -3
- package/package.json +6 -8
package/dist/index.js
CHANGED
|
@@ -2,62 +2,18 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* @file Command-line entry point for the chili (ChILI) CLI.
|
|
4
4
|
*
|
|
5
|
-
* @
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* This warning originates from the `proxy-from-env` package (version 1.1.0)
|
|
11
|
-
* used by axios for proxy configuration. The package uses the legacy `url.parse()`
|
|
12
|
-
* API which is deprecated in favor of the WHATWG URL API.
|
|
5
|
+
* This is a thin wrapper: all command wiring and execution live in {@link run}
|
|
6
|
+
* (./run.js) so the same logic can be driven in-process by a host such as chell
|
|
7
|
+
* without spawning a separate `node` subprocess. This file only adds the
|
|
8
|
+
* bin-only concerns — shell completion and fatal-exit handling.
|
|
13
9
|
*
|
|
14
|
-
*
|
|
15
|
-
* - It's a transitive dependency (axios → proxy-from-env) we don't control
|
|
16
|
-
* - proxy-from-env 1.1.0 is the latest version and hasn't been updated
|
|
17
|
-
* - According to the warning: "CVEs are not issued for url.parse() vulnerabilities"
|
|
18
|
-
* - The warning doesn't affect functionality, only console output
|
|
19
|
-
* - This is a well-known issue in the Node.js ecosystem
|
|
20
|
-
*
|
|
21
|
-
* This can be removed once:
|
|
22
|
-
* - proxy-from-env migrates to WHATWG URL API, OR
|
|
23
|
-
* - axios replaces proxy-from-env with an alternative
|
|
24
|
-
*
|
|
25
|
-
* Tracking: https://github.com/Rob--W/proxy-from-env/issues/51
|
|
10
|
+
* @module
|
|
26
11
|
*/
|
|
27
|
-
const originalEmitWarning = process.emitWarning;
|
|
28
|
-
process.emitWarning = function (warning, ...args) {
|
|
29
|
-
// Suppress only the specific DEP0169 warning
|
|
30
|
-
if (typeof warning === 'string' &&
|
|
31
|
-
(warning.includes('DEP0169') || warning.includes('url.parse()'))) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
// Allow all other warnings through
|
|
35
|
-
return originalEmitWarning.call(process, warning, ...args);
|
|
36
|
-
};
|
|
37
|
-
import { Command } from "commander";
|
|
38
|
-
import figlet from "figlet";
|
|
39
12
|
import omelette from "omelette";
|
|
40
|
-
import {
|
|
41
|
-
import { FeedGroupHandler, FeedMemberHandler } from "./feeds/feedHandler.js";
|
|
42
|
-
import { PluginGroupHandler, PluginMemberHandler, } from "./plugins/pluginHandler.js";
|
|
43
|
-
import { PluginMetaGroupHandler } from "./plugins/pluginMetaHandler.js";
|
|
44
|
-
import { PluginContextGroupHandler } from "./plugins/pluginGroupHandler.js";
|
|
45
|
-
import { inodeCommand_setup } from "./filesystem/inodeCommand.js";
|
|
46
|
-
import { contextCommand_setup } from "./context/contextCommand.js";
|
|
47
|
-
import { pathCommand_setup } from "./path/pathCommand.js";
|
|
48
|
-
import { fileBrowserCommand_setup } from "./filesystem/filesystemHandler.js";
|
|
49
|
-
import { manCommand_setup } from "./man/man.js";
|
|
50
|
-
import { chefsCommand_setup } from "./chefs/chefs.js";
|
|
51
|
-
import { PACSServerGroupHandler } from "./pacs/pacsServerHandler.js";
|
|
52
|
-
import { PACSQueryGroupHandler } from "./pacs/pacsQueryHandler.js";
|
|
53
|
-
import { PACSRetrieveGroupHandler } from "./pacs/pacsRetrieveHandler.js";
|
|
54
|
-
import { chrisConnection_init, NodeStorageProvider, errorStack_getAllOfType } from "@fnndsc/cumin";
|
|
55
|
-
import { FileGroupHandler } from "./filesystem/fileGroupHandler.js";
|
|
56
|
-
const program = new Command();
|
|
57
|
-
program.version("1.0.1").description("A CLI for ChRIS");
|
|
13
|
+
import { run } from "./run.js";
|
|
58
14
|
/**
|
|
59
|
-
* Sets up command completion for the
|
|
60
|
-
* This
|
|
15
|
+
* Sets up shell command completion for the standalone chili CLI using omelette.
|
|
16
|
+
* This is a bin-only concern; in-process hosts provide their own completion.
|
|
61
17
|
*/
|
|
62
18
|
function commandCompletion_setup() {
|
|
63
19
|
const completion = omelette(`chili|chili`);
|
|
@@ -95,7 +51,6 @@ function commandCompletion_setup() {
|
|
|
95
51
|
});
|
|
96
52
|
completion.on("man.doc", ({ reply }) => {
|
|
97
53
|
console.log("Autocomplete triggered for man doc command");
|
|
98
|
-
// We'll implement actual topic retrieval here later
|
|
99
54
|
reply([]);
|
|
100
55
|
});
|
|
101
56
|
completion.init();
|
|
@@ -104,136 +59,15 @@ function commandCompletion_setup() {
|
|
|
104
59
|
}
|
|
105
60
|
}
|
|
106
61
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
* @param program - The Commander.js program instance.
|
|
110
|
-
*/
|
|
111
|
-
async function handlers_initialize() {
|
|
112
|
-
// const client = await chrisConnection.client_get();
|
|
113
|
-
// We don't enforce connection here to allow --help to work.
|
|
114
|
-
// Commands will fail individually if not connected.
|
|
115
|
-
fileBrowserCommand_setup(program);
|
|
116
|
-
contextCommand_setup(program);
|
|
117
|
-
pathCommand_setup(program);
|
|
118
|
-
manCommand_setup(program);
|
|
119
|
-
chefsCommand_setup(program);
|
|
120
|
-
const pacsServerHandler = new PACSServerGroupHandler();
|
|
121
|
-
pacsServerHandler.pacsServerCommand_setup(program);
|
|
122
|
-
const pacsQueryHandler = new PACSQueryGroupHandler();
|
|
123
|
-
pacsQueryHandler.pacsQueryCommand_setup(program);
|
|
124
|
-
const pacsRetrieveHandler = new PACSRetrieveGroupHandler();
|
|
125
|
-
pacsRetrieveHandler.pacsRetrieveCommand_setup(program);
|
|
126
|
-
await inodeCommand_setup(program);
|
|
127
|
-
const pluginGroupHandler = new PluginGroupHandler();
|
|
128
|
-
pluginGroupHandler.pluginGroupCommand_setup(program);
|
|
129
|
-
const pluginMetaGroupHandler = new PluginMetaGroupHandler();
|
|
130
|
-
pluginMetaGroupHandler.pluginMetaGroupCommand_setup(program);
|
|
131
|
-
const feedGroupHandler = new FeedGroupHandler();
|
|
132
|
-
feedGroupHandler.feedGroupCommand_setup(program);
|
|
133
|
-
const feedMemberHandler = new FeedMemberHandler();
|
|
134
|
-
feedMemberHandler.feedCommand_setup(program);
|
|
135
|
-
const pluginMemberHandler = new PluginMemberHandler();
|
|
136
|
-
pluginMemberHandler.pluginCommand_setup(program);
|
|
137
|
-
try {
|
|
138
|
-
const filesGroupHandler = await FileGroupHandler.handler_create("files");
|
|
139
|
-
filesGroupHandler.fileGroupCommand_setup(program);
|
|
140
|
-
const linksGroupHandler = await FileGroupHandler.handler_create("links");
|
|
141
|
-
linksGroupHandler.fileGroupCommand_setup(program);
|
|
142
|
-
const dirsGroupHandler = await FileGroupHandler.handler_create("dirs");
|
|
143
|
-
dirsGroupHandler.fileGroupCommand_setup(program);
|
|
144
|
-
}
|
|
145
|
-
catch (e) {
|
|
146
|
-
const err = e instanceof Error ? e.message : String(e);
|
|
147
|
-
const errors = errorStack_getAllOfType("error");
|
|
148
|
-
const warnings = errorStack_getAllOfType("warning");
|
|
149
|
-
console.log(`Note: File group commands (files, dirs, links) are unavailable. Reason: ${err}`);
|
|
150
|
-
if (errors.length > 0) {
|
|
151
|
-
console.log("Errors:");
|
|
152
|
-
errors.forEach(msg => console.log(` - ${msg}`));
|
|
153
|
-
}
|
|
154
|
-
if (warnings.length > 0) {
|
|
155
|
-
console.log("Warnings:");
|
|
156
|
-
warnings.forEach(msg => console.log(` - ${msg}`));
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
try {
|
|
160
|
-
const computesOfPluginHandler = await PluginContextGroupHandler.handler_create("computesofplugin");
|
|
161
|
-
computesOfPluginHandler.pluginContextGroupCommand_setup(program);
|
|
162
|
-
const pluginInstancesHandler = await PluginContextGroupHandler.handler_create("instancesofplugin");
|
|
163
|
-
pluginInstancesHandler.pluginContextGroupCommand_setup(program);
|
|
164
|
-
const pluginParametersHandler = await PluginContextGroupHandler.handler_create("parametersofplugin");
|
|
165
|
-
pluginParametersHandler.pluginContextGroupCommand_setup(program);
|
|
166
|
-
}
|
|
167
|
-
catch (e) {
|
|
168
|
-
const err = e instanceof Error ? e.message : String(e);
|
|
169
|
-
const errors = errorStack_getAllOfType("error");
|
|
170
|
-
const warnings = errorStack_getAllOfType("warning");
|
|
171
|
-
console.log(`Note: Plugin context commands are unavailable. Reason: ${err}`);
|
|
172
|
-
if (errors.length > 0) {
|
|
173
|
-
console.log("Errors:");
|
|
174
|
-
errors.forEach(msg => console.log(` - ${msg}`));
|
|
175
|
-
}
|
|
176
|
-
if (warnings.length > 0) {
|
|
177
|
-
console.log("Warnings:");
|
|
178
|
-
warnings.forEach(msg => console.log(` - ${msg}`));
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
commandCompletion_setup();
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Parses the command line arguments to extract context information.
|
|
185
|
-
*
|
|
186
|
-
* @param args - The command line arguments array (process.argv).
|
|
187
|
-
* @returns A tuple containing the context string (if found) and the remaining arguments.
|
|
188
|
-
*/
|
|
189
|
-
function context_parse(args) {
|
|
190
|
-
// Find the first argument that looks like a context string (contains "=" but doesn't start with "-")
|
|
191
|
-
for (let i = 2; i < args.length; i++) {
|
|
192
|
-
const arg = args[i];
|
|
193
|
-
if (arg.includes("=") && !arg.startsWith("-")) {
|
|
194
|
-
const context = arg;
|
|
195
|
-
// Reconstruct args without the context string
|
|
196
|
-
const newArgs = [...args.slice(0, i), ...args.slice(i + 1)];
|
|
197
|
-
return [context, newArgs];
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
return [undefined, args];
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Main function to run the ChILI CLI.
|
|
204
|
-
* Handles initialization, context parsing, and command execution.
|
|
62
|
+
* Bin entry: register shell completion, then run the requested chili command.
|
|
205
63
|
*/
|
|
206
64
|
async function main() {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const [context, newArgs] = context_parse(process.argv);
|
|
210
|
-
if (context) {
|
|
211
|
-
const contextSetSuccess = await connection.context_set(context);
|
|
212
|
-
if (!contextSetSuccess) {
|
|
213
|
-
console.error("Failed to set context. Exiting.");
|
|
214
|
-
process.exit(1);
|
|
215
|
-
}
|
|
216
|
-
process.argv = newArgs;
|
|
217
|
-
}
|
|
218
|
-
program
|
|
219
|
-
.name("chili")
|
|
220
|
-
.description("ChILI handles Intelligent Line Interactions")
|
|
221
|
-
.option("-v, --verbose", "enable verbose output")
|
|
222
|
-
.option("-c, --config <path>", "path to config file")
|
|
223
|
-
.option("-s, --nosplash", "disable splash screen");
|
|
224
|
-
connectCommand_setup(program);
|
|
225
|
-
await handlers_initialize(); // Call handlers_initialize here
|
|
226
|
-
program.parseOptions(process.argv);
|
|
227
|
-
const options = program.opts();
|
|
228
|
-
if (!options.nosplash) {
|
|
229
|
-
console.log(figlet.textSync("ChILI"));
|
|
230
|
-
console.log("ChILI handles Intelligent Line Interactions");
|
|
231
|
-
}
|
|
232
|
-
program.parse(process.argv);
|
|
65
|
+
commandCompletion_setup();
|
|
66
|
+
await run(process.argv.slice(2));
|
|
233
67
|
}
|
|
234
68
|
main().catch((error) => {
|
|
235
69
|
console.error("An error occurred:", error);
|
|
236
70
|
process.exit(1);
|
|
237
71
|
});
|
|
238
|
-
//
|
|
239
|
-
export { logical_toPhysical } from
|
|
72
|
+
// Re-export library utilities for consumers that import the package root.
|
|
73
|
+
export { logical_toPhysical } from "./utils/cli.js";
|
package/dist/man/renderer.d.ts
CHANGED
|
@@ -23,4 +23,4 @@ export declare function asciidoc_render(content: string, style: "figlet" | "asci
|
|
|
23
23
|
*
|
|
24
24
|
* @param filePath - The path to the file to open.
|
|
25
25
|
*/
|
|
26
|
-
export declare function browser_open(filePath: string): void
|
|
26
|
+
export declare function browser_open(filePath: string): Promise<void>;
|
package/dist/man/renderer.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import fs from "fs";
|
|
7
7
|
import path from "path";
|
|
8
8
|
import chalk from "chalk";
|
|
9
|
-
import
|
|
9
|
+
import { convert as adoc_convert } from "asciidoctor";
|
|
10
10
|
import { exec } from "child_process";
|
|
11
11
|
import os from "os";
|
|
12
12
|
const headingStyles = [
|
|
@@ -63,9 +63,8 @@ export function projectDir_get() {
|
|
|
63
63
|
* @param content - The AsciiDoc content string.
|
|
64
64
|
* @returns The converted HTML string.
|
|
65
65
|
*/
|
|
66
|
-
function adoc_htmlConvert(content) {
|
|
67
|
-
|
|
68
|
-
let result = ascii.convert(content, {
|
|
66
|
+
async function adoc_htmlConvert(content) {
|
|
67
|
+
let result = await adoc_convert(content, {
|
|
69
68
|
standalone: false,
|
|
70
69
|
attributes: {
|
|
71
70
|
showtitle: "",
|
|
@@ -107,7 +106,7 @@ function text_wrap(text, width) {
|
|
|
107
106
|
* @returns A Promise resolving to the formatted string.
|
|
108
107
|
*/
|
|
109
108
|
export async function asciidoc_render(content, style, width) {
|
|
110
|
-
let result = adoc_htmlConvert(content);
|
|
109
|
+
let result = await adoc_htmlConvert(content);
|
|
111
110
|
function ASCII_create(text, style) {
|
|
112
111
|
const transformedText = style.textTransform(text);
|
|
113
112
|
return style.color(transformedText);
|
|
@@ -159,12 +158,11 @@ export async function asciidoc_render(content, style, width) {
|
|
|
159
158
|
*
|
|
160
159
|
* @param filePath - The path to the file to open.
|
|
161
160
|
*/
|
|
162
|
-
export function browser_open(filePath) {
|
|
163
|
-
const ascii = asciidoctor();
|
|
161
|
+
export async function browser_open(filePath) {
|
|
164
162
|
const tempHtmlPath = path.join(os.tmpdir(), path.basename(filePath).replace(".adoc", ".html"));
|
|
165
163
|
try {
|
|
166
164
|
const content = fs.readFileSync(filePath, "utf-8");
|
|
167
|
-
const html =
|
|
165
|
+
const html = await adoc_convert(content, {
|
|
168
166
|
safe: "safe",
|
|
169
167
|
standalone: true,
|
|
170
168
|
attributes: { showtitle: true },
|
package/dist/path/pathCommand.js
CHANGED
|
@@ -13,7 +13,7 @@ import { table_display, border_draw } from "../screen/screen.js";
|
|
|
13
13
|
import { options_toParams } from "../utils/cli.js";
|
|
14
14
|
import archy from "archy";
|
|
15
15
|
import open from "open";
|
|
16
|
-
import {
|
|
16
|
+
import { execFile } from "child_process";
|
|
17
17
|
import os from "os";
|
|
18
18
|
import { files_downloadWithProgress } from "../commands/fs/download.js";
|
|
19
19
|
/**
|
|
@@ -160,10 +160,13 @@ async function mermaid_renderServerSide(mermaidDefinition, outputFile) {
|
|
|
160
160
|
const tempDir = os.tmpdir();
|
|
161
161
|
const inputFile = path.join(tempDir, "input.mmd");
|
|
162
162
|
fs.writeFileSync(inputFile, mermaidDefinition);
|
|
163
|
+
// Pass args as an array (execFile, no shell) so a user-supplied --save path
|
|
164
|
+
// cannot inject shell commands. Requires `mmdc` (@mermaid-js/mermaid-cli),
|
|
165
|
+
// which is fetched on demand via npx and is not a hard dependency.
|
|
163
166
|
return new Promise((resolve, reject) => {
|
|
164
|
-
|
|
167
|
+
execFile("npx", ["mmdc", "-i", inputFile, "-o", outputFile], (error) => {
|
|
165
168
|
if (error) {
|
|
166
|
-
console.error(`
|
|
169
|
+
console.error(`Mermaid render failed. Ensure @mermaid-js/mermaid-cli is available (npx mmdc): ${error.message}`);
|
|
167
170
|
reject(error);
|
|
168
171
|
return;
|
|
169
172
|
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { Command } from "commander";
|
|
7
7
|
import { CLIoptions } from "../utils/cli.js";
|
|
8
|
+
import { type CommandEnvelope } from "@fnndsc/cumin";
|
|
8
9
|
/**
|
|
9
10
|
* Handles commands related to groups of plugin contexts (computes, instances, parameters).
|
|
10
11
|
*/
|
|
@@ -33,6 +34,23 @@ export declare class PluginContextGroupHandler {
|
|
|
33
34
|
* Lists available fields for the current plugin context resource.
|
|
34
35
|
*/
|
|
35
36
|
parameters_fieldsList(): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Renders plugin parameters in "man page" style as an envelope.
|
|
39
|
+
*
|
|
40
|
+
* Sans-I/O counterpart to {@link parameters_listMan}.
|
|
41
|
+
*
|
|
42
|
+
* @param options - CLI options for filtering.
|
|
43
|
+
* @returns An envelope carrying the rendered parameters or an error.
|
|
44
|
+
*/
|
|
45
|
+
parameters_listManRender(options: CLIoptions): Promise<CommandEnvelope>;
|
|
46
|
+
/**
|
|
47
|
+
* Renders available fields for the current plugin context resource as an envelope.
|
|
48
|
+
*
|
|
49
|
+
* Sans-I/O counterpart to {@link parameters_fieldsList}.
|
|
50
|
+
*
|
|
51
|
+
* @returns An envelope carrying the field listing.
|
|
52
|
+
*/
|
|
53
|
+
parameters_fieldsRender(): Promise<CommandEnvelope>;
|
|
36
54
|
/**
|
|
37
55
|
* Sets up the Commander.js commands for plugin context group operations.
|
|
38
56
|
*
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
import { BaseGroupHandler } from "../handlers/baseGroupHandler.js";
|
|
7
7
|
import { options_toParams } from "../utils/cli.js";
|
|
8
8
|
import { PluginContextController } from "../controllers/pluginContextController.js";
|
|
9
|
-
import { pluginParameters_renderMan } from "../views/pluginParameters.js";
|
|
9
|
+
import { pluginParameters_renderMan, pluginParameters_manRender } from "../views/pluginParameters.js";
|
|
10
|
+
import { envelope_ok, envelope_error } from "@fnndsc/cumin";
|
|
10
11
|
class InitializationError extends Error {
|
|
11
12
|
constructor(message) {
|
|
12
13
|
super(message);
|
|
@@ -76,6 +77,44 @@ export class PluginContextGroupHandler {
|
|
|
76
77
|
await this.baseGroupHandler.resourceFields_list();
|
|
77
78
|
}
|
|
78
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Renders plugin parameters in "man page" style as an envelope.
|
|
82
|
+
*
|
|
83
|
+
* Sans-I/O counterpart to {@link parameters_listMan}.
|
|
84
|
+
*
|
|
85
|
+
* @param options - CLI options for filtering.
|
|
86
|
+
* @returns An envelope carrying the rendered parameters or an error.
|
|
87
|
+
*/
|
|
88
|
+
async parameters_listManRender(options) {
|
|
89
|
+
try {
|
|
90
|
+
const asset = this.controller.chrisObject.asset;
|
|
91
|
+
if (!asset || typeof asset.resources_listAndFilterByOptions !== 'function') {
|
|
92
|
+
return envelope_error('', undefined, "Underlying resource does not support listing.\n");
|
|
93
|
+
}
|
|
94
|
+
const params = options_toParams(options);
|
|
95
|
+
const results = await asset.resources_listAndFilterByOptions(params);
|
|
96
|
+
if (results) {
|
|
97
|
+
return envelope_ok(`${pluginParameters_manRender(results)}\n`);
|
|
98
|
+
}
|
|
99
|
+
return envelope_ok("No parameters found.\n");
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
return envelope_error('', undefined, `Error listing parameters: ${error}\n`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Renders available fields for the current plugin context resource as an envelope.
|
|
107
|
+
*
|
|
108
|
+
* Sans-I/O counterpart to {@link parameters_fieldsList}.
|
|
109
|
+
*
|
|
110
|
+
* @returns An envelope carrying the field listing.
|
|
111
|
+
*/
|
|
112
|
+
async parameters_fieldsRender() {
|
|
113
|
+
if (this.baseGroupHandler) {
|
|
114
|
+
return this.baseGroupHandler.resourceFields_render();
|
|
115
|
+
}
|
|
116
|
+
return envelope_ok('');
|
|
117
|
+
}
|
|
79
118
|
/**
|
|
80
119
|
* Sets up the Commander.js commands for plugin context group operations.
|
|
81
120
|
*
|
package/dist/run.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file In-process library entry for the chili (ChILI) CLI.
|
|
3
|
+
*
|
|
4
|
+
* Exposes {@link run}, which builds a fresh Commander program and executes a
|
|
5
|
+
* single chili command, returning when it completes. Unlike the bin entry
|
|
6
|
+
* (`index.ts`), importing this module has no side effect of running the CLI and
|
|
7
|
+
* never calls `process.exit`, so a host process such as chell can drive chili
|
|
8
|
+
* in-process instead of spawning a separate `node` subprocess.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Executes a single chili command in the current process.
|
|
14
|
+
*
|
|
15
|
+
* Builds a fresh Commander program (so repeated calls do not share parser
|
|
16
|
+
* state), wires all command handlers, and parses the supplied arguments. Help,
|
|
17
|
+
* version and usage errors are handled gracefully (Commander's message is
|
|
18
|
+
* already written) instead of terminating the process; genuine errors thrown by
|
|
19
|
+
* a command action propagate to the caller.
|
|
20
|
+
*
|
|
21
|
+
* @param argv - The chili arguments, e.g. `["feeds", "list", "-s"]` (without
|
|
22
|
+
* the leading `node`/script entries).
|
|
23
|
+
*/
|
|
24
|
+
export declare function run(argv: string[]): Promise<void>;
|
package/dist/run.js
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file In-process library entry for the chili (ChILI) CLI.
|
|
3
|
+
*
|
|
4
|
+
* Exposes {@link run}, which builds a fresh Commander program and executes a
|
|
5
|
+
* single chili command, returning when it completes. Unlike the bin entry
|
|
6
|
+
* (`index.ts`), importing this module has no side effect of running the CLI and
|
|
7
|
+
* never calls `process.exit`, so a host process such as chell can drive chili
|
|
8
|
+
* in-process instead of spawning a separate `node` subprocess.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import { Command, CommanderError } from "commander";
|
|
13
|
+
import figlet from "figlet";
|
|
14
|
+
import { connectCommand_setup } from "./connect/connectHandler.js";
|
|
15
|
+
import { FeedGroupHandler, FeedMemberHandler } from "./feeds/feedHandler.js";
|
|
16
|
+
import { PluginGroupHandler, PluginMemberHandler, } from "./plugins/pluginHandler.js";
|
|
17
|
+
import { PluginMetaGroupHandler } from "./plugins/pluginMetaHandler.js";
|
|
18
|
+
import { PluginContextGroupHandler } from "./plugins/pluginGroupHandler.js";
|
|
19
|
+
import { inodeCommand_setup } from "./filesystem/inodeCommand.js";
|
|
20
|
+
import { contextCommand_setup } from "./context/contextCommand.js";
|
|
21
|
+
import { pathCommand_setup } from "./path/pathCommand.js";
|
|
22
|
+
import { fileBrowserCommand_setup } from "./filesystem/filesystemHandler.js";
|
|
23
|
+
import { manCommand_setup } from "./man/man.js";
|
|
24
|
+
import { chefsCommand_setup } from "./chefs/chefs.js";
|
|
25
|
+
import { PACSServerGroupHandler } from "./pacs/pacsServerHandler.js";
|
|
26
|
+
import { PACSQueryGroupHandler } from "./pacs/pacsQueryHandler.js";
|
|
27
|
+
import { PACSRetrieveGroupHandler } from "./pacs/pacsRetrieveHandler.js";
|
|
28
|
+
import { chrisConnection_init, NodeStorageProvider, errorStack_getAllOfType, } from "@fnndsc/cumin";
|
|
29
|
+
import { FileGroupHandler } from "./filesystem/fileGroupHandler.js";
|
|
30
|
+
/**
|
|
31
|
+
* Suppress the DEP0169 (`url.parse()`) warning emitted transitively by
|
|
32
|
+
* axios -> proxy-from-env, which we do not control. Installed once at import.
|
|
33
|
+
* See the tracking note in the original bin entry for context.
|
|
34
|
+
*/
|
|
35
|
+
const originalEmitWarning = process.emitWarning;
|
|
36
|
+
process.emitWarning = function (warning, ...args) {
|
|
37
|
+
if (typeof warning === "string" &&
|
|
38
|
+
(warning.includes("DEP0169") || warning.includes("url.parse()"))) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
return originalEmitWarning.call(process, warning, ...args);
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Registers every chili command handler on the supplied program. The handler
|
|
45
|
+
* setup functions are program-parameterised, so a fresh program can be wired on
|
|
46
|
+
* each call without sharing Commander state across invocations.
|
|
47
|
+
*
|
|
48
|
+
* @param program - The Commander program to register commands on.
|
|
49
|
+
*/
|
|
50
|
+
async function handlers_initialize(program) {
|
|
51
|
+
// Connection is intentionally not enforced here so that `--help` works; each
|
|
52
|
+
// command fails individually if it needs a connection that is not present.
|
|
53
|
+
fileBrowserCommand_setup(program);
|
|
54
|
+
contextCommand_setup(program);
|
|
55
|
+
pathCommand_setup(program);
|
|
56
|
+
manCommand_setup(program);
|
|
57
|
+
chefsCommand_setup(program);
|
|
58
|
+
const pacsServerHandler = new PACSServerGroupHandler();
|
|
59
|
+
pacsServerHandler.pacsServerCommand_setup(program);
|
|
60
|
+
const pacsQueryHandler = new PACSQueryGroupHandler();
|
|
61
|
+
pacsQueryHandler.pacsQueryCommand_setup(program);
|
|
62
|
+
const pacsRetrieveHandler = new PACSRetrieveGroupHandler();
|
|
63
|
+
pacsRetrieveHandler.pacsRetrieveCommand_setup(program);
|
|
64
|
+
await inodeCommand_setup(program);
|
|
65
|
+
const pluginGroupHandler = new PluginGroupHandler();
|
|
66
|
+
pluginGroupHandler.pluginGroupCommand_setup(program);
|
|
67
|
+
const pluginMetaGroupHandler = new PluginMetaGroupHandler();
|
|
68
|
+
pluginMetaGroupHandler.pluginMetaGroupCommand_setup(program);
|
|
69
|
+
const feedGroupHandler = new FeedGroupHandler();
|
|
70
|
+
feedGroupHandler.feedGroupCommand_setup(program);
|
|
71
|
+
const feedMemberHandler = new FeedMemberHandler();
|
|
72
|
+
feedMemberHandler.feedCommand_setup(program);
|
|
73
|
+
const pluginMemberHandler = new PluginMemberHandler();
|
|
74
|
+
pluginMemberHandler.pluginCommand_setup(program);
|
|
75
|
+
try {
|
|
76
|
+
const filesGroupHandler = await FileGroupHandler.handler_create("files");
|
|
77
|
+
filesGroupHandler.fileGroupCommand_setup(program);
|
|
78
|
+
const linksGroupHandler = await FileGroupHandler.handler_create("links");
|
|
79
|
+
linksGroupHandler.fileGroupCommand_setup(program);
|
|
80
|
+
const dirsGroupHandler = await FileGroupHandler.handler_create("dirs");
|
|
81
|
+
dirsGroupHandler.fileGroupCommand_setup(program);
|
|
82
|
+
}
|
|
83
|
+
catch (e) {
|
|
84
|
+
const err = e instanceof Error ? e.message : String(e);
|
|
85
|
+
const errors = errorStack_getAllOfType("error");
|
|
86
|
+
const warnings = errorStack_getAllOfType("warning");
|
|
87
|
+
console.log(`Note: File group commands (files, dirs, links) are unavailable. Reason: ${err}`);
|
|
88
|
+
if (errors.length > 0) {
|
|
89
|
+
console.log("Errors:");
|
|
90
|
+
errors.forEach((msg) => console.log(` - ${msg}`));
|
|
91
|
+
}
|
|
92
|
+
if (warnings.length > 0) {
|
|
93
|
+
console.log("Warnings:");
|
|
94
|
+
warnings.forEach((msg) => console.log(` - ${msg}`));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const computesOfPluginHandler = await PluginContextGroupHandler.handler_create("computesofplugin");
|
|
99
|
+
computesOfPluginHandler.pluginContextGroupCommand_setup(program);
|
|
100
|
+
const pluginInstancesHandler = await PluginContextGroupHandler.handler_create("instancesofplugin");
|
|
101
|
+
pluginInstancesHandler.pluginContextGroupCommand_setup(program);
|
|
102
|
+
const pluginParametersHandler = await PluginContextGroupHandler.handler_create("parametersofplugin");
|
|
103
|
+
pluginParametersHandler.pluginContextGroupCommand_setup(program);
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
106
|
+
const err = e instanceof Error ? e.message : String(e);
|
|
107
|
+
const errors = errorStack_getAllOfType("error");
|
|
108
|
+
const warnings = errorStack_getAllOfType("warning");
|
|
109
|
+
console.log(`Note: Plugin context commands are unavailable. Reason: ${err}`);
|
|
110
|
+
if (errors.length > 0) {
|
|
111
|
+
console.log("Errors:");
|
|
112
|
+
errors.forEach((msg) => console.log(` - ${msg}`));
|
|
113
|
+
}
|
|
114
|
+
if (warnings.length > 0) {
|
|
115
|
+
console.log("Warnings:");
|
|
116
|
+
warnings.forEach((msg) => console.log(` - ${msg}`));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Extracts a leading `key=value` context string from an argv array.
|
|
122
|
+
*
|
|
123
|
+
* @param args - An argv array shaped like `process.argv` (exec, script, ...).
|
|
124
|
+
* @returns A tuple of the context string (if any) and argv with it removed.
|
|
125
|
+
*/
|
|
126
|
+
function context_parse(args) {
|
|
127
|
+
for (let i = 2; i < args.length; i++) {
|
|
128
|
+
const arg = args[i];
|
|
129
|
+
if (arg.includes("=") && !arg.startsWith("-")) {
|
|
130
|
+
const context = arg;
|
|
131
|
+
const newArgs = [...args.slice(0, i), ...args.slice(i + 1)];
|
|
132
|
+
return [context, newArgs];
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return [undefined, args];
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Executes a single chili command in the current process.
|
|
139
|
+
*
|
|
140
|
+
* Builds a fresh Commander program (so repeated calls do not share parser
|
|
141
|
+
* state), wires all command handlers, and parses the supplied arguments. Help,
|
|
142
|
+
* version and usage errors are handled gracefully (Commander's message is
|
|
143
|
+
* already written) instead of terminating the process; genuine errors thrown by
|
|
144
|
+
* a command action propagate to the caller.
|
|
145
|
+
*
|
|
146
|
+
* @param argv - The chili arguments, e.g. `["feeds", "list", "-s"]` (without
|
|
147
|
+
* the leading `node`/script entries).
|
|
148
|
+
*/
|
|
149
|
+
export async function run(argv) {
|
|
150
|
+
const nodeStorageProvider = new NodeStorageProvider();
|
|
151
|
+
const connection = await chrisConnection_init(nodeStorageProvider);
|
|
152
|
+
// Commander's default parsing expects argv[0]/argv[1] to be exec/script.
|
|
153
|
+
let fullArgv = ["node", "chili", ...argv];
|
|
154
|
+
const [context, newArgs] = context_parse(fullArgv);
|
|
155
|
+
if (context) {
|
|
156
|
+
const contextSetSuccess = await connection.context_set(context);
|
|
157
|
+
if (!contextSetSuccess) {
|
|
158
|
+
console.error("Failed to set context.");
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
fullArgv = newArgs;
|
|
162
|
+
}
|
|
163
|
+
const program = new Command();
|
|
164
|
+
program
|
|
165
|
+
.name("chili")
|
|
166
|
+
.description("ChILI handles Intelligent Line Interactions")
|
|
167
|
+
.version("1.0.1")
|
|
168
|
+
.option("-v, --verbose", "enable verbose output")
|
|
169
|
+
.option("-c, --config <path>", "path to config file")
|
|
170
|
+
.option("-s, --nosplash", "disable splash screen")
|
|
171
|
+
.exitOverride();
|
|
172
|
+
connectCommand_setup(program);
|
|
173
|
+
await handlers_initialize(program);
|
|
174
|
+
program.parseOptions(fullArgv);
|
|
175
|
+
const options = program.opts();
|
|
176
|
+
if (!options.nosplash) {
|
|
177
|
+
console.log(figlet.textSync("ChILI"));
|
|
178
|
+
console.log("ChILI handles Intelligent Line Interactions");
|
|
179
|
+
}
|
|
180
|
+
try {
|
|
181
|
+
await program.parseAsync(fullArgv);
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
// Under exitOverride, --help/--version/usage errors throw a CommanderError
|
|
185
|
+
// whose message Commander has already written. Swallow these so the host
|
|
186
|
+
// (e.g. a chell REPL) is not torn down; rethrow anything else.
|
|
187
|
+
if (err instanceof CommanderError) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
throw err;
|
|
191
|
+
}
|
|
192
|
+
}
|
package/dist/screen/screen.d.ts
CHANGED
|
@@ -75,6 +75,19 @@ export declare function border_draw(text: string, borders?: Borders): string;
|
|
|
75
75
|
* @param options - Optional table display options.
|
|
76
76
|
* @returns The `TableContent` object or null on error.
|
|
77
77
|
*/
|
|
78
|
+
/**
|
|
79
|
+
* Renders a table to a string, the string form of {@link table_display}.
|
|
80
|
+
*
|
|
81
|
+
* Envelope-returning callers use this to return their output rather than
|
|
82
|
+
* printing it; table_display remains the printing form for callers not yet
|
|
83
|
+
* converted. Returns an empty string when there is no table to render.
|
|
84
|
+
*
|
|
85
|
+
* @param tableData - The rows to render.
|
|
86
|
+
* @param headers - Column headers.
|
|
87
|
+
* @param options - Table formatting options.
|
|
88
|
+
* @returns The rendered table (with a trailing newline), or an empty string.
|
|
89
|
+
*/
|
|
90
|
+
export declare function table_render(tableData: TableDataRow[] | string[][] | string[], headers: string[] | string, options?: TableOptions): string;
|
|
78
91
|
export declare function table_display(tableData: TableDataRow[] | string[][] | string[], headers: string[] | string, options?: TableOptions): TableContent | null;
|
|
79
92
|
/**
|
|
80
93
|
* Provides screen utilities for logging and table output.
|