@jbrowse/cli 3.5.1 → 3.6.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 +291 -607
- package/bin/run +1 -6
- package/bundle/index.js +4459 -0
- package/package.json +12 -37
- package/bin/dev +0 -17
- package/bin/dev.cmd +0 -3
- package/bin/run.cmd +0 -3
- package/lib/base.js +0 -157
- package/lib/commands/add-assembly.js +0 -491
- package/lib/commands/add-connection.js +0 -170
- package/lib/commands/add-track-json.js +0 -67
- package/lib/commands/add-track.js +0 -564
- package/lib/commands/admin-server.js +0 -153
- package/lib/commands/create.js +0 -111
- package/lib/commands/make-pif.js +0 -116
- package/lib/commands/remove-track.js +0 -37
- package/lib/commands/set-default-session.js +0 -98
- package/lib/commands/sort-bed.js +0 -45
- package/lib/commands/sort-gff.js +0 -45
- package/lib/commands/text-index.js +0 -380
- package/lib/commands/upgrade.js +0 -109
- package/lib/fetchWithProxy.js +0 -12
- package/lib/index.js +0 -6
- package/lib/types/common.js +0 -128
- package/lib/types/gff3Adapter.js +0 -73
- package/lib/types/vcfAdapter.js +0 -76
- package/lib/util.js +0 -35
- package/oclif.manifest.json +0 -1169
|
@@ -1,67 +0,0 @@
|
|
|
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
|
-
const fs_1 = require("fs");
|
|
7
|
-
const core_1 = require("@oclif/core");
|
|
8
|
-
const base_1 = __importDefault(require("../base"));
|
|
9
|
-
class AddTrackJson extends base_1.default {
|
|
10
|
-
async run() {
|
|
11
|
-
const { args, flags: runFlags } = await this.parse(AddTrackJson);
|
|
12
|
-
const output = runFlags.target || runFlags.out || '.';
|
|
13
|
-
const isDir = (await fs_1.promises.lstat(output)).isDirectory();
|
|
14
|
-
this.target = isDir ? `${output}/config.json` : output;
|
|
15
|
-
const { track: inputtedTrack } = args;
|
|
16
|
-
this.debug(`Sequence location is: ${inputtedTrack}`);
|
|
17
|
-
const { update } = runFlags;
|
|
18
|
-
const config = await this.readJsonFile(this.target);
|
|
19
|
-
this.debug(`Found existing config file ${this.target}`);
|
|
20
|
-
const track = await this.readInlineOrFileJson(inputtedTrack);
|
|
21
|
-
if (!config.tracks) {
|
|
22
|
-
config.tracks = [];
|
|
23
|
-
}
|
|
24
|
-
const idx = config.tracks.findIndex(({ trackId }) => trackId === track.trackId);
|
|
25
|
-
if (idx !== -1) {
|
|
26
|
-
const existing = config.tracks[idx]?.name;
|
|
27
|
-
this.debug(`Found existing track ${existing} in configuration`);
|
|
28
|
-
if (update) {
|
|
29
|
-
this.debug(`Overwriting track ${existing} in configuration`);
|
|
30
|
-
config.tracks[idx] = track;
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
this.error(`Cannot add track ${track.name}, a track with that trackId already exists: ${existing}`, { exit: 160 });
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
config.tracks.push(track);
|
|
38
|
-
}
|
|
39
|
-
this.debug(`Writing configuration to file ${this.target}`);
|
|
40
|
-
await this.writeJsonFile(this.target, config);
|
|
41
|
-
this.log(`${idx !== -1 ? 'Overwrote' : 'Added'} assembly "${track.name}" ${idx !== -1 ? 'in' : 'to'} ${this.target}`);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
AddTrackJson.description = 'Add a track configuration directly from a JSON hunk to the JBrowse 2 configuration';
|
|
45
|
-
AddTrackJson.examples = [
|
|
46
|
-
'$ jbrowse add-track-json track.json',
|
|
47
|
-
'$ jbrowse add-track-json track.json --update',
|
|
48
|
-
];
|
|
49
|
-
AddTrackJson.args = {
|
|
50
|
-
track: core_1.Args.string({
|
|
51
|
-
required: true,
|
|
52
|
-
description: 'track JSON file or command line arg blob',
|
|
53
|
-
}),
|
|
54
|
-
};
|
|
55
|
-
AddTrackJson.flags = {
|
|
56
|
-
update: core_1.Flags.boolean({
|
|
57
|
-
char: 'u',
|
|
58
|
-
description: 'update the contents of an existing track, matched based on trackId',
|
|
59
|
-
}),
|
|
60
|
-
target: core_1.Flags.string({
|
|
61
|
-
description: 'path to config file in JB2 installation directory to write out to.\nCreates ./config.json if nonexistent',
|
|
62
|
-
}),
|
|
63
|
-
out: core_1.Flags.string({
|
|
64
|
-
description: 'synonym for target',
|
|
65
|
-
}),
|
|
66
|
-
};
|
|
67
|
-
exports.default = AddTrackJson;
|
|
@@ -1,564 +0,0 @@
|
|
|
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
|
-
const fs_1 = __importDefault(require("fs"));
|
|
7
|
-
const path_1 = __importDefault(require("path"));
|
|
8
|
-
const core_1 = require("@oclif/core");
|
|
9
|
-
const json_parse_better_errors_1 = __importDefault(require("json-parse-better-errors"));
|
|
10
|
-
const base_1 = __importDefault(require("../base"));
|
|
11
|
-
const { copyFile, rename, symlink } = fs_1.default.promises;
|
|
12
|
-
const { COPYFILE_EXCL } = fs_1.default.constants;
|
|
13
|
-
function makeLocationProtocol(protocol) {
|
|
14
|
-
return (location) => {
|
|
15
|
-
if (protocol === 'uri') {
|
|
16
|
-
return {
|
|
17
|
-
uri: location,
|
|
18
|
-
locationType: 'UriLocation',
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
if (protocol === 'localPath') {
|
|
22
|
-
return {
|
|
23
|
-
localPath: location,
|
|
24
|
-
locationType: 'LocalPathLocation',
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
throw new Error(`invalid protocol ${protocol}`);
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
function fileOperation({ srcFilename, destFilename, mode, }) {
|
|
31
|
-
if (mode === 'copy') {
|
|
32
|
-
return copyFile(srcFilename, destFilename, COPYFILE_EXCL);
|
|
33
|
-
}
|
|
34
|
-
else if (mode === 'move') {
|
|
35
|
-
return rename(srcFilename, destFilename);
|
|
36
|
-
}
|
|
37
|
-
else if (mode === 'symlink') {
|
|
38
|
-
return symlink(path_1.default.resolve(srcFilename), destFilename);
|
|
39
|
-
}
|
|
40
|
-
return undefined;
|
|
41
|
-
}
|
|
42
|
-
// get path of destination, and remove file at that path if it exists and force
|
|
43
|
-
// is set
|
|
44
|
-
function destinationFn({ destinationDir, srcFilename, subDir, force, }) {
|
|
45
|
-
const dest = path_1.default.resolve(path_1.default.join(destinationDir, subDir, path_1.default.basename(srcFilename)));
|
|
46
|
-
if (force) {
|
|
47
|
-
try {
|
|
48
|
-
fs_1.default.unlinkSync(dest);
|
|
49
|
-
}
|
|
50
|
-
catch (e) {
|
|
51
|
-
/* unconditionally unlinkSync, due to
|
|
52
|
-
* https://github.com/nodejs/node/issues/14025#issuecomment-754021370
|
|
53
|
-
* and https://github.com/GMOD/jbrowse-components/issues/2768 */
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return dest;
|
|
57
|
-
}
|
|
58
|
-
const isUrl = (loc) => loc?.match(/^https?:\/\//);
|
|
59
|
-
class AddTrack extends base_1.default {
|
|
60
|
-
async run() {
|
|
61
|
-
const { args: runArgs, flags: runFlags } = await this.parse(AddTrack);
|
|
62
|
-
const { track: argsTrack } = runArgs;
|
|
63
|
-
const { config, skipCheck, force, overwrite, category, description, load, subDir, target, protocol, out, indexFile: index, bed1, bed2, } = runFlags;
|
|
64
|
-
const output = target || out || '.';
|
|
65
|
-
const isDir = fs_1.default.lstatSync(output).isDirectory();
|
|
66
|
-
this.target = isDir ? `${output}/config.json` : output;
|
|
67
|
-
let { trackType, trackId, name, assemblyNames } = runFlags;
|
|
68
|
-
const configDir = path_1.default.dirname(this.target);
|
|
69
|
-
if (!argsTrack) {
|
|
70
|
-
this.error('No track provided. Example usage: jbrowse add-track yourfile.bam', { exit: 120 });
|
|
71
|
-
}
|
|
72
|
-
if (subDir) {
|
|
73
|
-
const dir = path_1.default.join(configDir, subDir);
|
|
74
|
-
if (!fs_1.default.existsSync(dir)) {
|
|
75
|
-
fs_1.default.mkdirSync(dir);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
const location = argsTrack;
|
|
79
|
-
const mapLoc = (p) => {
|
|
80
|
-
return !p || isUrl(p) || load === 'inPlace'
|
|
81
|
-
? p
|
|
82
|
-
: path_1.default.join(subDir, path_1.default.basename(p));
|
|
83
|
-
};
|
|
84
|
-
const adapter = this.guessAdapter({
|
|
85
|
-
protocol,
|
|
86
|
-
location: mapLoc(location),
|
|
87
|
-
index: index ? mapLoc(index) : undefined,
|
|
88
|
-
bed1: bed1 ? mapLoc(bed1) : undefined,
|
|
89
|
-
bed2: bed2 ? mapLoc(bed2) : undefined,
|
|
90
|
-
});
|
|
91
|
-
if ([
|
|
92
|
-
'PAFAdapter',
|
|
93
|
-
'PairwiseIndexedPAFAdapter',
|
|
94
|
-
'DeltaAdapter',
|
|
95
|
-
'ChainAdapter',
|
|
96
|
-
'MashMapAdapter',
|
|
97
|
-
'MCScanAnchorsAdapter',
|
|
98
|
-
'MCScanSimpleAnchorsAdapter',
|
|
99
|
-
].includes(adapter.type)) {
|
|
100
|
-
// @ts-expect-error
|
|
101
|
-
// this is for the adapter's assembly names
|
|
102
|
-
adapter.assemblyNames = assemblyNames.split(',').map(a => a.trim());
|
|
103
|
-
}
|
|
104
|
-
if (isUrl(location) && load) {
|
|
105
|
-
this.error('The --load flag is used for local files only, but a URL was provided', { exit: 100 });
|
|
106
|
-
}
|
|
107
|
-
else if (!isUrl(location) && !load) {
|
|
108
|
-
this.error(`The --load flag should be used if a local file is used, example --load
|
|
109
|
-
copy to copy the file into the config directory. Options for load are
|
|
110
|
-
copy/move/symlink/inPlace (inPlace for no file operations)`, { exit: 110 });
|
|
111
|
-
}
|
|
112
|
-
if (adapter.type === 'UNKNOWN') {
|
|
113
|
-
this.error('Track type is not recognized', { exit: 120 });
|
|
114
|
-
}
|
|
115
|
-
if (adapter.type === 'UNSUPPORTED') {
|
|
116
|
-
this.error('Track type is not supported', { exit: 130 });
|
|
117
|
-
}
|
|
118
|
-
// only add track if there is an existing config.json
|
|
119
|
-
const configContents = await this.readJsonFile(this.target);
|
|
120
|
-
if (!configContents.assemblies?.length) {
|
|
121
|
-
this.error('No assemblies found. Please add one before adding tracks', {
|
|
122
|
-
exit: 150,
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
if (configContents.assemblies.length > 1 && !assemblyNames) {
|
|
126
|
-
this.error('Too many assemblies, cannot default to one. Please specify the assembly with the --assemblyNames flag');
|
|
127
|
-
}
|
|
128
|
-
// set up the track information
|
|
129
|
-
trackType = trackType || this.guessTrackType(adapter.type);
|
|
130
|
-
trackId = trackId || path_1.default.basename(location, path_1.default.extname(location));
|
|
131
|
-
name = name || trackId;
|
|
132
|
-
assemblyNames = assemblyNames || configContents.assemblies[0]?.name || '';
|
|
133
|
-
const configObj = config ? (0, json_parse_better_errors_1.default)(config) : {};
|
|
134
|
-
const trackConfig = {
|
|
135
|
-
type: trackType,
|
|
136
|
-
trackId,
|
|
137
|
-
name,
|
|
138
|
-
adapter,
|
|
139
|
-
category: category?.split(',').map(c => c.trim()),
|
|
140
|
-
assemblyNames: assemblyNames.split(',').map(a => a.trim()),
|
|
141
|
-
description,
|
|
142
|
-
...configObj,
|
|
143
|
-
};
|
|
144
|
-
// any special track modifications go here
|
|
145
|
-
if (trackType === 'AlignmentsTrack') {
|
|
146
|
-
const assembly = configContents.assemblies.find(asm => asm.name === assemblyNames);
|
|
147
|
-
if (assembly) {
|
|
148
|
-
// @ts-expect-error
|
|
149
|
-
trackConfig.adapter.sequenceAdapter = assembly.sequence.adapter;
|
|
150
|
-
}
|
|
151
|
-
else if (!skipCheck) {
|
|
152
|
-
this.error(`Failed to find assemblyName ${assemblyNames}`);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
if (!configContents.tracks) {
|
|
156
|
-
configContents.tracks = [];
|
|
157
|
-
}
|
|
158
|
-
const idx = configContents.tracks.findIndex(c => c.trackId === trackId);
|
|
159
|
-
if (idx !== -1) {
|
|
160
|
-
this.debug(`Found existing trackId ${trackId} in configuration`);
|
|
161
|
-
if (force || overwrite) {
|
|
162
|
-
this.debug(`Overwriting track ${trackId} in configuration`);
|
|
163
|
-
configContents.tracks[idx] = trackConfig;
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
this.error(`Cannot add track with id ${trackId}, a track with that id already exists (use --force to override)`, { exit: 160 });
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
configContents.tracks.push(trackConfig);
|
|
171
|
-
}
|
|
172
|
-
if (load && load !== 'inPlace') {
|
|
173
|
-
await Promise.all(Object.values(this.guessFileNames({ location, index, bed1, bed2 }))
|
|
174
|
-
.filter(f => !!f)
|
|
175
|
-
.map(srcFilename => fileOperation({
|
|
176
|
-
mode: load,
|
|
177
|
-
srcFilename,
|
|
178
|
-
destFilename: destinationFn({
|
|
179
|
-
destinationDir: configDir,
|
|
180
|
-
srcFilename,
|
|
181
|
-
force,
|
|
182
|
-
subDir,
|
|
183
|
-
}),
|
|
184
|
-
})));
|
|
185
|
-
}
|
|
186
|
-
this.debug(`Writing configuration to file ${this.target}`);
|
|
187
|
-
await this.writeJsonFile(this.target, configContents);
|
|
188
|
-
this.log(`${idx !== -1 ? 'Overwrote' : 'Added'} track with name "${name}" and trackId "${trackId}" ${idx !== -1 ? 'in' : 'to'} ${this.target}`);
|
|
189
|
-
}
|
|
190
|
-
guessFileNames({ location, index, bed1, bed2, }) {
|
|
191
|
-
if (/\.anchors(.simple)?$/i.test(location)) {
|
|
192
|
-
return {
|
|
193
|
-
file: location,
|
|
194
|
-
bed1: bed1,
|
|
195
|
-
bed2: bed2,
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
else if (/\.bam$/i.test(location)) {
|
|
199
|
-
return {
|
|
200
|
-
file: location,
|
|
201
|
-
index: index || `${location}.bai`,
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
else if (/\.cram$/i.test(location)) {
|
|
205
|
-
return {
|
|
206
|
-
file: location,
|
|
207
|
-
index: index || `${location}.crai`,
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
else if (/\.gff3?\.b?gz$/i.test(location) ||
|
|
211
|
-
/\.vcf\.b?gz$/i.test(location) ||
|
|
212
|
-
/\.bed\.b?gz$/i.test(location) ||
|
|
213
|
-
/\.pif\.b?gz$/i.test(location)) {
|
|
214
|
-
return {
|
|
215
|
-
file: location,
|
|
216
|
-
index: index || `${location}.tbi`,
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
else if (/\.(fa|fasta|fas|fna|mfa)$/i.test(location)) {
|
|
220
|
-
return {
|
|
221
|
-
file: location,
|
|
222
|
-
index: index || `${location}.fai`,
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
else if (/\.(fa|fasta|fas|fna|mfa)\.b?gz$/i.test(location)) {
|
|
226
|
-
return {
|
|
227
|
-
file: location,
|
|
228
|
-
index: `${location}.fai`,
|
|
229
|
-
index2: `${location}.gzi`,
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
else if (/\.2bit$/i.test(location) ||
|
|
233
|
-
/\.bedpe(\.gz)?$/i.test(location) ||
|
|
234
|
-
/\/trackData.jsonz?$/i.test(location) ||
|
|
235
|
-
/\/sparql$/i.test(location) ||
|
|
236
|
-
/\.out(\.gz)?$/i.test(location) ||
|
|
237
|
-
/\.paf(\.gz)?$/i.test(location) ||
|
|
238
|
-
/\.delta(\.gz)?$/i.test(location) ||
|
|
239
|
-
/\.bed?$/i.test(location) ||
|
|
240
|
-
/\.(bw|bigwig)$/i.test(location) ||
|
|
241
|
-
/\.(bb|bigbed)$/i.test(location) ||
|
|
242
|
-
/\.vcf$/i.test(location) ||
|
|
243
|
-
/\.gtf?$/i.test(location) ||
|
|
244
|
-
/\.gff3?$/i.test(location) ||
|
|
245
|
-
/\.chain(\.gz)?$/i.test(location) ||
|
|
246
|
-
/\.hic$/i.test(location)) {
|
|
247
|
-
return {
|
|
248
|
-
file: location,
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
return {};
|
|
252
|
-
}
|
|
253
|
-
// find way to import this instead of having to paste it
|
|
254
|
-
guessAdapter({ location, protocol, index, bed1, bed2, }) {
|
|
255
|
-
const makeLocation = makeLocationProtocol(protocol);
|
|
256
|
-
if (/\.bam$/i.test(location)) {
|
|
257
|
-
return {
|
|
258
|
-
type: 'BamAdapter',
|
|
259
|
-
bamLocation: makeLocation(location),
|
|
260
|
-
index: {
|
|
261
|
-
location: makeLocation(index || `${location}.bai`),
|
|
262
|
-
indexType: index?.toUpperCase().endsWith('CSI') ? 'CSI' : 'BAI',
|
|
263
|
-
},
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
else if (/\.cram$/i.test(location)) {
|
|
267
|
-
return {
|
|
268
|
-
type: 'CramAdapter',
|
|
269
|
-
cramLocation: makeLocation(location),
|
|
270
|
-
craiLocation: makeLocation(`${location}.crai`),
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
else if (/\.gff3?$/i.test(location)) {
|
|
274
|
-
return {
|
|
275
|
-
type: 'Gff3Adapter',
|
|
276
|
-
gffLocation: makeLocation(location),
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
else if (/\.gff3?\.b?gz$/i.test(location)) {
|
|
280
|
-
return {
|
|
281
|
-
type: 'Gff3TabixAdapter',
|
|
282
|
-
gffGzLocation: makeLocation(location),
|
|
283
|
-
index: {
|
|
284
|
-
location: makeLocation(index || `${location}.tbi`),
|
|
285
|
-
indexType: index?.toUpperCase().endsWith('CSI') ? 'CSI' : 'TBI',
|
|
286
|
-
},
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
else if (/\.gtf?$/i.test(location)) {
|
|
290
|
-
return {
|
|
291
|
-
type: 'GtfAdapter',
|
|
292
|
-
gtfLocation: makeLocation(location),
|
|
293
|
-
};
|
|
294
|
-
}
|
|
295
|
-
else if (/\.vcf$/i.test(location)) {
|
|
296
|
-
return {
|
|
297
|
-
type: 'VcfAdapter',
|
|
298
|
-
vcfLocation: makeLocation(location),
|
|
299
|
-
};
|
|
300
|
-
}
|
|
301
|
-
else if (/\.vcf\.b?gz$/i.test(location)) {
|
|
302
|
-
return {
|
|
303
|
-
type: 'VcfTabixAdapter',
|
|
304
|
-
vcfGzLocation: makeLocation(location),
|
|
305
|
-
index: {
|
|
306
|
-
location: makeLocation(index || `${location}.tbi`),
|
|
307
|
-
indexType: index?.toUpperCase().endsWith('CSI') ? 'CSI' : 'TBI',
|
|
308
|
-
},
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
else if (/\.vcf\.idx$/i.test(location)) {
|
|
312
|
-
return {
|
|
313
|
-
type: 'UNSUPPORTED',
|
|
314
|
-
};
|
|
315
|
-
}
|
|
316
|
-
else if (/\.bedpe(.gz)?$/i.test(location)) {
|
|
317
|
-
return {
|
|
318
|
-
type: 'BedpeAdapter',
|
|
319
|
-
bedpeLocation: makeLocation(location),
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
else if (/\.bed$/i.test(location)) {
|
|
323
|
-
return {
|
|
324
|
-
type: 'BedAdapter',
|
|
325
|
-
bedLocation: makeLocation(location),
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
else if (/\.pif\.b?gz$/i.test(location)) {
|
|
329
|
-
return {
|
|
330
|
-
type: 'PairwiseIndexedPAFAdapter',
|
|
331
|
-
pifGzLocation: makeLocation(location),
|
|
332
|
-
index: {
|
|
333
|
-
location: makeLocation(index || `${location}.tbi`),
|
|
334
|
-
indexType: index?.toUpperCase().endsWith('CSI') ? 'CSI' : 'TBI',
|
|
335
|
-
},
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
else if (/\.bed\.b?gz$/i.test(location)) {
|
|
339
|
-
return {
|
|
340
|
-
type: 'BedTabixAdapter',
|
|
341
|
-
bedGzLocation: makeLocation(location),
|
|
342
|
-
index: {
|
|
343
|
-
location: makeLocation(index || `${location}.tbi`),
|
|
344
|
-
indexType: index?.toUpperCase().endsWith('CSI') ? 'CSI' : 'TBI',
|
|
345
|
-
},
|
|
346
|
-
};
|
|
347
|
-
}
|
|
348
|
-
else if (/\.(bb|bigbed)$/i.test(location)) {
|
|
349
|
-
return {
|
|
350
|
-
type: 'BigBedAdapter',
|
|
351
|
-
bigBedLocation: makeLocation(location),
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
else if (/\.(bw|bigwig)$/i.test(location)) {
|
|
355
|
-
return {
|
|
356
|
-
type: 'BigWigAdapter',
|
|
357
|
-
bigWigLocation: makeLocation(location),
|
|
358
|
-
};
|
|
359
|
-
}
|
|
360
|
-
else if (/\.(fa|fasta|fna|mfa)$/i.test(location)) {
|
|
361
|
-
return {
|
|
362
|
-
type: 'IndexedFastaAdapter',
|
|
363
|
-
fastaLocation: makeLocation(location),
|
|
364
|
-
faiLocation: makeLocation(index || `${location}.fai`),
|
|
365
|
-
};
|
|
366
|
-
}
|
|
367
|
-
else if (/\.(fa|fasta|fna|mfa)\.b?gz$/i.test(location)) {
|
|
368
|
-
return {
|
|
369
|
-
type: 'BgzipFastaAdapter',
|
|
370
|
-
fastaLocation: makeLocation(location),
|
|
371
|
-
faiLocation: makeLocation(`${location}.fai`),
|
|
372
|
-
gziLocation: makeLocation(`${location}.gzi`),
|
|
373
|
-
};
|
|
374
|
-
}
|
|
375
|
-
else if (/\.2bit$/i.test(location)) {
|
|
376
|
-
return {
|
|
377
|
-
type: 'TwoBitAdapter',
|
|
378
|
-
twoBitLocation: makeLocation(location),
|
|
379
|
-
};
|
|
380
|
-
}
|
|
381
|
-
else if (/\.sizes$/i.test(location)) {
|
|
382
|
-
return {
|
|
383
|
-
type: 'UNSUPPORTED',
|
|
384
|
-
};
|
|
385
|
-
}
|
|
386
|
-
else if (/\/trackData.jsonz?$/i.test(location)) {
|
|
387
|
-
return {
|
|
388
|
-
type: 'NCListAdapter',
|
|
389
|
-
rootUrlTemplate: makeLocation(location),
|
|
390
|
-
};
|
|
391
|
-
}
|
|
392
|
-
else if (/\/sparql$/i.test(location)) {
|
|
393
|
-
return {
|
|
394
|
-
type: 'SPARQLAdapter',
|
|
395
|
-
endpoint: location,
|
|
396
|
-
};
|
|
397
|
-
}
|
|
398
|
-
else if (/\.hic$/i.test(location)) {
|
|
399
|
-
return {
|
|
400
|
-
type: 'HicAdapter',
|
|
401
|
-
hicLocation: makeLocation(location),
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
else if (/\.paf(.gz)?$/i.test(location)) {
|
|
405
|
-
return {
|
|
406
|
-
type: 'PAFAdapter',
|
|
407
|
-
pafLocation: makeLocation(location),
|
|
408
|
-
};
|
|
409
|
-
}
|
|
410
|
-
else if (/\.out(.gz)?$/i.test(location)) {
|
|
411
|
-
return {
|
|
412
|
-
type: 'MashMapAdapter',
|
|
413
|
-
outLocation: makeLocation(location),
|
|
414
|
-
};
|
|
415
|
-
}
|
|
416
|
-
else if (/\.chain(.gz)?$/i.test(location)) {
|
|
417
|
-
return {
|
|
418
|
-
type: 'ChainAdapter',
|
|
419
|
-
chainLocation: makeLocation(location),
|
|
420
|
-
};
|
|
421
|
-
}
|
|
422
|
-
else if (/\.delta(.gz)?$/i.test(location)) {
|
|
423
|
-
return {
|
|
424
|
-
type: 'DeltaAdapter',
|
|
425
|
-
deltaLocation: makeLocation(location),
|
|
426
|
-
};
|
|
427
|
-
}
|
|
428
|
-
else if (/\.anchors(.gz)?$/i.test(location)) {
|
|
429
|
-
return {
|
|
430
|
-
type: 'MCScanAnchorsAdapter',
|
|
431
|
-
mcscanAnchorsLocation: makeLocation(location),
|
|
432
|
-
bed1Location: bed1 ? makeLocation(bed1) : undefined,
|
|
433
|
-
bed2Location: bed2 ? makeLocation(bed2) : undefined,
|
|
434
|
-
};
|
|
435
|
-
}
|
|
436
|
-
else if (/\.anchors.simple(.gz)?$/i.test(location)) {
|
|
437
|
-
return {
|
|
438
|
-
type: 'MCScanSimpleAnchorsAdapter',
|
|
439
|
-
mcscanSimpleAnchorsLocation: makeLocation(location),
|
|
440
|
-
bed1Location: bed1 ? makeLocation(bed1) : undefined,
|
|
441
|
-
bed2Location: bed2 ? makeLocation(bed2) : undefined,
|
|
442
|
-
};
|
|
443
|
-
}
|
|
444
|
-
return {
|
|
445
|
-
type: 'UNKNOWN',
|
|
446
|
-
};
|
|
447
|
-
}
|
|
448
|
-
guessTrackType(adapterType) {
|
|
449
|
-
return adapterTypesToTrackTypeMap[adapterType] || 'FeatureTrack';
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
AddTrack.description = 'Add a track to a JBrowse 2 configuration';
|
|
453
|
-
AddTrack.examples = [
|
|
454
|
-
'# copy /path/to/my.bam and /path/to/my.bam.bai to current directory and adds track to config.json',
|
|
455
|
-
'$ jbrowse add-track /path/to/my.bam --load copy',
|
|
456
|
-
'',
|
|
457
|
-
'# copy my.bam and my.bam.bai to /path/to/jb2/bam and adds track entry to /path/to/jb2/bam/config.json',
|
|
458
|
-
'$ jbrowse add-track my.bam --load copy --out /path/to/jb2 --subDir bam',
|
|
459
|
-
'',
|
|
460
|
-
'# same as above, but specify path to bai file. needed for if the bai file does not have the extension .bam.bai',
|
|
461
|
-
'$ jbrowse add-track my.bam --indexFile my.bai --load copy',
|
|
462
|
-
'',
|
|
463
|
-
'# creates symlink for /path/to/my.bam and adds track to config.json',
|
|
464
|
-
'$ jbrowse add-track /path/to/my.bam --load symlink',
|
|
465
|
-
'',
|
|
466
|
-
'# add track from URL to config.json, no --load flag needed',
|
|
467
|
-
'$ jbrowse add-track https://mywebsite.com/my.bam',
|
|
468
|
-
'',
|
|
469
|
-
'# --load inPlace adds a track without doing file operations',
|
|
470
|
-
'$ jbrowse add-track /url/relative/path.bam --load inPlace',
|
|
471
|
-
];
|
|
472
|
-
AddTrack.args = {
|
|
473
|
-
track: core_1.Args.string({
|
|
474
|
-
required: true,
|
|
475
|
-
description: 'Track file or URL',
|
|
476
|
-
}),
|
|
477
|
-
};
|
|
478
|
-
AddTrack.flags = {
|
|
479
|
-
trackType: core_1.Flags.string({
|
|
480
|
-
char: 't',
|
|
481
|
-
description: 'Type of track, by default inferred from track file',
|
|
482
|
-
}),
|
|
483
|
-
name: core_1.Flags.string({
|
|
484
|
-
char: 'n',
|
|
485
|
-
description: 'Name of the track. Will be defaulted to the trackId if none specified',
|
|
486
|
-
}),
|
|
487
|
-
indexFile: core_1.Flags.string({
|
|
488
|
-
description: 'Optional index file for the track',
|
|
489
|
-
}),
|
|
490
|
-
description: core_1.Flags.string({
|
|
491
|
-
char: 'd',
|
|
492
|
-
description: 'Optional description of the track',
|
|
493
|
-
}),
|
|
494
|
-
assemblyNames: core_1.Flags.string({
|
|
495
|
-
char: 'a',
|
|
496
|
-
description: 'Assembly name or names for track as comma separated string. If none, will default to the assembly in your config file',
|
|
497
|
-
}),
|
|
498
|
-
category: core_1.Flags.string({
|
|
499
|
-
description: 'Optional Comma separated string of categories to group tracks',
|
|
500
|
-
}),
|
|
501
|
-
config: core_1.Flags.string({
|
|
502
|
-
description: `Any extra config settings to add to a track. i.e '{"defaultRendering": "density"}'`,
|
|
503
|
-
}),
|
|
504
|
-
target: core_1.Flags.string({
|
|
505
|
-
description: 'path to config file in JB2 installation to write out to.',
|
|
506
|
-
}),
|
|
507
|
-
out: core_1.Flags.string({
|
|
508
|
-
description: 'synonym for target',
|
|
509
|
-
}),
|
|
510
|
-
subDir: core_1.Flags.string({
|
|
511
|
-
description: 'when using --load a file, output to a subdirectory of the target dir',
|
|
512
|
-
default: '',
|
|
513
|
-
}),
|
|
514
|
-
help: core_1.Flags.help({ char: 'h' }),
|
|
515
|
-
trackId: core_1.Flags.string({
|
|
516
|
-
description: 'trackId for the track, by default inferred from filename, must be unique throughout config',
|
|
517
|
-
}),
|
|
518
|
-
load: core_1.Flags.string({
|
|
519
|
-
char: 'l',
|
|
520
|
-
description: 'Required flag when using a local file. Choose how to manage the track. Copy, symlink, or move the track to the JBrowse directory. Or inPlace to leave track alone',
|
|
521
|
-
options: ['copy', 'symlink', 'move', 'inPlace'],
|
|
522
|
-
}),
|
|
523
|
-
skipCheck: core_1.Flags.boolean({
|
|
524
|
-
description: 'Skip check for whether or not the file or URL exists or if you are in a JBrowse directory',
|
|
525
|
-
}),
|
|
526
|
-
overwrite: core_1.Flags.boolean({
|
|
527
|
-
description: 'Overwrites existing track if it shares the same trackId',
|
|
528
|
-
}),
|
|
529
|
-
force: core_1.Flags.boolean({
|
|
530
|
-
char: 'f',
|
|
531
|
-
description: 'Equivalent to `--skipCheck --overwrite`',
|
|
532
|
-
}),
|
|
533
|
-
protocol: core_1.Flags.string({
|
|
534
|
-
description: 'Force protocol to a specific value',
|
|
535
|
-
default: 'uri',
|
|
536
|
-
}),
|
|
537
|
-
bed1: core_1.Flags.string({
|
|
538
|
-
description: 'Used only for mcscan anchors/simpleAnchors types',
|
|
539
|
-
}),
|
|
540
|
-
bed2: core_1.Flags.string({
|
|
541
|
-
description: 'Used only for mcscan anchors/simpleAnchors types',
|
|
542
|
-
}),
|
|
543
|
-
};
|
|
544
|
-
exports.default = AddTrack;
|
|
545
|
-
const adapterTypesToTrackTypeMap = {
|
|
546
|
-
BamAdapter: 'AlignmentsTrack',
|
|
547
|
-
CramAdapter: 'AlignmentsTrack',
|
|
548
|
-
BgzipFastaAdapter: 'ReferenceSequenceTrack',
|
|
549
|
-
BigWigAdapter: 'QuantitativeTrack',
|
|
550
|
-
IndexedFastaAdapter: 'ReferenceSequenceTrack',
|
|
551
|
-
TwoBitAdapter: 'ReferenceSequenceTrack',
|
|
552
|
-
VcfTabixAdapter: 'VariantTrack',
|
|
553
|
-
VcfAdapter: 'VariantTrack',
|
|
554
|
-
BedpeAdapter: 'VariantTrack',
|
|
555
|
-
BedAdapter: 'FeatureTrack',
|
|
556
|
-
HicAdapter: 'HicTrack',
|
|
557
|
-
PAFAdapter: 'SyntenyTrack',
|
|
558
|
-
DeltaAdapter: 'SyntenyTrack',
|
|
559
|
-
ChainAdapter: 'SyntenyTrack',
|
|
560
|
-
MashMapAdapter: 'SyntenyTrack',
|
|
561
|
-
PairwiseIndexedPAFAdapter: 'SyntenyTrack',
|
|
562
|
-
MCScanAnchorsAdapter: 'SyntenyTrack',
|
|
563
|
-
MCScanSimpleAnchorsAdapter: 'SyntenyTrack',
|
|
564
|
-
};
|