@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
@@ -1,19 +1,18 @@
1
- /* eslint-disable @typescript-eslint/restrict-template-expressions */
2
- /* eslint-disable @typescript-eslint/restrict-plus-operands */
3
1
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
4
2
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
5
3
  import { Flags } from '@oclif/core';
6
4
  import { ObjectId } from 'bson';
7
5
  import { fetch } from 'undici';
8
6
  import { BaseCommand } from '../../baseCommand.js';
9
- import { createFetchErrorMessage, getFeatureById, idReader, localhostToAddress, queryApollo, wrapLines, } from '../../utils.js';
7
+ import { createFetchErrorMessage, getFeatureById, idReader, localhostToAddress, queryApollo, } from '../../utils.js';
10
8
  export default class Get extends BaseCommand {
11
9
  static summary = 'Add a child feature (e.g. add an exon to an mRNA)';
12
- static description = wrapLines('See the other commands under `apollo feature` to retrive the parent ID of interest and to populate the child feature with attributes.');
10
+ static description = 'See the other commands under `apollo feature` \
11
+ to retrive the parent ID of interest and to populate the child feature with attributes.';
13
12
  static examples = [
14
13
  {
15
14
  description: 'Add an exon at genomic coordinates 10..20 to this feature ID:',
16
- command: '<%= config.bin %> <%= command.id %> -i 6605826fbd0eee691f83e73f -t exon -s 10 -e 20',
15
+ command: '<%= config.bin %> <%= command.id %> -i 660...73f -t exon -s 10 -e 20',
17
16
  },
18
17
  ];
19
18
  static flags = {
@@ -46,12 +45,12 @@ export default class Get extends BaseCommand {
46
45
  if (flags.start <= 0) {
47
46
  this.error('Coordinates must be greater than 0');
48
47
  }
49
- const ff = idReader([flags['feature-id']]);
48
+ const ff = await idReader([flags['feature-id']]);
50
49
  if (ff.length !== 1) {
51
50
  this.error(`Expected only one feature identifier. Got ${ff.length}`);
52
51
  }
53
52
  const [featureId] = ff;
54
- const access = await this.getAccess(flags['config-file'], flags.profile);
53
+ const access = await this.getAccess();
55
54
  const res = await getFeatureById(access.address, access.accessToken, featureId);
56
55
  if (!res.ok) {
57
56
  const errorMessage = await createFetchErrorMessage(res, 'getFeatureById failed');
@@ -63,17 +62,16 @@ export default class Get extends BaseCommand {
63
62
  const errorMessage = await createFetchErrorMessage(childRes, 'Add child failed');
64
63
  throw new Error(errorMessage);
65
64
  }
66
- this.exit(0);
67
65
  }
68
- async addChild(address, accessToken, parentFeature, start, end, type) {
69
- const pStart = parentFeature['start'];
70
- const pEnd = parentFeature['end'];
71
- if (start < pStart || end > pEnd) {
72
- this.error(`Error: Child feature coordinates (${start + 1}-${end}) cannot extend beyond parent coordinates (${pStart + 1}-${pEnd})`);
66
+ async addChild(address, accessToken, parentFeature, min, max, type) {
67
+ const pMin = parentFeature.min;
68
+ const pMax = parentFeature.max;
69
+ if (min < pMin || max > pMax) {
70
+ this.error(`Error: Child feature coordinates (${min + 1}-${max}) cannot extend beyond parent coordinates (${pMin + 1}-${pMax})`);
73
71
  }
74
72
  const res = await queryApollo(address, accessToken, 'refSeqs');
75
73
  const refSeqs = (await res.json());
76
- const refSeq = parentFeature['refSeq'];
74
+ const { refSeq } = parentFeature;
77
75
  let assembly = '';
78
76
  for (const x of refSeqs) {
79
77
  if (x['_id'] === refSeq) {
@@ -83,17 +81,18 @@ export default class Get extends BaseCommand {
83
81
  }
84
82
  const change = {
85
83
  typeName: 'AddFeatureChange',
86
- changedIds: [parentFeature['_id']],
84
+ // eslint-disable-next-line unicorn/consistent-destructuring
85
+ changedIds: [parentFeature._id],
87
86
  assembly,
88
87
  addedFeature: {
89
88
  _id: new ObjectId().toHexString(),
90
- gffId: '',
91
89
  refSeq,
92
- start,
93
- end,
90
+ min,
91
+ max,
94
92
  type,
95
93
  },
96
- parentFeatureId: parentFeature['_id'],
94
+ // eslint-disable-next-line unicorn/consistent-destructuring
95
+ parentFeatureId: parentFeature._id,
97
96
  };
98
97
  const url = new URL(localhostToAddress(`${address}/changes`));
99
98
  const auth = {
@@ -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 { convertAssemblyNameToId, createFetchErrorMessage, idReader, localhostToAddress, queryApollo, wrapLines, } from '../../utils.js';
4
+ import { convertAssemblyNameToId, createFetchErrorMessage, idReader, localhostToAddress, queryApollo, } from '../../utils.js';
5
5
  export default class Check extends BaseCommand {
6
6
  static summary = 'Get check results';
7
- static description = wrapLines('Use this command to view which features fail checks along with the reason for failing.\
8
- Use `apollo assembly check` for managing which checks should be applied to an assembly');
7
+ static description = 'Use this command to view which features fail checks along with the reason for failing.\
8
+ Use `apollo assembly check` for managing which checks should be applied to an assembly';
9
9
  static examples = [
10
10
  {
11
11
  description: 'Get all check results in the database:',
@@ -29,10 +29,10 @@ export default class Check extends BaseCommand {
29
29
  };
30
30
  async run() {
31
31
  const { flags } = await this.parse(Check);
32
- const access = await this.getAccess(flags['config-file'], flags.profile);
32
+ const access = await this.getAccess();
33
33
  let keepFeatures = new Set();
34
34
  if (flags['feature-id'] !== undefined) {
35
- keepFeatures = new Set(idReader(flags['feature-id']));
35
+ keepFeatures = new Set(await idReader(flags['feature-id']));
36
36
  }
37
37
  const keepAsmId = await keepAssemblies(access.address, access.accessToken, flags.assembly);
38
38
  const res = await queryApollo(access.address, access.accessToken, 'refseqs');
@@ -50,15 +50,15 @@ export default class Check extends BaseCommand {
50
50
  if (flags['feature-id'] === undefined) {
51
51
  keep = true;
52
52
  }
53
- else {
54
- for (const x of chk['ids']) {
55
- if (keepFeatures.has(x)) {
53
+ else if (chk.ids !== undefined) {
54
+ for (const x of chk.ids) {
55
+ if (x !== undefined && keepFeatures.has(x.toString())) {
56
56
  keep = true;
57
57
  break;
58
58
  }
59
59
  }
60
60
  }
61
- if (keep && refseqId.has(chk['refSeq'])) {
61
+ if (keep && refseqId.has(chk.refSeq)) {
62
62
  results.push(chk);
63
63
  }
64
64
  }
@@ -71,11 +71,11 @@ async function keepAssemblies(address, accessToken, assembly) {
71
71
  const res = await queryApollo(address, accessToken, 'assemblies');
72
72
  const asm = (await res.json());
73
73
  for (const x of asm) {
74
- keepAssembly.push(x['_id']);
74
+ keepAssembly.push(x._id);
75
75
  }
76
76
  }
77
77
  else {
78
- const ids = idReader([assembly]);
78
+ const ids = await idReader([assembly]);
79
79
  keepAssembly = await convertAssemblyNameToId(address, accessToken, ids);
80
80
  }
81
81
  return keepAssembly;
@@ -2,11 +2,12 @@ import { Flags } from '@oclif/core';
2
2
  import { ObjectId } from 'bson';
3
3
  import { fetch } from 'undici';
4
4
  import { BaseCommand } from '../../baseCommand.js';
5
- import { createFetchErrorMessage, getAssemblyFromRefseq, getFeatureById, getRefseqId, localhostToAddress, wrapLines, } from '../../utils.js';
5
+ import { createFetchErrorMessage, getAssemblyFromRefseq, getFeatureById, getRefseqId, localhostToAddress, } from '../../utils.js';
6
6
  export default class Copy extends BaseCommand {
7
7
  static summary = 'Copy a feature to another location';
8
- static description = wrapLines('The feature may be copied to the same or to a different assembly. \
9
- he destination reference sequence may be selected by name only if unique in the database or by name and assembly or by identifier.');
8
+ static description = 'The feature may be copied to the same or to a different assembly. \
9
+ The destination reference sequence may be selected by name only if unique in \
10
+ the database or by name and assembly or by identifier.';
10
11
  static examples = [
11
12
  {
12
13
  description: 'Copy this feature ID to chr1:100 in assembly hg38:',
@@ -40,7 +41,7 @@ export default class Copy extends BaseCommand {
40
41
  if (flags.start <= 0) {
41
42
  this.error('Start coordinate must be greater than 0');
42
43
  }
43
- const access = await this.getAccess(flags['config-file'], flags.profile);
44
+ const access = await this.getAccess();
44
45
  const res = await getFeatureById(access.address, access.accessToken, flags['feature-id']);
45
46
  if (!res.ok) {
46
47
  const errorMessage = await createFetchErrorMessage(res, 'getFeatureById failed');
@@ -60,11 +61,9 @@ export default class Copy extends BaseCommand {
60
61
  const errorMessage = await createFetchErrorMessage(rescopy, 'Copy feature failed');
61
62
  throw new Error(errorMessage);
62
63
  }
63
- this.exit(0);
64
64
  }
65
- async copyFeature(address, accessToken, feature, refseq, start, assembly, newId) {
66
- const featureLen = feature['end'] -
67
- feature['start'];
65
+ async copyFeature(address, accessToken, feature, refseq, min, assembly, newId) {
66
+ const featureLen = feature.max - feature.min;
68
67
  const change = {
69
68
  typeName: 'AddFeatureChange',
70
69
  changedIds: [newId],
@@ -72,12 +71,11 @@ export default class Copy extends BaseCommand {
72
71
  addedFeature: {
73
72
  _id: newId,
74
73
  refSeq: refseq,
75
- start: start - 1,
76
- end: start + featureLen - 1,
77
- type: feature['type'],
78
- attributes: feature['attributes'],
79
- discontinuousLocations: feature['discontinuousLocations'],
80
- strand: feature['strand'],
74
+ min: min - 1,
75
+ max: min + featureLen - 1,
76
+ type: feature.type,
77
+ attributes: feature.attributes,
78
+ strand: feature.strand,
81
79
  },
82
80
  copyFeature: true,
83
81
  allIds: [newId],
@@ -1,24 +1,19 @@
1
- /* eslint-disable @typescript-eslint/no-unsafe-argument */
2
- /* eslint-disable @typescript-eslint/no-unsafe-assignment */
3
1
  import { Flags } from '@oclif/core';
4
2
  import { fetch } from 'undici';
5
3
  import { BaseCommand } from '../../baseCommand.js';
6
- import { createFetchErrorMessage, getFeatureById, idReader, localhostToAddress, wrapLines, } from '../../utils.js';
4
+ import { createFetchErrorMessage, getFeatureById, idReader, localhostToAddress, } from '../../utils.js';
7
5
  async function deleteFeature(address, accessToken, feature) {
8
6
  const changeJson = {
9
7
  typeName: 'DeleteFeatureChange',
10
- changedIds: [feature],
11
- assembly: feature['assembly'],
8
+ changedIds: [feature._id],
9
+ assembly: '111222333444555666777888', // Use a placeholder objectId (i.e. some 24 chars)
12
10
  deletedFeature: {
13
- _id: feature['_id'],
14
- gffId: feature['gffId'],
15
- refSeq: feature['refSeq'],
16
- type: feature['type'],
17
- start: feature['start'],
18
- end: feature['end'],
19
- discontinuousLocations: feature['discontinuousLocations'],
20
- score: feature['score'],
21
- attributes: feature['attributes'],
11
+ _id: feature._id,
12
+ refSeq: feature.refSeq,
13
+ type: feature.type,
14
+ min: feature.min,
15
+ max: feature.max,
16
+ attributes: feature.attributes,
22
17
  },
23
18
  };
24
19
  const url = new URL(localhostToAddress(`${address}/changes`));
@@ -39,7 +34,7 @@ async function deleteFeature(address, accessToken, feature) {
39
34
  }
40
35
  export default class Delete extends BaseCommand {
41
36
  static summary = 'Delete one or more features by ID';
42
- static description = wrapLines('Note that deleting a child feature after deleting its parent will result in an error unless you set -f/--force.');
37
+ static description = 'Note that deleting a child feature after deleting its parent will result in an error unless you set -f/--force.';
43
38
  static flags = {
44
39
  'feature-id': Flags.string({
45
40
  char: 'i',
@@ -58,12 +53,12 @@ export default class Delete extends BaseCommand {
58
53
  };
59
54
  async run() {
60
55
  const { flags } = await this.parse(Delete);
61
- const tmpIds = idReader(flags['feature-id']);
56
+ const tmpIds = await idReader(flags['feature-id']);
62
57
  const featureIds = new Set();
63
58
  for (const x of tmpIds) {
64
59
  featureIds.add(x);
65
60
  }
66
- const access = await this.getAccess(flags['config-file'], flags.profile);
61
+ const access = await this.getAccess();
67
62
  for (const featureId of featureIds) {
68
63
  const res = await getFeatureById(access.address, access.accessToken, featureId);
69
64
  if (res.status === 404 && flags.force) {
@@ -75,7 +70,7 @@ export default class Delete extends BaseCommand {
75
70
  }
76
71
  const feature = JSON.parse(await res.text());
77
72
  if (flags['dry-run']) {
78
- this.log(feature);
73
+ this.log(JSON.stringify(feature, null, 2));
79
74
  }
80
75
  else {
81
76
  const delFet = await deleteFeature(access.address, access.accessToken, feature);
@@ -85,6 +80,5 @@ export default class Delete extends BaseCommand {
85
80
  }
86
81
  }
87
82
  }
88
- this.exit(0);
89
83
  }
90
84
  }
@@ -1,14 +1,12 @@
1
- /* eslint-disable @typescript-eslint/no-unsafe-argument */
2
- /* eslint-disable @typescript-eslint/no-unsafe-member-access */
3
- /* eslint-disable @typescript-eslint/no-unsafe-assignment */
4
1
  import { Flags } from '@oclif/core';
5
2
  import { fetch } from 'undici';
6
3
  import { BaseCommand } from '../../baseCommand.js';
7
- import { createFetchErrorMessage, getAssemblyFromRefseq, getFeatureById, idReader, localhostToAddress, wrapLines, } from '../../utils.js';
4
+ import { createFetchErrorMessage, getAssemblyFromRefseq, getFeatureById, idReader, localhostToAddress, } from '../../utils.js';
8
5
  export default class EditAttibute extends BaseCommand {
9
6
  static summary = 'Add, edit, or view a feature attribute';
10
- static description = wrapLines('Be aware that there is no checking whether attributes names and values are valid. \
11
- 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';
12
10
  static examples = [
13
11
  {
14
12
  description: 'Add attribute "domains" with a list of values:',
@@ -49,18 +47,21 @@ export default class EditAttibute extends BaseCommand {
49
47
  if (flags.delete && flags.value) {
50
48
  this.error('Error: Options --delete and --value are mutually exclusive');
51
49
  }
52
- const ff = idReader([flags['feature-id']]);
50
+ const ff = await idReader([flags['feature-id']]);
53
51
  if (ff.length !== 1) {
54
52
  this.error(`Expected only one feature identifier. Got ${ff.length}`);
55
53
  }
56
54
  const [featureId] = ff;
57
- const access = await this.getAccess(flags['config-file'], flags.profile);
55
+ const access = await this.getAccess();
58
56
  const response = await getFeatureById(access.address, access.accessToken, featureId);
59
57
  if (!response.ok) {
60
58
  const errorMessage = await createFetchErrorMessage(response, 'getFeatureById failed');
61
59
  throw new Error(errorMessage);
62
60
  }
63
61
  const featureJson = JSON.parse(await response.text());
62
+ if (featureJson.attributes === undefined) {
63
+ featureJson.attributes = {};
64
+ }
64
65
  if (flags.value === undefined && !flags.delete) {
65
66
  this.log(JSON.stringify(featureJson.attributes[flags.attribute]));
66
67
  return;
@@ -72,13 +73,20 @@ export default class EditAttibute extends BaseCommand {
72
73
  else {
73
74
  featureJson.attributes[flags.attribute] = flags.value;
74
75
  }
75
- const assembly = await getAssemblyFromRefseq(access.address, access.accessToken, featureJson['refSeq']);
76
+ const assembly = await getAssemblyFromRefseq(access.address, access.accessToken, featureJson.refSeq);
77
+ const attrs = {};
78
+ for (const [key, val] of Object.entries(featureJson.attributes)) {
79
+ if (!val) {
80
+ continue;
81
+ }
82
+ attrs[key] = [...val];
83
+ }
76
84
  const changeJson = {
77
85
  typeName: 'FeatureAttributeChange',
78
86
  changedIds: [featureId],
79
87
  assembly,
80
88
  featureId,
81
- attributes: featureJson.attributes,
89
+ attributes: attrs,
82
90
  };
83
91
  const url = new URL(localhostToAddress(`${access.address}/changes`));
84
92
  const auth = {
@@ -94,6 +102,5 @@ export default class EditAttibute extends BaseCommand {
94
102
  const errorMessage = await createFetchErrorMessage(res, 'edit-attribute failed');
95
103
  throw new Error(errorMessage);
96
104
  }
97
- this.exit(0);
98
105
  }
99
106
  }
@@ -1,14 +1,11 @@
1
- /* eslint-disable @typescript-eslint/no-unsafe-member-access */
2
- /* eslint-disable @typescript-eslint/no-unsafe-argument */
3
- /* eslint-disable @typescript-eslint/no-unsafe-assignment */
4
1
  import { Flags } from '@oclif/core';
5
2
  import { fetch } from 'undici';
6
3
  import { BaseCommand } from '../../baseCommand.js';
7
- import { createFetchErrorMessage, getAssemblyFromRefseq, getFeatureById, idReader, localhostToAddress, wrapLines, } from '../../utils.js';
4
+ import { createFetchErrorMessage, getAssemblyFromRefseq, getFeatureById, idReader, localhostToAddress, } from '../../utils.js';
8
5
  export default class Get extends BaseCommand {
9
6
  static summary = 'Edit feature start and/or end coordinates';
10
- static description = wrapLines("If editing a child feature that new coordinates must be within the parent's coordinates.\
11
- 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`";
12
9
  static examples = [
13
10
  {
14
11
  description: 'Edit start and end:',
@@ -50,27 +47,27 @@ export default class Get extends BaseCommand {
50
47
  if (flags.start !== undefined) {
51
48
  flags.start -= 1;
52
49
  }
53
- const ff = idReader([flags['feature-id']]);
50
+ const ff = await idReader([flags['feature-id']]);
54
51
  if (ff.length !== 1) {
55
52
  this.error(`Expected only one feature identifier. Got ${ff.length}`);
56
53
  }
57
54
  const [featureId] = ff;
58
- const access = await this.getAccess(flags['config-file'], flags.profile);
55
+ const access = await this.getAccess();
59
56
  const res = await getFeatureById(access.address, access.accessToken, featureId);
60
57
  if (!res.ok) {
61
58
  const errorMessage = await createFetchErrorMessage(res, 'getFeatureById failed');
62
59
  throw new Error(errorMessage);
63
60
  }
64
61
  const featureJson = JSON.parse(await res.text());
65
- const assembly = await getAssemblyFromRefseq(access.address, access.accessToken, featureJson['refSeq']);
66
- const currentEnd = featureJson['end'];
62
+ const assembly = await getAssemblyFromRefseq(access.address, access.accessToken, featureJson.refSeq);
63
+ const currentEnd = featureJson.max;
67
64
  let edit = ['Start', 'End'];
68
65
  if (flags.start !== undefined && flags.start > currentEnd) {
69
- // Edit End first so you avoid an intermediate start > end
66
+ // Edit End (Max) first so you avoid an intermediate start > end
70
67
  edit = ['End', 'Start'];
71
68
  }
72
69
  for (const coord of edit) {
73
- const currentStart = featureJson['start'];
70
+ const currentStart = featureJson.min;
74
71
  if (coord === 'Start' &&
75
72
  (flags.start === undefined || flags.start === currentStart)) {
76
73
  continue;
@@ -79,18 +76,36 @@ export default class Get extends BaseCommand {
79
76
  (flags.end === undefined || flags.end === currentEnd)) {
80
77
  continue;
81
78
  }
82
- const changeJson = {
83
- typeName: `Location${coord}Change`,
84
- changedIds: [featureId],
85
- assembly,
86
- featureId,
87
- [`old${coord}`]: featureJson[coord.toLowerCase()],
88
- [`new${coord}`]: flags[coord.toLowerCase()],
89
- };
79
+ let body;
80
+ if (coord === 'Start' && flags.start !== undefined) {
81
+ const oldCoord = featureJson.min;
82
+ body = {
83
+ typeName: 'LocationStartChange',
84
+ changedIds: [featureId],
85
+ assembly,
86
+ featureId,
87
+ ['oldStart']: oldCoord,
88
+ ['newStart']: flags.start,
89
+ };
90
+ }
91
+ else if (coord === 'End' && flags.end !== undefined) {
92
+ const oldCoord = featureJson.max;
93
+ body = {
94
+ typeName: 'LocationEndChange',
95
+ changedIds: [featureId],
96
+ assembly,
97
+ featureId,
98
+ ['oldEnd']: oldCoord,
99
+ ['newEnd']: flags.end,
100
+ };
101
+ }
102
+ else {
103
+ throw new Error(`Unexpected coordinate name: "${coord}"`);
104
+ }
90
105
  const url = new URL(localhostToAddress(`${access.address}/changes`));
91
106
  const auth = {
92
107
  method: 'POST',
93
- body: JSON.stringify(changeJson),
108
+ body: JSON.stringify(body),
94
109
  headers: {
95
110
  authorization: `Bearer ${access.accessToken}`,
96
111
  'Content-Type': 'application/json',
@@ -1,14 +1,11 @@
1
- /* eslint-disable @typescript-eslint/no-unsafe-argument */
2
- /* eslint-disable @typescript-eslint/no-unsafe-member-access */
3
- /* eslint-disable @typescript-eslint/no-unsafe-assignment */
4
1
  import { Flags } from '@oclif/core';
5
2
  import { fetch } from 'undici';
6
3
  import { BaseCommand } from '../../baseCommand.js';
7
- import { createFetchErrorMessage, getAssemblyFromRefseq, getFeatureById, idReader, localhostToAddress, wrapLines, } from '../../utils.js';
4
+ import { createFetchErrorMessage, getAssemblyFromRefseq, getFeatureById, idReader, localhostToAddress, } from '../../utils.js';
8
5
  export default class Get extends BaseCommand {
9
6
  static summary = 'Edit or view feature type';
10
- static description = wrapLines('Feature type is column 3 in gff format.\
11
- 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.';
12
9
  static flags = {
13
10
  'feature-id': Flags.string({
14
11
  char: 'i',
@@ -22,19 +19,19 @@ export default class Get extends BaseCommand {
22
19
  };
23
20
  async run() {
24
21
  const { flags } = await this.parse(Get);
25
- const ff = idReader([flags['feature-id']]);
22
+ const ff = await idReader([flags['feature-id']]);
26
23
  if (ff.length !== 1) {
27
24
  this.error(`Expected only one feature identifier. Got ${ff.length}`);
28
25
  }
29
26
  const [featureId] = ff;
30
- const access = await this.getAccess(flags['config-file'], flags.profile);
27
+ const access = await this.getAccess();
31
28
  const response = await getFeatureById(access.address, access.accessToken, featureId);
32
29
  if (!response.ok) {
33
30
  const errorMessage = await createFetchErrorMessage(response, 'getFeatureById failed');
34
31
  throw new Error(errorMessage);
35
32
  }
36
33
  const featureJson = JSON.parse(await response.text());
37
- const currentType = featureJson['type'];
34
+ const currentType = featureJson.type;
38
35
  if (flags.type === undefined) {
39
36
  this.log(currentType);
40
37
  return;
@@ -43,7 +40,7 @@ export default class Get extends BaseCommand {
43
40
  this.logToStderr(`NOTE: Feature ${featureId} is already of type "${flags.type}"`);
44
41
  return;
45
42
  }
46
- const assembly = await getAssemblyFromRefseq(access.address, access.accessToken, featureJson['refSeq']);
43
+ const assembly = await getAssemblyFromRefseq(access.address, access.accessToken, featureJson.refSeq);
47
44
  const changeJson = {
48
45
  typeName: 'TypeChange',
49
46
  changedIds: [featureId],
@@ -66,6 +63,5 @@ export default class Get extends BaseCommand {
66
63
  const errorMessage = await createFetchErrorMessage(res, 'edit-type failed');
67
64
  throw new Error(errorMessage);
68
65
  }
69
- this.exit(0);
70
66
  }
71
67
  }
@@ -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`));
@@ -64,6 +64,5 @@ export default class Get extends BaseCommand {
64
64
  throw new Error(errorMessage);
65
65
  }
66
66
  }
67
- this.exit(0);
68
67
  }
69
68
  }
@@ -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) {
@@ -33,7 +33,6 @@ export default class Get extends BaseCommand {
33
33
  results.push(res);
34
34
  }
35
35
  this.log(JSON.stringify(results, null, 2));
36
- this.exit(0);
37
36
  }
38
37
  async getFeatureId(address, token, featureId) {
39
38
  const url = new URL(localhostToAddress(`${address}/features/${featureId}`));
@@ -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) {
@@ -50,7 +50,6 @@ export default class Get extends BaseCommand {
50
50
  }
51
51
  }
52
52
  this.log(JSON.stringify(results, null, 2));
53
- this.exit(0);
54
53
  }
55
54
  async getFeatures(address, token, refSeq, start, end) {
56
55
  const url = new URL(localhostToAddress(`${address}/features/getFeatures`));
@@ -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: {