lhcb-ntuple-wizard 2.0.1 → 2.0.3
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 +3 -4
- package/dist/App.js +1 -3
- package/dist/components/BookkeepingPathDropdown.d.ts +1 -0
- package/dist/components/BookkeepingPathDropdown.js +35 -0
- package/dist/components/DatasetInfo.d.ts +1 -1
- package/dist/components/DatasetInfo.js +9 -3
- package/dist/components/DttNameInput.d.ts +2 -2
- package/dist/components/DttNameInput.js +16 -18
- package/dist/components/NtupleWizard.d.ts +2 -7
- package/dist/components/NtupleWizard.js +6 -11
- package/dist/components/ProductionNameInput.d.ts +1 -0
- package/dist/components/ProductionNameInput.js +7 -0
- package/dist/components/RequestButtonGroup.d.ts +7 -0
- package/dist/components/RequestButtonGroup.js +29 -0
- package/dist/components/RequestEmailInput.d.ts +1 -0
- package/dist/components/RequestEmailInput.js +7 -0
- package/dist/components/RequestRow.d.ts +7 -0
- package/dist/components/RequestRow.js +20 -0
- package/dist/components/StrippingLineBadge.js +2 -3
- package/dist/components/StrippingLineDropdown.d.ts +1 -0
- package/dist/components/StrippingLineDropdown.js +48 -0
- package/dist/components/modals/ReasonForRequestModal.d.ts +2 -3
- package/dist/components/modals/ReasonForRequestModal.js +1 -8
- package/dist/components/modals/UploadDttConfigModal.d.ts +2 -2
- package/dist/components/modals/UploadDttConfigModal.js +46 -27
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +2 -0
- package/dist/models/bkPath.d.ts +9 -9
- package/dist/models/bkPath.js +37 -30
- package/dist/models/dtt.d.ts +33 -3
- package/dist/models/dtt.js +62 -0
- package/dist/models/yamlFile.d.ts +14 -1
- package/dist/models/yamlFile.js +16 -38
- package/dist/pages/DecaySearchPage.js +1 -1
- package/dist/pages/DecayTreeConfigPage.js +2 -4
- package/dist/pages/RequestPage.d.ts +20 -0
- package/dist/pages/RequestPage.js +101 -0
- package/dist/providers/RequestProvider.d.ts +14 -1
- package/dist/providers/RequestProvider.js +48 -2
- package/dist/providers/RowProvider.d.ts +15 -0
- package/dist/providers/RowProvider.js +41 -0
- package/dist/providers/RowsProvider.d.ts +4 -1
- package/dist/providers/RowsProvider.js +9 -2
- package/dist/utils/utils.d.ts +12 -1
- package/dist/utils/utils.js +533 -0
- package/package.json +8 -4
- package/dist/components/LineTableRow.d.ts +0 -9
- package/dist/components/LineTableRow.js +0 -123
- package/dist/components/SubmitRequestButton.d.ts +0 -10
- package/dist/components/SubmitRequestButton.js +0 -31
- package/dist/components/modals/UploadProdConfigModal.d.ts +0 -5
- package/dist/components/modals/UploadProdConfigModal.js +0 -27
- package/dist/models/blobFile.d.ts +0 -12
- package/dist/models/blobFile.js +0 -1
- package/dist/models/strippingLineOption.d.ts +0 -6
- package/dist/models/strippingLineOption.js +0 -1
- package/dist/pages/LinesTablePage.d.ts +0 -14
- package/dist/pages/LinesTablePage.js +0 -125
- package/dist/providers/ProductionConfigProvider.d.ts +0 -14
- package/dist/providers/ProductionConfigProvider.js +0 -76
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { Dispatch, ReactNode, SetStateAction } from "react";
|
|
2
|
-
import { RowData } from "../models/rowData.js";
|
|
2
|
+
import { ConfiguredRow, RowData } from "../models/rowData.js";
|
|
3
3
|
import { YamlFile } from "../models/yamlFile";
|
|
4
4
|
interface RowsContextType {
|
|
5
5
|
rows: RowData[];
|
|
6
|
+
configuredRows: ConfiguredRow[];
|
|
6
7
|
setRows: Dispatch<SetStateAction<RowData[]>>;
|
|
8
|
+
updateRow: (id: number, update: (row: RowData) => RowData) => void;
|
|
9
|
+
removeRow: (id: number) => void;
|
|
7
10
|
generateAllFiles: () => YamlFile[];
|
|
8
11
|
}
|
|
9
12
|
interface Props {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { createContext, useContext, useEffect, useState } from "react";
|
|
2
|
+
import { createContext, useContext, useEffect, useMemo, useState } from "react";
|
|
3
3
|
import Dtt from "../models/dtt";
|
|
4
4
|
import { useMetadata } from "./MetadataProvider";
|
|
5
5
|
import { YamlFile } from "../models/yamlFile";
|
|
@@ -11,6 +11,12 @@ export const RowsProvider = ({ children }) => {
|
|
|
11
11
|
useEffect(() => {
|
|
12
12
|
localStorage.setItem("rows", JSON.stringify(rows));
|
|
13
13
|
}, [rows]);
|
|
14
|
+
const updateRow = (id, update) => {
|
|
15
|
+
setRows((prev) => prev.map((r) => (r.id === id ? update(r) : r)));
|
|
16
|
+
};
|
|
17
|
+
const removeRow = (id) => {
|
|
18
|
+
setRows((prev) => prev.filter((r) => r.id !== id));
|
|
19
|
+
};
|
|
14
20
|
const generateAllFiles = () => {
|
|
15
21
|
if (!metadata) {
|
|
16
22
|
return [];
|
|
@@ -20,7 +26,8 @@ export const RowsProvider = ({ children }) => {
|
|
|
20
26
|
YamlFile.createInfoYaml(rows, metadata),
|
|
21
27
|
];
|
|
22
28
|
};
|
|
23
|
-
|
|
29
|
+
const configuredRows = useMemo(() => rows.filter((r) => !!r.dtt), [rows]);
|
|
30
|
+
return (_jsx(RowsContext.Provider, { value: { rows, configuredRows, setRows, updateRow, removeRow, generateAllFiles }, children: children }));
|
|
24
31
|
};
|
|
25
32
|
export const useRows = () => {
|
|
26
33
|
const context = useContext(RowsContext);
|
package/dist/utils/utils.d.ts
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
import { YamlFile } from "../models/yamlFile";
|
|
1
|
+
import { InfoYaml, YamlFile } from "../models/yamlFile";
|
|
2
|
+
import { SavedDttConfig } from "../models/dtt";
|
|
3
|
+
import { RowData } from "../models/rowData";
|
|
4
|
+
import { MetadataContext } from "../providers/MetadataProvider";
|
|
5
|
+
export declare function parseProductionFiles(files: File[], metadata: MetadataContext): Promise<string | {
|
|
6
|
+
rows: RowData[];
|
|
7
|
+
emails: string[];
|
|
8
|
+
}>;
|
|
9
|
+
export declare function processProductionFiles(metadata: MetadataContext, configs: SavedDttConfig[], infoYaml: InfoYaml | null): string | {
|
|
10
|
+
rows: RowData[];
|
|
11
|
+
emails: string[];
|
|
12
|
+
};
|
|
2
13
|
/**
|
|
3
14
|
* Sanitizes a user-provided filename to prevent path traversal (Zip Slip)
|
|
4
15
|
* and unsafe filesystem characters.
|
package/dist/utils/utils.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as __typia_transform__accessExpressionAsString from "typia/lib/internal/_accessExpressionAsString.js";
|
|
2
|
+
import * as __typia_transform__validateReport from "typia/lib/internal/_validateReport.js";
|
|
1
3
|
/*****************************************************************************\
|
|
2
4
|
* (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration *
|
|
3
5
|
* *
|
|
@@ -9,6 +11,537 @@
|
|
|
9
11
|
* or submit itself to any jurisdiction. *
|
|
10
12
|
\*****************************************************************************/
|
|
11
13
|
import JsZip from "jszip";
|
|
14
|
+
import yaml from "js-yaml";
|
|
15
|
+
import Dtt from "../models/dtt";
|
|
16
|
+
import typia from "typia";
|
|
17
|
+
const parseInput = (decay, input) => {
|
|
18
|
+
const [, , stream, , lineName] = input.split("/");
|
|
19
|
+
const line = `Stripping${lineName}`;
|
|
20
|
+
return {
|
|
21
|
+
stream,
|
|
22
|
+
line,
|
|
23
|
+
versions: decay.lines[`${stream}/${line}`],
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
const addBkPathsToRows = (infoYaml, rows) => {
|
|
27
|
+
for (const row of rows) {
|
|
28
|
+
if (!row.dtt?.config.name) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
const dttName = row.dtt.config.name.split("/")[1];
|
|
32
|
+
for (const [key, jobConfig] of Object.entries(infoYaml)) {
|
|
33
|
+
if (key === "defaults") {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const job = jobConfig;
|
|
37
|
+
if (job.options.some((option) => option.split(".")[0] === dttName)) {
|
|
38
|
+
row.paths.push(job.input.bk_query);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
async function parseYamlFile(file) {
|
|
44
|
+
const text = await file.text();
|
|
45
|
+
try {
|
|
46
|
+
return yaml.load(text, { schema: yaml.JSON_SCHEMA });
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
console.error(`YAML file '${file.name}' is invalid:`, e);
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async function parseInfoYamlFile(file) {
|
|
54
|
+
const rawConfig = await parseYamlFile(file);
|
|
55
|
+
if (!rawConfig) {
|
|
56
|
+
return "'info.yaml' is not a valid yaml file";
|
|
57
|
+
}
|
|
58
|
+
const validationResult = (() => { const _io0 = input => "object" === typeof input.defaults && null !== input.defaults && _io1(input.defaults) && Object.keys(input).every(key => {
|
|
59
|
+
if (["defaults"].some(prop => key === prop))
|
|
60
|
+
return true;
|
|
61
|
+
const value = input[key];
|
|
62
|
+
if (undefined === value)
|
|
63
|
+
return true;
|
|
64
|
+
return undefined === value || "object" === typeof value && null !== value && _io2(value);
|
|
65
|
+
}); const _io1 = input => "string" === typeof input.application && "string" === typeof input.wg && (Array.isArray(input.inform) && input.inform.every(elem => "string" === typeof elem)) && "boolean" === typeof input.automatically_configure && "string" === typeof input.output; const _io2 = input => Array.isArray(input.options) && input.options.every(elem => "string" === typeof elem) && ("object" === typeof input.input && null !== input.input && _io3(input.input)) && (undefined === input.root_in_tes || "string" === typeof input.root_in_tes); const _io3 = input => "string" === typeof input.bk_query; const _vo0 = (input, _path, _exceptionable = true) => [("object" === typeof input.defaults && null !== input.defaults || _report(_exceptionable, {
|
|
66
|
+
path: _path + ".defaults",
|
|
67
|
+
expected: "InfoYamlDefaults",
|
|
68
|
+
value: input.defaults
|
|
69
|
+
})) && _vo1(input.defaults, _path + ".defaults", true && _exceptionable) || _report(_exceptionable, {
|
|
70
|
+
path: _path + ".defaults",
|
|
71
|
+
expected: "InfoYamlDefaults",
|
|
72
|
+
value: input.defaults
|
|
73
|
+
}), false === _exceptionable || Object.keys(input).map(key => {
|
|
74
|
+
if (["defaults"].some(prop => key === prop))
|
|
75
|
+
return true;
|
|
76
|
+
const value = input[key];
|
|
77
|
+
if (undefined === value)
|
|
78
|
+
return true;
|
|
79
|
+
return undefined === value || ("object" === typeof value && null !== value || _report(_exceptionable, {
|
|
80
|
+
path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
|
|
81
|
+
expected: "(JobConfig | undefined)",
|
|
82
|
+
value: value
|
|
83
|
+
})) && _vo2(value, _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key), true && _exceptionable) || _report(_exceptionable, {
|
|
84
|
+
path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
|
|
85
|
+
expected: "(JobConfig | undefined)",
|
|
86
|
+
value: value
|
|
87
|
+
});
|
|
88
|
+
}).every(flag => flag)].every(flag => flag); const _vo1 = (input, _path, _exceptionable = true) => ["string" === typeof input.application || _report(_exceptionable, {
|
|
89
|
+
path: _path + ".application",
|
|
90
|
+
expected: "string",
|
|
91
|
+
value: input.application
|
|
92
|
+
}), "string" === typeof input.wg || _report(_exceptionable, {
|
|
93
|
+
path: _path + ".wg",
|
|
94
|
+
expected: "string",
|
|
95
|
+
value: input.wg
|
|
96
|
+
}), (Array.isArray(input.inform) || _report(_exceptionable, {
|
|
97
|
+
path: _path + ".inform",
|
|
98
|
+
expected: "Array<string>",
|
|
99
|
+
value: input.inform
|
|
100
|
+
})) && input.inform.map((elem, _index3) => "string" === typeof elem || _report(_exceptionable, {
|
|
101
|
+
path: _path + ".inform[" + _index3 + "]",
|
|
102
|
+
expected: "string",
|
|
103
|
+
value: elem
|
|
104
|
+
})).every(flag => flag) || _report(_exceptionable, {
|
|
105
|
+
path: _path + ".inform",
|
|
106
|
+
expected: "Array<string>",
|
|
107
|
+
value: input.inform
|
|
108
|
+
}), "boolean" === typeof input.automatically_configure || _report(_exceptionable, {
|
|
109
|
+
path: _path + ".automatically_configure",
|
|
110
|
+
expected: "boolean",
|
|
111
|
+
value: input.automatically_configure
|
|
112
|
+
}), "string" === typeof input.output || _report(_exceptionable, {
|
|
113
|
+
path: _path + ".output",
|
|
114
|
+
expected: "string",
|
|
115
|
+
value: input.output
|
|
116
|
+
})].every(flag => flag); const _vo2 = (input, _path, _exceptionable = true) => [(Array.isArray(input.options) || _report(_exceptionable, {
|
|
117
|
+
path: _path + ".options",
|
|
118
|
+
expected: "Array<string>",
|
|
119
|
+
value: input.options
|
|
120
|
+
})) && input.options.map((elem, _index4) => "string" === typeof elem || _report(_exceptionable, {
|
|
121
|
+
path: _path + ".options[" + _index4 + "]",
|
|
122
|
+
expected: "string",
|
|
123
|
+
value: elem
|
|
124
|
+
})).every(flag => flag) || _report(_exceptionable, {
|
|
125
|
+
path: _path + ".options",
|
|
126
|
+
expected: "Array<string>",
|
|
127
|
+
value: input.options
|
|
128
|
+
}), ("object" === typeof input.input && null !== input.input || _report(_exceptionable, {
|
|
129
|
+
path: _path + ".input",
|
|
130
|
+
expected: "__type",
|
|
131
|
+
value: input.input
|
|
132
|
+
})) && _vo3(input.input, _path + ".input", true && _exceptionable) || _report(_exceptionable, {
|
|
133
|
+
path: _path + ".input",
|
|
134
|
+
expected: "__type",
|
|
135
|
+
value: input.input
|
|
136
|
+
}), undefined === input.root_in_tes || "string" === typeof input.root_in_tes || _report(_exceptionable, {
|
|
137
|
+
path: _path + ".root_in_tes",
|
|
138
|
+
expected: "(string | undefined)",
|
|
139
|
+
value: input.root_in_tes
|
|
140
|
+
})].every(flag => flag); const _vo3 = (input, _path, _exceptionable = true) => ["string" === typeof input.bk_query || _report(_exceptionable, {
|
|
141
|
+
path: _path + ".bk_query",
|
|
142
|
+
expected: "string",
|
|
143
|
+
value: input.bk_query
|
|
144
|
+
})].every(flag => flag); const __is = input => "object" === typeof input && null !== input && _io0(input); let errors; let _report; return input => {
|
|
145
|
+
if (false === __is(input)) {
|
|
146
|
+
errors = [];
|
|
147
|
+
_report = __typia_transform__validateReport._validateReport(errors);
|
|
148
|
+
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
149
|
+
path: _path + "",
|
|
150
|
+
expected: "InfoYaml",
|
|
151
|
+
value: input
|
|
152
|
+
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
153
|
+
path: _path + "",
|
|
154
|
+
expected: "InfoYaml",
|
|
155
|
+
value: input
|
|
156
|
+
}))(input, "$input", true);
|
|
157
|
+
const success = 0 === errors.length;
|
|
158
|
+
return success ? {
|
|
159
|
+
success,
|
|
160
|
+
data: input
|
|
161
|
+
} : {
|
|
162
|
+
success,
|
|
163
|
+
errors,
|
|
164
|
+
data: input
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
success: true,
|
|
169
|
+
data: input
|
|
170
|
+
};
|
|
171
|
+
}; })()(rawConfig);
|
|
172
|
+
if (!validationResult.success) {
|
|
173
|
+
return "'info.yaml' does not have the expected structure";
|
|
174
|
+
}
|
|
175
|
+
return validationResult.data;
|
|
176
|
+
}
|
|
177
|
+
async function parseDttConfigFile(file) {
|
|
178
|
+
const rawConfig = await parseYamlFile(file);
|
|
179
|
+
if (!rawConfig) {
|
|
180
|
+
return `'${file.name}' is not a valid yaml file`;
|
|
181
|
+
}
|
|
182
|
+
const validationResult = (() => { const _ip0 = input => {
|
|
183
|
+
const array = input;
|
|
184
|
+
const top = input[0];
|
|
185
|
+
if (0 === input.length)
|
|
186
|
+
return true;
|
|
187
|
+
const arrayPredicators = [
|
|
188
|
+
[
|
|
189
|
+
top => "string" === typeof top,
|
|
190
|
+
entire => entire.every(elem => "string" === typeof elem)
|
|
191
|
+
],
|
|
192
|
+
[
|
|
193
|
+
top => "number" === typeof top,
|
|
194
|
+
entire => entire.every(elem => "number" === typeof elem)
|
|
195
|
+
]
|
|
196
|
+
];
|
|
197
|
+
const passed = arrayPredicators.filter(pred => pred[0](top));
|
|
198
|
+
if (1 === passed.length)
|
|
199
|
+
return passed[0][1](array);
|
|
200
|
+
else if (1 < passed.length)
|
|
201
|
+
for (const pred of passed)
|
|
202
|
+
if (array.every(value => true === pred[0](value)))
|
|
203
|
+
return pred[1](array);
|
|
204
|
+
return false;
|
|
205
|
+
}; const _vp1 = (input, _path, _exceptionable = true) => {
|
|
206
|
+
const array = input;
|
|
207
|
+
const top = input[0];
|
|
208
|
+
if (0 === input.length)
|
|
209
|
+
return true;
|
|
210
|
+
const arrayPredicators = [
|
|
211
|
+
[
|
|
212
|
+
top => "string" === typeof top,
|
|
213
|
+
entire => entire.map((elem, _index16) => "string" === typeof elem || _report(_exceptionable, {
|
|
214
|
+
path: _path + "[" + _index16 + "]",
|
|
215
|
+
expected: "string",
|
|
216
|
+
value: elem
|
|
217
|
+
})).every(flag => flag)
|
|
218
|
+
],
|
|
219
|
+
[
|
|
220
|
+
top => "number" === typeof top,
|
|
221
|
+
entire => entire.map((elem, _index17) => "number" === typeof elem || _report(_exceptionable, {
|
|
222
|
+
path: _path + "[" + _index17 + "]",
|
|
223
|
+
expected: "number",
|
|
224
|
+
value: elem
|
|
225
|
+
})).every(flag => flag)
|
|
226
|
+
]
|
|
227
|
+
];
|
|
228
|
+
const passed = arrayPredicators.filter(pred => pred[0](top));
|
|
229
|
+
if (1 === passed.length)
|
|
230
|
+
return passed[0][1](array);
|
|
231
|
+
else if (1 < passed.length)
|
|
232
|
+
for (const pred of passed)
|
|
233
|
+
if (array.every(value => true === pred[0](value)))
|
|
234
|
+
return pred[1](array);
|
|
235
|
+
return _report(_exceptionable, {
|
|
236
|
+
path: _path,
|
|
237
|
+
expected: "(Array<string> | Array<number>)",
|
|
238
|
+
value: input
|
|
239
|
+
});
|
|
240
|
+
}; const _io0 = input => "object" === typeof input.branches && null !== input.branches && false === Array.isArray(input.branches) && _io1(input.branches) && (undefined === input.descriptorTemplate || "string" === typeof input.descriptorTemplate) && ("object" === typeof input.groups && null !== input.groups && false === Array.isArray(input.groups) && _io7(input.groups)) && (undefined === input.inputs || Array.isArray(input.inputs) && input.inputs.every(elem => "string" === typeof elem)) && (undefined === input.name || "string" === typeof input.name) && (Array.isArray(input.tools) && input.tools.every(elem => "object" === typeof elem && null !== elem && false === Array.isArray(elem) && _io3(elem))); const _io1 = input => Object.keys(input).every(key => {
|
|
241
|
+
const value = input[key];
|
|
242
|
+
if (undefined === value)
|
|
243
|
+
return true;
|
|
244
|
+
return "object" === typeof value && null !== value && _io2(value);
|
|
245
|
+
}); const _io2 = input => "string" === typeof input.particle && (Array.isArray(input.tools) && input.tools.every(elem => "object" === typeof elem && null !== elem && false === Array.isArray(elem) && _io3(elem))); const _io3 = input => Object.keys(input).every(key => {
|
|
246
|
+
const value = input[key];
|
|
247
|
+
if (undefined === value)
|
|
248
|
+
return true;
|
|
249
|
+
return "object" === typeof value && null !== value && false === Array.isArray(value) && _io4(value);
|
|
250
|
+
}); const _io4 = input => Object.keys(input).every(key => {
|
|
251
|
+
const value = input[key];
|
|
252
|
+
if (undefined === value)
|
|
253
|
+
return true;
|
|
254
|
+
return null !== value && undefined !== value && ("string" === typeof value || "number" === typeof value || "boolean" === typeof value || (Array.isArray(value) && (_ip0(value) || false) || "object" === typeof value && null !== value && false === Array.isArray(value) && _iu0(value)));
|
|
255
|
+
}); const _io5 = input => Object.keys(input).every(key => {
|
|
256
|
+
const value = input[key];
|
|
257
|
+
if (undefined === value)
|
|
258
|
+
return true;
|
|
259
|
+
return "string" === typeof value;
|
|
260
|
+
}); const _io6 = input => Object.keys(input).every(key => {
|
|
261
|
+
const value = input[key];
|
|
262
|
+
if (undefined === value)
|
|
263
|
+
return true;
|
|
264
|
+
return Array.isArray(value) && value.every(elem => "string" === typeof elem);
|
|
265
|
+
}); const _io7 = input => Object.keys(input).every(key => {
|
|
266
|
+
const value = input[key];
|
|
267
|
+
if (undefined === value)
|
|
268
|
+
return true;
|
|
269
|
+
return "object" === typeof value && null !== value && _io8(value);
|
|
270
|
+
}); const _io8 = input => Array.isArray(input.particles) && input.particles.every(elem => "string" === typeof elem) && (Array.isArray(input.tools) && input.tools.every(elem => "object" === typeof elem && null !== elem && false === Array.isArray(elem) && _io3(elem))); const _iu0 = input => (() => {
|
|
271
|
+
if (_io6(input))
|
|
272
|
+
return _io6(input);
|
|
273
|
+
if (_io5(input))
|
|
274
|
+
return _io5(input);
|
|
275
|
+
return false;
|
|
276
|
+
})(); const _vo0 = (input, _path, _exceptionable = true) => [("object" === typeof input.branches && null !== input.branches && false === Array.isArray(input.branches) || _report(_exceptionable, {
|
|
277
|
+
path: _path + ".branches",
|
|
278
|
+
expected: "__type",
|
|
279
|
+
value: input.branches
|
|
280
|
+
})) && _vo1(input.branches, _path + ".branches", true && _exceptionable) || _report(_exceptionable, {
|
|
281
|
+
path: _path + ".branches",
|
|
282
|
+
expected: "__type",
|
|
283
|
+
value: input.branches
|
|
284
|
+
}), undefined === input.descriptorTemplate || "string" === typeof input.descriptorTemplate || _report(_exceptionable, {
|
|
285
|
+
path: _path + ".descriptorTemplate",
|
|
286
|
+
expected: "(string | undefined)",
|
|
287
|
+
value: input.descriptorTemplate
|
|
288
|
+
}), ("object" === typeof input.groups && null !== input.groups && false === Array.isArray(input.groups) || _report(_exceptionable, {
|
|
289
|
+
path: _path + ".groups",
|
|
290
|
+
expected: "__type.o4",
|
|
291
|
+
value: input.groups
|
|
292
|
+
})) && _vo7(input.groups, _path + ".groups", true && _exceptionable) || _report(_exceptionable, {
|
|
293
|
+
path: _path + ".groups",
|
|
294
|
+
expected: "__type.o4",
|
|
295
|
+
value: input.groups
|
|
296
|
+
}), undefined === input.inputs || (Array.isArray(input.inputs) || _report(_exceptionable, {
|
|
297
|
+
path: _path + ".inputs",
|
|
298
|
+
expected: "(Array<string> | undefined)",
|
|
299
|
+
value: input.inputs
|
|
300
|
+
})) && input.inputs.map((elem, _index11) => "string" === typeof elem || _report(_exceptionable, {
|
|
301
|
+
path: _path + ".inputs[" + _index11 + "]",
|
|
302
|
+
expected: "string",
|
|
303
|
+
value: elem
|
|
304
|
+
})).every(flag => flag) || _report(_exceptionable, {
|
|
305
|
+
path: _path + ".inputs",
|
|
306
|
+
expected: "(Array<string> | undefined)",
|
|
307
|
+
value: input.inputs
|
|
308
|
+
}), undefined === input.name || "string" === typeof input.name || _report(_exceptionable, {
|
|
309
|
+
path: _path + ".name",
|
|
310
|
+
expected: "(string | undefined)",
|
|
311
|
+
value: input.name
|
|
312
|
+
}), (Array.isArray(input.tools) || _report(_exceptionable, {
|
|
313
|
+
path: _path + ".tools",
|
|
314
|
+
expected: "Array<SavedToolConfig>",
|
|
315
|
+
value: input.tools
|
|
316
|
+
})) && input.tools.map((elem, _index12) => ("object" === typeof elem && null !== elem && false === Array.isArray(elem) || _report(_exceptionable, {
|
|
317
|
+
path: _path + ".tools[" + _index12 + "]",
|
|
318
|
+
expected: "SavedToolConfig",
|
|
319
|
+
value: elem
|
|
320
|
+
})) && _vo3(elem, _path + ".tools[" + _index12 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
321
|
+
path: _path + ".tools[" + _index12 + "]",
|
|
322
|
+
expected: "SavedToolConfig",
|
|
323
|
+
value: elem
|
|
324
|
+
})).every(flag => flag) || _report(_exceptionable, {
|
|
325
|
+
path: _path + ".tools",
|
|
326
|
+
expected: "Array<SavedToolConfig>",
|
|
327
|
+
value: input.tools
|
|
328
|
+
})].every(flag => flag); const _vo1 = (input, _path, _exceptionable = true) => [false === _exceptionable || Object.keys(input).map(key => {
|
|
329
|
+
const value = input[key];
|
|
330
|
+
if (undefined === value)
|
|
331
|
+
return true;
|
|
332
|
+
return ("object" === typeof value && null !== value || _report(_exceptionable, {
|
|
333
|
+
path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
|
|
334
|
+
expected: "SavedBranchConfig",
|
|
335
|
+
value: value
|
|
336
|
+
})) && _vo2(value, _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key), true && _exceptionable) || _report(_exceptionable, {
|
|
337
|
+
path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
|
|
338
|
+
expected: "SavedBranchConfig",
|
|
339
|
+
value: value
|
|
340
|
+
});
|
|
341
|
+
}).every(flag => flag)].every(flag => flag); const _vo2 = (input, _path, _exceptionable = true) => ["string" === typeof input.particle || _report(_exceptionable, {
|
|
342
|
+
path: _path + ".particle",
|
|
343
|
+
expected: "string",
|
|
344
|
+
value: input.particle
|
|
345
|
+
}), (Array.isArray(input.tools) || _report(_exceptionable, {
|
|
346
|
+
path: _path + ".tools",
|
|
347
|
+
expected: "Array<SavedToolConfig>",
|
|
348
|
+
value: input.tools
|
|
349
|
+
})) && input.tools.map((elem, _index13) => ("object" === typeof elem && null !== elem && false === Array.isArray(elem) || _report(_exceptionable, {
|
|
350
|
+
path: _path + ".tools[" + _index13 + "]",
|
|
351
|
+
expected: "SavedToolConfig",
|
|
352
|
+
value: elem
|
|
353
|
+
})) && _vo3(elem, _path + ".tools[" + _index13 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
354
|
+
path: _path + ".tools[" + _index13 + "]",
|
|
355
|
+
expected: "SavedToolConfig",
|
|
356
|
+
value: elem
|
|
357
|
+
})).every(flag => flag) || _report(_exceptionable, {
|
|
358
|
+
path: _path + ".tools",
|
|
359
|
+
expected: "Array<SavedToolConfig>",
|
|
360
|
+
value: input.tools
|
|
361
|
+
})].every(flag => flag); const _vo3 = (input, _path, _exceptionable = true) => [false === _exceptionable || Object.keys(input).map(key => {
|
|
362
|
+
const value = input[key];
|
|
363
|
+
if (undefined === value)
|
|
364
|
+
return true;
|
|
365
|
+
return ("object" === typeof value && null !== value && false === Array.isArray(value) || _report(_exceptionable, {
|
|
366
|
+
path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
|
|
367
|
+
expected: "__type.o1",
|
|
368
|
+
value: value
|
|
369
|
+
})) && _vo4(value, _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key), true && _exceptionable) || _report(_exceptionable, {
|
|
370
|
+
path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
|
|
371
|
+
expected: "__type.o1",
|
|
372
|
+
value: value
|
|
373
|
+
});
|
|
374
|
+
}).every(flag => flag)].every(flag => flag); const _vo4 = (input, _path, _exceptionable = true) => [false === _exceptionable || Object.keys(input).map(key => {
|
|
375
|
+
const value = input[key];
|
|
376
|
+
if (undefined === value)
|
|
377
|
+
return true;
|
|
378
|
+
return (null !== value || _report(_exceptionable, {
|
|
379
|
+
path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
|
|
380
|
+
expected: "(Array<number> | Array<string> | __type.o2 | __type.o3 | boolean | number | string)",
|
|
381
|
+
value: value
|
|
382
|
+
})) && (undefined !== value || _report(_exceptionable, {
|
|
383
|
+
path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
|
|
384
|
+
expected: "(Array<number> | Array<string> | __type.o2 | __type.o3 | boolean | number | string)",
|
|
385
|
+
value: value
|
|
386
|
+
})) && ("string" === typeof value || "number" === typeof value || "boolean" === typeof value || (Array.isArray(value) && (_vp1(value, _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key), true && _exceptionable) || _report(_exceptionable, {
|
|
387
|
+
path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
|
|
388
|
+
expected: "Array<string> | Array<number>",
|
|
389
|
+
value: value
|
|
390
|
+
})) || "object" === typeof value && null !== value && false === Array.isArray(value) && _vu0(value, _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key), true && _exceptionable) || _report(_exceptionable, {
|
|
391
|
+
path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
|
|
392
|
+
expected: "(Array<number> | Array<string> | __type.o2 | __type.o3 | boolean | number | string)",
|
|
393
|
+
value: value
|
|
394
|
+
})) || _report(_exceptionable, {
|
|
395
|
+
path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
|
|
396
|
+
expected: "(Array<number> | Array<string> | __type.o2 | __type.o3 | boolean | number | string)",
|
|
397
|
+
value: value
|
|
398
|
+
}));
|
|
399
|
+
}).every(flag => flag)].every(flag => flag); const _vo5 = (input, _path, _exceptionable = true) => [false === _exceptionable || Object.keys(input).map(key => {
|
|
400
|
+
const value = input[key];
|
|
401
|
+
if (undefined === value)
|
|
402
|
+
return true;
|
|
403
|
+
return "string" === typeof value || _report(_exceptionable, {
|
|
404
|
+
path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
|
|
405
|
+
expected: "string",
|
|
406
|
+
value: value
|
|
407
|
+
});
|
|
408
|
+
}).every(flag => flag)].every(flag => flag); const _vo6 = (input, _path, _exceptionable = true) => [false === _exceptionable || Object.keys(input).map(key => {
|
|
409
|
+
const value = input[key];
|
|
410
|
+
if (undefined === value)
|
|
411
|
+
return true;
|
|
412
|
+
return (Array.isArray(value) || _report(_exceptionable, {
|
|
413
|
+
path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
|
|
414
|
+
expected: "Array<string>",
|
|
415
|
+
value: value
|
|
416
|
+
})) && value.map((elem, _index18) => "string" === typeof elem || _report(_exceptionable, {
|
|
417
|
+
path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key) + "[" + _index18 + "]",
|
|
418
|
+
expected: "string",
|
|
419
|
+
value: elem
|
|
420
|
+
})).every(flag => flag) || _report(_exceptionable, {
|
|
421
|
+
path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
|
|
422
|
+
expected: "Array<string>",
|
|
423
|
+
value: value
|
|
424
|
+
});
|
|
425
|
+
}).every(flag => flag)].every(flag => flag); const _vo7 = (input, _path, _exceptionable = true) => [false === _exceptionable || Object.keys(input).map(key => {
|
|
426
|
+
const value = input[key];
|
|
427
|
+
if (undefined === value)
|
|
428
|
+
return true;
|
|
429
|
+
return ("object" === typeof value && null !== value || _report(_exceptionable, {
|
|
430
|
+
path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
|
|
431
|
+
expected: "SavedGroupConfig",
|
|
432
|
+
value: value
|
|
433
|
+
})) && _vo8(value, _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key), true && _exceptionable) || _report(_exceptionable, {
|
|
434
|
+
path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
|
|
435
|
+
expected: "SavedGroupConfig",
|
|
436
|
+
value: value
|
|
437
|
+
});
|
|
438
|
+
}).every(flag => flag)].every(flag => flag); const _vo8 = (input, _path, _exceptionable = true) => [(Array.isArray(input.particles) || _report(_exceptionable, {
|
|
439
|
+
path: _path + ".particles",
|
|
440
|
+
expected: "Array<string>",
|
|
441
|
+
value: input.particles
|
|
442
|
+
})) && input.particles.map((elem, _index19) => "string" === typeof elem || _report(_exceptionable, {
|
|
443
|
+
path: _path + ".particles[" + _index19 + "]",
|
|
444
|
+
expected: "string",
|
|
445
|
+
value: elem
|
|
446
|
+
})).every(flag => flag) || _report(_exceptionable, {
|
|
447
|
+
path: _path + ".particles",
|
|
448
|
+
expected: "Array<string>",
|
|
449
|
+
value: input.particles
|
|
450
|
+
}), (Array.isArray(input.tools) || _report(_exceptionable, {
|
|
451
|
+
path: _path + ".tools",
|
|
452
|
+
expected: "Array<SavedToolConfig>",
|
|
453
|
+
value: input.tools
|
|
454
|
+
})) && input.tools.map((elem, _index20) => ("object" === typeof elem && null !== elem && false === Array.isArray(elem) || _report(_exceptionable, {
|
|
455
|
+
path: _path + ".tools[" + _index20 + "]",
|
|
456
|
+
expected: "SavedToolConfig",
|
|
457
|
+
value: elem
|
|
458
|
+
})) && _vo3(elem, _path + ".tools[" + _index20 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
459
|
+
path: _path + ".tools[" + _index20 + "]",
|
|
460
|
+
expected: "SavedToolConfig",
|
|
461
|
+
value: elem
|
|
462
|
+
})).every(flag => flag) || _report(_exceptionable, {
|
|
463
|
+
path: _path + ".tools",
|
|
464
|
+
expected: "Array<SavedToolConfig>",
|
|
465
|
+
value: input.tools
|
|
466
|
+
})].every(flag => flag); const _vu0 = (input, _path, _exceptionable = true) => _vo6(input, _path, false && _exceptionable) || _vo5(input, _path, false && _exceptionable); const __is = input => "object" === typeof input && null !== input && _io0(input); let errors; let _report; return input => {
|
|
467
|
+
if (false === __is(input)) {
|
|
468
|
+
errors = [];
|
|
469
|
+
_report = __typia_transform__validateReport._validateReport(errors);
|
|
470
|
+
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
471
|
+
path: _path + "",
|
|
472
|
+
expected: "SavedDttConfig",
|
|
473
|
+
value: input
|
|
474
|
+
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
475
|
+
path: _path + "",
|
|
476
|
+
expected: "SavedDttConfig",
|
|
477
|
+
value: input
|
|
478
|
+
}))(input, "$input", true);
|
|
479
|
+
const success = 0 === errors.length;
|
|
480
|
+
return success ? {
|
|
481
|
+
success,
|
|
482
|
+
data: input
|
|
483
|
+
} : {
|
|
484
|
+
success,
|
|
485
|
+
errors,
|
|
486
|
+
data: input
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
return {
|
|
490
|
+
success: true,
|
|
491
|
+
data: input
|
|
492
|
+
};
|
|
493
|
+
}; })()(rawConfig);
|
|
494
|
+
if (!validationResult.success) {
|
|
495
|
+
return `'${file.name}' does not have the expected structure`;
|
|
496
|
+
}
|
|
497
|
+
return validationResult.data;
|
|
498
|
+
}
|
|
499
|
+
export async function parseProductionFiles(files, metadata) {
|
|
500
|
+
const infoYamlFile = files.find((f) => f.name === "info.yaml");
|
|
501
|
+
const infoYamlResult = infoYamlFile ? await parseInfoYamlFile(infoYamlFile) : null;
|
|
502
|
+
if (typeof infoYamlResult === "string") {
|
|
503
|
+
// The info.yaml is invalid
|
|
504
|
+
return infoYamlResult;
|
|
505
|
+
}
|
|
506
|
+
const dttConfigFiles = files.filter((f) => f.name !== "info.yaml");
|
|
507
|
+
const dttConfigPromises = dttConfigFiles.map((f) => parseDttConfigFile(f));
|
|
508
|
+
const dttConfigResults = await Promise.all(dttConfigPromises);
|
|
509
|
+
const dttConfigErrors = dttConfigResults.filter((r) => typeof r === "string");
|
|
510
|
+
if (dttConfigErrors.length > 0) {
|
|
511
|
+
// One of the DTT config files is invalid
|
|
512
|
+
return dttConfigErrors.join("\n");
|
|
513
|
+
}
|
|
514
|
+
return processProductionFiles(metadata, dttConfigResults, infoYamlResult);
|
|
515
|
+
}
|
|
516
|
+
export function processProductionFiles(metadata, configs, infoYaml) {
|
|
517
|
+
const rows = [];
|
|
518
|
+
const emailsToInform = [];
|
|
519
|
+
for (const config of configs) {
|
|
520
|
+
const decay = Object.values(metadata.decays).find((d) => d.descriptors.template === config.descriptorTemplate);
|
|
521
|
+
if (!decay) {
|
|
522
|
+
return `[${config.name}] Unknown decay '${config.descriptorTemplate}'`;
|
|
523
|
+
}
|
|
524
|
+
if (!config.inputs) {
|
|
525
|
+
return `[${config.name}] No inputs defined`;
|
|
526
|
+
}
|
|
527
|
+
rows.push({
|
|
528
|
+
id: rows.length,
|
|
529
|
+
decay,
|
|
530
|
+
lines: config.inputs.map((input) => parseInput(decay, input)),
|
|
531
|
+
paths: [],
|
|
532
|
+
pathOptions: [],
|
|
533
|
+
dtt: Dtt.fromSavedConfig(config, metadata.tupleTools.tupleTools),
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
if (infoYaml) {
|
|
537
|
+
const email = infoYaml.defaults.inform[0];
|
|
538
|
+
if (email) {
|
|
539
|
+
emailsToInform.push(email);
|
|
540
|
+
}
|
|
541
|
+
addBkPathsToRows(infoYaml, rows);
|
|
542
|
+
}
|
|
543
|
+
return { rows, emails: emailsToInform };
|
|
544
|
+
}
|
|
12
545
|
/**
|
|
13
546
|
* Sanitizes a user-provided filename to prevent path traversal (Zip Slip)
|
|
14
547
|
* and unsafe filesystem characters.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lhcb-ntuple-wizard",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
4
4
|
"description": "An application to access large-scale open data from LHCb",
|
|
5
5
|
"url": "https://gitlab.cern.ch/lhcb-dpa/wp6-analysis-preservation-and-open-data/lhcb-ntuple-wizard-frontend/issues",
|
|
6
6
|
"private": false,
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
"react-bootstrap-icons": "1.11.6",
|
|
32
32
|
"react-graph-vis": "1.0.7",
|
|
33
33
|
"react-infinite-scroll-component": "^6.1.1",
|
|
34
|
-
"react-select": "5.10.2"
|
|
34
|
+
"react-select": "5.10.2",
|
|
35
|
+
"typia": "^11.0.3"
|
|
35
36
|
},
|
|
36
37
|
"peerDependencies": {
|
|
37
38
|
"react": ">=19",
|
|
@@ -44,7 +45,8 @@
|
|
|
44
45
|
"scripts": {
|
|
45
46
|
"start": "vite --open",
|
|
46
47
|
"build": "tsc",
|
|
47
|
-
"prepublishOnly": "npm run build"
|
|
48
|
+
"prepublishOnly": "npm run build",
|
|
49
|
+
"prepare": "ts-patch install"
|
|
48
50
|
},
|
|
49
51
|
"browserslist": {
|
|
50
52
|
"production": [
|
|
@@ -66,6 +68,7 @@
|
|
|
66
68
|
"@babel/preset-env": "7.28.3",
|
|
67
69
|
"@babel/preset-react": "7.27.1",
|
|
68
70
|
"@eslint/js": "^9.17.0",
|
|
71
|
+
"@kennethwkz/unplugin-typia": "^2.6.7",
|
|
69
72
|
"@types/jest": "^30.0.0",
|
|
70
73
|
"@types/js-yaml": "^4.0.9",
|
|
71
74
|
"@types/lodash": "^4.17.21",
|
|
@@ -84,7 +87,8 @@
|
|
|
84
87
|
"react": "^19.2.3",
|
|
85
88
|
"react-dom": "^19.2.3",
|
|
86
89
|
"react-router-dom": "^7.12.0",
|
|
87
|
-
"
|
|
90
|
+
"ts-patch": "^3.3.0",
|
|
91
|
+
"typescript": "~5.9.3",
|
|
88
92
|
"vite": "7.3.0",
|
|
89
93
|
"vite-tsconfig-paths": "^6.0.3"
|
|
90
94
|
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { RowData } from "../models/rowData";
|
|
2
|
-
interface Props {
|
|
3
|
-
row: RowData;
|
|
4
|
-
hideDownloadButtons: boolean;
|
|
5
|
-
hideUploadButtons: boolean;
|
|
6
|
-
variablesPath: string;
|
|
7
|
-
}
|
|
8
|
-
export declare function LineTableRow({ row, hideDownloadButtons, hideUploadButtons, variablesPath }: Props): import("react/jsx-runtime").JSX.Element | null;
|
|
9
|
-
export {};
|