@jbrowse/cli 3.5.1 → 3.6.1

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.
Files changed (72) hide show
  1. package/README.md +291 -607
  2. package/bin/run +1 -6
  3. package/bundle/index.js +4459 -0
  4. package/dist/base.js +5 -0
  5. package/dist/bin.js +3 -0
  6. package/dist/commands/add-assembly.js +143 -0
  7. package/dist/commands/add-connection.js +177 -0
  8. package/dist/commands/add-track-json.js +81 -0
  9. package/dist/commands/add-track-utils/adapter-utils.js +304 -0
  10. package/dist/commands/add-track-utils/file-operations.js +36 -0
  11. package/dist/commands/add-track-utils/track-config.js +63 -0
  12. package/dist/commands/add-track-utils/validators.js +74 -0
  13. package/dist/commands/add-track.js +193 -0
  14. package/dist/commands/admin-server-utils.js +238 -0
  15. package/dist/commands/admin-server.js +51 -0
  16. package/dist/commands/assembly-utils.js +410 -0
  17. package/dist/commands/create.js +121 -0
  18. package/dist/commands/make-pif-utils/cigar-utils.js +29 -0
  19. package/dist/commands/make-pif-utils/file-utils.js +38 -0
  20. package/dist/commands/make-pif-utils/pif-generator.js +64 -0
  21. package/dist/commands/make-pif-utils/validators.js +22 -0
  22. package/dist/commands/make-pif.js +58 -0
  23. package/dist/commands/remove-track.js +58 -0
  24. package/dist/commands/set-default-session.js +104 -0
  25. package/dist/commands/sort-bed-utils/constants.js +12 -0
  26. package/dist/commands/sort-bed-utils/process-utils.js +23 -0
  27. package/dist/commands/sort-bed-utils/sort-utils.js +24 -0
  28. package/dist/commands/sort-bed-utils/validators.js +22 -0
  29. package/dist/commands/sort-bed.js +49 -0
  30. package/dist/commands/sort-gff-utils/constants.js +13 -0
  31. package/dist/commands/sort-gff-utils/process-utils.js +23 -0
  32. package/dist/commands/sort-gff-utils/sort-utils.js +55 -0
  33. package/dist/commands/sort-gff-utils/validators.js +21 -0
  34. package/dist/commands/sort-gff.js +49 -0
  35. package/dist/commands/text-index-utils/adapter-utils.js +63 -0
  36. package/dist/commands/text-index-utils/aggregate.js +87 -0
  37. package/dist/commands/text-index-utils/config-utils.js +59 -0
  38. package/dist/commands/text-index-utils/file-list.js +31 -0
  39. package/dist/commands/text-index-utils/index.js +9 -0
  40. package/dist/commands/text-index-utils/indexing-utils.js +84 -0
  41. package/dist/commands/text-index-utils/per-track.js +65 -0
  42. package/dist/commands/text-index-utils/validators.js +20 -0
  43. package/dist/commands/text-index.js +113 -0
  44. package/dist/commands/track-utils.js +85 -0
  45. package/dist/commands/upgrade.js +122 -0
  46. package/dist/index.js +119 -0
  47. package/dist/utils.js +154 -0
  48. package/package.json +13 -38
  49. package/bin/dev +0 -17
  50. package/bin/dev.cmd +0 -3
  51. package/bin/run.cmd +0 -3
  52. package/lib/base.js +0 -157
  53. package/lib/commands/add-assembly.js +0 -491
  54. package/lib/commands/add-connection.js +0 -170
  55. package/lib/commands/add-track-json.js +0 -67
  56. package/lib/commands/add-track.js +0 -564
  57. package/lib/commands/admin-server.js +0 -153
  58. package/lib/commands/create.js +0 -111
  59. package/lib/commands/make-pif.js +0 -116
  60. package/lib/commands/remove-track.js +0 -37
  61. package/lib/commands/set-default-session.js +0 -98
  62. package/lib/commands/sort-bed.js +0 -45
  63. package/lib/commands/sort-gff.js +0 -45
  64. package/lib/commands/text-index.js +0 -380
  65. package/lib/commands/upgrade.js +0 -109
  66. package/lib/index.js +0 -6
  67. package/oclif.manifest.json +0 -1169
  68. /package/{lib → dist}/fetchWithProxy.js +0 -0
  69. /package/{lib → dist}/types/common.js +0 -0
  70. /package/{lib → dist}/types/gff3Adapter.js +0 -0
  71. /package/{lib → dist}/types/vcfAdapter.js +0 -0
  72. /package/{lib → dist}/util.js +0 -0
package/lib/base.js DELETED
@@ -1,157 +0,0 @@
1
- "use strict";
2
- /**
3
- * By convention, exit codes in this base class are below 100
4
- */
5
- var __importDefault = (this && this.__importDefault) || function (mod) {
6
- return (mod && mod.__esModule) ? mod : { "default": mod };
7
- };
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- const fs_1 = require("fs");
10
- const path_1 = __importDefault(require("path"));
11
- const core_1 = require("@oclif/core");
12
- const json_parse_better_errors_1 = __importDefault(require("json-parse-better-errors"));
13
- const fetchWithProxy_1 = __importDefault(require("./fetchWithProxy"));
14
- class JBrowseCommand extends core_1.Command {
15
- async init() { }
16
- async readFile(location) {
17
- return fs_1.promises.readFile(location, { encoding: 'utf8' });
18
- }
19
- async readJsonFile(location) {
20
- let contents;
21
- try {
22
- contents = await fs_1.promises.readFile(location, { encoding: 'utf8' });
23
- }
24
- catch (error) {
25
- this.error(error instanceof Error ? error : `${error}`, {
26
- suggestions: [
27
- `Make sure the file "${location}" exists or use --out to point to a directory with a config.json`,
28
- 'Run `jbrowse add-assembly` to create a config file',
29
- ],
30
- exit: 40,
31
- });
32
- }
33
- let result;
34
- try {
35
- result = (0, json_parse_better_errors_1.default)(contents);
36
- }
37
- catch (error) {
38
- this.error(error instanceof Error ? error : `${error}`, {
39
- suggestions: [`Make sure "${location}" is a valid JSON file`],
40
- exit: 50,
41
- });
42
- }
43
- return result;
44
- }
45
- async writeJsonFile(location, contents) {
46
- this.debug(`Writing JSON file to ${process.cwd()} ${location}`);
47
- return fs_1.promises.writeFile(location, JSON.stringify(contents, null, 2));
48
- }
49
- async resolveFileLocation(location, check = true, inPlace = false) {
50
- let locationUrl;
51
- try {
52
- locationUrl = new URL(location);
53
- }
54
- catch (error) {
55
- // ignore
56
- }
57
- if (locationUrl) {
58
- if (check) {
59
- // @ts-expect-error
60
- const response = await (0, fetchWithProxy_1.default)(locationUrl, { method: 'HEAD' });
61
- if (!response.ok) {
62
- throw new Error(`${locationUrl} result ${response.statusText}`);
63
- }
64
- }
65
- return locationUrl.href;
66
- }
67
- let locationPath;
68
- try {
69
- locationPath = check ? await fs_1.promises.realpath(location) : location;
70
- }
71
- catch (e) {
72
- // ignore
73
- }
74
- if (locationPath) {
75
- const filePath = path_1.default.relative(process.cwd(), locationPath);
76
- if (inPlace && filePath.startsWith('..')) {
77
- this.warn(`Location ${filePath} is not in the JBrowse directory. Make sure it is still in your server directory.`);
78
- }
79
- return inPlace ? location : filePath;
80
- }
81
- return this.error(`Could not resolve to a file or a URL: "${location}"`, {
82
- exit: 40,
83
- });
84
- }
85
- async readInlineOrFileJson(inlineOrFileName) {
86
- let result;
87
- // see if it's inline JSON
88
- try {
89
- result = (0, json_parse_better_errors_1.default)(inlineOrFileName);
90
- }
91
- catch (error) {
92
- this.debug(`Not valid inline JSON, attempting to parse as filename: '${inlineOrFileName}'`);
93
- // not inline JSON, must be location of a JSON file
94
- result = await this.readJsonFile(inlineOrFileName);
95
- }
96
- return result;
97
- }
98
- async fetchGithubVersions() {
99
- let versions = [];
100
- for await (const iter of this.fetchVersions()) {
101
- versions = [...versions, ...iter];
102
- }
103
- return versions;
104
- }
105
- async getLatest() {
106
- for await (const versions of this.fetchVersions()) {
107
- // if a release was just uploaded, or an erroneous build was made then it
108
- // might have no build asset
109
- const nonprereleases = versions
110
- .filter(release => !release.prerelease)
111
- .filter(release => release.assets?.length);
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');
117
- }
118
- return file;
119
- }
120
- }
121
- throw new Error('no version tags found');
122
- }
123
- async *fetchVersions() {
124
- let page = 1;
125
- let result;
126
- do {
127
- const url = `https://api.github.com/repos/GMOD/jbrowse-components/releases?page=${page}`;
128
- const response = await (0, fetchWithProxy_1.default)(url);
129
- if (response.ok) {
130
- result = (await response.json());
131
- yield result.filter(release => release.tag_name.startsWith('v'));
132
- page++;
133
- }
134
- else {
135
- throw new Error(`HTTP ${response.status} fetching ${url}`);
136
- }
137
- } while (result.length);
138
- }
139
- async getTag(tag) {
140
- const response = await (0, fetchWithProxy_1.default)(`https://api.github.com/repos/GMOD/jbrowse-components/releases/tags/${tag}`);
141
- if (response.ok) {
142
- const result = (await response.json());
143
- const file = result.assets?.find(f => f.name.includes('jbrowse-web'))?.browser_download_url;
144
- if (!file) {
145
- this.error('Could not find version specified. Use --listVersions to see all available versions', { exit: 90 });
146
- }
147
- return file;
148
- }
149
- return this.error(`Could not find version: ${response.statusText}`, {
150
- exit: 90,
151
- });
152
- }
153
- async getBranch(branch) {
154
- return `https://s3.amazonaws.com/jbrowse.org/code/jb2/${branch}/jbrowse-web-${branch}.zip`;
155
- }
156
- }
157
- exports.default = JBrowseCommand;
@@ -1,491 +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 base_1 = __importDefault(require("../base"));
10
- const { rename, copyFile, mkdir, symlink } = fs_1.default.promises;
11
- function isValidJSON(string) {
12
- try {
13
- JSON.parse(string);
14
- return true;
15
- }
16
- catch (error) {
17
- return false;
18
- }
19
- }
20
- class AddAssembly extends base_1.default {
21
- async getAssembly() {
22
- let sequence;
23
- const { args: runArgs, flags: runFlags } = await this.parse(AddAssembly);
24
- const { sequence: argsSequence } = runArgs;
25
- if (this.needLoadData(argsSequence) && !runFlags.load) {
26
- this.error('Please specify the loading operation for this file with --load copy|symlink|move|inPlace', { exit: 110 });
27
- }
28
- else if (!this.needLoadData(argsSequence) && runFlags.load) {
29
- this.error('URL detected with --load flag. Please rerun the function without the --load flag', { exit: 120 });
30
- }
31
- let { name } = runFlags;
32
- let { type } = runFlags;
33
- if (type) {
34
- this.debug(`Type is: ${type}`);
35
- }
36
- else {
37
- type = this.guessSequenceType(argsSequence);
38
- this.debug(`No type specified, guessing type: ${type}`);
39
- }
40
- if (name) {
41
- this.debug(`Name is: ${name}`);
42
- }
43
- switch (type) {
44
- case 'indexedFasta': {
45
- const { skipCheck, force, load, faiLocation } = runFlags;
46
- let sequenceLocation = await this.resolveFileLocation(argsSequence, !(skipCheck || force), load === 'inPlace');
47
- this.debug(`FASTA location resolved to: ${sequenceLocation}`);
48
- let indexLocation = await this.resolveFileLocation(faiLocation || `${argsSequence}.fai`, !(skipCheck || force), load === 'inPlace');
49
- this.debug(`FASTA index location resolved to: ${indexLocation}`);
50
- if (!name) {
51
- name = path_1.default.basename(sequenceLocation, sequenceLocation.endsWith('.fasta') ? '.fasta' : '.fa');
52
- this.debug(`Guessing name: ${name}`);
53
- }
54
- const loaded = load
55
- ? await this.loadData(load, [sequenceLocation, indexLocation])
56
- : false;
57
- if (loaded) {
58
- sequenceLocation = path_1.default.basename(sequenceLocation);
59
- indexLocation = path_1.default.basename(indexLocation);
60
- }
61
- sequence = {
62
- type: 'ReferenceSequenceTrack',
63
- trackId: `${name}-ReferenceSequenceTrack`,
64
- adapter: {
65
- type: 'IndexedFastaAdapter',
66
- fastaLocation: {
67
- uri: sequenceLocation,
68
- locationType: 'UriLocation',
69
- },
70
- faiLocation: { uri: indexLocation, locationType: 'UriLocation' },
71
- },
72
- };
73
- break;
74
- }
75
- case 'bgzipFasta': {
76
- let sequenceLocation = await this.resolveFileLocation(argsSequence, !(runFlags.skipCheck || runFlags.force), runFlags.load === 'inPlace');
77
- this.debug(`compressed FASTA location resolved to: ${sequenceLocation}`);
78
- let indexLocation = await this.resolveFileLocation(runFlags.faiLocation || `${sequenceLocation}.fai`, !(runFlags.skipCheck || runFlags.force), runFlags.load === 'inPlace');
79
- this.debug(`compressed FASTA index location resolved to: ${indexLocation}`);
80
- let bgzipIndexLocation = await this.resolveFileLocation(runFlags.gziLocation || `${sequenceLocation}.gzi`, !(runFlags.skipCheck || runFlags.force), runFlags.load === 'inPlace');
81
- this.debug(`bgzip index location resolved to: ${bgzipIndexLocation}`);
82
- if (!name) {
83
- name = path_1.default.basename(sequenceLocation, sequenceLocation.endsWith('.fasta.gz') ? '.fasta.gz' : '.fa.gz');
84
- this.debug(`Guessing name: ${name}`);
85
- }
86
- const loaded = runFlags.load
87
- ? await this.loadData(runFlags.load, [
88
- sequenceLocation,
89
- indexLocation,
90
- bgzipIndexLocation,
91
- ])
92
- : false;
93
- if (loaded) {
94
- sequenceLocation = path_1.default.basename(sequenceLocation);
95
- indexLocation = path_1.default.basename(indexLocation);
96
- bgzipIndexLocation = path_1.default.basename(bgzipIndexLocation);
97
- }
98
- sequence = {
99
- type: 'ReferenceSequenceTrack',
100
- trackId: `${name}-ReferenceSequenceTrack`,
101
- adapter: {
102
- type: 'BgzipFastaAdapter',
103
- fastaLocation: {
104
- uri: sequenceLocation,
105
- locationType: 'UriLocation',
106
- },
107
- faiLocation: { uri: indexLocation, locationType: 'UriLocation' },
108
- gziLocation: {
109
- uri: bgzipIndexLocation,
110
- locationType: 'UriLocation',
111
- },
112
- },
113
- };
114
- break;
115
- }
116
- case 'twoBit': {
117
- let sequenceLocation = await this.resolveFileLocation(argsSequence, !(runFlags.skipCheck || runFlags.force), runFlags.load === 'inPlace');
118
- this.debug(`2bit location resolved to: ${sequenceLocation}`);
119
- if (!name) {
120
- name = path_1.default.basename(sequenceLocation, '.2bit');
121
- this.debug(`Guessing name: ${name}`);
122
- }
123
- const loaded = runFlags.load
124
- ? await this.loadData(runFlags.load, [sequenceLocation])
125
- : false;
126
- if (loaded) {
127
- sequenceLocation = path_1.default.basename(sequenceLocation);
128
- }
129
- sequence = {
130
- type: 'ReferenceSequenceTrack',
131
- trackId: `${name}-ReferenceSequenceTrack`,
132
- adapter: {
133
- type: 'TwoBitAdapter',
134
- twoBitLocation: {
135
- uri: sequenceLocation,
136
- locationType: 'UriLocation',
137
- },
138
- },
139
- };
140
- break;
141
- }
142
- case 'chromSizes': {
143
- let sequenceLocation = await this.resolveFileLocation(argsSequence, !(runFlags.skipCheck || runFlags.force), runFlags.load === 'inPlace');
144
- this.debug(`chrom.sizes location resolved to: ${sequenceLocation}`);
145
- if (!name) {
146
- name = path_1.default.basename(sequenceLocation, '.chrom.sizes');
147
- this.debug(`Guessing name: ${name}`);
148
- }
149
- const loaded = runFlags.load
150
- ? await this.loadData(runFlags.load, [sequenceLocation])
151
- : false;
152
- if (loaded) {
153
- sequenceLocation = path_1.default.basename(sequenceLocation);
154
- }
155
- sequence = {
156
- type: 'ReferenceSequenceTrack',
157
- trackId: `${name}-ReferenceSequenceTrack`,
158
- adapter: {
159
- type: 'ChromSizesAdapter',
160
- chromSizesLocation: {
161
- uri: sequenceLocation,
162
- locationType: 'UriLocation',
163
- },
164
- },
165
- };
166
- break;
167
- }
168
- case 'custom': {
169
- const adapter = await this.readInlineOrFileJson(argsSequence);
170
- this.debug(`Custom adapter: ${JSON.stringify(adapter)}`);
171
- if (!name) {
172
- if (isValidJSON(argsSequence)) {
173
- this.error('Must provide --name when using custom inline JSON sequence', { exit: 130 });
174
- }
175
- else {
176
- name = path_1.default.basename(argsSequence, '.json');
177
- }
178
- this.debug(`Guessing name: ${name}`);
179
- }
180
- if (!('type' in adapter)) {
181
- this.error(`No "type" specified in sequence adapter "${JSON.stringify(adapter)}"`, { exit: 140 });
182
- }
183
- sequence = {
184
- type: 'ReferenceSequenceTrack',
185
- trackId: `${name}-ReferenceSequenceTrack`,
186
- adapter,
187
- };
188
- break;
189
- }
190
- }
191
- return { name, sequence };
192
- }
193
- async run() {
194
- // https://stackoverflow.com/a/35008327/2129219
195
- const exists = (s) => new Promise(r => {
196
- fs_1.default.access(s, fs_1.default.constants.F_OK, e => {
197
- r(!e);
198
- });
199
- });
200
- const { args: runArgs, flags: runFlags } = await this.parse(AddAssembly);
201
- const output = runFlags.target || runFlags.out || '.';
202
- if (!(await exists(output))) {
203
- const dir = output.endsWith('.json') ? path_1.default.dirname(output) : output;
204
- await mkdir(dir, { recursive: true });
205
- }
206
- let isDir = false;
207
- try {
208
- isDir = fs_1.default.statSync(output).isDirectory();
209
- }
210
- catch (e) { }
211
- this.target = isDir ? path_1.default.join(output, 'config.json') : output;
212
- const { sequence: argsSequence } = runArgs;
213
- this.debug(`Sequence location is: ${argsSequence}`);
214
- const { name } = runFlags;
215
- const assembly = await this.getAssembly();
216
- if (runFlags.alias?.length) {
217
- this.debug(`Adding assembly aliases: ${runFlags.alias}`);
218
- assembly.aliases = runFlags.alias;
219
- }
220
- if (runFlags.refNameColors) {
221
- const colors = runFlags.refNameColors
222
- .split(',')
223
- .map(color => color.trim());
224
- this.debug(`Adding refName colors: ${colors}`);
225
- assembly.refNameColors = colors;
226
- }
227
- if (runFlags.refNameAliases) {
228
- if (runFlags.refNameAliasesType &&
229
- runFlags.refNameAliasesType === 'custom') {
230
- const refNameAliasesConfig = await this.readInlineOrFileJson(runFlags.refNameAliases);
231
- if (!refNameAliasesConfig.type) {
232
- this.error(`No "type" specified in refNameAliases adapter "${JSON.stringify(refNameAliasesConfig)}"`, { exit: 150 });
233
- }
234
- this.debug(`Adding custom refNameAliases config: ${JSON.stringify(refNameAliasesConfig)}`);
235
- assembly.refNameAliases = {
236
- adapter: refNameAliasesConfig,
237
- };
238
- }
239
- else {
240
- const refNameAliasesLocation = await this.resolveFileLocation(runFlags.refNameAliases, !(runFlags.skipCheck || runFlags.force), runFlags.load === 'inPlace');
241
- this.debug(`refName aliases file location resolved to: ${refNameAliasesLocation}`);
242
- assembly.refNameAliases = {
243
- adapter: {
244
- type: 'RefNameAliasAdapter',
245
- location: {
246
- uri: refNameAliasesLocation,
247
- locationType: 'UriLocation',
248
- },
249
- },
250
- };
251
- }
252
- }
253
- if (runFlags.displayName) {
254
- assembly.displayName = runFlags.displayName;
255
- }
256
- const defaultConfig = {
257
- assemblies: [],
258
- configuration: {},
259
- connections: [],
260
- defaultSession: {
261
- name: 'New Session',
262
- },
263
- tracks: [],
264
- };
265
- let configContents;
266
- if (fs_1.default.existsSync(this.target)) {
267
- this.debug(`Found existing config file ${this.target}`);
268
- configContents = {
269
- ...defaultConfig,
270
- ...(await this.readJsonFile(this.target)),
271
- };
272
- }
273
- else {
274
- this.debug(`Creating config file ${this.target}`);
275
- configContents = { ...defaultConfig };
276
- }
277
- if (!configContents.assemblies) {
278
- configContents.assemblies = [];
279
- }
280
- const idx = configContents.assemblies.findIndex(configAssembly => configAssembly.name === assembly.name);
281
- if (idx !== -1) {
282
- this.debug(`Found existing assembly ${name} in configuration`);
283
- if (runFlags.overwrite || runFlags.force) {
284
- this.debug(`Overwriting assembly ${name} in configuration`);
285
- configContents.assemblies[idx] = assembly;
286
- }
287
- else {
288
- this.error(`Cannot add assembly with name ${assembly.name}, an assembly with that name already exists`, { exit: 160 });
289
- }
290
- }
291
- else {
292
- configContents.assemblies.push(assembly);
293
- }
294
- this.debug(`Writing configuration to file ${this.target}`);
295
- await this.writeJsonFile(this.target, configContents);
296
- this.log(`${idx !== -1 ? 'Overwrote' : 'Added'} assembly "${assembly.name}" ${idx !== -1 ? 'in' : 'to'} ${this.target}`);
297
- }
298
- guessSequenceType(sequence) {
299
- if (sequence.endsWith('.fa') ||
300
- sequence.endsWith('.fna') ||
301
- sequence.endsWith('.fasta')) {
302
- return 'indexedFasta';
303
- }
304
- if (sequence.endsWith('.fa.gz') ||
305
- sequence.endsWith('.fna.gz') ||
306
- sequence.endsWith('.fasta.gz')) {
307
- return 'bgzipFasta';
308
- }
309
- if (sequence.endsWith('.2bit')) {
310
- return 'twoBit';
311
- }
312
- if (sequence.endsWith('.chrom.sizes')) {
313
- return 'chromSizes';
314
- }
315
- if (sequence.endsWith('.json')) {
316
- return 'custom';
317
- }
318
- if (isValidJSON(sequence)) {
319
- return 'custom';
320
- }
321
- return this.error('Could not determine sequence type automatically, add --type to specify it', { exit: 170 });
322
- }
323
- needLoadData(location) {
324
- let locationUrl;
325
- try {
326
- locationUrl = new URL(location);
327
- }
328
- catch (error) {
329
- // ignore
330
- }
331
- if (locationUrl) {
332
- return false;
333
- }
334
- return true;
335
- }
336
- async loadData(load, filePaths) {
337
- let locationUrl;
338
- const destination = this.target;
339
- try {
340
- locationUrl = new URL(filePaths[0]);
341
- }
342
- catch (error) {
343
- // ignore
344
- }
345
- if (locationUrl) {
346
- return false;
347
- }
348
- switch (load) {
349
- case 'copy': {
350
- await Promise.all(filePaths.map(async (filePath) => {
351
- if (!filePath) {
352
- return undefined;
353
- }
354
- return copyFile(filePath, path_1.default.join(path_1.default.dirname(destination), path_1.default.basename(filePath)));
355
- }));
356
- return true;
357
- }
358
- case 'symlink': {
359
- await Promise.all(filePaths.map(async (filePath) => {
360
- if (!filePath) {
361
- return undefined;
362
- }
363
- return symlink(path_1.default.resolve(filePath), path_1.default.join(path_1.default.dirname(destination), path_1.default.basename(filePath)));
364
- }));
365
- return true;
366
- }
367
- case 'move': {
368
- await Promise.all(filePaths.map(async (filePath) => {
369
- if (!filePath) {
370
- return undefined;
371
- }
372
- return rename(filePath, path_1.default.join(path_1.default.dirname(destination), path_1.default.basename(filePath)));
373
- }));
374
- return true;
375
- }
376
- case 'inPlace': {
377
- return false;
378
- }
379
- }
380
- return false;
381
- }
382
- }
383
- AddAssembly.description = 'Add an assembly to a JBrowse 2 configuration';
384
- AddAssembly.examples = [
385
- '# add assembly to installation in current directory. assumes .fai file also exists, and copies GRCh38.fa and GRCh38.fa.fai to current directory',
386
- '$ jbrowse add-assembly GRCh38.fa --load copy',
387
- '',
388
- '# add assembly to a specific jb2 installation path using --out, and copies the .fa and .fa.fai file to /path/to/jb2',
389
- '$ jbrowse add-assembly GRCh38.fa --out /path/to/jb2/ --load copy',
390
- '',
391
- '# force indexedFasta for add-assembly without relying on file extension',
392
- '$ jbrowse add-assembly GRCh38.xyz --type indexedFasta --load copy',
393
- '',
394
- '# add displayName for an assembly',
395
- '$ jbrowse add-assembly myFile.fa.gz --name hg38 --displayName "Homo sapiens (hg38)"',
396
- '',
397
- '# use chrom.sizes file for assembly instead of a fasta file',
398
- '$ jbrowse add-assembly GRCh38.chrom.sizes --load inPlace',
399
- '',
400
- '# add assembly from preconfigured json file, expert option',
401
- '$ jbrowse add-assembly GRCh38.config.json --load copy',
402
- '',
403
- '# add assembly from a 2bit file, also note pointing direct to a URL so no --load flag needed',
404
- '$ jbrowse add-assembly https://example.com/data/sample.2bit',
405
- '',
406
- '# add a bgzip indexed fasta inferred by fa.gz extension. assumes .fa.gz.gzi and .fa.gz.fai files also exists',
407
- '$ jbrowse add-assembly myfile.fa.gz --load copy',
408
- ];
409
- AddAssembly.args = {
410
- sequence: core_1.Args.string({
411
- required: true,
412
- description: `sequence file or URL
413
-
414
- If TYPE is indexedFasta or bgzipFasta, the index file defaults to <location>.fai
415
- and can be optionally specified with --faiLocation
416
- If TYPE is bgzipFasta, the gzip index file defaults to <location>.gzi and can be
417
- optionally specified with --gziLocation`,
418
- }),
419
- };
420
- AddAssembly.flags = {
421
- type: core_1.Flags.string({
422
- char: 't',
423
- description: `type of sequence, by default inferred from sequence file
424
-
425
- indexedFasta An index FASTA (e.g. .fa or .fasta) file;
426
- can optionally specify --faiLocation
427
-
428
- bgzipFasta A block-gzipped and indexed FASTA (e.g. .fa.gz or .fasta.gz) file;
429
- can optionally specify --faiLocation and/or --gziLocation
430
-
431
- twoBit A twoBit (e.g. .2bit) file
432
-
433
- chromSizes A chromosome sizes (e.g. .chrom.sizes) file
434
-
435
- custom Either a JSON file location or inline JSON that defines a custom
436
- sequence adapter; must provide --name if using inline JSON`,
437
- options: ['indexedFasta', 'bgzipFasta', 'twoBit', 'chromSizes', 'custom'],
438
- }),
439
- name: core_1.Flags.string({
440
- char: 'n',
441
- description: 'Name of the assembly; if not specified, will be guessed using the sequence file name',
442
- }),
443
- alias: core_1.Flags.string({
444
- char: 'a',
445
- description: 'An alias for the assembly name (e.g. "hg38" if the name of the assembly is "GRCh38");\ncan be specified multiple times',
446
- multiple: true,
447
- }),
448
- displayName: core_1.Flags.string({
449
- description: 'The display name to specify for the assembly, e.g. "Homo sapiens (hg38)" while the name can be a shorter identifier like "hg38"',
450
- }),
451
- faiLocation: core_1.Flags.string({
452
- description: '[default: <fastaLocation>.fai] FASTA index file or URL',
453
- }),
454
- gziLocation: core_1.Flags.string({
455
- description: '[default: <fastaLocation>.gzi] FASTA gzip index file or URL',
456
- }),
457
- refNameAliases: core_1.Flags.string({
458
- description: 'Reference sequence name aliases file or URL; assumed to be a tab-separated aliases\nfile unless --refNameAliasesType is specified',
459
- }),
460
- refNameAliasesType: core_1.Flags.string({
461
- 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',
462
- options: ['aliases', 'custom'],
463
- dependsOn: ['refNameAliases'],
464
- }),
465
- refNameColors: core_1.Flags.string({
466
- description: 'A comma-separated list of color strings for the reference sequence names; will cycle\nthrough colors if there are fewer colors than sequences',
467
- }),
468
- target: core_1.Flags.string({
469
- description: 'path to config file in JB2 installation directory to write out to.\nCreates ./config.json if nonexistent',
470
- }),
471
- out: core_1.Flags.string({
472
- description: 'synonym for target',
473
- }),
474
- help: core_1.Flags.help({ char: 'h' }),
475
- load: core_1.Flags.string({
476
- char: 'l',
477
- 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',
478
- options: ['copy', 'symlink', 'move', 'inPlace'],
479
- }),
480
- skipCheck: core_1.Flags.boolean({
481
- description: "Don't check whether or not the sequence file or URL exists or if you are in a JBrowse directory",
482
- }),
483
- overwrite: core_1.Flags.boolean({
484
- description: 'Overwrite existing assembly if one with the same name exists',
485
- }),
486
- force: core_1.Flags.boolean({
487
- char: 'f',
488
- description: 'Equivalent to `--skipCheck --overwrite`',
489
- }),
490
- };
491
- exports.default = AddAssembly;