@fnndsc/brasa 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builtins/debug.d.ts +8 -0
- package/dist/builtins/debug.js +39 -0
- package/dist/builtins/debug.js.map +1 -0
- package/dist/builtins/executable.d.ts +22 -0
- package/dist/builtins/executable.js +115 -0
- package/dist/builtins/executable.js.map +1 -0
- package/dist/builtins/fs/cat.d.ts +16 -0
- package/dist/builtins/fs/cat.js +266 -0
- package/dist/builtins/fs/cat.js.map +1 -0
- package/dist/builtins/fs/cd.d.ts +42 -0
- package/dist/builtins/fs/cd.js +193 -0
- package/dist/builtins/fs/cd.js.map +1 -0
- package/dist/builtins/fs/cp.d.ts +10 -0
- package/dist/builtins/fs/cp.js +86 -0
- package/dist/builtins/fs/cp.js.map +1 -0
- package/dist/builtins/fs/download.d.ts +6 -0
- package/dist/builtins/fs/download.js +45 -0
- package/dist/builtins/fs/download.js.map +1 -0
- package/dist/builtins/fs/du.d.ts +58 -0
- package/dist/builtins/fs/du.js +210 -0
- package/dist/builtins/fs/du.js.map +1 -0
- package/dist/builtins/fs/edit.d.ts +7 -0
- package/dist/builtins/fs/edit.js +104 -0
- package/dist/builtins/fs/edit.js.map +1 -0
- package/dist/builtins/fs/ls.d.ts +8 -0
- package/dist/builtins/fs/ls.js +68 -0
- package/dist/builtins/fs/ls.js.map +1 -0
- package/dist/builtins/fs/mkdir.d.ts +9 -0
- package/dist/builtins/fs/mkdir.js +52 -0
- package/dist/builtins/fs/mkdir.js.map +1 -0
- package/dist/builtins/fs/mv.d.ts +10 -0
- package/dist/builtins/fs/mv.js +88 -0
- package/dist/builtins/fs/mv.js.map +1 -0
- package/dist/builtins/fs/pull.args.d.ts +22 -0
- package/dist/builtins/fs/pull.args.js +30 -0
- package/dist/builtins/fs/pull.args.js.map +1 -0
- package/dist/builtins/fs/pull.d.ts +26 -0
- package/dist/builtins/fs/pull.js +445 -0
- package/dist/builtins/fs/pull.js.map +1 -0
- package/dist/builtins/fs/pwd.d.ts +10 -0
- package/dist/builtins/fs/pwd.js +73 -0
- package/dist/builtins/fs/pwd.js.map +1 -0
- package/dist/builtins/fs/rm.d.ts +37 -0
- package/dist/builtins/fs/rm.js +197 -0
- package/dist/builtins/fs/rm.js.map +1 -0
- package/dist/builtins/fs/touch.d.ts +9 -0
- package/dist/builtins/fs/touch.js +76 -0
- package/dist/builtins/fs/touch.js.map +1 -0
- package/dist/builtins/fs/tree.d.ts +15 -0
- package/dist/builtins/fs/tree.js +84 -0
- package/dist/builtins/fs/tree.js.map +1 -0
- package/dist/builtins/fs/upload.d.ts +6 -0
- package/dist/builtins/fs/upload.js +48 -0
- package/dist/builtins/fs/upload.js.map +1 -0
- package/dist/builtins/help.d.ts +74 -0
- package/dist/builtins/help.js +1217 -0
- package/dist/builtins/help.js.map +1 -0
- package/dist/builtins/index.d.ts +45 -0
- package/dist/builtins/index.js +45 -0
- package/dist/builtins/index.js.map +1 -0
- package/dist/builtins/net/connect.d.ts +7 -0
- package/dist/builtins/net/connect.js +42 -0
- package/dist/builtins/net/connect.js.map +1 -0
- package/dist/builtins/net/cubepath.d.ts +18 -0
- package/dist/builtins/net/cubepath.js +102 -0
- package/dist/builtins/net/cubepath.js.map +1 -0
- package/dist/builtins/net/logout.d.ts +6 -0
- package/dist/builtins/net/logout.js +24 -0
- package/dist/builtins/net/logout.js.map +1 -0
- package/dist/builtins/net/pacs.d.ts +24 -0
- package/dist/builtins/net/pacs.js +121 -0
- package/dist/builtins/net/pacs.js.map +1 -0
- package/dist/builtins/net/pacsUtils.d.ts +85 -0
- package/dist/builtins/net/pacsUtils.js +184 -0
- package/dist/builtins/net/pacsUtils.js.map +1 -0
- package/dist/builtins/net/query.d.ts +60 -0
- package/dist/builtins/net/query.js +324 -0
- package/dist/builtins/net/query.js.map +1 -0
- package/dist/builtins/parametersofplugin.d.ts +13 -0
- package/dist/builtins/parametersofplugin.js +43 -0
- package/dist/builtins/parametersofplugin.js.map +1 -0
- package/dist/builtins/pluginExecute.d.ts +27 -0
- package/dist/builtins/pluginExecute.js +165 -0
- package/dist/builtins/pluginExecute.js.map +1 -0
- package/dist/builtins/proc.d.ts +6 -0
- package/dist/builtins/proc.helpers.d.ts +68 -0
- package/dist/builtins/proc.helpers.js +102 -0
- package/dist/builtins/proc.helpers.js.map +1 -0
- package/dist/builtins/proc.js +289 -0
- package/dist/builtins/proc.js.map +1 -0
- package/dist/builtins/res/compute.d.ts +6 -0
- package/dist/builtins/res/compute.js +55 -0
- package/dist/builtins/res/compute.js.map +1 -0
- package/dist/builtins/res/feed.d.ts +6 -0
- package/dist/builtins/res/feed.js +244 -0
- package/dist/builtins/res/feed.js.map +1 -0
- package/dist/builtins/res/feed.notes.d.ts +28 -0
- package/dist/builtins/res/feed.notes.js +24 -0
- package/dist/builtins/res/feed.notes.js.map +1 -0
- package/dist/builtins/res/files.d.ts +18 -0
- package/dist/builtins/res/files.js +85 -0
- package/dist/builtins/res/files.js.map +1 -0
- package/dist/builtins/res/group.d.ts +6 -0
- package/dist/builtins/res/group.js +54 -0
- package/dist/builtins/res/group.js.map +1 -0
- package/dist/builtins/res/pipeline.args.d.ts +22 -0
- package/dist/builtins/res/pipeline.args.js +28 -0
- package/dist/builtins/res/pipeline.args.js.map +1 -0
- package/dist/builtins/res/pipeline.d.ts +20 -0
- package/dist/builtins/res/pipeline.js +252 -0
- package/dist/builtins/res/pipeline.js.map +1 -0
- package/dist/builtins/res/plugin.d.ts +13 -0
- package/dist/builtins/res/plugin.js +140 -0
- package/dist/builtins/res/plugin.js.map +1 -0
- package/dist/builtins/res/plugininstance.d.ts +6 -0
- package/dist/builtins/res/plugininstance.js +53 -0
- package/dist/builtins/res/plugininstance.js.map +1 -0
- package/dist/builtins/res/pluginmeta.d.ts +6 -0
- package/dist/builtins/res/pluginmeta.js +53 -0
- package/dist/builtins/res/pluginmeta.js.map +1 -0
- package/dist/builtins/res/tag.d.ts +6 -0
- package/dist/builtins/res/tag.js +53 -0
- package/dist/builtins/res/tag.js.map +1 -0
- package/dist/builtins/res/workflow.d.ts +6 -0
- package/dist/builtins/res/workflow.js +53 -0
- package/dist/builtins/res/workflow.js.map +1 -0
- package/dist/builtins/store.d.ts +6 -0
- package/dist/builtins/store.js +107 -0
- package/dist/builtins/store.js.map +1 -0
- package/dist/builtins/sys/context.d.ts +6 -0
- package/dist/builtins/sys/context.js +50 -0
- package/dist/builtins/sys/context.js.map +1 -0
- package/dist/builtins/sys/physicalmode.d.ts +8 -0
- package/dist/builtins/sys/physicalmode.js +34 -0
- package/dist/builtins/sys/physicalmode.js.map +1 -0
- package/dist/builtins/sys/timing.d.ts +8 -0
- package/dist/builtins/sys/timing.js +34 -0
- package/dist/builtins/sys/timing.js.map +1 -0
- package/dist/builtins/sys/version.d.ts +15 -0
- package/dist/builtins/sys/version.js +23 -0
- package/dist/builtins/sys/version.js.map +1 -0
- package/dist/builtins/sys/whoami.d.ts +17 -0
- package/dist/builtins/sys/whoami.js +44 -0
- package/dist/builtins/sys/whoami.js.map +1 -0
- package/dist/builtins/utils.d.ts +55 -0
- package/dist/builtins/utils.js +145 -0
- package/dist/builtins/utils.js.map +1 -0
- package/dist/builtins/wildcard.d.ts +26 -0
- package/dist/builtins/wildcard.js +120 -0
- package/dist/builtins/wildcard.js.map +1 -0
- package/dist/command-keys.d.ts +8 -0
- package/dist/command-keys.js +32 -0
- package/dist/command-keys.js.map +1 -0
- package/dist/config/storeConfig.d.ts +57 -0
- package/dist/config/storeConfig.js +78 -0
- package/dist/config/storeConfig.js.map +1 -0
- package/dist/core/chiliDelegate.d.ts +21 -0
- package/dist/core/chiliDelegate.js +32 -0
- package/dist/core/chiliDelegate.js.map +1 -0
- package/dist/core/connect.d.ts +38 -0
- package/dist/core/connect.js +46 -0
- package/dist/core/connect.js.map +1 -0
- package/dist/core/dispatch.d.ts +95 -0
- package/dist/core/dispatch.js +618 -0
- package/dist/core/dispatch.js.map +1 -0
- package/dist/core/engine.d.ts +91 -0
- package/dist/core/engine.js +222 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/preprocess.d.ts +46 -0
- package/dist/core/preprocess.js +146 -0
- package/dist/core/preprocess.js.map +1 -0
- package/dist/core/progress.d.ts +50 -0
- package/dist/core/progress.js +21 -0
- package/dist/core/progress.js.map +1 -0
- package/dist/core/promptContext.d.ts +49 -0
- package/dist/core/promptContext.js +39 -0
- package/dist/core/promptContext.js.map +1 -0
- package/dist/core/question.d.ts +27 -0
- package/dist/core/question.js +33 -0
- package/dist/core/question.js.map +1 -0
- package/dist/core/sink.d.ts +207 -0
- package/dist/core/sink.js +329 -0
- package/dist/core/sink.js.map +1 -0
- package/dist/core/surface.d.ts +172 -0
- package/dist/core/surface.js +105 -0
- package/dist/core/surface.js.map +1 -0
- package/dist/core/version.d.ts +20 -0
- package/dist/core/version.js +82 -0
- package/dist/core/version.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/completer/index.d.ts +15 -0
- package/dist/lib/completer/index.js +212 -0
- package/dist/lib/completer/index.js.map +1 -0
- package/dist/lib/completer/pathComplete.helpers.d.ts +22 -0
- package/dist/lib/completer/pathComplete.helpers.js +49 -0
- package/dist/lib/completer/pathComplete.helpers.js.map +1 -0
- package/dist/lib/parser.d.ts +13 -0
- package/dist/lib/parser.js +52 -0
- package/dist/lib/parser.js.map +1 -0
- package/dist/lib/pipe.d.ts +11 -0
- package/dist/lib/pipe.js +90 -0
- package/dist/lib/pipe.js.map +1 -0
- package/dist/lib/prefetch.d.ts +25 -0
- package/dist/lib/prefetch.js +64 -0
- package/dist/lib/prefetch.js.map +1 -0
- package/dist/lib/semicolonParser.d.ts +22 -0
- package/dist/lib/semicolonParser.js +53 -0
- package/dist/lib/semicolonParser.js.map +1 -0
- package/dist/lib/spinner.d.ts +23 -0
- package/dist/lib/spinner.js +71 -0
- package/dist/lib/spinner.js.map +1 -0
- package/dist/lib/vfs/providers/static.d.ts +65 -0
- package/dist/lib/vfs/providers/static.js +164 -0
- package/dist/lib/vfs/providers/static.js.map +1 -0
- package/dist/lib/vfs/providers/static_content.d.ts +27 -0
- package/dist/lib/vfs/providers/static_content.js +180 -0
- package/dist/lib/vfs/providers/static_content.js.map +1 -0
- package/dist/lib/vfs/vfs.d.ts +59 -0
- package/dist/lib/vfs/vfs.js +202 -0
- package/dist/lib/vfs/vfs.js.map +1 -0
- package/dist/session/index.d.ts +76 -0
- package/dist/session/index.js +120 -0
- package/dist/session/index.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Shared PACS utilities for VFS path traversal and CUBE FS resolution.
|
|
3
|
+
*
|
|
4
|
+
* Used by `pull` and `cubepath` builtins.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import { errorStack, pacsQuery_resultDecode, pacsServers_list, chrisContext, Context } from '@fnndsc/cumin';
|
|
9
|
+
/**
|
|
10
|
+
* Safely unwraps a DICOM tag value (may be `{value: ...}` wrapper or plain string/number).
|
|
11
|
+
*/
|
|
12
|
+
export function pacs_tagValueExtract(val) {
|
|
13
|
+
if (val && typeof val === 'object') {
|
|
14
|
+
const r = val;
|
|
15
|
+
if ('value' in r)
|
|
16
|
+
return String(r.value ?? '');
|
|
17
|
+
if ('Value' in r && Array.isArray(r.Value) && r.Value.length > 0)
|
|
18
|
+
return String(r.Value[0] ?? '');
|
|
19
|
+
}
|
|
20
|
+
return String(val ?? '');
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Extracts the UID portion of a VFS folder name (`<prefix>_<uid>_<label>`).
|
|
24
|
+
*/
|
|
25
|
+
export function folderUID_get(folder, prefix) {
|
|
26
|
+
const withoutPrefix = folder.replace(new RegExp(`^${prefix}_`), '');
|
|
27
|
+
return withoutPrefix.split('_')[0];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Resolves a PACS server identifier string from a numeric ID or context.
|
|
31
|
+
*
|
|
32
|
+
* @param override - Optional numeric-string PACS server ID from flags.
|
|
33
|
+
* @returns Resolved identifier string, or null if unavailable.
|
|
34
|
+
*/
|
|
35
|
+
export async function pacsServer_resolve(override) {
|
|
36
|
+
const raw = override ?? await chrisContext.current_get(Context.PACSserver);
|
|
37
|
+
if (!raw) {
|
|
38
|
+
const serversResult = await pacsServers_list();
|
|
39
|
+
if (serversResult.ok && serversResult.value.length > 0) {
|
|
40
|
+
return String(serversResult.value[0].id);
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
if (/^\d+$/.test(raw)) {
|
|
45
|
+
const allServers = await pacsServers_list();
|
|
46
|
+
if (allServers.ok) {
|
|
47
|
+
const srv = allServers.value.find(s => s.id === Number(raw));
|
|
48
|
+
if (srv?.identifier)
|
|
49
|
+
return srv.identifier;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return raw;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Walks a `/net/pacs/queries/...` VFS path and collects series info.
|
|
56
|
+
*
|
|
57
|
+
* Supports query-level, study-level, and series-level paths.
|
|
58
|
+
*
|
|
59
|
+
* @param pathStr - Absolute VFS path to a query, study, or series directory.
|
|
60
|
+
* @param fallbackPacsName - PACS identifier used when RetrieveAETitle is absent.
|
|
61
|
+
* @param callerTag - Command name for error messages (e.g. 'pull', 'cubepath').
|
|
62
|
+
* @returns Array of PACSSeriesInfo for all matched series.
|
|
63
|
+
*/
|
|
64
|
+
export async function pacs_seriesCollect(pathStr, fallbackPacsName, callerTag = 'pacs') {
|
|
65
|
+
const effective = pathStr.startsWith('/') ? pathStr : '/' + pathStr;
|
|
66
|
+
const parts = effective.split('/').filter(Boolean);
|
|
67
|
+
if (parts.length < 4 ||
|
|
68
|
+
parts[0] !== 'net' ||
|
|
69
|
+
parts[1] !== 'pacs' ||
|
|
70
|
+
parts[2] !== 'queries') {
|
|
71
|
+
errorStack.stack_push('error', `${callerTag}: Not a PACS query path: ${pathStr}`);
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
const queryFolder = parts[3];
|
|
75
|
+
const qidMatch = /_qid:(\d+)/.exec(queryFolder);
|
|
76
|
+
const queryId = qidMatch ? Number(qidMatch[1]) : NaN;
|
|
77
|
+
if (Number.isNaN(queryId)) {
|
|
78
|
+
errorStack.stack_push('error', `${callerTag}: Cannot parse query ID from: ${queryFolder}`);
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
const queryLabel = queryFolder.replace(/_qid:\d+.*$/, '');
|
|
82
|
+
const decodedResult = await pacsQuery_resultDecode(queryId);
|
|
83
|
+
if (!decodedResult.ok || !decodedResult.value.json) {
|
|
84
|
+
errorStack.stack_push('error', `${callerTag}: Failed to decode results for query ${queryId}`);
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
const raw = decodedResult.value.json;
|
|
88
|
+
let studiesSource;
|
|
89
|
+
if (raw && typeof raw === 'object') {
|
|
90
|
+
const r = raw;
|
|
91
|
+
studiesSource =
|
|
92
|
+
'studies' in r ? r.studies :
|
|
93
|
+
'Studies' in r ? r.Studies :
|
|
94
|
+
'results' in r ? r.results :
|
|
95
|
+
raw;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
studiesSource = raw;
|
|
99
|
+
}
|
|
100
|
+
const studies = (Array.isArray(studiesSource) ? studiesSource : [studiesSource]);
|
|
101
|
+
const targetStudyUID = parts.length >= 5
|
|
102
|
+
? folderUID_get(parts[4], 'Study')
|
|
103
|
+
: null;
|
|
104
|
+
const targetSeriesUID = parts.length >= 6
|
|
105
|
+
? folderUID_get(parts[5], 'Series')
|
|
106
|
+
: null;
|
|
107
|
+
const infos = [];
|
|
108
|
+
for (const studyObj of studies) {
|
|
109
|
+
if (!studyObj || typeof studyObj !== 'object')
|
|
110
|
+
continue;
|
|
111
|
+
const studyUID = pacs_tagValueExtract(studyObj.StudyInstanceUID ?? studyObj.uid);
|
|
112
|
+
if (targetStudyUID && studyUID !== targetStudyUID)
|
|
113
|
+
continue;
|
|
114
|
+
const studyLabel = pacs_tagValueExtract(studyObj.StudyDescription ?? 'Study').replace(/[\s/]/g, '_');
|
|
115
|
+
const retrieveAETitle = pacs_tagValueExtract(studyObj.RetrieveAETitle ?? '');
|
|
116
|
+
const pacsName = retrieveAETitle || fallbackPacsName;
|
|
117
|
+
const seriesArr = (Array.isArray(studyObj.series) ? studyObj.series :
|
|
118
|
+
Array.isArray(studyObj.Series) ? studyObj.Series :
|
|
119
|
+
Array.isArray(studyObj.results) ? studyObj.results :
|
|
120
|
+
[]);
|
|
121
|
+
for (const seriesObj of seriesArr) {
|
|
122
|
+
if (!seriesObj || typeof seriesObj !== 'object')
|
|
123
|
+
continue;
|
|
124
|
+
const seriesUID = pacs_tagValueExtract(seriesObj.SeriesInstanceUID ?? seriesObj.uid);
|
|
125
|
+
if (!seriesUID)
|
|
126
|
+
continue;
|
|
127
|
+
if (targetSeriesUID && seriesUID !== targetSeriesUID)
|
|
128
|
+
continue;
|
|
129
|
+
const seriesLabel = pacs_tagValueExtract(seriesObj.SeriesDescription ?? 'Series').replace(/[\s/]/g, '_');
|
|
130
|
+
const expectedFiles = Number(pacs_tagValueExtract(seriesObj.NumberOfSeriesRelatedInstances ?? '0')) || 0;
|
|
131
|
+
infos.push({
|
|
132
|
+
label: `${queryLabel}|${studyLabel}|${seriesLabel}`,
|
|
133
|
+
seriesLabel,
|
|
134
|
+
studyLabel,
|
|
135
|
+
queryLabel,
|
|
136
|
+
seriesUID,
|
|
137
|
+
studyUID,
|
|
138
|
+
pacsName,
|
|
139
|
+
expectedFiles,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return infos;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Resolves the CUBE FS folder path and actual file count for a series.
|
|
147
|
+
*
|
|
148
|
+
* Retries up to `maxAttempts` times with `retryDelayMs` between attempts
|
|
149
|
+
* to handle the timing gap between LONK completion and pacsseries DB indexing.
|
|
150
|
+
*
|
|
151
|
+
* @param seriesUID - DICOM SeriesInstanceUID.
|
|
152
|
+
* @param pacsClient - ChRIS API client with getPACSSeriesList and getPACSFiles.
|
|
153
|
+
* @param maxAttempts - Number of attempts before giving up (default 4).
|
|
154
|
+
* @param retryDelayMs - Delay between attempts in ms (default 2000).
|
|
155
|
+
* @returns SeriesCubePath on success, or null if not found.
|
|
156
|
+
*/
|
|
157
|
+
export async function series_cubePathGet(seriesUID, pacsClient, maxAttempts = 4, retryDelayMs = 2_000) {
|
|
158
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
159
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
160
|
+
try {
|
|
161
|
+
if (attempt > 0)
|
|
162
|
+
await sleep(retryDelayMs);
|
|
163
|
+
const seriesList = await pacsClient.getPACSSeriesList({ SeriesInstanceUID: seriesUID, limit: 1 });
|
|
164
|
+
const items = seriesList.getItems();
|
|
165
|
+
if (items.length === 0)
|
|
166
|
+
continue;
|
|
167
|
+
const series = items[0];
|
|
168
|
+
const raw = series?.data?.folder_path;
|
|
169
|
+
if (!raw)
|
|
170
|
+
continue;
|
|
171
|
+
// Display path has leading slash; fname query uses raw (API stores without leading slash)
|
|
172
|
+
const folderPath = raw.startsWith('/') ? raw : `/${raw}`;
|
|
173
|
+
const fnameQuery = raw.startsWith('/') ? raw.slice(1) : raw;
|
|
174
|
+
const fileList = await pacsClient.getPACSFiles({ fname: fnameQuery, limit: 1 });
|
|
175
|
+
const fileCount = Math.max(0, fileList.totalCount);
|
|
176
|
+
return { folderPath, fileCount };
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
// retry
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=pacsUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pacsUtils.js","sourceRoot":"","sources":["../../../src/builtins/net/pacsUtils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Builtin query command.
|
|
3
|
+
*
|
|
4
|
+
* Creates a PACS query, polls until the result is populated, displays the found
|
|
5
|
+
* studies/series, and prints the VFS path for downstream `pull` or `cd` use.
|
|
6
|
+
*
|
|
7
|
+
* Also exports `pacsQuery_createAndWait` for reuse by `builtin_pull`.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import { PACSQueryDecodedResult } from '@fnndsc/cumin';
|
|
12
|
+
/**
|
|
13
|
+
* Result of a successful query-create-and-wait operation.
|
|
14
|
+
*
|
|
15
|
+
* @property queryId - ID of the created PACSQuery.
|
|
16
|
+
* @property vfsPath - Full `/net/pacs/queries/<id>_<desc>` path.
|
|
17
|
+
* @property decoded - Decoded query result payload.
|
|
18
|
+
*/
|
|
19
|
+
export interface QueryCreateResult {
|
|
20
|
+
queryId: number;
|
|
21
|
+
vfsPath: string;
|
|
22
|
+
decoded: PACSQueryDecodedResult;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Parses a comma-separated `Key:Value[,Key:Value]` expression into an object.
|
|
26
|
+
* Falls back to JSON parse if the string starts with `{`.
|
|
27
|
+
*
|
|
28
|
+
* @param expr - Query expression string.
|
|
29
|
+
* @returns Parsed key-value record, or null if invalid.
|
|
30
|
+
*/
|
|
31
|
+
export declare function queryExpr_parse(expr: string): Record<string, string> | null;
|
|
32
|
+
/**
|
|
33
|
+
* Builds the VFS path for a query, matching the PacsVfsProvider folder-naming logic.
|
|
34
|
+
*
|
|
35
|
+
* @param queryId - The numeric query ID.
|
|
36
|
+
* @param queryObj - The parsed query key-value pairs.
|
|
37
|
+
* @param username - Optional username to embed in the folder name.
|
|
38
|
+
* @returns Absolute VFS path string.
|
|
39
|
+
*/
|
|
40
|
+
export declare function queryVfsPath_build(queryId: number, queryObj: Record<string, string>, username?: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* Creates a PACS query and blocks until the result is populated or timeout.
|
|
43
|
+
*
|
|
44
|
+
* @param queryExpr - Comma-separated `Key:Value` string or JSON object string.
|
|
45
|
+
* @param title - Title for the new PACSQuery record.
|
|
46
|
+
* @param pacsserver - PACS server ID or identifier string.
|
|
47
|
+
* @param onStatus - Optional callback called each poll tick with a status message.
|
|
48
|
+
* @returns QueryCreateResult on success, or null on failure/timeout.
|
|
49
|
+
*/
|
|
50
|
+
export declare function pacsQuery_createAndWait(queryExpr: string, title: string, pacsserver: string, onStatus?: (msg: string) => void): Promise<QueryCreateResult | null>;
|
|
51
|
+
/**
|
|
52
|
+
* Creates a PACS query, waits for results, displays findings, and prints the VFS path.
|
|
53
|
+
*
|
|
54
|
+
* @param args - `<queryExpression> [--title <title>] [--pacsserver <id>] [--table] [--help]`
|
|
55
|
+
* @example
|
|
56
|
+
* query PatientID:1234
|
|
57
|
+
* query 'PatientID:1234,StudyDate:20240101' --title 'Hip DDH Jan 2024'
|
|
58
|
+
* query AccessionNumber:12345678 --table
|
|
59
|
+
*/
|
|
60
|
+
export declare function builtin_query(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Builtin query command.
|
|
3
|
+
*
|
|
4
|
+
* Creates a PACS query, polls until the result is populated, displays the found
|
|
5
|
+
* studies/series, and prints the VFS path for downstream `pull` or `cd` use.
|
|
6
|
+
*
|
|
7
|
+
* Also exports `pacsQuery_createAndWait` for reuse by `builtin_pull`.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import chalk from 'chalk';
|
|
12
|
+
import { errorStack, chrisContext, Context, pacsQuery_get, pacsQuery_resultDecode, pacsQueries_create, pacsServers_list, } from '@fnndsc/cumin';
|
|
13
|
+
import { screen } from '@fnndsc/chili/screen/screen.js';
|
|
14
|
+
import { spinner } from '../../lib/spinner.js';
|
|
15
|
+
import { args_checkHasHelpFlag, help_show } from '../help.js';
|
|
16
|
+
const QUERY_POLL_INTERVAL_MS = 2_000;
|
|
17
|
+
const QUERY_TIMEOUT_MS = 60_000;
|
|
18
|
+
/**
|
|
19
|
+
* Parses a comma-separated `Key:Value[,Key:Value]` expression into an object.
|
|
20
|
+
* Falls back to JSON parse if the string starts with `{`.
|
|
21
|
+
*
|
|
22
|
+
* @param expr - Query expression string.
|
|
23
|
+
* @returns Parsed key-value record, or null if invalid.
|
|
24
|
+
*/
|
|
25
|
+
export function queryExpr_parse(expr) {
|
|
26
|
+
if (expr.trimStart().startsWith('{')) {
|
|
27
|
+
try {
|
|
28
|
+
const parsed = JSON.parse(expr);
|
|
29
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
30
|
+
return parsed;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// fall through
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const result = {};
|
|
39
|
+
for (const part of expr.split(',')) {
|
|
40
|
+
const colonIdx = part.indexOf(':');
|
|
41
|
+
if (colonIdx < 1)
|
|
42
|
+
return null;
|
|
43
|
+
const key = part.slice(0, colonIdx).trim();
|
|
44
|
+
const value = part.slice(colonIdx + 1).trim();
|
|
45
|
+
if (!key || !value)
|
|
46
|
+
return null;
|
|
47
|
+
result[key] = value;
|
|
48
|
+
}
|
|
49
|
+
return Object.keys(result).length > 0 ? result : null;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Builds the VFS path for a query, matching the PacsVfsProvider folder-naming logic.
|
|
53
|
+
*
|
|
54
|
+
* @param queryId - The numeric query ID.
|
|
55
|
+
* @param queryObj - The parsed query key-value pairs.
|
|
56
|
+
* @param username - Optional username to embed in the folder name.
|
|
57
|
+
* @returns Absolute VFS path string.
|
|
58
|
+
*/
|
|
59
|
+
export function queryVfsPath_build(queryId, queryObj, username) {
|
|
60
|
+
const parts = Object.entries(queryObj)
|
|
61
|
+
.filter(([, v]) => v.trim().length > 0)
|
|
62
|
+
.map(([k, v]) => `${k}:${v}`);
|
|
63
|
+
const desc = parts.join('_') || 'query';
|
|
64
|
+
const userSuffix = username ? `_${username}` : '';
|
|
65
|
+
return `/net/pacs/queries/${desc}_qid:${queryId}${userSuffix}`;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Creates a PACS query and blocks until the result is populated or timeout.
|
|
69
|
+
*
|
|
70
|
+
* @param queryExpr - Comma-separated `Key:Value` string or JSON object string.
|
|
71
|
+
* @param title - Title for the new PACSQuery record.
|
|
72
|
+
* @param pacsserver - PACS server ID or identifier string.
|
|
73
|
+
* @param onStatus - Optional callback called each poll tick with a status message.
|
|
74
|
+
* @returns QueryCreateResult on success, or null on failure/timeout.
|
|
75
|
+
*/
|
|
76
|
+
export async function pacsQuery_createAndWait(queryExpr, title, pacsserver, onStatus) {
|
|
77
|
+
const queryObj = queryExpr_parse(queryExpr);
|
|
78
|
+
if (!queryObj) {
|
|
79
|
+
errorStack.stack_push('error', `query: Invalid expression: "${queryExpr}". Use Key:Value or JSON.`);
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
const payload = {
|
|
83
|
+
title,
|
|
84
|
+
query: JSON.stringify(queryObj),
|
|
85
|
+
};
|
|
86
|
+
const createResult = await pacsQueries_create(pacsserver, payload);
|
|
87
|
+
if (!createResult.ok) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
const queryId = createResult.value.id;
|
|
91
|
+
const ownerUsername = typeof createResult.value.owner_username === 'string' ? createResult.value.owner_username : undefined;
|
|
92
|
+
const vfsPath = queryVfsPath_build(queryId, queryObj, ownerUsername);
|
|
93
|
+
const deadline = Date.now() + QUERY_TIMEOUT_MS;
|
|
94
|
+
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
|
|
95
|
+
let succeededWithoutPayload = 0;
|
|
96
|
+
while (Date.now() < deadline) {
|
|
97
|
+
const statusResult = await pacsQuery_get(queryId);
|
|
98
|
+
const status = statusResult.ok ? (statusResult.value.status ?? 'pending') : 'pending';
|
|
99
|
+
onStatus?.(`Query ${queryId} — ${status}`);
|
|
100
|
+
const decodeResult = await pacsQuery_resultDecode(queryId);
|
|
101
|
+
if (decodeResult.ok && decodeResult.value.json !== undefined) {
|
|
102
|
+
return { queryId, vfsPath, decoded: decodeResult.value };
|
|
103
|
+
}
|
|
104
|
+
if (!decodeResult.ok) {
|
|
105
|
+
// A missing payload is the expected state while polling; drop the
|
|
106
|
+
// error the probe pushed so the stack doesn't fill with one copy
|
|
107
|
+
// per poll tick.
|
|
108
|
+
errorStack.stack_pop();
|
|
109
|
+
}
|
|
110
|
+
// A succeeded query with no stored payload means the PACS matched
|
|
111
|
+
// nothing; a couple of grace polls cover result-write lag.
|
|
112
|
+
if (status === 'succeeded' && ++succeededWithoutPayload >= 2) {
|
|
113
|
+
return { queryId, vfsPath, decoded: { raw: '' } };
|
|
114
|
+
}
|
|
115
|
+
await sleep(QUERY_POLL_INTERVAL_MS);
|
|
116
|
+
}
|
|
117
|
+
errorStack.stack_push('error', `query: Timed out waiting for query ${queryId} result.`);
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Renders decoded PACS query JSON into a human-readable study/series summary.
|
|
122
|
+
*
|
|
123
|
+
* @param decoded - Decoded query result from `pacsQuery_resultDecode`.
|
|
124
|
+
* @returns Formatted multi-line string, or null if no displayable content.
|
|
125
|
+
*/
|
|
126
|
+
function queryResult_render(decoded) {
|
|
127
|
+
const payload = decoded.json;
|
|
128
|
+
if (!payload || typeof payload !== 'object')
|
|
129
|
+
return null;
|
|
130
|
+
const tagVal = (v) => {
|
|
131
|
+
if (v && typeof v === 'object' && 'value' in v) {
|
|
132
|
+
return String(v.value ?? '');
|
|
133
|
+
}
|
|
134
|
+
return String(v ?? '');
|
|
135
|
+
};
|
|
136
|
+
const lines = [];
|
|
137
|
+
const payloadArr = Array.isArray(payload) ? payload : [payload];
|
|
138
|
+
let totalSeries = 0;
|
|
139
|
+
payloadArr.forEach((studyRaw, sIdx) => {
|
|
140
|
+
if (!studyRaw || typeof studyRaw !== 'object')
|
|
141
|
+
return;
|
|
142
|
+
const study = studyRaw;
|
|
143
|
+
const studyDesc = tagVal(study.StudyDescription ?? '');
|
|
144
|
+
const patientName = tagVal(study.PatientName ?? study.patient_name ?? '');
|
|
145
|
+
const patientId = tagVal(study.PatientID ?? study.patient_id ?? '');
|
|
146
|
+
const studyDate = tagVal(study.StudyDate ?? '');
|
|
147
|
+
const modalities = tagVal(study.ModalitiesInStudy ?? '');
|
|
148
|
+
const accession = tagVal(study.AccessionNumber ?? '');
|
|
149
|
+
lines.push(chalk.bold.cyan(` Study ${sIdx + 1}: ${studyDesc || '(no description)'}`));
|
|
150
|
+
if (patientName)
|
|
151
|
+
lines.push(chalk.gray(` Patient: ${patientName}${patientId ? ` (ID: ${patientId})` : ''}`));
|
|
152
|
+
if (studyDate)
|
|
153
|
+
lines.push(chalk.gray(` Date: ${studyDate}`));
|
|
154
|
+
if (modalities)
|
|
155
|
+
lines.push(chalk.gray(` Modality: ${modalities}`));
|
|
156
|
+
if (accession)
|
|
157
|
+
lines.push(chalk.gray(` Accession: ${accession}`));
|
|
158
|
+
const seriesArr = Array.isArray(study.series) ? study.series :
|
|
159
|
+
Array.isArray(study.Series) ? study.Series :
|
|
160
|
+
Array.isArray(study.results) ? study.results :
|
|
161
|
+
[];
|
|
162
|
+
if (seriesArr.length > 0) {
|
|
163
|
+
lines.push('');
|
|
164
|
+
seriesArr.forEach((seriesRaw, rIdx) => {
|
|
165
|
+
if (!seriesRaw || typeof seriesRaw !== 'object')
|
|
166
|
+
return;
|
|
167
|
+
const series = seriesRaw;
|
|
168
|
+
const desc = tagVal(series.SeriesDescription ?? '');
|
|
169
|
+
const mod = tagVal(series.Modality ?? '');
|
|
170
|
+
const count = tagVal(series.NumberOfSeriesRelatedInstances ?? '');
|
|
171
|
+
const countStr = count ? chalk.gray(` (${count} files)`) : '';
|
|
172
|
+
const modStr = mod ? chalk.yellow(` [${mod}]`) : '';
|
|
173
|
+
lines.push(` ${chalk.white(`Series ${rIdx + 1}:`)} ${desc || '(no description)'}${modStr}${countStr}`);
|
|
174
|
+
totalSeries++;
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
lines.push('');
|
|
178
|
+
});
|
|
179
|
+
if (lines.length === 0)
|
|
180
|
+
return null;
|
|
181
|
+
lines.unshift(chalk.gray(` ${payloadArr.length} study/studies, ${totalSeries} series`));
|
|
182
|
+
lines.unshift('');
|
|
183
|
+
return lines.join('\n');
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Renders decoded PACS query JSON as a per-study table with one row per series.
|
|
187
|
+
*
|
|
188
|
+
* Columns: Study, #, Description, Modality, Files.
|
|
189
|
+
*
|
|
190
|
+
* @param decoded - Decoded query result from `pacsQuery_resultDecode`.
|
|
191
|
+
* @param title - Optional title shown above the table.
|
|
192
|
+
* @returns Formatted table string, or null if no displayable content.
|
|
193
|
+
*/
|
|
194
|
+
function queryResult_renderTable(decoded, title) {
|
|
195
|
+
const payload = decoded.json;
|
|
196
|
+
if (!payload || typeof payload !== 'object')
|
|
197
|
+
return null;
|
|
198
|
+
const tagVal = (v) => {
|
|
199
|
+
if (v && typeof v === 'object' && 'value' in v) {
|
|
200
|
+
return String(v.value ?? '');
|
|
201
|
+
}
|
|
202
|
+
return String(v ?? '');
|
|
203
|
+
};
|
|
204
|
+
const rows = [];
|
|
205
|
+
const payloadArr = Array.isArray(payload) ? payload : [payload];
|
|
206
|
+
payloadArr.forEach((studyRaw, sIdx) => {
|
|
207
|
+
if (!studyRaw || typeof studyRaw !== 'object')
|
|
208
|
+
return;
|
|
209
|
+
const study = studyRaw;
|
|
210
|
+
const studyLabel = tagVal(study.StudyDescription ?? `Study ${sIdx + 1}`);
|
|
211
|
+
const accession = tagVal(study.AccessionNumber ?? '');
|
|
212
|
+
const studyDisplay = accession ? `${studyLabel} [${accession}]` : studyLabel;
|
|
213
|
+
const seriesArr = Array.isArray(study.series) ? study.series :
|
|
214
|
+
Array.isArray(study.Series) ? study.Series :
|
|
215
|
+
Array.isArray(study.results) ? study.results :
|
|
216
|
+
[];
|
|
217
|
+
seriesArr.forEach((seriesRaw, rIdx) => {
|
|
218
|
+
if (!seriesRaw || typeof seriesRaw !== 'object')
|
|
219
|
+
return;
|
|
220
|
+
const series = seriesRaw;
|
|
221
|
+
rows.push({
|
|
222
|
+
Study: studyDisplay,
|
|
223
|
+
'#': String(rIdx + 1),
|
|
224
|
+
Description: tagVal(series.SeriesDescription ?? ''),
|
|
225
|
+
Modality: tagVal(series.Modality ?? ''),
|
|
226
|
+
Files: tagVal(series.NumberOfSeriesRelatedInstances ?? ''),
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
if (rows.length === 0)
|
|
231
|
+
return null;
|
|
232
|
+
return screen.table_output(rows, { title: { title: title ?? 'Query Results' } });
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Creates a PACS query, waits for results, displays findings, and prints the VFS path.
|
|
236
|
+
*
|
|
237
|
+
* @param args - `<queryExpression> [--title <title>] [--pacsserver <id>] [--table] [--help]`
|
|
238
|
+
* @example
|
|
239
|
+
* query PatientID:1234
|
|
240
|
+
* query 'PatientID:1234,StudyDate:20240101' --title 'Hip DDH Jan 2024'
|
|
241
|
+
* query AccessionNumber:12345678 --table
|
|
242
|
+
*/
|
|
243
|
+
export async function builtin_query(args) {
|
|
244
|
+
if (args_checkHasHelpFlag(args, 'query')) {
|
|
245
|
+
help_show('query');
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
let title = `Query ${Date.now()}`;
|
|
249
|
+
let pacsserverOverride = null;
|
|
250
|
+
let tableMode = false;
|
|
251
|
+
const positional = [];
|
|
252
|
+
for (let i = 0; i < args.length; i++) {
|
|
253
|
+
if (args[i] === '--title' && i + 1 < args.length) {
|
|
254
|
+
title = args[++i];
|
|
255
|
+
}
|
|
256
|
+
else if (args[i] === '--pacsserver' && i + 1 < args.length) {
|
|
257
|
+
pacsserverOverride = args[++i];
|
|
258
|
+
}
|
|
259
|
+
else if (args[i] === '--table') {
|
|
260
|
+
tableMode = true;
|
|
261
|
+
}
|
|
262
|
+
else if (!args[i].startsWith('--')) {
|
|
263
|
+
positional.push(args[i]);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (positional.length === 0) {
|
|
267
|
+
console.error(chalk.red('query: Missing query expression. Usage: query <Key:Value[,...]> [--title <title>]'));
|
|
268
|
+
process.exitCode = 1;
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
const queryExpr = positional.join(' ');
|
|
272
|
+
// Validate expression early
|
|
273
|
+
if (!queryExpr_parse(queryExpr)) {
|
|
274
|
+
console.error(chalk.red(`query: Invalid expression: "${queryExpr}". Use Key:Value pairs (e.g. PatientID:1234) or JSON.`));
|
|
275
|
+
process.exitCode = 1;
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
// Resolve PACS server
|
|
279
|
+
let pacsserver = pacsserverOverride ?? await chrisContext.current_get(Context.PACSserver);
|
|
280
|
+
if (!pacsserver) {
|
|
281
|
+
const serversResult = await pacsServers_list();
|
|
282
|
+
if (serversResult.ok && serversResult.value.length > 0) {
|
|
283
|
+
pacsserver = String(serversResult.value[0].id);
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
console.error(chalk.red('query: No PACS server available. Set one with: pacs connect <id>'));
|
|
287
|
+
process.exitCode = 1;
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
spinner.start(`Querying PACS for ${queryExpr}...`, true);
|
|
292
|
+
const result = await pacsQuery_createAndWait(queryExpr, title, pacsserver, (msg) => spinner.updateMessage(msg));
|
|
293
|
+
spinner.stop();
|
|
294
|
+
if (!result) {
|
|
295
|
+
const errs = errorStack.stack_getAll?.() ?? [];
|
|
296
|
+
if (errs.length) {
|
|
297
|
+
// Print the stack directly: in -c/-f mode nothing else will.
|
|
298
|
+
errs.forEach((err) => {
|
|
299
|
+
const msg = typeof err === 'string' ? err : (err.message ?? String(err));
|
|
300
|
+
console.error(chalk.red(msg));
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
console.error(chalk.red('query: Failed — check connection and PACS server context.'));
|
|
305
|
+
}
|
|
306
|
+
process.exitCode = 1;
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const rendered = tableMode
|
|
310
|
+
? queryResult_renderTable(result.decoded, title !== `Query ${Date.now()}` ? title : undefined)
|
|
311
|
+
: queryResult_render(result.decoded);
|
|
312
|
+
if (!rendered) {
|
|
313
|
+
// Nothing matched: browsing or pulling the empty query would be
|
|
314
|
+
// meaningless, so no hints.
|
|
315
|
+
console.log(chalk.yellow(`⚠ Query ${result.queryId} complete — no studies found.`));
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
console.log(chalk.green(`✓ Query ${result.queryId} complete`));
|
|
319
|
+
console.log(rendered);
|
|
320
|
+
console.log(chalk.bold(` VFS path: ${chalk.cyan(result.vfsPath)}`));
|
|
321
|
+
console.log(chalk.gray(` cd ${result.vfsPath}`));
|
|
322
|
+
console.log(chalk.gray(` pull ${result.vfsPath}`));
|
|
323
|
+
}
|
|
324
|
+
//# sourceMappingURL=query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/builtins/net/query.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Builtin that lists the parameters of a plugin.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Handles the 'parametersofplugin' builtin command.
|
|
8
|
+
* This command displays information about plugin parameters.
|
|
9
|
+
*
|
|
10
|
+
* @param args - Arguments passed to the command.
|
|
11
|
+
* @returns A Promise that resolves once the command has been processed.
|
|
12
|
+
*/
|
|
13
|
+
export declare function builtin_parametersofplugin(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Builtin that lists the parameters of a plugin.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import { commandArgs_process } from './utils.js';
|
|
8
|
+
import { PluginContextGroupHandler } from '@fnndsc/chili/plugins/pluginGroupHandler.js';
|
|
9
|
+
/**
|
|
10
|
+
* Handles the 'parametersofplugin' builtin command.
|
|
11
|
+
* This command displays information about plugin parameters.
|
|
12
|
+
*
|
|
13
|
+
* @param args - Arguments passed to the command.
|
|
14
|
+
* @returns A Promise that resolves once the command has been processed.
|
|
15
|
+
*/
|
|
16
|
+
export async function builtin_parametersofplugin(args) {
|
|
17
|
+
const parsedArgs = commandArgs_process(args);
|
|
18
|
+
const subcommand = parsedArgs._[0]; // e.g., 'list', 'fieldslist'
|
|
19
|
+
const pluginIdFromArgs = parsedArgs['plugin-id'];
|
|
20
|
+
if (!subcommand) {
|
|
21
|
+
console.log(chalk.red('Usage: parametersofplugin <list|fieldslist> [--plugin-id <id>] ...'));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
// Instantiate the specialized handler
|
|
26
|
+
const handler = await PluginContextGroupHandler.handler_create('parametersofplugin', pluginIdFromArgs ? Number(pluginIdFromArgs) : undefined);
|
|
27
|
+
if (subcommand === 'list') {
|
|
28
|
+
// Use the specialized man-page style listing for parameters
|
|
29
|
+
await handler.parameters_listMan(parsedArgs);
|
|
30
|
+
}
|
|
31
|
+
else if (subcommand === 'fieldslist') {
|
|
32
|
+
await handler.parameters_fieldsList();
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
console.log(chalk.yellow(`Unknown parametersofplugin subcommand: ${subcommand}`));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
40
|
+
console.error(chalk.red(`Error in parametersofplugin: ${msg}`));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=parametersofplugin.js.map
|