@apollo-annotation/cli 0.1.17 → 0.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +120 -58
- package/bin/dev.js +2 -2
- package/bin/run.js +2 -2
- package/dist/ApolloConf.d.ts +22 -0
- package/dist/ApolloConf.js +144 -0
- package/dist/baseCommand.js +7 -17
- package/dist/commands/assembly/add-fasta.js +16 -27
- package/dist/commands/assembly/add-gff.js +11 -24
- package/dist/commands/assembly/check.js +7 -18
- package/dist/commands/assembly/delete.js +1 -1
- package/dist/commands/assembly/get.test.js +3 -3
- package/dist/commands/assembly/sequence.js +7 -21
- package/dist/commands/change/get.test.js +1 -1
- package/dist/commands/config.js +21 -53
- package/dist/commands/feature/add-child.js +21 -29
- package/dist/commands/feature/check.js +5 -5
- package/dist/commands/feature/copy.js +20 -32
- package/dist/commands/feature/delete.js +16 -31
- package/dist/commands/feature/edit-attribute.js +15 -10
- package/dist/commands/feature/edit-coords.js +39 -27
- package/dist/commands/feature/edit-type.js +5 -8
- package/dist/commands/feature/edit.js +3 -16
- package/dist/commands/feature/get-id.js +0 -1
- package/dist/commands/feature/get.js +6 -18
- package/dist/commands/feature/import.js +22 -41
- package/dist/commands/feature/search.js +1 -1
- package/dist/commands/login.js +17 -29
- package/dist/commands/logout.js +5 -14
- package/dist/commands/refseq/add-alias.d.ts +14 -0
- package/dist/commands/refseq/add-alias.js +72 -0
- package/dist/commands/status.js +5 -13
- package/dist/commands/user/get.test.js +1 -1
- package/dist/test/fixtures.js +2 -2
- package/dist/utils.d.ts +3 -3
- package/dist/utils.js +50 -25
- package/oclif.manifest.json +163 -102
- package/package.json +11 -3
- package/dist/Config.d.ts +0 -43
- package/dist/Config.js +0 -233
- package/dist/commands/config.test.d.ts +0 -1
- package/dist/commands/config.test.js +0 -188
- package/dist/commands/login.test.d.ts +0 -1
- package/dist/commands/login.test.js +0 -52
- package/dist/commands/logout.test.d.ts +0 -1
- package/dist/commands/logout.test.js +0 -67
- package/dist/commands/status.test.d.ts +0 -1
- package/dist/commands/status.test.js +0 -54
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
2
1
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
3
2
|
import * as fs from 'node:fs';
|
|
4
3
|
import * as path from 'node:path';
|
|
5
4
|
import { Flags } from '@oclif/core';
|
|
6
5
|
import { ObjectId } from 'bson';
|
|
7
6
|
import { BaseCommand } from '../../baseCommand.js';
|
|
8
|
-
import { submitAssembly, uploadFile, wrapLines } from '../../utils.js';
|
|
7
|
+
import { createFetchErrorMessage, submitAssembly, uploadFile, wrapLines, } from '../../utils.js';
|
|
9
8
|
export default class Get extends BaseCommand {
|
|
10
9
|
static description = 'Add new assembly from local or external fasta file';
|
|
11
10
|
static examples = [
|
|
@@ -42,11 +41,10 @@ export default class Get extends BaseCommand {
|
|
|
42
41
|
const access = await this.getAccess(flags['config-file'], flags.profile);
|
|
43
42
|
const assemblyName = flags.assembly ?? path.basename(flags['input-file']);
|
|
44
43
|
const isExternal = isValidHttpUrl(flags['input-file']);
|
|
45
|
-
let
|
|
44
|
+
let res;
|
|
46
45
|
if (isExternal) {
|
|
47
46
|
if (flags.index === undefined) {
|
|
48
|
-
this.
|
|
49
|
-
this.exit(1);
|
|
47
|
+
this.error('Please provide the URL to the index of the external fasta file');
|
|
50
48
|
}
|
|
51
49
|
const body = {
|
|
52
50
|
assemblyName,
|
|
@@ -56,34 +54,25 @@ export default class Get extends BaseCommand {
|
|
|
56
54
|
fai: flags.index,
|
|
57
55
|
},
|
|
58
56
|
};
|
|
59
|
-
|
|
57
|
+
res = (await submitAssembly(access.address, access.accessToken, body, flags.force));
|
|
60
58
|
}
|
|
61
59
|
else {
|
|
62
60
|
if (!isExternal && !fs.existsSync(flags['input-file'])) {
|
|
63
|
-
this.
|
|
64
|
-
this.exit(1);
|
|
65
|
-
}
|
|
66
|
-
try {
|
|
67
|
-
const fileId = await uploadFile(access.address, access.accessToken, flags['input-file'], 'text/x-fasta');
|
|
68
|
-
const body = {
|
|
69
|
-
assemblyName,
|
|
70
|
-
fileId,
|
|
71
|
-
typeName: 'AddAssemblyFromFileChange',
|
|
72
|
-
assembly: new ObjectId().toHexString(),
|
|
73
|
-
};
|
|
74
|
-
response = (await submitAssembly(access.address, access.accessToken, body, flags.force));
|
|
75
|
-
}
|
|
76
|
-
catch (error) {
|
|
77
|
-
this.logToStderr(error.message);
|
|
78
|
-
this.exit(1);
|
|
61
|
+
this.error(`File ${flags['input-file']} does not exist`);
|
|
79
62
|
}
|
|
63
|
+
const fileId = await uploadFile(access.address, access.accessToken, flags['input-file'], 'text/x-fasta');
|
|
64
|
+
const body = {
|
|
65
|
+
assemblyName,
|
|
66
|
+
fileId,
|
|
67
|
+
typeName: 'AddAssemblyFromFileChange',
|
|
68
|
+
assembly: new ObjectId().toHexString(),
|
|
69
|
+
};
|
|
70
|
+
res = (await submitAssembly(access.address, access.accessToken, body, flags.force));
|
|
80
71
|
}
|
|
81
|
-
if (!
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
this.exit(1);
|
|
72
|
+
if (!res.ok) {
|
|
73
|
+
const errorMessage = await createFetchErrorMessage(res, 'Submit assembly failed');
|
|
74
|
+
throw new Error(errorMessage);
|
|
85
75
|
}
|
|
86
|
-
this.exit(0);
|
|
87
76
|
}
|
|
88
77
|
}
|
|
89
78
|
function isValidHttpUrl(x) {
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
2
|
-
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
3
1
|
import * as fs from 'node:fs';
|
|
4
2
|
import * as path from 'node:path';
|
|
5
3
|
import { Flags } from '@oclif/core';
|
|
6
4
|
import { ObjectId } from 'bson';
|
|
7
5
|
import { BaseCommand } from '../../baseCommand.js';
|
|
8
|
-
import { submitAssembly, uploadFile, wrapLines } from '../../utils.js';
|
|
6
|
+
import { createFetchErrorMessage, submitAssembly, uploadFile, wrapLines, } from '../../utils.js';
|
|
9
7
|
export default class AddGff extends BaseCommand {
|
|
10
8
|
static summary = 'Add new assembly from gff or gft file';
|
|
11
9
|
static description = wrapLines('The gff file is expected to contain sequences as per gff specifications. Features are also imported by default.');
|
|
@@ -41,8 +39,7 @@ export default class AddGff extends BaseCommand {
|
|
|
41
39
|
async run() {
|
|
42
40
|
const { flags } = await this.parse(AddGff);
|
|
43
41
|
if (!fs.existsSync(flags['input-file'])) {
|
|
44
|
-
this.
|
|
45
|
-
this.exit(1);
|
|
42
|
+
this.error(`File ${flags['input-file']} does not exist`);
|
|
46
43
|
}
|
|
47
44
|
const access = await this.getAccess(flags['config-file'], flags.profile);
|
|
48
45
|
const fileId = await uploadFile(access.address, access.accessToken, flags['input-file'], 'text/x-gff3');
|
|
@@ -51,26 +48,16 @@ export default class AddGff extends BaseCommand {
|
|
|
51
48
|
typeName = 'AddAssemblyFromFileChange';
|
|
52
49
|
}
|
|
53
50
|
const assemblyName = flags.assembly ?? path.basename(flags['input-file']);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
};
|
|
62
|
-
res = await submitAssembly(access.address, access.accessToken, body, flags.force);
|
|
63
|
-
}
|
|
64
|
-
catch (error) {
|
|
65
|
-
this.logToStderr(error.message);
|
|
66
|
-
this.exit(1);
|
|
67
|
-
}
|
|
51
|
+
const body = {
|
|
52
|
+
assemblyName,
|
|
53
|
+
fileId,
|
|
54
|
+
typeName,
|
|
55
|
+
assembly: new ObjectId().toHexString(),
|
|
56
|
+
};
|
|
57
|
+
const res = await submitAssembly(access.address, access.accessToken, body, flags.force);
|
|
68
58
|
if (!res.ok) {
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
this.logToStderr(message);
|
|
72
|
-
this.exit(1);
|
|
59
|
+
const errorMessage = await createFetchErrorMessage(res, 'getFeatureById failed');
|
|
60
|
+
throw new Error(errorMessage);
|
|
73
61
|
}
|
|
74
|
-
this.exit(0);
|
|
75
62
|
}
|
|
76
63
|
}
|
|
@@ -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 {
|
|
4
|
+
import { convertCheckNameToId, createFetchErrorMessage, getAssembly, idReader, localhostToAddress, wrapLines, } from '../../utils.js';
|
|
5
5
|
async function setChecks(address, accessToken, assembly, checkId) {
|
|
6
6
|
const check = {
|
|
7
7
|
_id: assembly,
|
|
@@ -55,7 +55,7 @@ function getCheckTypesForAssembly(checkTypes, assembly) {
|
|
|
55
55
|
export default class Check extends BaseCommand {
|
|
56
56
|
static summary = 'Add, view, or delete checks to assembly';
|
|
57
57
|
static description = wrapLines('Manage checks, i.e. the rules ensuring features in an assembly are plausible. \
|
|
58
|
-
This command only sets the
|
|
58
|
+
This command only sets the checks to apply, to retrieve features flagged by these checks use `apollo feature check`.');
|
|
59
59
|
static examples = [
|
|
60
60
|
{
|
|
61
61
|
description: 'View available check types:',
|
|
@@ -95,33 +95,23 @@ export default class Check extends BaseCommand {
|
|
|
95
95
|
const checkTypes = await getCheckTypes(access.address, access.accessToken);
|
|
96
96
|
if (flags.check === undefined && flags.assembly === undefined) {
|
|
97
97
|
this.log(JSON.stringify(checkTypes, null, 2));
|
|
98
|
-
|
|
98
|
+
return;
|
|
99
99
|
}
|
|
100
100
|
if (flags.assembly === undefined) {
|
|
101
|
-
this.
|
|
102
|
-
this.exit(1);
|
|
101
|
+
this.error('Please specify the assembly to manage for checks');
|
|
103
102
|
}
|
|
104
103
|
const asm = idReader([flags.assembly]);
|
|
105
104
|
const assembly = await getAssembly(access.address, access.accessToken, asm[0]);
|
|
106
105
|
if (Object.keys(assembly).length === 0) {
|
|
107
|
-
this.
|
|
108
|
-
this.exit(1);
|
|
106
|
+
this.error(`Assembly ${flags.assembly} not found`);
|
|
109
107
|
}
|
|
110
108
|
const currentChecks = getCheckTypesForAssembly(checkTypes, assembly);
|
|
111
109
|
if (flags.check === undefined) {
|
|
112
110
|
this.log(JSON.stringify(currentChecks, null, 2));
|
|
113
|
-
|
|
111
|
+
return;
|
|
114
112
|
}
|
|
115
113
|
let inputCheckIds = [];
|
|
116
|
-
|
|
117
|
-
inputCheckIds = await convertCheckNameToId(access.address, access.accessToken, flags.check);
|
|
118
|
-
}
|
|
119
|
-
catch (error) {
|
|
120
|
-
if (error instanceof CheckError) {
|
|
121
|
-
this.logToStderr(error.message);
|
|
122
|
-
this.exit(1);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
114
|
+
inputCheckIds = await convertCheckNameToId(access.address, access.accessToken, flags.check);
|
|
125
115
|
const newChecks = new Set();
|
|
126
116
|
if (flags.delete) {
|
|
127
117
|
const currentCheckIds = new Set();
|
|
@@ -143,6 +133,5 @@ export default class Check extends BaseCommand {
|
|
|
143
133
|
}
|
|
144
134
|
}
|
|
145
135
|
await setChecks(access.address, access.accessToken, assembly['_id'], [...newChecks.values()]);
|
|
146
|
-
this.exit(0);
|
|
147
136
|
}
|
|
148
137
|
}
|
|
@@ -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.
|
|
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.
|
|
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.
|
|
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,7 +1,6 @@
|
|
|
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
5
|
import { createFetchErrorMessage, getRefseqId, idReader, localhostToAddress, queryApollo, wrapLines, } from '../../utils.js';
|
|
7
6
|
async function getSequence(address, accessToken, refSeq, start, end) {
|
|
@@ -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
|
-
|
|
19
|
+
dispatcher: new Agent({ headersTimeout: 60 * 60 * 1000 }),
|
|
25
20
|
};
|
|
26
21
|
const response = await fetch(uri, auth);
|
|
27
22
|
if (!response.ok) {
|
|
@@ -66,8 +61,7 @@ export default class ApolloCmd extends BaseCommand {
|
|
|
66
61
|
const { flags } = await this.parse(ApolloCmd);
|
|
67
62
|
const endCoord = flags.end ?? Number.MAX_SAFE_INTEGER;
|
|
68
63
|
if (flags.start <= 0 || endCoord <= 0) {
|
|
69
|
-
this.
|
|
70
|
-
this.exit(1);
|
|
64
|
+
this.error('Start and end coordinates must be greater than 0.');
|
|
71
65
|
}
|
|
72
66
|
const access = await this.getAccess(flags['config-file'], flags.profile);
|
|
73
67
|
let assembly = undefined;
|
|
@@ -76,16 +70,9 @@ export default class ApolloCmd extends BaseCommand {
|
|
|
76
70
|
[assembly] = idReader([flags.assembly]);
|
|
77
71
|
}
|
|
78
72
|
let refseqIds = [];
|
|
79
|
-
|
|
80
|
-
refseqIds = await getRefseqId(access.address, access.accessToken, flags.refseq, assembly);
|
|
81
|
-
}
|
|
82
|
-
catch (error) {
|
|
83
|
-
this.logToStderr(error.message);
|
|
84
|
-
this.exit(1);
|
|
85
|
-
}
|
|
73
|
+
refseqIds = await getRefseqId(access.address, access.accessToken, flags.refseq, assembly);
|
|
86
74
|
if (refseqIds.length === 0) {
|
|
87
|
-
this.
|
|
88
|
-
this.exit(1);
|
|
75
|
+
this.error('No reference sequence found');
|
|
89
76
|
}
|
|
90
77
|
const refs = await queryApollo(access.address, access.accessToken, 'refSeqs');
|
|
91
78
|
const refSeqs = (await refs.json());
|
|
@@ -95,8 +82,8 @@ export default class ApolloCmd extends BaseCommand {
|
|
|
95
82
|
const seq = new TextDecoder().decode(seqObj?.value);
|
|
96
83
|
let header = '';
|
|
97
84
|
for (const x of refSeqs) {
|
|
98
|
-
if (x
|
|
99
|
-
const rname = x
|
|
85
|
+
if (x._id === rid) {
|
|
86
|
+
const rname = x.name;
|
|
100
87
|
header = `>${rname}:${flags.start}..${flags.start + seq.length - 1}`;
|
|
101
88
|
break;
|
|
102
89
|
}
|
|
@@ -104,7 +91,6 @@ export default class ApolloCmd extends BaseCommand {
|
|
|
104
91
|
this.log(header);
|
|
105
92
|
this.log(splitStringIntoChunks(seq, 80).join('\n'));
|
|
106
93
|
}
|
|
107
|
-
this.exit(0);
|
|
108
94
|
}
|
|
109
95
|
}
|
|
110
96
|
function splitStringIntoChunks(input, chunkSize) {
|
|
@@ -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.
|
|
10
|
+
copyFile(`${TEST_DATA_DIR}/complete_config.yml`, CONFIG_FILE, VERBOSE);
|
|
11
11
|
});
|
|
12
12
|
after(() => {
|
|
13
13
|
fs.rmSync(CONFIG_FILE);
|
package/dist/commands/config.js
CHANGED
|
@@ -5,8 +5,8 @@ import password from '@inquirer/password';
|
|
|
5
5
|
import select from '@inquirer/select';
|
|
6
6
|
import { Args, Flags } from '@oclif/core';
|
|
7
7
|
import { fetch } from 'undici';
|
|
8
|
+
import { ApolloConf, KEYS, optionDesc } from '../ApolloConf.js';
|
|
8
9
|
import { BaseCommand } from '../baseCommand.js';
|
|
9
|
-
import { Config, ConfigError, KEYS, optionDesc } from '../Config.js';
|
|
10
10
|
import { createFetchErrorMessage, localhostToAddress, wrapLines, } from '../utils.js';
|
|
11
11
|
export default class ApolloConfig extends BaseCommand {
|
|
12
12
|
static summary = 'Get or set apollo configuration options';
|
|
@@ -53,13 +53,13 @@ export default class ApolloConfig extends BaseCommand {
|
|
|
53
53
|
let configFile = flags['config-file'];
|
|
54
54
|
configFile =
|
|
55
55
|
configFile === undefined
|
|
56
|
-
? path.join(this.config.configDir, 'config.
|
|
56
|
+
? path.join(this.config.configDir, 'config.yml')
|
|
57
57
|
: path.resolve(configFile);
|
|
58
58
|
if (flags['get-config-file']) {
|
|
59
59
|
this.log(configFile);
|
|
60
|
-
|
|
60
|
+
return;
|
|
61
61
|
}
|
|
62
|
-
const config = new
|
|
62
|
+
const config = new ApolloConf(configFile);
|
|
63
63
|
if (args.key === undefined) {
|
|
64
64
|
await this.interactiveSetup(config, flags.profile);
|
|
65
65
|
}
|
|
@@ -71,33 +71,16 @@ export default class ApolloConfig extends BaseCommand {
|
|
|
71
71
|
if (flags.profile !== undefined) {
|
|
72
72
|
profileName = flags.profile;
|
|
73
73
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
config.set(args.key, args.value, profileName);
|
|
81
|
-
}
|
|
74
|
+
if (args.value === undefined) {
|
|
75
|
+
const currentValue = config.get(`${profileName}.${args.key}`);
|
|
76
|
+
this.log(currentValue);
|
|
77
|
+
return;
|
|
82
78
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
this.logToStderr(error.message);
|
|
86
|
-
}
|
|
87
|
-
this.exit(1);
|
|
79
|
+
if (args.key === 'accessType') {
|
|
80
|
+
config.setAccessType(profileName, args.value);
|
|
88
81
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (v) {
|
|
92
|
-
this.logToStderr(v);
|
|
93
|
-
}
|
|
94
|
-
try {
|
|
95
|
-
config.writeConfigFile();
|
|
96
|
-
}
|
|
97
|
-
catch (error) {
|
|
98
|
-
if (error instanceof ConfigError) {
|
|
99
|
-
this.logToStderr(error.message);
|
|
100
|
-
this.exit(1);
|
|
82
|
+
else {
|
|
83
|
+
config.set(`${profileName}.${args.key}`, args.value);
|
|
101
84
|
}
|
|
102
85
|
}
|
|
103
86
|
}
|
|
@@ -107,34 +90,19 @@ export default class ApolloConfig extends BaseCommand {
|
|
|
107
90
|
}
|
|
108
91
|
let setMe = true;
|
|
109
92
|
while (setMe) {
|
|
110
|
-
const address = await this.askAddress(config.get(KEYS[KEYS.address]
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
setMe = false;
|
|
114
|
-
}
|
|
115
|
-
catch (error) {
|
|
116
|
-
if (error instanceof ConfigError) {
|
|
117
|
-
this.logToStderr(error.message);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
93
|
+
const address = await this.askAddress(config.get(`${profileName}.${KEYS[KEYS.address]}`));
|
|
94
|
+
config.set(`${profileName}.${KEYS[KEYS.address]}`, address);
|
|
95
|
+
setMe = false;
|
|
120
96
|
}
|
|
121
|
-
const address = config.get(KEYS[KEYS.address]
|
|
97
|
+
const address = config.get(`${profileName}.${KEYS[KEYS.address]}`);
|
|
122
98
|
let accessType = '';
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
catch (error) {
|
|
127
|
-
if (error instanceof ConfigError) {
|
|
128
|
-
this.logToStderr(error.message);
|
|
129
|
-
this.exit(1);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
config.set(KEYS[KEYS.accessType], accessType, profileName);
|
|
99
|
+
accessType = await this.selectAccessType(address);
|
|
100
|
+
config.setAccessType(profileName, accessType);
|
|
133
101
|
if (accessType === 'root') {
|
|
134
|
-
const username = await this.askUsername(config.get(KEYS.rootCredentials_username
|
|
135
|
-
config.set(
|
|
102
|
+
const username = await this.askUsername(config.get(`${profileName}.${KEYS.rootCredentials_username}`));
|
|
103
|
+
config.set(`${profileName}.rootCredentials.username`, username);
|
|
136
104
|
const password = await this.askPassword();
|
|
137
|
-
config.set(
|
|
105
|
+
config.set(`${profileName}.rootCredentials.password`, password);
|
|
138
106
|
}
|
|
139
107
|
}
|
|
140
108
|
async askProfileName(currentProfiles) {
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
|
2
|
-
/* eslint-disable @typescript-eslint/restrict-plus-operands */
|
|
3
|
-
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
4
1
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
5
2
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
6
3
|
import { Flags } from '@oclif/core';
|
|
@@ -42,44 +39,38 @@ export default class Get extends BaseCommand {
|
|
|
42
39
|
async run() {
|
|
43
40
|
const { flags } = await this.parse(Get);
|
|
44
41
|
if (flags.end < flags.start) {
|
|
45
|
-
this.
|
|
46
|
-
this.exit(1);
|
|
42
|
+
this.error('Error: End coordinate is lower than the start coordinate');
|
|
47
43
|
}
|
|
48
44
|
if (flags.start <= 0) {
|
|
49
|
-
this.
|
|
50
|
-
this.exit(1);
|
|
45
|
+
this.error('Coordinates must be greater than 0');
|
|
51
46
|
}
|
|
52
47
|
const ff = idReader([flags['feature-id']]);
|
|
53
48
|
if (ff.length !== 1) {
|
|
54
|
-
this.
|
|
49
|
+
this.error(`Expected only one feature identifier. Got ${ff.length}`);
|
|
55
50
|
}
|
|
56
51
|
const [featureId] = ff;
|
|
57
52
|
const access = await this.getAccess(flags['config-file'], flags.profile);
|
|
58
|
-
const
|
|
59
|
-
if (!
|
|
60
|
-
const errorMessage = await createFetchErrorMessage(
|
|
53
|
+
const res = await getFeatureById(access.address, access.accessToken, featureId);
|
|
54
|
+
if (!res.ok) {
|
|
55
|
+
const errorMessage = await createFetchErrorMessage(res, 'getFeatureById failed');
|
|
61
56
|
throw new Error(errorMessage);
|
|
62
57
|
}
|
|
63
|
-
const feature = JSON.parse(await
|
|
58
|
+
const feature = JSON.parse(await res.text());
|
|
64
59
|
const childRes = await this.addChild(access.address, access.accessToken, feature, flags.start - 1, flags.end, flags.type);
|
|
65
60
|
if (!childRes.ok) {
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
this.logToStderr(message);
|
|
69
|
-
this.exit(1);
|
|
61
|
+
const errorMessage = await createFetchErrorMessage(childRes, 'Add child failed');
|
|
62
|
+
throw new Error(errorMessage);
|
|
70
63
|
}
|
|
71
|
-
this.exit(0);
|
|
72
64
|
}
|
|
73
|
-
async addChild(address, accessToken, parentFeature,
|
|
74
|
-
const
|
|
75
|
-
const
|
|
76
|
-
if (
|
|
77
|
-
this.
|
|
78
|
-
this.exit(1);
|
|
65
|
+
async addChild(address, accessToken, parentFeature, min, max, type) {
|
|
66
|
+
const pMin = parentFeature.min;
|
|
67
|
+
const pMax = parentFeature.max;
|
|
68
|
+
if (min < pMin || max > pMax) {
|
|
69
|
+
this.error(`Error: Child feature coordinates (${min + 1}-${max}) cannot extend beyond parent coordinates (${pMin + 1}-${pMax})`);
|
|
79
70
|
}
|
|
80
71
|
const res = await queryApollo(address, accessToken, 'refSeqs');
|
|
81
72
|
const refSeqs = (await res.json());
|
|
82
|
-
const refSeq = parentFeature
|
|
73
|
+
const { refSeq } = parentFeature;
|
|
83
74
|
let assembly = '';
|
|
84
75
|
for (const x of refSeqs) {
|
|
85
76
|
if (x['_id'] === refSeq) {
|
|
@@ -89,17 +80,18 @@ export default class Get extends BaseCommand {
|
|
|
89
80
|
}
|
|
90
81
|
const change = {
|
|
91
82
|
typeName: 'AddFeatureChange',
|
|
92
|
-
|
|
83
|
+
// eslint-disable-next-line unicorn/consistent-destructuring
|
|
84
|
+
changedIds: [parentFeature._id],
|
|
93
85
|
assembly,
|
|
94
86
|
addedFeature: {
|
|
95
87
|
_id: new ObjectId().toHexString(),
|
|
96
|
-
gffId: '',
|
|
97
88
|
refSeq,
|
|
98
|
-
|
|
99
|
-
|
|
89
|
+
min,
|
|
90
|
+
max,
|
|
100
91
|
type,
|
|
101
92
|
},
|
|
102
|
-
|
|
93
|
+
// eslint-disable-next-line unicorn/consistent-destructuring
|
|
94
|
+
parentFeatureId: parentFeature._id,
|
|
103
95
|
};
|
|
104
96
|
const url = new URL(localhostToAddress(`${address}/changes`));
|
|
105
97
|
const auth = {
|
|
@@ -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
|
|
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
|
|
61
|
+
if (keep && refseqId.has(chk.refSeq)) {
|
|
62
62
|
results.push(chk);
|
|
63
63
|
}
|
|
64
64
|
}
|
|
@@ -71,7 +71,7 @@ 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
|
|
74
|
+
keepAssembly.push(x._id);
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
else {
|
|
@@ -38,42 +38,31 @@ export default class Copy extends BaseCommand {
|
|
|
38
38
|
async run() {
|
|
39
39
|
const { flags } = await this.parse(Copy);
|
|
40
40
|
if (flags.start <= 0) {
|
|
41
|
-
this.
|
|
42
|
-
this.exit(1);
|
|
41
|
+
this.error('Start coordinate must be greater than 0');
|
|
43
42
|
}
|
|
44
43
|
const access = await this.getAccess(flags['config-file'], flags.profile);
|
|
45
|
-
const
|
|
46
|
-
if (!
|
|
47
|
-
const errorMessage = await createFetchErrorMessage(
|
|
44
|
+
const res = await getFeatureById(access.address, access.accessToken, flags['feature-id']);
|
|
45
|
+
if (!res.ok) {
|
|
46
|
+
const errorMessage = await createFetchErrorMessage(res, 'getFeatureById failed');
|
|
48
47
|
throw new Error(errorMessage);
|
|
49
48
|
}
|
|
50
|
-
const feature = (await
|
|
49
|
+
const feature = (await res.json());
|
|
51
50
|
let refseqIds = [];
|
|
52
|
-
|
|
53
|
-
refseqIds = await getRefseqId(access.address, access.accessToken, flags.refseq, flags.assembly);
|
|
54
|
-
}
|
|
55
|
-
catch (error) {
|
|
56
|
-
this.logToStderr(error.message);
|
|
57
|
-
this.exit(1);
|
|
58
|
-
}
|
|
51
|
+
refseqIds = await getRefseqId(access.address, access.accessToken, flags.refseq, flags.assembly);
|
|
59
52
|
if (refseqIds.length === 0) {
|
|
60
|
-
this.
|
|
61
|
-
this.exit(1);
|
|
53
|
+
this.error('No reference sequence found');
|
|
62
54
|
}
|
|
63
55
|
const [refseq] = refseqIds;
|
|
64
56
|
const assembly = await getAssemblyFromRefseq(access.address, access.accessToken, refseq);
|
|
65
57
|
const newId = new ObjectId().toHexString();
|
|
66
58
|
const rescopy = await this.copyFeature(access.address, access.accessToken, feature, refseq, flags.start, assembly, newId);
|
|
67
59
|
if (!rescopy.ok) {
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
this.exit(1);
|
|
60
|
+
const errorMessage = await createFetchErrorMessage(rescopy, 'Copy feature failed');
|
|
61
|
+
throw new Error(errorMessage);
|
|
71
62
|
}
|
|
72
|
-
this.exit(0);
|
|
73
63
|
}
|
|
74
|
-
async copyFeature(address, accessToken, feature, refseq,
|
|
75
|
-
const featureLen = feature
|
|
76
|
-
feature['start'];
|
|
64
|
+
async copyFeature(address, accessToken, feature, refseq, min, assembly, newId) {
|
|
65
|
+
const featureLen = feature.max - feature.min;
|
|
77
66
|
const change = {
|
|
78
67
|
typeName: 'AddFeatureChange',
|
|
79
68
|
changedIds: [newId],
|
|
@@ -81,12 +70,11 @@ export default class Copy extends BaseCommand {
|
|
|
81
70
|
addedFeature: {
|
|
82
71
|
_id: newId,
|
|
83
72
|
refSeq: refseq,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
type: feature
|
|
87
|
-
attributes: feature
|
|
88
|
-
|
|
89
|
-
strand: feature['strand'],
|
|
73
|
+
min: min - 1,
|
|
74
|
+
max: min + featureLen - 1,
|
|
75
|
+
type: feature.type,
|
|
76
|
+
attributes: feature.attributes,
|
|
77
|
+
strand: feature.strand,
|
|
90
78
|
},
|
|
91
79
|
copyFeature: true,
|
|
92
80
|
allIds: [newId],
|
|
@@ -100,11 +88,11 @@ export default class Copy extends BaseCommand {
|
|
|
100
88
|
'Content-Type': 'application/json',
|
|
101
89
|
},
|
|
102
90
|
};
|
|
103
|
-
const
|
|
104
|
-
if (!
|
|
105
|
-
const errorMessage = await createFetchErrorMessage(
|
|
91
|
+
const res = await fetch(url, auth);
|
|
92
|
+
if (!res.ok) {
|
|
93
|
+
const errorMessage = await createFetchErrorMessage(res, 'copyFeature failed');
|
|
106
94
|
throw new Error(errorMessage);
|
|
107
95
|
}
|
|
108
|
-
return
|
|
96
|
+
return res;
|
|
109
97
|
}
|
|
110
98
|
}
|