@jbrowse/cli 3.6.5 → 4.0.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 +4 -0
- package/bin/run +0 -0
- package/bundle/index.js +2280 -2722
- package/dist/bin.js +2 -2
- package/dist/commands/{add-assembly.js → add-assembly/index.js} +10 -10
- package/dist/commands/{assembly-utils.js → add-assembly/utils.js} +69 -105
- package/dist/commands/add-connection.js +11 -16
- package/dist/commands/add-track-json.js +26 -31
- package/dist/commands/add-track-utils/track-config.js +3 -15
- package/dist/commands/add-track-utils/validators.js +4 -9
- package/dist/commands/add-track.js +23 -25
- package/dist/commands/admin-server/index.js +100 -0
- package/dist/commands/{admin-server-utils.js → admin-server/utils.js} +7 -58
- package/dist/commands/create.js +8 -8
- package/dist/commands/{make-pif.js → make-pif/index.js} +11 -17
- package/dist/commands/{make-pif-utils → make-pif}/pif-generator.js +6 -6
- package/dist/commands/{sort-bed-utils/process-utils.js → process-utils.js} +0 -10
- package/dist/commands/remove-track.js +6 -11
- package/dist/commands/set-default-session.js +8 -12
- package/dist/commands/shared/config-operations.js +37 -0
- package/dist/commands/shared/sort-utils.js +57 -0
- package/dist/commands/shared/validators.js +18 -0
- package/dist/commands/sort-bed.js +13 -24
- package/dist/commands/sort-gff.js +13 -24
- package/dist/commands/text-index/adapter-utils.js +43 -0
- package/dist/commands/text-index/aggregate.js +52 -0
- package/dist/commands/{text-index.js → text-index/command.js} +13 -6
- package/dist/commands/text-index/config-utils.js +134 -0
- package/dist/commands/{text-index-utils → text-index}/file-list.js +12 -15
- package/dist/commands/text-index/index.js +11 -0
- package/dist/commands/{text-index-utils → text-index}/indexing-utils.js +30 -20
- package/dist/commands/text-index/per-track.js +54 -0
- package/dist/commands/track-utils.js +33 -33
- package/dist/commands/upgrade.js +8 -8
- package/dist/index.js +39 -27
- package/dist/types/common.js +9 -8
- package/dist/types/gff3Adapter.js +17 -48
- package/dist/types/streamUtils.js +66 -0
- package/dist/types/vcfAdapter.js +17 -54
- package/dist/util.js +14 -7
- package/dist/utils.js +10 -5
- package/package.json +14 -16
- package/dist/commands/admin-server.js +0 -55
- package/dist/commands/make-pif-utils/validators.js +0 -22
- package/dist/commands/sort-bed-utils/constants.js +0 -12
- package/dist/commands/sort-bed-utils/sort-utils.js +0 -24
- package/dist/commands/sort-bed-utils/validators.js +0 -22
- package/dist/commands/sort-gff-utils/constants.js +0 -13
- package/dist/commands/sort-gff-utils/process-utils.js +0 -23
- package/dist/commands/sort-gff-utils/sort-utils.js +0 -55
- package/dist/commands/sort-gff-utils/validators.js +0 -21
- package/dist/commands/text-index-utils/adapter-utils.js +0 -63
- package/dist/commands/text-index-utils/aggregate.js +0 -87
- package/dist/commands/text-index-utils/config-utils.js +0 -59
- package/dist/commands/text-index-utils/index.js +0 -9
- package/dist/commands/text-index-utils/per-track.js +0 -65
- /package/dist/commands/{make-pif-utils → make-pif}/cigar-utils.js +0 -0
- /package/dist/commands/{make-pif-utils → make-pif}/file-utils.js +0 -0
- /package/dist/commands/{text-index-utils → text-index}/validators.js +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateFileArgument = validateFileArgument;
|
|
4
|
+
exports.validateRequiredCommands = validateRequiredCommands;
|
|
5
|
+
const command_exists_1 = require("command-exists");
|
|
6
|
+
function validateFileArgument(file, commandName, fileType) {
|
|
7
|
+
if (!file && process.stdin.isTTY) {
|
|
8
|
+
throw new Error(`Missing required argument: file\n` +
|
|
9
|
+
`Usage: jbrowse ${commandName} <file>\n` +
|
|
10
|
+
` OR pipe data via stdin: cat file.${fileType} | jbrowse ${commandName}`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function validateRequiredCommands(requiredCommands) {
|
|
14
|
+
const missingCommands = requiredCommands.filter(cmd => !(0, command_exists_1.sync)(cmd));
|
|
15
|
+
if (missingCommands.length > 0) {
|
|
16
|
+
throw new Error(`Unable to run command, requires unix type environment with: ${requiredCommands.join(', ')}`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.run = run;
|
|
4
4
|
const util_1 = require("util");
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const validators_1 = require("./sort-bed-utils/validators");
|
|
5
|
+
const utils_ts_1 = require("../utils.js");
|
|
6
|
+
const process_utils_ts_1 = require("./process-utils.js");
|
|
7
|
+
const sort_utils_ts_1 = require("./shared/sort-utils.js");
|
|
8
|
+
const validators_ts_1 = require("./shared/validators.js");
|
|
10
9
|
async function run(args) {
|
|
11
10
|
const options = {
|
|
12
11
|
help: {
|
|
@@ -19,31 +18,21 @@ async function run(args) {
|
|
|
19
18
|
options,
|
|
20
19
|
allowPositionals: true,
|
|
21
20
|
});
|
|
22
|
-
const description = constants_1.SORT_BED_DESCRIPTION;
|
|
23
|
-
const examples = constants_1.SORT_BED_EXAMPLES;
|
|
24
21
|
if (flags.help) {
|
|
25
|
-
(0,
|
|
26
|
-
description,
|
|
27
|
-
examples,
|
|
22
|
+
(0, utils_ts_1.printHelp)({
|
|
23
|
+
description: sort_utils_ts_1.BED_CONFIG.description,
|
|
24
|
+
examples: sort_utils_ts_1.BED_CONFIG.examples,
|
|
28
25
|
usage: 'jbrowse sort-bed [file] [options]',
|
|
29
26
|
options,
|
|
30
27
|
});
|
|
31
28
|
return;
|
|
32
29
|
}
|
|
33
30
|
const file = positionals[0];
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
(0,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const exitCode = await (0, process_utils_1.waitForProcessClose)(child);
|
|
41
|
-
if (exitCode !== 0) {
|
|
42
|
-
console.error(`Sort process exited with code ${exitCode}`);
|
|
43
|
-
process.exit(exitCode || 1);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
catch (error) {
|
|
47
|
-
(0, process_utils_1.handleProcessError)(error);
|
|
31
|
+
(0, validators_ts_1.validateFileArgument)(file, 'sort-bed', 'bed');
|
|
32
|
+
(0, validators_ts_1.validateRequiredCommands)(['sh', 'sort', 'grep']);
|
|
33
|
+
const child = (0, sort_utils_ts_1.spawnSortProcess)(file, sort_utils_ts_1.BED_CONFIG.sortColumn);
|
|
34
|
+
const exitCode = await (0, process_utils_ts_1.waitForProcessClose)(child);
|
|
35
|
+
if (exitCode !== 0) {
|
|
36
|
+
throw new Error(`Sort process exited with code ${exitCode}`);
|
|
48
37
|
}
|
|
49
38
|
}
|
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.run = run;
|
|
4
4
|
const util_1 = require("util");
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const validators_1 = require("./sort-gff-utils/validators");
|
|
5
|
+
const utils_ts_1 = require("../utils.js");
|
|
6
|
+
const process_utils_ts_1 = require("./process-utils.js");
|
|
7
|
+
const sort_utils_ts_1 = require("./shared/sort-utils.js");
|
|
8
|
+
const validators_ts_1 = require("./shared/validators.js");
|
|
10
9
|
async function run(args) {
|
|
11
10
|
const options = {
|
|
12
11
|
help: {
|
|
@@ -19,31 +18,21 @@ async function run(args) {
|
|
|
19
18
|
options,
|
|
20
19
|
allowPositionals: true,
|
|
21
20
|
});
|
|
22
|
-
const description = constants_1.SORT_GFF_DESCRIPTION;
|
|
23
|
-
const examples = constants_1.SORT_GFF_EXAMPLES;
|
|
24
21
|
if (flags.help) {
|
|
25
|
-
(0,
|
|
26
|
-
description,
|
|
27
|
-
examples,
|
|
22
|
+
(0, utils_ts_1.printHelp)({
|
|
23
|
+
description: sort_utils_ts_1.GFF_CONFIG.description,
|
|
24
|
+
examples: sort_utils_ts_1.GFF_CONFIG.examples,
|
|
28
25
|
usage: 'jbrowse sort-gff [file] [options]',
|
|
29
26
|
options,
|
|
30
27
|
});
|
|
31
28
|
return;
|
|
32
29
|
}
|
|
33
30
|
const file = positionals[0];
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
(0,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const exitCode = await (0, process_utils_1.waitForProcessClose)(child);
|
|
41
|
-
if (exitCode !== 0) {
|
|
42
|
-
console.error(`Sort process exited with code ${exitCode}`);
|
|
43
|
-
process.exit(exitCode || 1);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
catch (error) {
|
|
47
|
-
(0, process_utils_1.handleProcessError)(error);
|
|
31
|
+
(0, validators_ts_1.validateFileArgument)(file, 'sort-gff', 'gff');
|
|
32
|
+
(0, validators_ts_1.validateRequiredCommands)(['sh', 'sort', 'grep']);
|
|
33
|
+
const child = (0, sort_utils_ts_1.spawnSortProcess)(file, sort_utils_ts_1.GFF_CONFIG.sortColumn);
|
|
34
|
+
const exitCode = await (0, process_utils_ts_1.waitForProcessClose)(child);
|
|
35
|
+
if (exitCode !== 0) {
|
|
36
|
+
throw new Error(`Sort process exited with code ${exitCode}`);
|
|
48
37
|
}
|
|
49
38
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getLoc = getLoc;
|
|
4
|
+
exports.createTrixAdapter = createTrixAdapter;
|
|
5
|
+
exports.getAdapterLocation = getAdapterLocation;
|
|
6
|
+
const config_utils_ts_1 = require("./config-utils.js");
|
|
7
|
+
function getLoc(elt) {
|
|
8
|
+
return elt.locationType === 'LocalPathLocation' ? elt.localPath : elt.uri;
|
|
9
|
+
}
|
|
10
|
+
function createTrixAdapter(name, assemblyNames, idSuffix = 'index') {
|
|
11
|
+
const safeName = (0, config_utils_ts_1.sanitizeNameForPath)(name);
|
|
12
|
+
return {
|
|
13
|
+
type: 'TrixTextSearchAdapter',
|
|
14
|
+
textSearchAdapterId: `${safeName}-${idSuffix}`,
|
|
15
|
+
ixFilePath: {
|
|
16
|
+
uri: `trix/${safeName}.ix`,
|
|
17
|
+
locationType: 'UriLocation',
|
|
18
|
+
},
|
|
19
|
+
ixxFilePath: {
|
|
20
|
+
uri: `trix/${safeName}.ixx`,
|
|
21
|
+
locationType: 'UriLocation',
|
|
22
|
+
},
|
|
23
|
+
metaFilePath: {
|
|
24
|
+
uri: `trix/${safeName}_meta.json`,
|
|
25
|
+
locationType: 'UriLocation',
|
|
26
|
+
},
|
|
27
|
+
assemblyNames,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const ADAPTER_LOCATION_KEYS = {
|
|
31
|
+
Gff3TabixAdapter: 'gffGzLocation',
|
|
32
|
+
Gff3Adapter: 'gffLocation',
|
|
33
|
+
VcfAdapter: 'vcfLocation',
|
|
34
|
+
VcfTabixAdapter: 'vcfGzLocation',
|
|
35
|
+
};
|
|
36
|
+
function getAdapterLocation(adapter) {
|
|
37
|
+
const key = ADAPTER_LOCATION_KEYS[adapter?.type ?? ''];
|
|
38
|
+
return key
|
|
39
|
+
? // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
40
|
+
(adapter?.[key] ??
|
|
41
|
+
adapter)
|
|
42
|
+
: undefined;
|
|
43
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.aggregateIndex = aggregateIndex;
|
|
4
|
+
const adapter_utils_ts_1 = require("./adapter-utils.js");
|
|
5
|
+
const config_utils_ts_1 = require("./config-utils.js");
|
|
6
|
+
const indexing_utils_ts_1 = require("./indexing-utils.js");
|
|
7
|
+
const utils_ts_1 = require("../../utils.js");
|
|
8
|
+
async function aggregateIndex(flags) {
|
|
9
|
+
const { out, target, tracks, excludeTracks, assemblies, attributes, quiet, force, exclude, dryrun, prefixSize, } = flags;
|
|
10
|
+
const { config, configPath, outLocation } = await (0, config_utils_ts_1.loadConfigForIndexing)(target, out, utils_ts_1.resolveConfigPath);
|
|
11
|
+
const aggregateTextSearchAdapters = config.aggregateTextSearchAdapters || [];
|
|
12
|
+
const asms = (0, config_utils_ts_1.getAssemblyNames)(config, assemblies);
|
|
13
|
+
for (const asm of asms) {
|
|
14
|
+
const trackConfigs = (0, config_utils_ts_1.getTrackConfigs)(config, (0, config_utils_ts_1.parseCommaSeparatedString)(tracks), asm, (0, config_utils_ts_1.parseCommaSeparatedString)(excludeTracks));
|
|
15
|
+
if (!trackConfigs.length) {
|
|
16
|
+
console.log(`Indexing assembly ${asm}...(no tracks found)...`);
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
console.log(`Indexing assembly ${asm}...`);
|
|
20
|
+
if (dryrun) {
|
|
21
|
+
console.log(trackConfigs.map(e => `${e.trackId} ${e.adapter?.type}`).join('\n'));
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
const id = `${asm}-index`;
|
|
25
|
+
const idx = aggregateTextSearchAdapters.findIndex(x => x.textSearchAdapterId === id);
|
|
26
|
+
if (idx !== -1 && !force) {
|
|
27
|
+
console.log(`Note: ${asm} has already been indexed with this configuration, use --force to overwrite this assembly. Skipping for now`);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
await (0, indexing_utils_ts_1.indexDriver)({
|
|
31
|
+
trackConfigs,
|
|
32
|
+
outLocation,
|
|
33
|
+
name: asm,
|
|
34
|
+
assemblyNames: [asm],
|
|
35
|
+
...(0, config_utils_ts_1.prepareIndexDriverFlags)({ attributes, exclude, quiet, prefixSize }),
|
|
36
|
+
});
|
|
37
|
+
const trixConf = (0, adapter_utils_ts_1.createTrixAdapter)(asm, [asm]);
|
|
38
|
+
if (idx === -1) {
|
|
39
|
+
aggregateTextSearchAdapters.push(trixConf);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
aggregateTextSearchAdapters[idx] = trixConf;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (!dryrun) {
|
|
47
|
+
(0, config_utils_ts_1.writeConf)({
|
|
48
|
+
...config,
|
|
49
|
+
aggregateTextSearchAdapters,
|
|
50
|
+
}, configPath);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.run = run;
|
|
4
4
|
const util_1 = require("util");
|
|
5
|
-
const
|
|
6
|
-
const
|
|
5
|
+
const index_ts_1 = require("./index.js");
|
|
6
|
+
const utils_ts_1 = require("../../utils.js");
|
|
7
7
|
async function run(args) {
|
|
8
8
|
const options = {
|
|
9
9
|
help: {
|
|
@@ -15,6 +15,10 @@ async function run(args) {
|
|
|
15
15
|
type: 'string',
|
|
16
16
|
description: 'Specific tracks to index, formatted as comma separated trackIds. If unspecified, indexes all available tracks',
|
|
17
17
|
},
|
|
18
|
+
excludeTracks: {
|
|
19
|
+
type: 'string',
|
|
20
|
+
description: 'Specific tracks to exclude from indexing, formatted as comma separated trackIds',
|
|
21
|
+
},
|
|
18
22
|
target: {
|
|
19
23
|
type: 'string',
|
|
20
24
|
description: 'Path to config file in JB2 installation directory to read from.',
|
|
@@ -82,6 +86,9 @@ async function run(args) {
|
|
|
82
86
|
"# indexes specific trackIds that it can find in the current directory's config.json",
|
|
83
87
|
'$ jbrowse text-index --tracks=track1,track2,track3',
|
|
84
88
|
'',
|
|
89
|
+
'# indexes all tracks except specific trackIds',
|
|
90
|
+
'$ jbrowse text-index --exclude-tracks=track1,track2,track3',
|
|
91
|
+
'',
|
|
85
92
|
"# indexes all tracks in a directory's config.json or in a specific config file",
|
|
86
93
|
'$ jbrowse text-index --out /path/to/jb2/',
|
|
87
94
|
'',
|
|
@@ -92,7 +99,7 @@ async function run(args) {
|
|
|
92
99
|
'$ jbrowse text-index --file myfile.gff3.gz --file myfile.vcfgz --out indexes',
|
|
93
100
|
];
|
|
94
101
|
if (flags.help) {
|
|
95
|
-
(0,
|
|
102
|
+
(0, utils_ts_1.printHelp)({
|
|
96
103
|
description,
|
|
97
104
|
examples,
|
|
98
105
|
usage: 'jbrowse text-index [options]',
|
|
@@ -102,12 +109,12 @@ async function run(args) {
|
|
|
102
109
|
}
|
|
103
110
|
const { perTrack, file } = flags;
|
|
104
111
|
if (file) {
|
|
105
|
-
await (0,
|
|
112
|
+
await (0, index_ts_1.indexFileList)(flags);
|
|
106
113
|
}
|
|
107
114
|
else if (perTrack) {
|
|
108
|
-
await (0,
|
|
115
|
+
await (0, index_ts_1.perTrackIndex)(flags);
|
|
109
116
|
}
|
|
110
117
|
else {
|
|
111
|
-
await (0,
|
|
118
|
+
await (0, index_ts_1.aggregateIndex)(flags);
|
|
112
119
|
}
|
|
113
120
|
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseCommaSeparatedString = parseCommaSeparatedString;
|
|
7
|
+
exports.sanitizeNameForPath = sanitizeNameForPath;
|
|
8
|
+
exports.validatePrefixSize = validatePrefixSize;
|
|
9
|
+
exports.prepareIndexDriverFlags = prepareIndexDriverFlags;
|
|
10
|
+
exports.readConf = readConf;
|
|
11
|
+
exports.writeConf = writeConf;
|
|
12
|
+
exports.loadConfigForIndexing = loadConfigForIndexing;
|
|
13
|
+
exports.ensureTrixDir = ensureTrixDir;
|
|
14
|
+
exports.getAssemblyNames = getAssemblyNames;
|
|
15
|
+
exports.getTrackConfigs = getTrackConfigs;
|
|
16
|
+
const fs_1 = __importDefault(require("fs"));
|
|
17
|
+
const path_1 = __importDefault(require("path"));
|
|
18
|
+
const common_ts_1 = require("../../types/common.js");
|
|
19
|
+
/**
|
|
20
|
+
* Parses a comma-separated string into an array of trimmed, non-empty strings
|
|
21
|
+
*/
|
|
22
|
+
function parseCommaSeparatedString(value) {
|
|
23
|
+
return (value
|
|
24
|
+
?.split(',')
|
|
25
|
+
.map(s => s.trim())
|
|
26
|
+
.filter(Boolean) ?? []);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Sanitizes a name for use in file paths by replacing invalid characters
|
|
30
|
+
* Replaces characters that are problematic in file paths: / \ : * ? " < > |
|
|
31
|
+
*/
|
|
32
|
+
function sanitizeNameForPath(name) {
|
|
33
|
+
return name.replace(/[/\\:*?"<>|]/g, '_');
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Validates and parses a prefix size value
|
|
37
|
+
*/
|
|
38
|
+
function validatePrefixSize(value) {
|
|
39
|
+
if (!value) {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
const parsed = typeof value === 'number' ? value : parseInt(value, 10);
|
|
43
|
+
if (isNaN(parsed) || parsed < 0) {
|
|
44
|
+
throw new Error(`Invalid prefixSize: "${value}". Must be a positive number.`);
|
|
45
|
+
}
|
|
46
|
+
return parsed;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Prepares common indexDriver parameters from raw flag values
|
|
50
|
+
*/
|
|
51
|
+
function prepareIndexDriverFlags(flags) {
|
|
52
|
+
return {
|
|
53
|
+
attributes: parseCommaSeparatedString(flags.attributes),
|
|
54
|
+
typesToExclude: parseCommaSeparatedString(flags.exclude),
|
|
55
|
+
quiet: flags.quiet ?? false,
|
|
56
|
+
prefixSize: validatePrefixSize(flags.prefixSize),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function readConf(configPath) {
|
|
60
|
+
return JSON.parse(fs_1.default.readFileSync(configPath, 'utf8'));
|
|
61
|
+
}
|
|
62
|
+
function writeConf(obj, configPath) {
|
|
63
|
+
fs_1.default.writeFileSync(configPath, JSON.stringify(obj, null, 2));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Loads config and prepares output location for indexing
|
|
67
|
+
*/
|
|
68
|
+
async function loadConfigForIndexing(target, out, resolveConfigPath) {
|
|
69
|
+
const configPath = await resolveConfigPath(target, out);
|
|
70
|
+
const outLocation = path_1.default.dirname(configPath);
|
|
71
|
+
const config = readConf(configPath);
|
|
72
|
+
ensureTrixDir(outLocation);
|
|
73
|
+
return { config, configPath, outLocation };
|
|
74
|
+
}
|
|
75
|
+
function ensureTrixDir(outLocation) {
|
|
76
|
+
const trixDir = path_1.default.join(outLocation, 'trix');
|
|
77
|
+
if (!fs_1.default.existsSync(trixDir)) {
|
|
78
|
+
fs_1.default.mkdirSync(trixDir);
|
|
79
|
+
}
|
|
80
|
+
return trixDir;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Extracts all assembly names from a config object
|
|
84
|
+
* Handles both single assembly (config.assembly) and multiple assemblies (config.assemblies)
|
|
85
|
+
*/
|
|
86
|
+
function extractAssemblyNamesFromConfig(config) {
|
|
87
|
+
if (config.assemblies) {
|
|
88
|
+
return config.assemblies.map(a => a.name);
|
|
89
|
+
}
|
|
90
|
+
if (config.assembly) {
|
|
91
|
+
return [config.assembly.name];
|
|
92
|
+
}
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
function getAssemblyNames(config, assemblies) {
|
|
96
|
+
const asms = assemblies
|
|
97
|
+
? parseCommaSeparatedString(assemblies)
|
|
98
|
+
: extractAssemblyNamesFromConfig(config);
|
|
99
|
+
if (!asms.length) {
|
|
100
|
+
throw new Error('No assemblies found');
|
|
101
|
+
}
|
|
102
|
+
return asms;
|
|
103
|
+
}
|
|
104
|
+
function getTrackConfigs(config, trackIds, assemblyName, excludeTrackIds) {
|
|
105
|
+
const { tracks } = config;
|
|
106
|
+
if (!tracks) {
|
|
107
|
+
return [];
|
|
108
|
+
}
|
|
109
|
+
const trackIdsToIndex = trackIds || tracks.map(track => track.trackId);
|
|
110
|
+
const excludeSet = new Set(excludeTrackIds || []);
|
|
111
|
+
return trackIdsToIndex
|
|
112
|
+
.map(trackId => {
|
|
113
|
+
const currentTrack = tracks.find(t => trackId === t.trackId);
|
|
114
|
+
if (!currentTrack) {
|
|
115
|
+
throw new Error(`Track not found in config.json for trackId ${trackId}, please add track configuration before indexing.`);
|
|
116
|
+
}
|
|
117
|
+
return currentTrack;
|
|
118
|
+
})
|
|
119
|
+
.filter(track => {
|
|
120
|
+
if (excludeSet.has(track.trackId)) {
|
|
121
|
+
console.log(`Skipping ${track.trackId}: excluded via --exclude-tracks`);
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
if (!(0, common_ts_1.supported)(track.adapter?.type)) {
|
|
125
|
+
console.log(`Skipping ${track.trackId}: unsupported adapter type '${track.adapter?.type}'`);
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
if (assemblyName && !track.assemblyNames.includes(assemblyName)) {
|
|
129
|
+
console.log(`Skipping ${track.trackId}: not in assembly '${assemblyName}'`);
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
return true;
|
|
133
|
+
});
|
|
134
|
+
}
|
|
@@ -4,28 +4,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.indexFileList = indexFileList;
|
|
7
|
-
const fs_1 = __importDefault(require("fs"));
|
|
8
7
|
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const
|
|
10
|
-
const
|
|
8
|
+
const config_utils_ts_1 = require("./config-utils.js");
|
|
9
|
+
const indexing_utils_ts_1 = require("./indexing-utils.js");
|
|
10
|
+
const validators_ts_1 = require("./validators.js");
|
|
11
11
|
async function indexFileList(flags) {
|
|
12
12
|
const { out, target, fileId, file, attributes, quiet, exclude, prefixSize } = flags;
|
|
13
|
-
(0,
|
|
13
|
+
(0, validators_ts_1.validateFileInput)(file);
|
|
14
14
|
const outFlag = target || out || '.';
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
await (0,
|
|
15
|
+
(0, config_utils_ts_1.ensureTrixDir)(outFlag);
|
|
16
|
+
const trackConfigs = (0, indexing_utils_ts_1.prepareFileTrackConfigs)(file, fileId);
|
|
17
|
+
const name = trackConfigs.length > 1
|
|
18
|
+
? 'aggregate'
|
|
19
|
+
: (0, config_utils_ts_1.sanitizeNameForPath)(path_1.default.basename(file[0]));
|
|
20
|
+
await (0, indexing_utils_ts_1.indexDriver)({
|
|
21
21
|
trackConfigs,
|
|
22
22
|
outLocation: outFlag,
|
|
23
|
-
name
|
|
24
|
-
quiet,
|
|
25
|
-
attributes: attributes.split(','),
|
|
26
|
-
typesToExclude: exclude.split(','),
|
|
23
|
+
name,
|
|
27
24
|
assemblyNames: [],
|
|
28
|
-
prefixSize,
|
|
25
|
+
...(0, config_utils_ts_1.prepareIndexDriverFlags)({ attributes, exclude, quiet, prefixSize }),
|
|
29
26
|
});
|
|
30
27
|
console.log('Successfully created index for these files. See https://jbrowse.org/storybook/lgv/main/?path=/story/text-searching--page for info about usage');
|
|
31
28
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.run = exports.indexFileList = exports.perTrackIndex = exports.aggregateIndex = void 0;
|
|
4
|
+
var aggregate_ts_1 = require("./aggregate.js");
|
|
5
|
+
Object.defineProperty(exports, "aggregateIndex", { enumerable: true, get: function () { return aggregate_ts_1.aggregateIndex; } });
|
|
6
|
+
var per_track_ts_1 = require("./per-track.js");
|
|
7
|
+
Object.defineProperty(exports, "perTrackIndex", { enumerable: true, get: function () { return per_track_ts_1.perTrackIndex; } });
|
|
8
|
+
var file_list_ts_1 = require("./file-list.js");
|
|
9
|
+
Object.defineProperty(exports, "indexFileList", { enumerable: true, get: function () { return file_list_ts_1.indexFileList; } });
|
|
10
|
+
var command_ts_1 = require("./command.js");
|
|
11
|
+
Object.defineProperty(exports, "run", { enumerable: true, get: function () { return command_ts_1.run; } });
|
|
@@ -9,38 +9,47 @@ exports.indexDriver = indexDriver;
|
|
|
9
9
|
exports.prepareFileTrackConfigs = prepareFileTrackConfigs;
|
|
10
10
|
const path_1 = __importDefault(require("path"));
|
|
11
11
|
const stream_1 = require("stream");
|
|
12
|
+
const cli_progress_1 = require("cli-progress");
|
|
12
13
|
const ixixx_1 = require("ixixx");
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
async function runIxIxx({ readStream, outLocation, name, prefixSize, }) {
|
|
14
|
+
const adapter_utils_ts_1 = require("./adapter-utils.js");
|
|
15
|
+
const common_ts_1 = require("../../types/common.js");
|
|
16
|
+
const gff3Adapter_ts_1 = require("../../types/gff3Adapter.js");
|
|
17
|
+
const vcfAdapter_ts_1 = require("../../types/vcfAdapter.js");
|
|
18
|
+
async function runIxIxx({ readStream, outLocation, name, prefixSize, quiet, }) {
|
|
19
|
+
const progressBar = new cli_progress_1.SingleBar({ format: '{bar} Sorting and writing index...', etaBuffer: 2000 }, cli_progress_1.Presets.shades_classic);
|
|
20
|
+
if (!quiet) {
|
|
21
|
+
progressBar.start(1, 0);
|
|
22
|
+
}
|
|
18
23
|
await (0, ixixx_1.ixIxxStream)(readStream, path_1.default.join(outLocation, 'trix', `${name}.ix`), path_1.default.join(outLocation, 'trix', `${name}.ixx`), prefixSize);
|
|
24
|
+
if (!quiet) {
|
|
25
|
+
progressBar.update(1);
|
|
26
|
+
progressBar.stop();
|
|
27
|
+
}
|
|
19
28
|
}
|
|
20
29
|
async function* indexFiles({ trackConfigs, attributes, outLocation, quiet, typesToExclude, }) {
|
|
21
30
|
for (const config of trackConfigs) {
|
|
22
31
|
const { adapter, textSearching } = config;
|
|
23
32
|
const { type } = adapter || {};
|
|
24
33
|
const { indexingFeatureTypesToExclude = typesToExclude, indexingAttributes = attributes, } = textSearching || {};
|
|
25
|
-
const loc = (0,
|
|
34
|
+
const loc = (0, adapter_utils_ts_1.getAdapterLocation)(adapter);
|
|
26
35
|
if (!loc) {
|
|
27
36
|
continue;
|
|
28
37
|
}
|
|
29
38
|
if (type === 'Gff3TabixAdapter' || type === 'Gff3Adapter') {
|
|
30
|
-
yield* (0,
|
|
39
|
+
yield* (0, gff3Adapter_ts_1.indexGff3)({
|
|
31
40
|
config,
|
|
32
41
|
attributesToIndex: indexingAttributes,
|
|
33
|
-
inLocation: (0,
|
|
42
|
+
inLocation: (0, adapter_utils_ts_1.getLoc)(loc),
|
|
34
43
|
outLocation,
|
|
35
44
|
typesToExclude: indexingFeatureTypesToExclude,
|
|
36
45
|
quiet,
|
|
37
46
|
});
|
|
38
47
|
}
|
|
39
48
|
else if (type === 'VcfTabixAdapter' || type === 'VcfAdapter') {
|
|
40
|
-
yield* (0,
|
|
49
|
+
yield* (0, vcfAdapter_ts_1.indexVcf)({
|
|
41
50
|
config,
|
|
42
51
|
attributesToIndex: indexingAttributes,
|
|
43
|
-
inLocation: (0,
|
|
52
|
+
inLocation: (0, adapter_utils_ts_1.getLoc)(loc),
|
|
44
53
|
outLocation,
|
|
45
54
|
typesToExclude: indexingFeatureTypesToExclude,
|
|
46
55
|
quiet,
|
|
@@ -60,9 +69,10 @@ async function indexDriver({ trackConfigs, attributes, outLocation, name, quiet,
|
|
|
60
69
|
readStream,
|
|
61
70
|
outLocation,
|
|
62
71
|
name,
|
|
63
|
-
prefixSize
|
|
72
|
+
prefixSize,
|
|
73
|
+
quiet,
|
|
64
74
|
});
|
|
65
|
-
await (0,
|
|
75
|
+
await (0, common_ts_1.generateMeta)({
|
|
66
76
|
trackConfigs,
|
|
67
77
|
attributes,
|
|
68
78
|
outLocation,
|
|
@@ -72,13 +82,13 @@ async function indexDriver({ trackConfigs, attributes, outLocation, name, quiet,
|
|
|
72
82
|
});
|
|
73
83
|
}
|
|
74
84
|
function prepareFileTrackConfigs(files, fileIds) {
|
|
75
|
-
|
|
76
|
-
.map(file =>
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
trackConfigs[i].trackId = element;
|
|
85
|
+
return files
|
|
86
|
+
.map((file, i) => {
|
|
87
|
+
const config = (0, common_ts_1.guessAdapterFromFileName)(file);
|
|
88
|
+
if (fileIds?.[i]) {
|
|
89
|
+
config.trackId = fileIds[i];
|
|
81
90
|
}
|
|
82
|
-
|
|
83
|
-
|
|
91
|
+
return config;
|
|
92
|
+
})
|
|
93
|
+
.filter(fileConfig => (0, common_ts_1.supported)(fileConfig.adapter?.type));
|
|
84
94
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.perTrackIndex = perTrackIndex;
|
|
4
|
+
const adapter_utils_ts_1 = require("./adapter-utils.js");
|
|
5
|
+
const config_utils_ts_1 = require("./config-utils.js");
|
|
6
|
+
const indexing_utils_ts_1 = require("./indexing-utils.js");
|
|
7
|
+
const validators_ts_1 = require("./validators.js");
|
|
8
|
+
const utils_ts_1 = require("../../utils.js");
|
|
9
|
+
async function perTrackIndex(flags) {
|
|
10
|
+
const { out, target, tracks, excludeTracks, assemblies, attributes, quiet, force, exclude, prefixSize, } = flags;
|
|
11
|
+
const { config, configPath, outLocation } = await (0, config_utils_ts_1.loadConfigForIndexing)(target, out, utils_ts_1.resolveConfigPath);
|
|
12
|
+
const configTracks = config.tracks || [];
|
|
13
|
+
(0, validators_ts_1.validateAssembliesForPerTrack)(assemblies);
|
|
14
|
+
const confs = (0, config_utils_ts_1.getTrackConfigs)(config, (0, config_utils_ts_1.parseCommaSeparatedString)(tracks), undefined, (0, config_utils_ts_1.parseCommaSeparatedString)(excludeTracks));
|
|
15
|
+
if (!confs.length) {
|
|
16
|
+
throw new Error('Tracks not found in config.json, please add track configurations before indexing.');
|
|
17
|
+
}
|
|
18
|
+
let hasChanges = false;
|
|
19
|
+
for (const trackConfig of confs) {
|
|
20
|
+
const { textSearching, trackId, assemblyNames } = trackConfig;
|
|
21
|
+
if (textSearching?.textSearchAdapter && !force) {
|
|
22
|
+
console.log(`Note: ${trackId} has already been indexed with this configuration, use --force to overwrite this track. Skipping for now`);
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
console.log(`Indexing track ${trackId}...`);
|
|
26
|
+
await (0, indexing_utils_ts_1.indexDriver)({
|
|
27
|
+
trackConfigs: [trackConfig],
|
|
28
|
+
outLocation,
|
|
29
|
+
name: trackId,
|
|
30
|
+
assemblyNames,
|
|
31
|
+
...(0, config_utils_ts_1.prepareIndexDriverFlags)({ attributes, exclude, quiet, prefixSize }),
|
|
32
|
+
});
|
|
33
|
+
if (!textSearching?.textSearchAdapter) {
|
|
34
|
+
// modifies track with new text search adapter
|
|
35
|
+
const index = configTracks.findIndex(track => trackId === track.trackId);
|
|
36
|
+
if (index !== -1) {
|
|
37
|
+
configTracks[index] = {
|
|
38
|
+
...trackConfig,
|
|
39
|
+
textSearching: {
|
|
40
|
+
...textSearching,
|
|
41
|
+
textSearchAdapter: (0, adapter_utils_ts_1.createTrixAdapter)(trackId, assemblyNames),
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
hasChanges = true;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
console.warn(`Warning: can't find trackId ${trackId}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (hasChanges) {
|
|
52
|
+
(0, config_utils_ts_1.writeConf)({ ...config, tracks: configTracks }, configPath);
|
|
53
|
+
}
|
|
54
|
+
}
|