@apollo-annotation/cli 0.1.19 → 0.1.20

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 (52) hide show
  1. package/README.md +283 -106
  2. package/dist/baseCommand.d.ts +1 -1
  3. package/dist/baseCommand.js +3 -4
  4. package/dist/commands/assembly/add-from-fasta.d.ts +23 -0
  5. package/dist/commands/assembly/add-from-fasta.js +165 -0
  6. package/dist/commands/assembly/{add-gff.d.ts → add-from-gff.d.ts} +5 -3
  7. package/dist/commands/assembly/{add-gff.js → add-from-gff.js} +20 -21
  8. package/dist/commands/assembly/check.js +9 -9
  9. package/dist/commands/assembly/delete.js +4 -4
  10. package/dist/commands/assembly/get.js +4 -4
  11. package/dist/commands/assembly/sequence.js +4 -4
  12. package/dist/commands/change/get.js +7 -7
  13. package/dist/commands/config.js +3 -4
  14. package/dist/commands/feature/add-child.js +6 -5
  15. package/dist/commands/feature/check.js +6 -6
  16. package/dist/commands/feature/copy.js +5 -4
  17. package/dist/commands/feature/delete.js +4 -4
  18. package/dist/commands/feature/edit-attribute.js +6 -5
  19. package/dist/commands/feature/edit-coords.js +5 -5
  20. package/dist/commands/feature/edit-type.js +5 -5
  21. package/dist/commands/feature/edit.js +5 -5
  22. package/dist/commands/feature/get-id.js +5 -5
  23. package/dist/commands/feature/get.js +3 -3
  24. package/dist/commands/feature/import.d.ts +2 -2
  25. package/dist/commands/feature/import.js +6 -6
  26. package/dist/commands/feature/search.js +6 -6
  27. package/dist/commands/file/delete.d.ts +13 -0
  28. package/dist/commands/file/delete.js +58 -0
  29. package/dist/commands/file/download.d.ts +14 -0
  30. package/dist/commands/file/download.js +45 -0
  31. package/dist/commands/file/get.d.ts +13 -0
  32. package/dist/commands/file/get.js +38 -0
  33. package/dist/commands/file/upload.d.ts +16 -0
  34. package/dist/commands/file/upload.js +88 -0
  35. package/dist/commands/jbrowse/get-config.d.ts +10 -0
  36. package/dist/commands/jbrowse/get-config.js +21 -0
  37. package/dist/commands/jbrowse/set-config.d.ts +13 -0
  38. package/dist/commands/jbrowse/set-config.js +51 -0
  39. package/dist/commands/login.js +11 -15
  40. package/dist/commands/logout.js +2 -2
  41. package/dist/commands/refseq/add-alias.js +3 -3
  42. package/dist/commands/refseq/get.js +8 -8
  43. package/dist/commands/status.js +4 -3
  44. package/dist/commands/user/get.js +3 -3
  45. package/dist/fileCommand.d.ts +5 -0
  46. package/dist/fileCommand.js +76 -0
  47. package/dist/utils.d.ts +20 -9
  48. package/dist/utils.js +25 -103
  49. package/oclif.manifest.json +445 -69
  50. package/package.json +50 -43
  51. package/dist/commands/assembly/add-fasta.d.ts +0 -15
  52. package/dist/commands/assembly/add-fasta.js +0 -87
@@ -1,11 +1,12 @@
1
1
  import { Flags } from '@oclif/core';
2
2
  import { fetch } from 'undici';
3
3
  import { BaseCommand } from '../../baseCommand.js';
4
- import { createFetchErrorMessage, getAssemblyFromRefseq, getFeatureById, idReader, localhostToAddress, wrapLines, } from '../../utils.js';
4
+ import { createFetchErrorMessage, getAssemblyFromRefseq, getFeatureById, idReader, localhostToAddress, } from '../../utils.js';
5
5
  export default class EditAttibute extends BaseCommand {
6
6
  static summary = 'Add, edit, or view a feature attribute';
7
- static description = wrapLines('Be aware that there is no checking whether attributes names and values are valid. \
8
- For example, you can create non-unique ID attributes or you can set gene ontology terms to non-existing terms');
7
+ static description = 'Be aware that there is no checking whether attributes names and values are valid. \
8
+ For example, you can create non-unique ID attributes or you can set gene ontology \
9
+ terms to non-existing terms';
9
10
  static examples = [
10
11
  {
11
12
  description: 'Add attribute "domains" with a list of values:',
@@ -46,12 +47,12 @@ export default class EditAttibute extends BaseCommand {
46
47
  if (flags.delete && flags.value) {
47
48
  this.error('Error: Options --delete and --value are mutually exclusive');
48
49
  }
49
- const ff = idReader([flags['feature-id']]);
50
+ const ff = await idReader([flags['feature-id']]);
50
51
  if (ff.length !== 1) {
51
52
  this.error(`Expected only one feature identifier. Got ${ff.length}`);
52
53
  }
53
54
  const [featureId] = ff;
54
- const access = await this.getAccess(flags['config-file'], flags.profile);
55
+ const access = await this.getAccess();
55
56
  const response = await getFeatureById(access.address, access.accessToken, featureId);
56
57
  if (!response.ok) {
57
58
  const errorMessage = await createFetchErrorMessage(response, 'getFeatureById failed');
@@ -1,11 +1,11 @@
1
1
  import { Flags } from '@oclif/core';
2
2
  import { fetch } from 'undici';
3
3
  import { BaseCommand } from '../../baseCommand.js';
4
- import { createFetchErrorMessage, getAssemblyFromRefseq, getFeatureById, idReader, localhostToAddress, wrapLines, } from '../../utils.js';
4
+ import { createFetchErrorMessage, getAssemblyFromRefseq, getFeatureById, idReader, localhostToAddress, } from '../../utils.js';
5
5
  export default class Get extends BaseCommand {
6
6
  static summary = 'Edit feature start and/or end coordinates';
7
- static description = wrapLines("If editing a child feature that new coordinates must be within the parent's coordinates.\
8
- To get the identifier of the feature to edit consider using `apollo feature get` or `apollo feature search`");
7
+ static description = "If editing a child feature that new coordinates must be within the parent's coordinates.\
8
+ To get the identifier of the feature to edit consider using `apollo feature get` or `apollo feature search`";
9
9
  static examples = [
10
10
  {
11
11
  description: 'Edit start and end:',
@@ -47,12 +47,12 @@ export default class Get extends BaseCommand {
47
47
  if (flags.start !== undefined) {
48
48
  flags.start -= 1;
49
49
  }
50
- const ff = idReader([flags['feature-id']]);
50
+ const ff = await idReader([flags['feature-id']]);
51
51
  if (ff.length !== 1) {
52
52
  this.error(`Expected only one feature identifier. Got ${ff.length}`);
53
53
  }
54
54
  const [featureId] = ff;
55
- const access = await this.getAccess(flags['config-file'], flags.profile);
55
+ const access = await this.getAccess();
56
56
  const res = await getFeatureById(access.address, access.accessToken, featureId);
57
57
  if (!res.ok) {
58
58
  const errorMessage = await createFetchErrorMessage(res, 'getFeatureById failed');
@@ -1,11 +1,11 @@
1
1
  import { Flags } from '@oclif/core';
2
2
  import { fetch } from 'undici';
3
3
  import { BaseCommand } from '../../baseCommand.js';
4
- import { createFetchErrorMessage, getAssemblyFromRefseq, getFeatureById, idReader, localhostToAddress, wrapLines, } from '../../utils.js';
4
+ import { createFetchErrorMessage, getAssemblyFromRefseq, getFeatureById, idReader, localhostToAddress, } from '../../utils.js';
5
5
  export default class Get extends BaseCommand {
6
6
  static summary = 'Edit or view feature type';
7
- static description = wrapLines('Feature type is column 3 in gff format.\
8
- It must be a valid sequence ontology term although but the valifdity of the new term is not checked.');
7
+ static description = 'Feature type is column 3 in gff format.\
8
+ It must be a valid sequence ontology term although but the valifdity of the new term is not checked.';
9
9
  static flags = {
10
10
  'feature-id': Flags.string({
11
11
  char: 'i',
@@ -19,12 +19,12 @@ export default class Get extends BaseCommand {
19
19
  };
20
20
  async run() {
21
21
  const { flags } = await this.parse(Get);
22
- const ff = idReader([flags['feature-id']]);
22
+ const ff = await idReader([flags['feature-id']]);
23
23
  if (ff.length !== 1) {
24
24
  this.error(`Expected only one feature identifier. Got ${ff.length}`);
25
25
  }
26
26
  const [featureId] = ff;
27
- const access = await this.getAccess(flags['config-file'], flags.profile);
27
+ const access = await this.getAccess();
28
28
  const response = await getFeatureById(access.address, access.accessToken, featureId);
29
29
  if (!response.ok) {
30
30
  const errorMessage = await createFetchErrorMessage(response, 'getFeatureById failed');
@@ -3,10 +3,10 @@ import * as fs from 'node:fs';
3
3
  import { Flags } from '@oclif/core';
4
4
  import { fetch } from 'undici';
5
5
  import { BaseCommand } from '../../baseCommand.js';
6
- import { createFetchErrorMessage, localhostToAddress, wrapLines, } from '../../utils.js';
6
+ import { createFetchErrorMessage, localhostToAddress, readStdin, } from '../../utils.js';
7
7
  export default class Get extends BaseCommand {
8
8
  static summary = 'Edit features using an appropiate json input';
9
- static description = wrapLines(`Edit a feature by submitting a json input with all the required attributes for Apollo to process it. This is a very low level command which most users probably do not need.
9
+ static description = `Edit a feature by submitting a json input with all the required attributes for Apollo to process it. This is a very low level command which most users probably do not need.
10
10
 
11
11
  Input may be a json string or a json file and it may be an array of changes. This is an example input for editing feature type:
12
12
 
@@ -19,7 +19,7 @@ export default class Get extends BaseCommand {
19
19
  "featureId": "6613f7d22c957525d631b1cc",
20
20
  "oldType": "BAC",
21
21
  "newType": "G_quartet"
22
- }`);
22
+ }`;
23
23
  static examples = [
24
24
  {
25
25
  description: 'Editing by passing a json to stdin:',
@@ -37,7 +37,7 @@ export default class Get extends BaseCommand {
37
37
  const { flags } = await this.parse(Get);
38
38
  let jsonStr = flags['json-input'];
39
39
  if (flags['json-input'] === '-') {
40
- jsonStr = fs.readFileSync(process.stdin.fd).toString();
40
+ jsonStr = await readStdin();
41
41
  }
42
42
  else if (fs.existsSync(flags['json-input'])) {
43
43
  jsonStr = fs.readFileSync(flags['json-input']).toString();
@@ -46,7 +46,7 @@ export default class Get extends BaseCommand {
46
46
  if (!Array.isArray(json)) {
47
47
  json = [json];
48
48
  }
49
- const access = await this.getAccess(flags['config-file'], flags.profile);
49
+ const access = await this.getAccess();
50
50
  for (const change of json) {
51
51
  const str = JSON.stringify(change);
52
52
  const url = new URL(localhostToAddress(`${access.address}/changes`));
@@ -1,10 +1,10 @@
1
1
  import { Flags } from '@oclif/core';
2
2
  import { fetch } from 'undici';
3
3
  import { BaseCommand } from '../../baseCommand.js';
4
- import { createFetchErrorMessage, idReader, localhostToAddress, wrapLines, } from '../../utils.js';
4
+ import { createFetchErrorMessage, idReader, localhostToAddress, } from '../../utils.js';
5
5
  export default class Get extends BaseCommand {
6
6
  static summary = 'Get features given their identifiers';
7
- static description = wrapLines('Invalid identifiers or identifiers not found in the database will be silently ignored');
7
+ static description = 'Invalid identifiers or identifiers not found in the database will be silently ignored';
8
8
  static examples = [
9
9
  {
10
10
  description: 'Get features for these identifiers:',
@@ -14,15 +14,15 @@ export default class Get extends BaseCommand {
14
14
  static flags = {
15
15
  'feature-id': Flags.string({
16
16
  char: 'i',
17
- description: wrapLines('Retrieves feature with these IDs. Use "-" to read IDs from stdin (one per line)', 40),
17
+ description: 'Retrieves feature with these IDs. Use "-" to read IDs from stdin (one per line)',
18
18
  multiple: true,
19
19
  default: ['-'],
20
20
  }),
21
21
  };
22
22
  async run() {
23
23
  const { flags } = await this.parse(Get);
24
- const access = await this.getAccess(flags['config-file'], flags.profile);
25
- let ids = idReader(flags['feature-id']);
24
+ const access = await this.getAccess();
25
+ let ids = await idReader(flags['feature-id']);
26
26
  ids = [...new Set(ids)];
27
27
  const results = [];
28
28
  for (const id of ids) {
@@ -1,7 +1,7 @@
1
1
  import { Flags } from '@oclif/core';
2
2
  import { fetch } from 'undici';
3
3
  import { BaseCommand } from '../../baseCommand.js';
4
- import { createFetchErrorMessage, getRefseqId, localhostToAddress, wrapLines, } from '../../utils.js';
4
+ import { createFetchErrorMessage, getRefseqId, localhostToAddress, } from '../../utils.js';
5
5
  export default class Get extends BaseCommand {
6
6
  static description = 'Get features in assembly, reference sequence or genomic window';
7
7
  static examples = [
@@ -10,7 +10,7 @@ export default class Get extends BaseCommand {
10
10
  command: '<%= config.bin %> <%= command.id %> -a myAssembly',
11
11
  },
12
12
  {
13
- description: wrapLines('Get features intersecting chr1:1..1000. You can omit the assembly name if there are no other reference sequences named chr1:'),
13
+ description: 'Get features intersecting chr1:1..1000. You can omit the assembly name if there are no other reference sequences named chr1:',
14
14
  command: '<%= config.bin %> <%= command.id %> -a myAssembly -r chr1 -s 1 -e 1000',
15
15
  },
16
16
  ];
@@ -39,7 +39,7 @@ export default class Get extends BaseCommand {
39
39
  if (flags.start <= 0 || endCoord <= 0) {
40
40
  this.error('Start and end coordinates must be greater than 0.');
41
41
  }
42
- const access = await this.getAccess(flags['config-file'], flags.profile);
42
+ const access = await this.getAccess();
43
43
  const refseqIds = await getRefseqId(access.address, access.accessToken, flags.refseq, flags.assembly);
44
44
  const results = [];
45
45
  for (const refseq of refseqIds) {
@@ -1,5 +1,5 @@
1
- import { BaseCommand } from '../../baseCommand.js';
2
- export default class Import extends BaseCommand<typeof Import> {
1
+ import { FileCommand } from '../../fileCommand.js';
2
+ export default class Import extends FileCommand {
3
3
  static summary: string;
4
4
  static description: string;
5
5
  static examples: {
@@ -1,9 +1,9 @@
1
1
  import * as fs from 'node:fs';
2
2
  import { Flags } from '@oclif/core';
3
3
  import { Agent, fetch } from 'undici';
4
- import { BaseCommand } from '../../baseCommand.js';
5
- import { convertAssemblyNameToId, createFetchErrorMessage, localhostToAddress, uploadFile, } from '../../utils.js';
6
- export default class Import extends BaseCommand {
4
+ import { FileCommand } from '../../fileCommand.js';
5
+ import { convertAssemblyNameToId, createFetchErrorMessage, localhostToAddress, } from '../../utils.js';
6
+ export default class Import extends FileCommand {
7
7
  static summary = 'Import features from local gff file';
8
8
  static description = 'By default, features are added to the existing ones.';
9
9
  static examples = [
@@ -15,7 +15,7 @@ export default class Import extends BaseCommand {
15
15
  static flags = {
16
16
  'input-file': Flags.string({
17
17
  char: 'i',
18
- description: 'Input gff or gtf file',
18
+ description: 'Input gff file',
19
19
  required: true,
20
20
  }),
21
21
  assembly: Flags.string({
@@ -33,12 +33,12 @@ export default class Import extends BaseCommand {
33
33
  if (!fs.existsSync(flags['input-file'])) {
34
34
  this.error(`File "${flags['input-file']}" does not exist`);
35
35
  }
36
- const access = await this.getAccess(flags['config-file'], flags.profile);
36
+ const access = await this.getAccess();
37
37
  const assembly = await convertAssemblyNameToId(access.address, access.accessToken, [flags.assembly]);
38
38
  if (assembly.length === 0) {
39
39
  this.error(`Assembly "${flags.assembly}" does not exist. Perhaps you want to create this assembly first`);
40
40
  }
41
- const uploadId = await uploadFile(access.address, access.accessToken, flags['input-file'], 'text/x-gff3');
41
+ const uploadId = await this.uploadFile(access.address, access.accessToken, flags['input-file'], 'text/x-gff3', false);
42
42
  const body = {
43
43
  typeName: 'AddFeaturesFromFileChange',
44
44
  assembly: assembly[0],
@@ -2,7 +2,7 @@
2
2
  import { Flags } from '@oclif/core';
3
3
  import { fetch } from 'undici';
4
4
  import { BaseCommand } from '../../baseCommand.js';
5
- import { convertAssemblyNameToId, createFetchErrorMessage, idReader, localhostToAddress, queryApollo, wrapLines, } from '../../utils.js';
5
+ import { convertAssemblyNameToId, createFetchErrorMessage, idReader, localhostToAddress, queryApollo, } from '../../utils.js';
6
6
  async function searchFeatures(address, accessToken, assemblies, term) {
7
7
  const url = new URL(localhostToAddress(`${address}/features/searchFeatures`));
8
8
  const searchParams = new URLSearchParams({
@@ -25,7 +25,7 @@ async function searchFeatures(address, accessToken, assemblies, term) {
25
25
  }
26
26
  export default class Search extends BaseCommand {
27
27
  static summary = 'Free text search for feature in one or more assemblies';
28
- static description = wrapLines(`Return features matching a query string. This command searches only in:
28
+ static description = `Return features matching a query string. This command searches only in:
29
29
 
30
30
  - Attribute *values* (not attribute names)
31
31
  - Source field (which in fact is stored as an attribute)
@@ -47,7 +47,7 @@ export default class Search extends BaseCommand {
47
47
  - "with"
48
48
  - "Finger"
49
49
  - "chr1"
50
- - "0.987"`);
50
+ - "0.987"`;
51
51
  static examples = [
52
52
  {
53
53
  description: 'Search "bac" in these assemblies:',
@@ -63,12 +63,12 @@ export default class Search extends BaseCommand {
63
63
  assembly: Flags.string({
64
64
  char: 'a',
65
65
  multiple: true,
66
- description: wrapLines('Assembly names or IDs to search; use "-" to read it from stdin. If omitted search all assemblies'),
66
+ description: 'Assembly names or IDs to search; use "-" to read it from stdin. If omitted search all assemblies',
67
67
  }),
68
68
  };
69
69
  async run() {
70
70
  const { flags } = await this.parse(Search);
71
- const access = await this.getAccess(flags['config-file'], flags.profile);
71
+ const access = await this.getAccess();
72
72
  let assemblyIds = [];
73
73
  if (flags.assembly === undefined) {
74
74
  const asm = await queryApollo(access.address, access.accessToken, 'assemblies');
@@ -77,7 +77,7 @@ export default class Search extends BaseCommand {
77
77
  }
78
78
  }
79
79
  else {
80
- const assembly = idReader(flags.assembly);
80
+ const assembly = await idReader(flags.assembly);
81
81
  assemblyIds = await convertAssemblyNameToId(access.address, access.accessToken, assembly);
82
82
  }
83
83
  if (assemblyIds.length === 0) {
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from '../../baseCommand.js';
2
+ export default class Delete extends BaseCommand<typeof Delete> {
3
+ static summary: string;
4
+ static description: string;
5
+ static examples: {
6
+ description: string;
7
+ command: string;
8
+ }[];
9
+ static flags: {
10
+ 'file-id': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string[], import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
11
+ };
12
+ run(): Promise<void>;
13
+ }
@@ -0,0 +1,58 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { fetch } from 'undici';
3
+ import { BaseCommand } from '../../baseCommand.js';
4
+ import { createFetchErrorMessage, filterJsonList, idReader, localhostToAddress, queryApollo, } from '../../utils.js';
5
+ export default class Delete extends BaseCommand {
6
+ static summary = 'Delete files from the Apollo server';
7
+ static description = 'Deleted files are printed to stdout. See also `apollo file get` to list the files on the server';
8
+ static examples = [
9
+ {
10
+ description: 'Delete file multiple files:',
11
+ command: '<%= config.bin %> <%= command.id %> -i 123...abc xyz...789',
12
+ },
13
+ ];
14
+ static flags = {
15
+ 'file-id': Flags.string({
16
+ char: 'i',
17
+ description: 'IDs of the files to delete',
18
+ default: ['-'],
19
+ multiple: true,
20
+ }),
21
+ };
22
+ async run() {
23
+ const { flags } = await this.parse(Delete);
24
+ const access = await this.getAccess();
25
+ const files = await queryApollo(access.address, access.accessToken, 'files');
26
+ const json = (await files.json());
27
+ const ff = await idReader(flags['file-id']);
28
+ let deleted = [];
29
+ for (const id of ff) {
30
+ const res = await deleteFile(access.address, access.accessToken, id);
31
+ if (res.status === 404) {
32
+ this.logToStderr(`File id "${id}" not found`);
33
+ }
34
+ else {
35
+ const fid = filterJsonList(json, [id], '_id');
36
+ deleted = [...deleted, ...fid];
37
+ }
38
+ }
39
+ this.log(JSON.stringify(deleted, null, 2));
40
+ this.logToStderr(`${deleted.length.toString()} file(s) deleted.`);
41
+ }
42
+ }
43
+ async function deleteFile(address, accessToken, fileId) {
44
+ const auth = {
45
+ method: 'DELETE',
46
+ headers: {
47
+ Authorization: `Bearer ${accessToken}`,
48
+ 'Content-Type': 'application/json',
49
+ },
50
+ };
51
+ const url = new URL(localhostToAddress(`${address}/files/${fileId}`));
52
+ const response = await fetch(url, auth);
53
+ if (!response.ok && response.status != 404) {
54
+ const errorMessage = await createFetchErrorMessage(response, 'deleteFile failed');
55
+ throw new Error(errorMessage);
56
+ }
57
+ return response;
58
+ }
@@ -0,0 +1,14 @@
1
+ import { BaseCommand } from '../../baseCommand.js';
2
+ export default class Download extends BaseCommand<typeof Download> {
3
+ static summary: string;
4
+ static description: string;
5
+ static examples: {
6
+ description: string;
7
+ command: string;
8
+ }[];
9
+ static flags: {
10
+ 'file-id': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
11
+ output: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
12
+ };
13
+ run(): Promise<void>;
14
+ }
@@ -0,0 +1,45 @@
1
+ import { createWriteStream } from 'node:fs';
2
+ import { Writable } from 'node:stream';
3
+ import { Flags } from '@oclif/core';
4
+ import { BaseCommand } from '../../baseCommand.js';
5
+ import { filterJsonList, idReader, queryApollo } from '../../utils.js';
6
+ export default class Download extends BaseCommand {
7
+ static summary = 'Download a file from the Apollo server';
8
+ static description = 'See also `apollo file get` to list the files on the server';
9
+ static examples = [
10
+ {
11
+ description: 'Download file with id xyz',
12
+ command: '<%= config.bin %> <%= command.id %> -i xyz -o genome.fa',
13
+ },
14
+ ];
15
+ static flags = {
16
+ 'file-id': Flags.string({
17
+ char: 'i',
18
+ description: 'ID of the file to download',
19
+ default: '-',
20
+ }),
21
+ output: Flags.string({
22
+ char: 'o',
23
+ description: 'Write output to this file or "-" for stdout. Default to the name of the uploaded file.',
24
+ }),
25
+ };
26
+ async run() {
27
+ const { flags } = await this.parse(Download);
28
+ const access = await this.getAccess();
29
+ const ff = await idReader([flags['file-id']]);
30
+ let res = await queryApollo(access.address, access.accessToken, 'files');
31
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
32
+ const json = JSON.parse(await res.text());
33
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
34
+ const [fileRec] = filterJsonList(json, ff, '_id');
35
+ const fileId = fileRec['_id'];
36
+ res = await queryApollo(access.address, access.accessToken, `files/${fileId}`);
37
+ let { output } = flags;
38
+ if (output === undefined) {
39
+ output = fileRec['basename'];
40
+ }
41
+ const fileWriteStream = createWriteStream(output);
42
+ await res.body?.pipeTo(Writable.toWeb(output === '-' ? process.stdout : fileWriteStream));
43
+ fileWriteStream.close();
44
+ }
45
+ }
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from '../../baseCommand.js';
2
+ export default class Get extends BaseCommand<typeof Get> {
3
+ static summary: string;
4
+ static description: string;
5
+ static examples: {
6
+ description: string;
7
+ command: string;
8
+ }[];
9
+ static flags: {
10
+ 'file-id': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
11
+ };
12
+ run(): Promise<void>;
13
+ }
@@ -0,0 +1,38 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { BaseCommand } from '../../baseCommand.js';
3
+ import { idReader, queryApollo } from '../../utils.js';
4
+ export default class Get extends BaseCommand {
5
+ static summary = 'Get list of files uploaded to the Apollo server';
6
+ static description = 'Print to stdout the list of files in json format';
7
+ static examples = [
8
+ {
9
+ description: 'Get files by id:',
10
+ command: '<%= config.bin %> <%= command.id %> -i xyz abc',
11
+ },
12
+ ];
13
+ static flags = {
14
+ 'file-id': Flags.string({
15
+ char: 'i',
16
+ description: 'Get files matching this IDs',
17
+ multiple: true,
18
+ }),
19
+ };
20
+ async run() {
21
+ const { flags } = await this.parse(Get);
22
+ const access = await this.getAccess();
23
+ const files = await queryApollo(access.address, access.accessToken, 'files');
24
+ const json = (await files.json());
25
+ let fileIds = [];
26
+ if (flags['file-id'] !== undefined) {
27
+ fileIds = await idReader(flags['file-id']);
28
+ }
29
+ const keep = [];
30
+ for (const x of json) {
31
+ if (flags['file-id'] === undefined ||
32
+ fileIds.includes(x['_id'])) {
33
+ keep.push(x);
34
+ }
35
+ }
36
+ this.log(JSON.stringify(keep, null, 2));
37
+ }
38
+ }
@@ -0,0 +1,16 @@
1
+ import { FileCommand } from '../../fileCommand.js';
2
+ export default class Upload extends FileCommand {
3
+ static summary: string;
4
+ static description: string;
5
+ static examples: {
6
+ description: string;
7
+ command: string;
8
+ }[];
9
+ static flags: {
10
+ 'input-file': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
11
+ type: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
12
+ gzip: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
13
+ decompressed: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
14
+ };
15
+ run(): Promise<void>;
16
+ }
@@ -0,0 +1,88 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { FileCommand } from '../../fileCommand.js';
3
+ import { filterJsonList, queryApollo } from '../../utils.js';
4
+ export default class Upload extends FileCommand {
5
+ static summary = 'Upload a local file to the Apollo server';
6
+ static description = `This command only uploads a file and returns the corresponding file id.
7
+ To add an assembly based on this file or to upload & add an assembly in a single pass \
8
+ see \`apollo assembly add-from-fasta\` and \`add-from-gff\``;
9
+ static examples = [
10
+ {
11
+ description: 'Upload local file, type auto-detected:',
12
+ command: '<%= config.bin %> <%= command.id %> -i genome.fa > file.json',
13
+ },
14
+ ];
15
+ static flags = {
16
+ 'input-file': Flags.string({
17
+ char: 'i',
18
+ description: 'Local file to upload',
19
+ required: true,
20
+ }),
21
+ type: Flags.string({
22
+ char: 't',
23
+ description: 'Set file type or autodetected it if not set.\n\
24
+ NB: There is no check for whether the file complies to this type',
25
+ options: [
26
+ 'text/x-fasta',
27
+ 'text/x-gff3',
28
+ 'application/x-bgzip-fasta',
29
+ 'text/x-fai',
30
+ 'application/x-gzi',
31
+ ],
32
+ }),
33
+ gzip: Flags.boolean({
34
+ char: 'z',
35
+ description: 'Override autodetection and instruct that input is gzip compressed',
36
+ exclusive: ['decompressed'],
37
+ }),
38
+ decompressed: Flags.boolean({
39
+ char: 'd',
40
+ description: 'Override autodetection and instruct that input is decompressed',
41
+ exclusive: ['gzip'],
42
+ }),
43
+ };
44
+ async run() {
45
+ const { flags } = await this.parse(Upload);
46
+ const access = await this.getAccess();
47
+ let { type } = flags;
48
+ if (type === undefined) {
49
+ const hasGzipExt = flags['input-file'].endsWith('.gz');
50
+ const infile = flags['input-file'].replace(/\.gz$/, '');
51
+ if (/\.fasta$|\.fas$|\.fa$|\.fna$/.test(infile) && hasGzipExt) {
52
+ this.error(`Unable to auto-detect file type for "${flags['input-file']}" since it may be gzip or bgzip compressed. Please set the -t/--type option`);
53
+ }
54
+ else if (/\.fasta$|\.fas$|\.fa$|\.fna$/.test(infile)) {
55
+ type = 'text/x-fasta';
56
+ }
57
+ else if (/\.gff$|\.gff3/.test(infile)) {
58
+ type = 'text/x-gff3';
59
+ }
60
+ else if (infile.endsWith('.fai')) {
61
+ type = 'text/x-fai';
62
+ }
63
+ else if (infile.endsWith('.gzi')) {
64
+ type = 'application/x-gzi';
65
+ }
66
+ else {
67
+ this.error(`Unable to auto-detect the type of file "${flags['input-file']}". Please set the --type/-t option.`);
68
+ }
69
+ }
70
+ let isGzip = flags['input-file'].endsWith('.gz');
71
+ // eslint-disable-next-line unicorn/consistent-destructuring
72
+ if (flags.gzip) {
73
+ isGzip = true;
74
+ }
75
+ // eslint-disable-next-line unicorn/consistent-destructuring
76
+ if (flags.decompressed) {
77
+ isGzip = false;
78
+ }
79
+ this.logToStderr(`Input is gzip'd: ${isGzip}`);
80
+ const fileId = await this.uploadFile(access.address, access.accessToken, flags['input-file'], type, isGzip);
81
+ const res = await queryApollo(access.address, access.accessToken, 'files');
82
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
83
+ const json = JSON.parse(await res.text());
84
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
85
+ const [rec] = filterJsonList(json, [fileId], '_id');
86
+ this.log(JSON.stringify(rec, null, 2));
87
+ }
88
+ }
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from '../../baseCommand.js';
2
+ export default class GetConfig extends BaseCommand<typeof GetConfig> {
3
+ static summary: string;
4
+ static description: string;
5
+ static examples: {
6
+ description: string;
7
+ command: string;
8
+ }[];
9
+ run(): Promise<void>;
10
+ }
@@ -0,0 +1,21 @@
1
+ import { BaseCommand } from '../../baseCommand.js';
2
+ import { queryApollo } from '../../utils.js';
3
+ export default class GetConfig extends BaseCommand {
4
+ static summary = 'Get JBrowse configuration from Apollo';
5
+ static description = 'Print to stdout the JBrowse configuration from Apollo in JSON format';
6
+ static examples = [
7
+ {
8
+ description: 'Get JBrowse configuration:',
9
+ command: '<%= config.bin %> <%= command.id %> > config.json',
10
+ },
11
+ ];
12
+ async run() {
13
+ const access = await this.getAccess();
14
+ const response = await queryApollo(access.address, access.accessToken, 'jbrowse/config.json');
15
+ if (!response.ok) {
16
+ throw new Error('Failed to fetch JBrowse configuration');
17
+ }
18
+ const json = (await response.json());
19
+ this.log(JSON.stringify(json, null, 2));
20
+ }
21
+ }
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from '../../baseCommand.js';
2
+ export default class SetConfig extends BaseCommand<typeof SetConfig> {
3
+ static summary: string;
4
+ static description: string;
5
+ static examples: {
6
+ description: string;
7
+ command: string;
8
+ }[];
9
+ static args: {
10
+ inputFile: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
11
+ };
12
+ run(): Promise<void>;
13
+ }