@styx-api/core 0.3.0 → 0.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/dist/index.cjs +57 -20
- package/dist/index.mjs +57 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/frontend/mrtrix/parser.ts +51 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@styx-api/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Styx compiler core: parses CLI tool descriptors (e.g. Boutiques), optimizes an IR, solves typed parameter bindings, and generates type-safe wrappers (TypeScript, Python, JSON Schema). Part of the Styx/NiWrap ecosystem.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"styx",
|
|
@@ -22,6 +22,10 @@ function isString(x: unknown): x is string {
|
|
|
22
22
|
return typeof x === "string";
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
function isNumber(x: unknown): x is number {
|
|
26
|
+
return typeof x === "number" && Number.isFinite(x);
|
|
27
|
+
}
|
|
28
|
+
|
|
25
29
|
function isArray(x: unknown): x is unknown[] {
|
|
26
30
|
return Array.isArray(x);
|
|
27
31
|
}
|
|
@@ -60,9 +64,10 @@ function emptyExpr(): Sequence {
|
|
|
60
64
|
* - option, 1 arg -> opt(seq(lit(-switch), value)) (flat optional)
|
|
61
65
|
* - option, >1 arg / multi -> opt|rep(seq(lit(-switch), ...)) (sub-struct)
|
|
62
66
|
*
|
|
63
|
-
* Type mapping mirrors the v1 `mrt2bt.js` converter's `set_type
|
|
64
|
-
*
|
|
65
|
-
*
|
|
67
|
+
* Type mapping mirrors the v1 `mrt2bt.js` converter's `set_type`, plus `choice`
|
|
68
|
+
* values: when the dump carries `choices` it lowers to an enum (an alternative
|
|
69
|
+
* of literals), else a plain string (older dumps that omit the values - as v1
|
|
70
|
+
* always did). Per-command quirks v1 hand-coded that the flat dump cannot
|
|
66
71
|
* express (e.g. dwi2fod/mtnormalise paired in/out args) are intentionally NOT
|
|
67
72
|
* special-cased here - they are patched on the niwrap side post-dump, keeping
|
|
68
73
|
* this frontend format-general.
|
|
@@ -160,6 +165,20 @@ export class MrtrixParser implements Frontend {
|
|
|
160
165
|
|
|
161
166
|
// -- Terminals --
|
|
162
167
|
|
|
168
|
+
/**
|
|
169
|
+
* Integer/float bounds, when the dump carries them. The C++ hook serializes
|
|
170
|
+
* `Argument::limits.{i,f}.{min,max}` as `min`/`max`, omitting the unbounded
|
|
171
|
+
* sentinels - so a present value is a real, tool-enforced bound.
|
|
172
|
+
*/
|
|
173
|
+
private numericBounds(arg: Record<string, unknown>): { minValue?: number; maxValue?: number } {
|
|
174
|
+
const lo = arg.min;
|
|
175
|
+
const hi = arg.max;
|
|
176
|
+
return {
|
|
177
|
+
...(isNumber(lo) && { minValue: lo }),
|
|
178
|
+
...(isNumber(hi) && { maxValue: hi }),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
163
182
|
/**
|
|
164
183
|
* Lower one MRtrix argument to its terminal node (carrying name + doc) and,
|
|
165
184
|
* for output types, an accompanying `Output`.
|
|
@@ -177,14 +196,38 @@ export class MrtrixParser implements Frontend {
|
|
|
177
196
|
const name = meta.name!;
|
|
178
197
|
|
|
179
198
|
switch (argType) {
|
|
180
|
-
case "integer":
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
return { node
|
|
199
|
+
case "integer": {
|
|
200
|
+
const node = int(meta);
|
|
201
|
+
Object.assign(node.attrs, this.numericBounds(arg));
|
|
202
|
+
return { node };
|
|
203
|
+
}
|
|
204
|
+
case "float": {
|
|
205
|
+
const node = float(meta);
|
|
206
|
+
Object.assign(node.attrs, this.numericBounds(arg));
|
|
207
|
+
return { node };
|
|
208
|
+
}
|
|
184
209
|
case "text":
|
|
185
|
-
case "choice": // choice values are not emitted in the dump; treat as string
|
|
186
210
|
case "undefined":
|
|
211
|
+
case "boolean":
|
|
212
|
+
// `boolean` rarely (if ever) appears in a dump; treat its literal token
|
|
213
|
+
// as a string rather than erroring on an unknown type.
|
|
187
214
|
return { node: str(meta) };
|
|
215
|
+
case "choice": {
|
|
216
|
+
// A `choice` carries its allowed values in `choices` (the C++ hook
|
|
217
|
+
// serializes `Argument::limits.choices`). Lower to an enum: an
|
|
218
|
+
// alternative of string literals. Older dumps omit the values - fall
|
|
219
|
+
// back to a plain string so they still compile.
|
|
220
|
+
const choices = arg.choices;
|
|
221
|
+
if (isArray(choices)) {
|
|
222
|
+
const alts = choices.filter(isString).map((c) => lit(c));
|
|
223
|
+
if (alts.length > 0) {
|
|
224
|
+
const node = alt(...alts);
|
|
225
|
+
node.meta = meta;
|
|
226
|
+
return { node };
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return { node: str(meta) };
|
|
230
|
+
}
|
|
188
231
|
// MRtrix sequences are always a single comma-separated token (parse_ints /
|
|
189
232
|
// parse_floats split on `,`), so the list is comma-joined, never spaced.
|
|
190
233
|
case "int seq": {
|