@apollo-annotation/cli 0.1.18 → 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 (59) hide show
  1. package/README.md +374 -135
  2. package/bin/dev.js +2 -2
  3. package/bin/run.js +2 -2
  4. package/dist/ApolloConf.js +1 -0
  5. package/dist/baseCommand.d.ts +1 -1
  6. package/dist/baseCommand.js +7 -7
  7. package/dist/commands/assembly/add-from-fasta.d.ts +23 -0
  8. package/dist/commands/assembly/add-from-fasta.js +165 -0
  9. package/dist/commands/assembly/{add-gff.d.ts → add-from-gff.d.ts} +5 -3
  10. package/dist/commands/assembly/{add-gff.js → add-from-gff.js} +20 -22
  11. package/dist/commands/assembly/check.js +9 -9
  12. package/dist/commands/assembly/delete.js +4 -4
  13. package/dist/commands/assembly/get.js +4 -4
  14. package/dist/commands/assembly/get.test.js +3 -3
  15. package/dist/commands/assembly/sequence.js +8 -14
  16. package/dist/commands/change/get.js +7 -7
  17. package/dist/commands/change/get.test.js +1 -1
  18. package/dist/commands/config.js +4 -5
  19. package/dist/commands/feature/add-child.js +18 -19
  20. package/dist/commands/feature/check.js +11 -11
  21. package/dist/commands/feature/copy.js +12 -14
  22. package/dist/commands/feature/delete.js +13 -19
  23. package/dist/commands/feature/edit-attribute.js +18 -11
  24. package/dist/commands/feature/edit-coords.js +36 -21
  25. package/dist/commands/feature/edit-type.js +7 -11
  26. package/dist/commands/feature/edit.js +5 -6
  27. package/dist/commands/feature/get-id.js +5 -6
  28. package/dist/commands/feature/get.js +3 -4
  29. package/dist/commands/feature/import.d.ts +2 -2
  30. package/dist/commands/feature/import.js +26 -39
  31. package/dist/commands/feature/search.js +7 -7
  32. package/dist/commands/file/delete.d.ts +13 -0
  33. package/dist/commands/file/delete.js +58 -0
  34. package/dist/commands/file/download.d.ts +14 -0
  35. package/dist/commands/file/download.js +45 -0
  36. package/dist/commands/file/get.d.ts +13 -0
  37. package/dist/commands/file/get.js +38 -0
  38. package/dist/commands/file/upload.d.ts +16 -0
  39. package/dist/commands/file/upload.js +88 -0
  40. package/dist/commands/jbrowse/get-config.d.ts +10 -0
  41. package/dist/commands/jbrowse/get-config.js +21 -0
  42. package/dist/commands/jbrowse/set-config.d.ts +13 -0
  43. package/dist/commands/jbrowse/set-config.js +51 -0
  44. package/dist/commands/login.js +12 -16
  45. package/dist/commands/logout.js +3 -3
  46. package/dist/commands/{assembly/add-fasta.d.ts → refseq/add-alias.d.ts} +3 -4
  47. package/dist/commands/refseq/add-alias.js +72 -0
  48. package/dist/commands/refseq/get.js +8 -8
  49. package/dist/commands/status.js +5 -4
  50. package/dist/commands/user/get.js +3 -3
  51. package/dist/commands/user/get.test.js +1 -1
  52. package/dist/fileCommand.d.ts +5 -0
  53. package/dist/fileCommand.js +76 -0
  54. package/dist/test/fixtures.js +2 -2
  55. package/dist/utils.d.ts +20 -9
  56. package/dist/utils.js +33 -80
  57. package/oclif.manifest.json +495 -58
  58. package/package.json +56 -42
  59. package/dist/commands/assembly/add-fasta.js +0 -88
package/bin/dev.js CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  // eslint-disable-next-line node/shebang
4
4
  async function main() {
5
- const {execute} = await import('@oclif/core')
6
- await execute({development: true, dir: import.meta.url})
5
+ const { execute } = await import('@oclif/core')
6
+ await execute({ development: true, dir: import.meta.url })
7
7
  }
8
8
 
9
9
  await main()
package/bin/run.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  async function main() {
4
- const {execute} = await import('@oclif/core')
5
- await execute({dir: import.meta.url})
4
+ const { execute } = await import('@oclif/core')
5
+ await execute({ dir: import.meta.url })
6
6
  }
7
7
 
8
8
  await main()
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unsafe-enum-comparison */
1
2
  import fs from 'node:fs';
2
3
  import path from 'node:path';
3
4
  import Conf from 'conf';
@@ -10,7 +10,7 @@ export declare abstract class BaseCommand<T extends typeof Command> extends Comm
10
10
  protected args: Args<T>;
11
11
  init(): Promise<void>;
12
12
  private getConfig;
13
- getAccess(configFile: string | undefined, profileName: string | undefined): Promise<{
13
+ getAccess(): Promise<{
14
14
  address: string;
15
15
  accessToken: string;
16
16
  }>;
@@ -26,22 +26,22 @@ export class BaseCommand extends Command {
26
26
  }
27
27
  getConfig(configFile) {
28
28
  if (configFile === undefined) {
29
- configFile = path.join(this.config.configDir, 'config.yaml');
29
+ configFile = path.join(this.config.configDir, 'config.yml');
30
30
  }
31
31
  checkConfigfileExists(configFile);
32
32
  const config = new ApolloConf(configFile);
33
33
  return config;
34
34
  }
35
- async getAccess(configFile, profileName) {
35
+ async getAccess() {
36
+ const { 'config-file': configFile, profile } = this.flags;
36
37
  const config = this.getConfig(configFile);
37
- if (profileName === undefined) {
38
- profileName = process.env.APOLLO_PROFILE ?? 'default';
39
- }
38
+ const profileName = process.env.APOLLO_PROFILE ?? profile ?? 'default';
40
39
  return config.getAccess(profileName);
41
40
  }
42
41
  async catch(err) {
43
- // add any custom logic to handle errors from the command
44
- // or simply return the parent class error handling
42
+ if (err.cause instanceof Error) {
43
+ console.error(err.cause);
44
+ }
45
45
  return super.catch(err);
46
46
  }
47
47
  async finally(_) {
@@ -0,0 +1,23 @@
1
+ import { FileCommand } from '../../fileCommand.js';
2
+ export default class AddFasta extends FileCommand {
3
+ static summary: string;
4
+ static description: string;
5
+ static examples: {
6
+ description: string;
7
+ command: string;
8
+ }[];
9
+ static args: {
10
+ input: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
11
+ };
12
+ static flags: {
13
+ assembly: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
14
+ index: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
15
+ force: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
16
+ 'not-editable': import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
17
+ fai: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
18
+ gzi: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
19
+ gzip: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
20
+ decompressed: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
21
+ };
22
+ run(): Promise<void>;
23
+ }
@@ -0,0 +1,165 @@
1
+ /* eslint-disable @typescript-eslint/no-unnecessary-condition */
2
+ import * as fs from 'node:fs';
3
+ import * as path from 'node:path';
4
+ import { Args, Flags } from '@oclif/core';
5
+ import { ObjectId } from 'bson';
6
+ import { FileCommand } from '../../fileCommand.js';
7
+ import { queryApollo, submitAssembly } from '../../utils.js';
8
+ export default class AddFasta extends FileCommand {
9
+ static summary = 'Add a new assembly from fasta input';
10
+ static description = `Add new assembly. The input fasta may be:
11
+ * A local file
12
+ * An external fasta file
13
+ * The id of a file previously uploaded to Apollo`;
14
+ static examples = [
15
+ {
16
+ description: 'From local file:',
17
+ command: '<%= config.bin %> <%= command.id %> genome.fa -a myAssembly',
18
+ },
19
+ {
20
+ description: 'From external source we also need the URL of the index:',
21
+ command: '<%= config.bin %> <%= command.id %> https://.../genome.fa -x https://.../genome.fa.fai -a myAssembly',
22
+ },
23
+ ];
24
+ static args = {
25
+ input: Args.string({
26
+ description: 'Input fasta file, local or remote, or id of a previously uploaded file',
27
+ required: true,
28
+ }),
29
+ };
30
+ static flags = {
31
+ assembly: Flags.string({
32
+ char: 'a',
33
+ description: 'Name for this assembly. Use the file name if omitted',
34
+ }),
35
+ index: Flags.string({
36
+ char: 'x',
37
+ description: 'URL of the index. Required if input is an external source',
38
+ }),
39
+ force: Flags.boolean({
40
+ char: 'f',
41
+ description: 'Delete existing assembly, if it exists',
42
+ }),
43
+ 'not-editable': Flags.boolean({
44
+ char: 'n',
45
+ description: "The fasta sequence is not editable. Apollo will not load it into \
46
+ the database and instead use the provided indexes to query it. This option assumes \
47
+ the fasta file is bgzip'd with `bgzip` and indexed with `samtools faidx`. \
48
+ Indexes should be named <my.fasta.gz>.gzi and <my.fasta.gz>.fai unless options --fai and --gzi are set",
49
+ }),
50
+ fai: Flags.string({
51
+ description: 'Fasta index of the (not-editable) fasta file',
52
+ }),
53
+ gzi: Flags.string({
54
+ description: 'Gzi index of the (not-editable) fasta file',
55
+ }),
56
+ gzip: Flags.boolean({
57
+ char: 'z',
58
+ description: 'For local file input: Override autodetection and instruct that input is gzip compressed',
59
+ exclusive: ['decompressed'],
60
+ }),
61
+ decompressed: Flags.boolean({
62
+ char: 'd',
63
+ description: 'For local file input: Override autodetection and instruct that input is decompressed',
64
+ exclusive: ['gzip'],
65
+ }),
66
+ };
67
+ async run() {
68
+ const { args } = await this.parse(AddFasta);
69
+ const { flags } = await this.parse(AddFasta);
70
+ const access = await this.getAccess();
71
+ const assemblyName = flags.assembly ?? path.basename(args.input);
72
+ const fastaIsFileId = await isFileId(args.input, access.address, access.accessToken);
73
+ const isExternal = isValidHttpUrl(args.input);
74
+ let body;
75
+ if (isExternal) {
76
+ if (flags.index === undefined) {
77
+ this.error('Please provide the URL to the index of the external fasta file');
78
+ }
79
+ body = {
80
+ assemblyName,
81
+ typeName: 'AddAssemblyFromExternalChange',
82
+ externalLocation: {
83
+ fa: args.input,
84
+ fai: flags.index,
85
+ },
86
+ };
87
+ }
88
+ else if (flags['not-editable']) {
89
+ const gzi = flags.gzi ?? `${args.input}.gzi`;
90
+ const fai = flags.fai ?? `${args.input}.fai`;
91
+ const gziIsFileId = await isFileId(gzi, access.address, access.accessToken);
92
+ const faiIsFileId = await isFileId(fai, access.address, access.accessToken);
93
+ if (!fs.existsSync(gzi) && !gziIsFileId) {
94
+ this.error(`Only bgzip'd and indexed fasta files are supported at the moment. "${gzi}" is neither a file or a file id`);
95
+ }
96
+ if (!fs.existsSync(fai) && !faiIsFileId) {
97
+ this.error(`Only bgzip'd and indexed fasta files are supported at the moment. "${fai}" is neither a file or a file id`);
98
+ }
99
+ const faId = fastaIsFileId
100
+ ? args.input
101
+ : await this.uploadFile(access.address, access.accessToken, args.input, 'application/x-bgzip-fasta', true);
102
+ const faiId = faiIsFileId
103
+ ? fai
104
+ : await this.uploadFile(access.address, access.accessToken, fai, 'text/x-fai', false);
105
+ const gziId = gziIsFileId
106
+ ? gzi
107
+ : await this.uploadFile(access.address, access.accessToken, gzi, 'application/x-gzi', false);
108
+ body = {
109
+ assemblyName,
110
+ typeName: 'AddAssemblyFromFileChange',
111
+ fileIds: {
112
+ fa: faId,
113
+ fai: faiId,
114
+ gzi: gziId,
115
+ },
116
+ };
117
+ }
118
+ else {
119
+ if (!isExternal && !fs.existsSync(args.input) && !fastaIsFileId) {
120
+ this.error(`Input "${args.input}" is not valid`);
121
+ }
122
+ let isGzip = args.input.endsWith('.gz');
123
+ if (flags.gzip) {
124
+ isGzip = true;
125
+ }
126
+ if (flags.decompressed) {
127
+ isGzip = false;
128
+ }
129
+ const fileId = fastaIsFileId
130
+ ? args.input
131
+ : await this.uploadFile(access.address, access.accessToken, args.input, 'text/x-fasta', isGzip);
132
+ body = {
133
+ assemblyName,
134
+ fileIds: { fa: fileId },
135
+ typeName: 'AddAssemblyFromFileChange',
136
+ assembly: new ObjectId().toHexString(),
137
+ };
138
+ }
139
+ const rec = await submitAssembly(access.address, access.accessToken, body, flags.force);
140
+ this.log(JSON.stringify(rec, null, 2));
141
+ }
142
+ }
143
+ function isValidHttpUrl(x) {
144
+ let url;
145
+ try {
146
+ url = new URL(x);
147
+ }
148
+ catch {
149
+ return false;
150
+ }
151
+ return url.protocol === 'http:' || url.protocol === 'https:';
152
+ }
153
+ async function isFileId(x, address, accessToken) {
154
+ if (x.length != 24) {
155
+ return false;
156
+ }
157
+ const files = await queryApollo(address, accessToken, 'files');
158
+ const json = (await files.json());
159
+ for (const fileDoc of json) {
160
+ if (fileDoc['_id'] === x) {
161
+ return true;
162
+ }
163
+ }
164
+ return false;
165
+ }
@@ -1,13 +1,15 @@
1
- import { BaseCommand } from '../../baseCommand.js';
2
- export default class AddGff extends BaseCommand<typeof AddGff> {
1
+ import { FileCommand } from '../../fileCommand.js';
2
+ export default class AddGff extends FileCommand {
3
3
  static summary: string;
4
4
  static description: string;
5
5
  static examples: {
6
6
  description: string;
7
7
  command: string;
8
8
  }[];
9
+ static args: {
10
+ 'input-file': import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
11
+ };
9
12
  static flags: {
10
- 'input-file': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
11
13
  assembly: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
12
14
  'omit-features': import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
13
15
  force: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
@@ -1,12 +1,12 @@
1
1
  import * as fs from 'node:fs';
2
2
  import * as path from 'node:path';
3
- import { Flags } from '@oclif/core';
3
+ import { Args, Flags } from '@oclif/core';
4
4
  import { ObjectId } from 'bson';
5
- import { BaseCommand } from '../../baseCommand.js';
6
- import { createFetchErrorMessage, submitAssembly, uploadFile, wrapLines, } from '../../utils.js';
7
- export default class AddGff extends BaseCommand {
5
+ import { FileCommand } from '../../fileCommand.js';
6
+ import { submitAssembly } from '../../utils.js';
7
+ export default class AddGff extends FileCommand {
8
8
  static summary = 'Add new assembly from gff or gft file';
9
- static description = wrapLines('The gff file is expected to contain sequences as per gff specifications. Features are also imported by default.');
9
+ static description = 'The gff file is expected to contain sequences as per gff specifications. Features are also imported by default.';
10
10
  static examples = [
11
11
  {
12
12
  description: 'Import sequences and features:',
@@ -14,15 +14,16 @@ export default class AddGff extends BaseCommand {
14
14
  },
15
15
  {
16
16
  description: 'Import sequences only:',
17
- command: '<%= config.bin %> <%= command.id %> -i genome.gff -a myAssembly -o',
17
+ command: '<%= config.bin %> <%= command.id %> genome.gff -a myAssembly -o',
18
18
  },
19
19
  ];
20
- static flags = {
21
- 'input-file': Flags.string({
22
- char: 'i',
23
- description: 'Input gff or gtf file',
20
+ static args = {
21
+ 'input-file': Args.string({
22
+ description: 'Input gff file',
24
23
  required: true,
25
24
  }),
25
+ };
26
+ static flags = {
26
27
  assembly: Flags.string({
27
28
  char: 'a',
28
29
  description: 'Name for this assembly. Use the file name if omitted',
@@ -37,28 +38,25 @@ export default class AddGff extends BaseCommand {
37
38
  }),
38
39
  };
39
40
  async run() {
41
+ const { args } = await this.parse(AddGff);
40
42
  const { flags } = await this.parse(AddGff);
41
- if (!fs.existsSync(flags['input-file'])) {
42
- this.error(`File ${flags['input-file']} does not exist`);
43
+ if (!fs.existsSync(args['input-file'])) {
44
+ this.error(`File ${args['input-file']} does not exist`);
43
45
  }
44
- const access = await this.getAccess(flags['config-file'], flags.profile);
45
- const fileId = await uploadFile(access.address, access.accessToken, flags['input-file'], 'text/x-gff3');
46
+ const access = await this.getAccess();
47
+ const fileId = await this.uploadFile(access.address, access.accessToken, args['input-file'], 'text/x-gff3', args['input-file'].endsWith('.gz'));
46
48
  let typeName = 'AddAssemblyAndFeaturesFromFileChange';
47
49
  if (flags['omit-features']) {
48
50
  typeName = 'AddAssemblyFromFileChange';
49
51
  }
50
- const assemblyName = flags.assembly ?? path.basename(flags['input-file']);
52
+ const assemblyName = flags.assembly ?? path.basename(args['input-file']);
51
53
  const body = {
52
54
  assemblyName,
53
- fileId,
55
+ fileIds: { fa: fileId },
54
56
  typeName,
55
57
  assembly: new ObjectId().toHexString(),
56
58
  };
57
- const res = await submitAssembly(access.address, access.accessToken, body, flags.force);
58
- if (!res.ok) {
59
- const errorMessage = await createFetchErrorMessage(res, 'getFeatureById failed');
60
- throw new Error(errorMessage);
61
- }
62
- this.exit(0);
59
+ const rec = await submitAssembly(access.address, access.accessToken, body, flags.force);
60
+ this.log(JSON.stringify(rec, null, 2));
63
61
  }
64
62
  }
@@ -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 { convertCheckNameToId, createFetchErrorMessage, getAssembly, idReader, localhostToAddress, wrapLines, } from '../../utils.js';
4
+ import { convertCheckNameToId, createFetchErrorMessage, getAssembly, idReader, localhostToAddress, } from '../../utils.js';
5
5
  async function setChecks(address, accessToken, assembly, checkId) {
6
6
  const check = {
7
7
  _id: assembly,
@@ -54,8 +54,9 @@ function getCheckTypesForAssembly(checkTypes, assembly) {
54
54
  }
55
55
  export default class Check extends BaseCommand {
56
56
  static summary = 'Add, view, or delete checks to assembly';
57
- static description = wrapLines('Manage checks, i.e. the rules ensuring features in an assembly are plausible. \
58
- This command only sets the checks to apply, to retrieve features flagged by these checks use `apollo feature check`.');
57
+ static description = 'Manage checks, i.e. the rules ensuring features in an assembly are plausible. \
58
+ This command only sets the checks to apply, to retrieve features flagged by \
59
+ these checks use `apollo feature check`.';
59
60
  static examples = [
60
61
  {
61
62
  description: 'View available check types:',
@@ -91,7 +92,7 @@ export default class Check extends BaseCommand {
91
92
  };
92
93
  async run() {
93
94
  const { flags } = await this.parse(Check);
94
- const access = await this.getAccess(flags['config-file'], flags.profile);
95
+ const access = await this.getAccess();
95
96
  const checkTypes = await getCheckTypes(access.address, access.accessToken);
96
97
  if (flags.check === undefined && flags.assembly === undefined) {
97
98
  this.log(JSON.stringify(checkTypes, null, 2));
@@ -100,11 +101,8 @@ export default class Check extends BaseCommand {
100
101
  if (flags.assembly === undefined) {
101
102
  this.error('Please specify the assembly to manage for checks');
102
103
  }
103
- const asm = idReader([flags.assembly]);
104
+ const asm = await idReader([flags.assembly]);
104
105
  const assembly = await getAssembly(access.address, access.accessToken, asm[0]);
105
- if (Object.keys(assembly).length === 0) {
106
- this.error(`Assembly ${flags.assembly} not found`);
107
- }
108
106
  const currentChecks = getCheckTypesForAssembly(checkTypes, assembly);
109
107
  if (flags.check === undefined) {
110
108
  this.log(JSON.stringify(currentChecks, null, 2));
@@ -132,6 +130,8 @@ export default class Check extends BaseCommand {
132
130
  newChecks.add(chk['_id']);
133
131
  }
134
132
  }
135
- await setChecks(access.address, access.accessToken, assembly['_id'], [...newChecks.values()]);
133
+ await setChecks(access.address, access.accessToken, assembly._id, [
134
+ ...newChecks.values(),
135
+ ]);
136
136
  }
137
137
  }
@@ -1,9 +1,9 @@
1
1
  import { Flags } from '@oclif/core';
2
2
  import { BaseCommand } from '../../baseCommand.js';
3
- import { convertAssemblyNameToId, deleteAssembly, getAssembly, idReader, wrapLines, } from '../../utils.js';
3
+ import { convertAssemblyNameToId, deleteAssembly, getAssembly, idReader, } from '../../utils.js';
4
4
  export default class Delete extends BaseCommand {
5
5
  static summary = 'Delete assemblies';
6
- static description = wrapLines('Assemblies to delete may be names or IDs');
6
+ static description = 'Assemblies to delete may be names or IDs';
7
7
  static examples = [
8
8
  {
9
9
  description: 'Delete multiple assemblies using name or ID:',
@@ -24,8 +24,8 @@ export default class Delete extends BaseCommand {
24
24
  };
25
25
  async run() {
26
26
  const { flags } = await this.parse(Delete);
27
- const access = await this.getAccess(flags['config-file'], flags.profile);
28
- const assembly = idReader(flags.assembly);
27
+ const access = await this.getAccess();
28
+ const assembly = await idReader(flags.assembly);
29
29
  const deleteIds = await convertAssemblyNameToId(access.address, access.accessToken, assembly);
30
30
  let i = 0;
31
31
  const deleted = [];
@@ -1,9 +1,9 @@
1
1
  import { Flags } from '@oclif/core';
2
2
  import { BaseCommand } from '../../baseCommand.js';
3
- import { convertAssemblyNameToId, idReader, queryApollo, wrapLines, } from '../../utils.js';
3
+ import { convertAssemblyNameToId, idReader, queryApollo } from '../../utils.js';
4
4
  export default class Get extends BaseCommand {
5
5
  static summary = 'Get available assemblies';
6
- static description = wrapLines('Print to stdout the list of assemblies in json format');
6
+ static description = 'Print to stdout the list of assemblies in json format';
7
7
  static flags = {
8
8
  assembly: Flags.string({
9
9
  char: 'a',
@@ -13,11 +13,11 @@ export default class Get extends BaseCommand {
13
13
  };
14
14
  async run() {
15
15
  const { flags } = await this.parse(Get);
16
- const access = await this.getAccess(flags['config-file'], flags.profile);
16
+ const access = await this.getAccess();
17
17
  const assemblies = await queryApollo(access.address, access.accessToken, 'assemblies');
18
18
  let assemblyIds = [];
19
19
  if (flags.assembly !== undefined) {
20
- const assembly = idReader(flags.assembly);
20
+ const assembly = await idReader(flags.assembly);
21
21
  assemblyIds = await convertAssemblyNameToId(access.address, access.accessToken, assembly);
22
22
  }
23
23
  const json = (await assemblies.json());
@@ -7,7 +7,7 @@ import { CONFIG_FILE, TEST_DATA_DIR, VERBOSE, copyFile, } from '../../test/fixtu
7
7
  const __dirname = fileURLToPath(new URL('.', import.meta.url));
8
8
  describe.skip('apollo assembly get: Fail without token', () => {
9
9
  before(() => {
10
- copyFile(`${TEST_DATA_DIR}/guest.yaml`, CONFIG_FILE, VERBOSE);
10
+ copyFile(`${TEST_DATA_DIR}/guest.yml`, CONFIG_FILE, VERBOSE);
11
11
  });
12
12
  after(() => {
13
13
  fs.rmSync(CONFIG_FILE);
@@ -24,7 +24,7 @@ describe.skip('apollo assembly get: Fail without token', () => {
24
24
  // TODO: Need valid token
25
25
  describe.skip('apollo assembly get: Get assemblies as YAML string', () => {
26
26
  before(() => {
27
- copyFile(`${TEST_DATA_DIR}/complete_config.yaml`, CONFIG_FILE, VERBOSE);
27
+ copyFile(`${TEST_DATA_DIR}/complete_config.yml`, CONFIG_FILE, VERBOSE);
28
28
  });
29
29
  after(() => {
30
30
  fs.rmSync(CONFIG_FILE);
@@ -38,7 +38,7 @@ describe.skip('apollo assembly get: Get assemblies as YAML string', () => {
38
38
  });
39
39
  });
40
40
  describe.skip('apollo assembly get: Test nock', () => {
41
- const cmd = ['assembly:get', '--config-file', 'tmp.yaml'];
41
+ const cmd = ['assembly:get', '--config-file', 'tmp.yml'];
42
42
  test
43
43
  .stdout()
44
44
  .nock('http://127.0.0.1:3999', (api) => api.persist().get('/assemblies').reply(200, { stuff: 'foo' }))
@@ -1,9 +1,8 @@
1
1
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
2
- /* eslint-disable @typescript-eslint/restrict-template-expressions */
3
2
  import { Flags } from '@oclif/core';
4
- import { fetch } from 'undici';
3
+ import { Agent, fetch } from 'undici';
5
4
  import { BaseCommand } from '../../baseCommand.js';
6
- import { createFetchErrorMessage, getRefseqId, idReader, localhostToAddress, queryApollo, wrapLines, } from '../../utils.js';
5
+ import { createFetchErrorMessage, getRefseqId, idReader, localhostToAddress, queryApollo, } from '../../utils.js';
7
6
  async function getSequence(address, accessToken, refSeq, start, end) {
8
7
  const url = new URL(localhostToAddress(`${address}/sequence`));
9
8
  const searchParams = new URLSearchParams({
@@ -13,15 +12,11 @@ async function getSequence(address, accessToken, refSeq, start, end) {
13
12
  });
14
13
  url.search = searchParams.toString();
15
14
  const uri = url.toString();
16
- const controller = new AbortController();
17
- setTimeout(() => {
18
- controller.abort();
19
- }, 24 * 60 * 60 * 1000);
20
15
  const auth = {
21
16
  headers: {
22
17
  authorization: `Bearer ${accessToken}`,
23
18
  },
24
- signal: controller.signal,
19
+ dispatcher: new Agent({ headersTimeout: 60 * 60 * 1000 }),
25
20
  };
26
21
  const response = await fetch(uri, auth);
27
22
  if (!response.ok) {
@@ -32,7 +27,7 @@ async function getSequence(address, accessToken, refSeq, start, end) {
32
27
  }
33
28
  export default class ApolloCmd extends BaseCommand {
34
29
  static summary = 'Get reference sequence in fasta format';
35
- static description = wrapLines('Return the reference sequence for a given assembly and coordinates');
30
+ static description = 'Return the reference sequence for a given assembly and coordinates';
36
31
  static examples = [
37
32
  {
38
33
  description: 'Get all sequences in myAssembly:',
@@ -68,11 +63,11 @@ export default class ApolloCmd extends BaseCommand {
68
63
  if (flags.start <= 0 || endCoord <= 0) {
69
64
  this.error('Start and end coordinates must be greater than 0.');
70
65
  }
71
- const access = await this.getAccess(flags['config-file'], flags.profile);
66
+ const access = await this.getAccess();
72
67
  let assembly = undefined;
73
68
  if (flags.assembly !== undefined) {
74
69
  ;
75
- [assembly] = idReader([flags.assembly]);
70
+ [assembly] = await idReader([flags.assembly]);
76
71
  }
77
72
  let refseqIds = [];
78
73
  refseqIds = await getRefseqId(access.address, access.accessToken, flags.refseq, assembly);
@@ -87,8 +82,8 @@ export default class ApolloCmd extends BaseCommand {
87
82
  const seq = new TextDecoder().decode(seqObj?.value);
88
83
  let header = '';
89
84
  for (const x of refSeqs) {
90
- if (x['_id'] === rid) {
91
- const rname = x['name'];
85
+ if (x._id === rid) {
86
+ const rname = x.name;
92
87
  header = `>${rname}:${flags.start}..${flags.start + seq.length - 1}`;
93
88
  break;
94
89
  }
@@ -96,7 +91,6 @@ export default class ApolloCmd extends BaseCommand {
96
91
  this.log(header);
97
92
  this.log(splitStringIntoChunks(seq, 80).join('\n'));
98
93
  }
99
- this.exit(0);
100
94
  }
101
95
  }
102
96
  function splitStringIntoChunks(input, chunkSize) {
@@ -1,12 +1,12 @@
1
1
  import { Flags } from '@oclif/core';
2
2
  import { BaseCommand } from '../../baseCommand.js';
3
- import { convertAssemblyNameToId, idReader, queryApollo, wrapLines, } from '../../utils.js';
3
+ import { convertAssemblyNameToId, idReader, queryApollo } from '../../utils.js';
4
4
  export default class Get extends BaseCommand {
5
5
  static summary = 'Get list of changes';
6
- static description = wrapLines('Return the change log in json format. Note \
7
- that when an assembly is deleted the link between common name and ID is lost \
8
- (it can still be recovered by inspecting the change log but at present this task is left to the user). \
9
- In such cases you need to use the assembly ID.');
6
+ static description = 'Return the change log in json format. Note \
7
+ that when an assembly is deleted the link between common name and ID is lost \
8
+ (it can still be recovered by inspecting the change log but at present this task is left to the user). \
9
+ In such cases you need to use the assembly ID.';
10
10
  static flags = {
11
11
  assembly: Flags.string({
12
12
  char: 'a',
@@ -16,13 +16,13 @@ export default class Get extends BaseCommand {
16
16
  };
17
17
  async run() {
18
18
  const { flags } = await this.parse(Get);
19
- const access = await this.getAccess(flags['config-file'], flags.profile);
19
+ const access = await this.getAccess();
20
20
  const changes = await queryApollo(access.address, access.accessToken, 'changes');
21
21
  const json = (await changes.json());
22
22
  let keep = json;
23
23
  if (flags.assembly !== undefined) {
24
24
  keep = [];
25
- const assembly = idReader(flags.assembly);
25
+ const assembly = await idReader(flags.assembly);
26
26
  const assemblyIds = await convertAssemblyNameToId(access.address, access.accessToken, assembly);
27
27
  for (const x of json) {
28
28
  if (assemblyIds.includes(x['assembly'])) {
@@ -7,7 +7,7 @@ const __dirname = fileURLToPath(new URL('.', import.meta.url));
7
7
  // TODO: Need valid token
8
8
  describe.skip('apollo change get: Get changes as YAML string', () => {
9
9
  before(() => {
10
- copyFile(`${TEST_DATA_DIR}/complete_config.yaml`, CONFIG_FILE, VERBOSE);
10
+ copyFile(`${TEST_DATA_DIR}/complete_config.yml`, CONFIG_FILE, VERBOSE);
11
11
  });
12
12
  after(() => {
13
13
  fs.rmSync(CONFIG_FILE);
@@ -7,13 +7,12 @@ import { Args, Flags } from '@oclif/core';
7
7
  import { fetch } from 'undici';
8
8
  import { ApolloConf, KEYS, optionDesc } from '../ApolloConf.js';
9
9
  import { BaseCommand } from '../baseCommand.js';
10
- import { createFetchErrorMessage, localhostToAddress, wrapLines, } from '../utils.js';
10
+ import { createFetchErrorMessage, localhostToAddress } from '../utils.js';
11
11
  export default class ApolloConfig extends BaseCommand {
12
12
  static summary = 'Get or set apollo configuration options';
13
- static description = wrapLines(`Use this command to create or edit a user profile with credentials to access Apollo. \
14
- Configuration options are:
13
+ static description = `Use this command to create or edit a user profile with credentials to access Apollo. Configuration options are:
15
14
 
16
- ${optionDesc().join('\n\n')}`);
15
+ ${optionDesc().join('\n\n')}`;
17
16
  static args = {
18
17
  key: Args.string({
19
18
  name: 'key',
@@ -53,7 +52,7 @@ export default class ApolloConfig extends BaseCommand {
53
52
  let configFile = flags['config-file'];
54
53
  configFile =
55
54
  configFile === undefined
56
- ? path.join(this.config.configDir, 'config.yaml')
55
+ ? path.join(this.config.configDir, 'config.yml')
57
56
  : path.resolve(configFile);
58
57
  if (flags['get-config-file']) {
59
58
  this.log(configFile);