@jbrowse/cli 2.6.2 → 2.7.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/bin/dev ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+
3
+ const oclif = require('@oclif/core')
4
+
5
+ const path = require('path')
6
+ const project = path.join(__dirname, '..', 'tsconfig.json')
7
+
8
+ // In dev mode -> use ts-node and dev plugins
9
+ process.env.NODE_ENV = 'development'
10
+
11
+ require('ts-node').register({ project })
12
+
13
+ // In dev mode, always show stack traces
14
+ oclif.settings.debug = true
15
+
16
+ // Start the CLI
17
+ oclif.run().then(oclif.flush).catch(oclif.Errors.handle)
package/bin/dev.cmd ADDED
@@ -0,0 +1,3 @@
1
+ @echo off
2
+
3
+ node "%~dp0\dev" %*
package/bin/run CHANGED
@@ -1,5 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- require('@oclif/command').run()
4
- .then(require('@oclif/command/flush'))
5
- .catch(require('@oclif/errors/handle'))
3
+ const oclif = require('@oclif/core')
4
+
5
+ oclif
6
+ .run()
7
+ .then(require('@oclif/core/flush'))
8
+ .catch(require('@oclif/core/handle'))
package/lib/base.js CHANGED
@@ -2,35 +2,16 @@
2
2
  /**
3
3
  * By convention, exit codes in this base class are below 100
4
4
  */
5
- var __asyncValues = (this && this.__asyncValues) || function (o) {
6
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
7
- var m = o[Symbol.asyncIterator], i;
8
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
9
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
10
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
11
- };
12
- var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
13
- var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
14
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
15
- var g = generator.apply(thisArg, _arguments || []), i, q = [];
16
- return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
17
- function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
18
- function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
19
- function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
20
- function fulfill(value) { resume("next", value); }
21
- function reject(value) { resume("throw", value); }
22
- function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
23
- };
24
5
  var __importDefault = (this && this.__importDefault) || function (mod) {
25
6
  return (mod && mod.__esModule) ? mod : { "default": mod };
26
7
  };
27
8
  Object.defineProperty(exports, "__esModule", { value: true });
28
- const command_1 = __importDefault(require("@oclif/command"));
9
+ const core_1 = require("@oclif/core");
29
10
  const fs_1 = require("fs");
30
11
  const path_1 = __importDefault(require("path"));
31
12
  const json_parse_better_errors_1 = __importDefault(require("json-parse-better-errors"));
32
13
  const fetchWithProxy_1 = __importDefault(require("./fetchWithProxy"));
33
- class JBrowseCommand extends command_1.default {
14
+ class JBrowseCommand extends core_1.Command {
34
15
  async init() { }
35
16
  async readFile(location) {
36
17
  return fs_1.promises.readFile(location, { encoding: 'utf8' });
@@ -115,80 +96,51 @@ class JBrowseCommand extends command_1.default {
115
96
  return result;
116
97
  }
117
98
  async fetchGithubVersions() {
118
- var _a, e_1, _b, _c;
119
99
  let versions = [];
120
- try {
121
- for (var _d = true, _e = __asyncValues(this.fetchVersions()), _f; _f = await _e.next(), _a = _f.done, !_a; _d = true) {
122
- _c = _f.value;
123
- _d = false;
124
- const iter = _c;
125
- versions = [...versions, ...iter];
126
- }
127
- }
128
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
129
- finally {
130
- try {
131
- if (!_d && !_a && (_b = _e.return)) await _b.call(_e);
132
- }
133
- finally { if (e_1) throw e_1.error; }
100
+ for await (const iter of this.fetchVersions()) {
101
+ versions = [...versions, ...iter];
134
102
  }
135
103
  return versions;
136
104
  }
137
105
  async getLatest() {
138
- var _a, e_2, _b, _c;
139
- var _d;
140
- try {
141
- for (var _e = true, _f = __asyncValues(this.fetchVersions()), _g; _g = await _f.next(), _a = _g.done, !_a; _e = true) {
142
- _c = _g.value;
143
- _e = false;
144
- const versions = _c;
145
- // if a release was just uploaded, or an erroneous build was made
146
- // then it might have no build asset
147
- const nonprereleases = versions
148
- .filter(release => release.prerelease === false)
149
- .filter(release => release.assets && release.assets.length > 0);
150
- if (nonprereleases.length > 0) {
151
- // @ts-expect-error
152
- const file = (_d = nonprereleases[0].assets.find(f => f.name.includes('jbrowse-web'))) === null || _d === void 0 ? void 0 : _d.browser_download_url;
153
- if (!file) {
154
- throw new Error('no jbrowse-web download found');
155
- }
156
- return file;
106
+ for await (const versions of this.fetchVersions()) {
107
+ // if a release was just uploaded, or an erroneous build was made
108
+ // then it might have no build asset
109
+ const nonprereleases = versions
110
+ .filter(release => release.prerelease === false)
111
+ .filter(release => release.assets && release.assets.length > 0);
112
+ if (nonprereleases.length > 0) {
113
+ // @ts-expect-error
114
+ const file = nonprereleases[0].assets.find(f => f.name.includes('jbrowse-web'))?.browser_download_url;
115
+ if (!file) {
116
+ throw new Error('no jbrowse-web download found');
157
117
  }
118
+ return file;
158
119
  }
159
120
  }
160
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
161
- finally {
162
- try {
163
- if (!_e && !_a && (_b = _f.return)) await _b.call(_f);
164
- }
165
- finally { if (e_2) throw e_2.error; }
166
- }
167
121
  throw new Error('no version tags found');
168
122
  }
169
- fetchVersions() {
170
- return __asyncGenerator(this, arguments, function* fetchVersions_1() {
171
- let page = 1;
172
- let result;
173
- do {
174
- const response = yield __await((0, fetchWithProxy_1.default)(`https://api.github.com/repos/GMOD/jbrowse-components/releases?page=${page}`));
175
- if (response.ok) {
176
- result = (yield __await(response.json()));
177
- yield yield __await(result.filter(release => release.tag_name.startsWith('v')));
178
- page++;
179
- }
180
- else {
181
- throw new Error(`${response.statusText}`);
182
- }
183
- } while (result && result.length > 0);
184
- });
123
+ async *fetchVersions() {
124
+ let page = 1;
125
+ let result;
126
+ do {
127
+ const response = await (0, fetchWithProxy_1.default)(`https://api.github.com/repos/GMOD/jbrowse-components/releases?page=${page}`);
128
+ if (response.ok) {
129
+ result = (await response.json());
130
+ yield result.filter(release => release.tag_name.startsWith('v'));
131
+ page++;
132
+ }
133
+ else {
134
+ throw new Error(`${response.statusText}`);
135
+ }
136
+ } while (result && result.length > 0);
185
137
  }
186
138
  async getTag(tag) {
187
- var _a, _b;
188
139
  const response = await (0, fetchWithProxy_1.default)(`https://api.github.com/repos/GMOD/jbrowse-components/releases/tags/${tag}`);
189
140
  if (response.ok) {
190
141
  const result = (await response.json());
191
- const file = (_b = (_a = result === null || result === void 0 ? void 0 : result.assets) === null || _a === void 0 ? void 0 : _a.find(f => f.name.includes('jbrowse-web'))) === null || _b === void 0 ? void 0 : _b.browser_download_url;
142
+ const file = result?.assets?.find(f => f.name.includes('jbrowse-web'))
143
+ ?.browser_download_url;
192
144
  if (!file) {
193
145
  this.error('Could not find version specified. Use --listVersions to see all available versions', { exit: 90 });
194
146
  }
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const command_1 = require("@oclif/command");
6
+ const core_1 = require("@oclif/core");
7
7
  const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const base_1 = __importDefault(require("../base"));
@@ -20,7 +20,7 @@ function isValidJSON(string) {
20
20
  class AddAssembly extends base_1.default {
21
21
  async getAssembly() {
22
22
  let sequence;
23
- const { args: runArgs, flags: runFlags } = this.parse(AddAssembly);
23
+ const { args: runArgs, flags: runFlags } = await this.parse(AddAssembly);
24
24
  const { sequence: argsSequence } = runArgs;
25
25
  if (this.needLoadData(argsSequence) && !runFlags.load) {
26
26
  this.error(`Please specify the loading operation for this file with --load copy|symlink|move|inPlace`, { exit: 110 });
@@ -193,7 +193,7 @@ class AddAssembly extends base_1.default {
193
193
  async run() {
194
194
  // https://stackoverflow.com/a/35008327/2129219
195
195
  const exists = (s) => new Promise(r => fs_1.default.access(s, fs_1.default.constants.F_OK, e => r(!e)));
196
- const { args: runArgs, flags: runFlags } = this.parse(AddAssembly);
196
+ const { args: runArgs, flags: runFlags } = await this.parse(AddAssembly);
197
197
  const output = runFlags.target || runFlags.out || '.';
198
198
  if (!(await exists(output))) {
199
199
  const dir = output.endsWith('.json') ? path_1.default.dirname(output) : output;
@@ -209,7 +209,7 @@ class AddAssembly extends base_1.default {
209
209
  this.debug(`Sequence location is: ${argsSequence}`);
210
210
  const { name } = runFlags;
211
211
  const assembly = await this.getAssembly();
212
- if (runFlags.alias && runFlags.alias.length) {
212
+ if (runFlags.alias?.length) {
213
213
  this.debug(`Adding assembly aliases: ${runFlags.alias}`);
214
214
  assembly.aliases = runFlags.alias;
215
215
  }
@@ -261,11 +261,14 @@ class AddAssembly extends base_1.default {
261
261
  let configContents;
262
262
  if (fs_1.default.existsSync(this.target)) {
263
263
  this.debug(`Found existing config file ${this.target}`);
264
- configContents = Object.assign(Object.assign({}, defaultConfig), (await this.readJsonFile(this.target)));
264
+ configContents = {
265
+ ...defaultConfig,
266
+ ...(await this.readJsonFile(this.target)),
267
+ };
265
268
  }
266
269
  else {
267
270
  this.debug(`Creating config file ${this.target}`);
268
- configContents = Object.assign({}, defaultConfig);
271
+ configContents = { ...defaultConfig };
269
272
  }
270
273
  if (!configContents.assemblies) {
271
274
  configContents.assemblies = [];
@@ -399,9 +402,8 @@ AddAssembly.examples = [
399
402
  '# add a bgzip indexed fasta inferred by fa.gz extension. assumes .fa.gz.gzi and .fa.gz.fai files also exists',
400
403
  '$ jbrowse add-assembly myfile.fa.gz --load copy',
401
404
  ];
402
- AddAssembly.args = [
403
- {
404
- name: 'sequence',
405
+ AddAssembly.args = {
406
+ sequence: core_1.Args.string({
405
407
  required: true,
406
408
  description: `sequence file or URL
407
409
 
@@ -409,10 +411,10 @@ If TYPE is indexedFasta or bgzipFasta, the index file defaults to <location>.fai
409
411
  and can be optionally specified with --faiLocation
410
412
  If TYPE is bgzipFasta, the gzip index file defaults to <location>.gzi and can be
411
413
  optionally specified with --gziLocation`,
412
- },
413
- ];
414
+ }),
415
+ };
414
416
  AddAssembly.flags = {
415
- type: command_1.flags.string({
417
+ type: core_1.Flags.string({
416
418
  char: 't',
417
419
  description: `type of sequence, by default inferred from sequence file
418
420
 
@@ -430,54 +432,54 @@ custom Either a JSON file location or inline JSON that defines a custom
430
432
  sequence adapter; must provide --name if using inline JSON`,
431
433
  options: ['indexedFasta', 'bgzipFasta', 'twoBit', 'chromSizes', 'custom'],
432
434
  }),
433
- name: command_1.flags.string({
435
+ name: core_1.Flags.string({
434
436
  char: 'n',
435
437
  description: 'Name of the assembly; if not specified, will be guessed using the sequence file name',
436
438
  }),
437
- alias: command_1.flags.string({
439
+ alias: core_1.Flags.string({
438
440
  char: 'a',
439
441
  description: 'An alias for the assembly name (e.g. "hg38" if the name of the assembly is "GRCh38");\ncan be specified multiple times',
440
442
  multiple: true,
441
443
  }),
442
- displayName: command_1.flags.string({
444
+ displayName: core_1.Flags.string({
443
445
  description: 'The display name to specify for the assembly, e.g. "Homo sapiens (hg38)" while the name can be a shorter identifier like "hg38"',
444
446
  }),
445
- faiLocation: command_1.flags.string({
447
+ faiLocation: core_1.Flags.string({
446
448
  description: '[default: <fastaLocation>.fai] FASTA index file or URL',
447
449
  }),
448
- gziLocation: command_1.flags.string({
450
+ gziLocation: core_1.Flags.string({
449
451
  description: '[default: <fastaLocation>.gzi] FASTA gzip index file or URL',
450
452
  }),
451
- refNameAliases: command_1.flags.string({
453
+ refNameAliases: core_1.Flags.string({
452
454
  description: 'Reference sequence name aliases file or URL; assumed to be a tab-separated aliases\nfile unless --refNameAliasesType is specified',
453
455
  }),
454
- refNameAliasesType: command_1.flags.string({
456
+ refNameAliasesType: core_1.Flags.string({
455
457
  description: 'Type of aliases defined by --refNameAliases; if "custom", --refNameAliases is either\na JSON file location or inline JSON that defines a custom sequence adapter',
456
458
  options: ['aliases', 'custom'],
457
459
  dependsOn: ['refNameAliases'],
458
460
  }),
459
- refNameColors: command_1.flags.string({
461
+ refNameColors: core_1.Flags.string({
460
462
  description: 'A comma-separated list of color strings for the reference sequence names; will cycle\nthrough colors if there are fewer colors than sequences',
461
463
  }),
462
- target: command_1.flags.string({
464
+ target: core_1.Flags.string({
463
465
  description: 'path to config file in JB2 installation directory to write out to.\nCreates ./config.json if nonexistent',
464
466
  }),
465
- out: command_1.flags.string({
467
+ out: core_1.Flags.string({
466
468
  description: 'synonym for target',
467
469
  }),
468
- help: command_1.flags.help({ char: 'h' }),
469
- load: command_1.flags.string({
470
+ help: core_1.Flags.help({ char: 'h' }),
471
+ load: core_1.Flags.string({
470
472
  char: 'l',
471
473
  description: 'Required flag when using a local file. Choose how to manage the data directory. Copy, symlink, or move the data directory to the JBrowse directory. Or use inPlace to modify the config without doing any file operations',
472
474
  options: ['copy', 'symlink', 'move', 'inPlace'],
473
475
  }),
474
- skipCheck: command_1.flags.boolean({
476
+ skipCheck: core_1.Flags.boolean({
475
477
  description: "Don't check whether or not the sequence file or URL exists or if you are in a JBrowse directory",
476
478
  }),
477
- overwrite: command_1.flags.boolean({
479
+ overwrite: core_1.Flags.boolean({
478
480
  description: 'Overwrite existing assembly if one with the same name exists',
479
481
  }),
480
- force: command_1.flags.boolean({
482
+ force: core_1.Flags.boolean({
481
483
  char: 'f',
482
484
  description: 'Equivalent to `--skipCheck --overwrite`',
483
485
  }),
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const command_1 = require("@oclif/command");
6
+ const core_1 = require("@oclif/core");
7
7
  const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const json_parse_better_errors_1 = __importDefault(require("json-parse-better-errors"));
@@ -12,8 +12,7 @@ const fetchWithProxy_1 = __importDefault(require("../fetchWithProxy"));
12
12
  const base_1 = __importDefault(require("../base"));
13
13
  class AddConnection extends base_1.default {
14
14
  async run() {
15
- var _a, _b;
16
- const { args: runArgs, flags: runFlags } = this.parse(AddConnection);
15
+ const { args: runArgs, flags: runFlags } = await this.parse(AddConnection);
17
16
  const output = runFlags.target || runFlags.out || '.';
18
17
  const isDir = fs_1.default.lstatSync(output).isDirectory();
19
18
  this.target = isDir ? `${output}/config.json` : output;
@@ -23,29 +22,37 @@ class AddConnection extends base_1.default {
23
22
  const url = await this.resolveURL(connectionUrlOrPath, !(skipCheck || force));
24
23
  const configContents = await this.readJsonFile(this.target);
25
24
  this.debug(`Using config file ${this.target}`);
26
- if (!((_a = configContents.assemblies) === null || _a === void 0 ? void 0 : _a.length)) {
25
+ if (!configContents.assemblies?.length) {
27
26
  this.error('No assemblies found. Please add one before adding connections', { exit: 120 });
28
27
  }
29
28
  const configType = type || this.determineConnectionType(url);
30
29
  const id = connectionId ||
31
30
  [configType, assemblyNames, +Date.now()].filter(f => !!f).join('-');
32
- const connectionConfig = Object.assign(Object.assign(Object.assign(Object.assign({ type: configType, name: name || id }, (configType === 'UCSCTrackHubConnection'
33
- ? {
34
- hubTxtLocation: {
35
- uri: url,
36
- locationType: 'UriLocation',
37
- },
38
- }
39
- : {})), (configType === 'JBrowse1Connection'
40
- ? {
41
- dataDirLocation: {
42
- uri: url,
43
- locationType: 'UriLocation',
44
- },
45
- }
46
- : {})), { connectionId: id, assemblyNames: assemblyNames || type === 'JBrowse1Connection'
47
- ? [(_b = configContents.assemblies[0]) === null || _b === void 0 ? void 0 : _b.name]
48
- : undefined }), (config ? (0, json_parse_better_errors_1.default)(config) : {}));
31
+ const connectionConfig = {
32
+ type: configType,
33
+ name: name || id,
34
+ ...(configType === 'UCSCTrackHubConnection'
35
+ ? {
36
+ hubTxtLocation: {
37
+ uri: url,
38
+ locationType: 'UriLocation',
39
+ },
40
+ }
41
+ : {}),
42
+ ...(configType === 'JBrowse1Connection'
43
+ ? {
44
+ dataDirLocation: {
45
+ uri: url,
46
+ locationType: 'UriLocation',
47
+ },
48
+ }
49
+ : {}),
50
+ connectionId: id,
51
+ assemblyNames: assemblyNames || type === 'JBrowse1Connection'
52
+ ? [configContents.assemblies[0]?.name]
53
+ : undefined,
54
+ ...(config ? (0, json_parse_better_errors_1.default)(config) : {}),
55
+ };
49
56
  if (!configContents.connections) {
50
57
  configContents.connections = [];
51
58
  }
@@ -121,47 +128,46 @@ AddConnection.examples = [
121
128
  `$ jbrowse add-connection http://mysite.com/path/to/custom --type custom --config '{"uri":{"url":"https://mysite.com/path/to/custom"}, "locationType": "UriLocation"}' -a hg19`,
122
129
  '$ jbrowse add-connection https://mysite.com/path/to/hub.txt --connectionId newId --name newName --target /path/to/jb2/installation/config.json',
123
130
  ];
124
- AddConnection.args = [
125
- {
126
- name: 'connectionUrlOrPath',
131
+ AddConnection.args = {
132
+ connectionUrlOrPath: core_1.Args.string({
127
133
  required: true,
128
134
  description: `URL of data directory\nFor hub file, usually called hub.txt\nFor JBrowse 1, location of JB1 data directory similar to http://mysite.com/jbrowse/data/ `,
129
- },
130
- ];
135
+ }),
136
+ };
131
137
  AddConnection.flags = {
132
- type: command_1.flags.string({
138
+ type: core_1.Flags.string({
133
139
  char: 't',
134
140
  description: 'type of connection, ex. JBrowse1Connection, UCSCTrackHubConnection, custom',
135
141
  }),
136
- assemblyNames: command_1.flags.string({
142
+ assemblyNames: core_1.Flags.string({
137
143
  char: 'a',
138
144
  description: 'For UCSC, optional: Comma separated list of assembly name(s) to filter from this connection. For JBrowse: a single assembly name',
139
145
  }),
140
- config: command_1.flags.string({
146
+ config: core_1.Flags.string({
141
147
  char: 'c',
142
148
  description: `Any extra config settings to add to connection in JSON object format, such as '{"uri":"url":"https://sample.com"}, "locationType": "UriLocation"}'`,
143
149
  }),
144
- connectionId: command_1.flags.string({
150
+ connectionId: core_1.Flags.string({
145
151
  description: `Id for the connection that must be unique to JBrowse. Defaults to 'connectionType-assemblyName-currentTime'`,
146
152
  }),
147
- name: command_1.flags.string({
153
+ name: core_1.Flags.string({
148
154
  char: 'n',
149
155
  description: 'Name of the connection. Defaults to connectionId if not provided',
150
156
  }),
151
- target: command_1.flags.string({
157
+ target: core_1.Flags.string({
152
158
  description: 'path to config file in JB2 installation directory to write out to.',
153
159
  }),
154
- out: command_1.flags.string({
160
+ out: core_1.Flags.string({
155
161
  description: 'synonym for target',
156
162
  }),
157
- help: command_1.flags.help({ char: 'h' }),
158
- skipCheck: command_1.flags.boolean({
163
+ help: core_1.Flags.help({ char: 'h' }),
164
+ skipCheck: core_1.Flags.boolean({
159
165
  description: "Don't check whether or not the data directory URL exists or if you are in a JBrowse directory",
160
166
  }),
161
- overwrite: command_1.flags.boolean({
167
+ overwrite: core_1.Flags.boolean({
162
168
  description: 'Overwrites any existing connections if same connection id',
163
169
  }),
164
- force: command_1.flags.boolean({
170
+ force: core_1.Flags.boolean({
165
171
  char: 'f',
166
172
  description: 'Equivalent to `--skipCheck --overwrite`',
167
173
  }),
@@ -3,12 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const command_1 = require("@oclif/command");
6
+ const core_1 = require("@oclif/core");
7
7
  const fs_1 = require("fs");
8
8
  const base_1 = __importDefault(require("../base"));
9
9
  class AddTrackJson extends base_1.default {
10
10
  async run() {
11
- const { args, flags: runFlags } = this.parse(AddTrackJson);
11
+ const { args, flags: runFlags } = await this.parse(AddTrackJson);
12
12
  const output = runFlags.target || runFlags.out || '.';
13
13
  const isDir = (await fs_1.promises.lstat(output)).isDirectory();
14
14
  this.target = isDir ? `${output}/config.json` : output;
@@ -46,22 +46,21 @@ AddTrackJson.examples = [
46
46
  '$ jbrowse add-track-json track.json',
47
47
  '$ jbrowse add-track-json track.json --update',
48
48
  ];
49
- AddTrackJson.args = [
50
- {
51
- name: 'track',
49
+ AddTrackJson.args = {
50
+ track: core_1.Args.string({
52
51
  required: true,
53
52
  description: `track JSON file or command line arg blob`,
54
- },
55
- ];
53
+ }),
54
+ };
56
55
  AddTrackJson.flags = {
57
- update: command_1.flags.boolean({
56
+ update: core_1.Flags.boolean({
58
57
  char: 'u',
59
58
  description: `update the contents of an existing track, matched based on trackId`,
60
59
  }),
61
- target: command_1.flags.string({
60
+ target: core_1.Flags.string({
62
61
  description: 'path to config file in JB2 installation directory to write out to.\nCreates ./config.json if nonexistent',
63
62
  }),
64
- out: command_1.flags.string({
63
+ out: core_1.Flags.string({
65
64
  description: 'synonym for target',
66
65
  }),
67
66
  };