@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.
- package/README.md +374 -135
- package/bin/dev.js +2 -2
- package/bin/run.js +2 -2
- package/dist/ApolloConf.js +1 -0
- package/dist/baseCommand.d.ts +1 -1
- package/dist/baseCommand.js +7 -7
- package/dist/commands/assembly/add-from-fasta.d.ts +23 -0
- package/dist/commands/assembly/add-from-fasta.js +165 -0
- package/dist/commands/assembly/{add-gff.d.ts → add-from-gff.d.ts} +5 -3
- package/dist/commands/assembly/{add-gff.js → add-from-gff.js} +20 -22
- package/dist/commands/assembly/check.js +9 -9
- package/dist/commands/assembly/delete.js +4 -4
- package/dist/commands/assembly/get.js +4 -4
- package/dist/commands/assembly/get.test.js +3 -3
- package/dist/commands/assembly/sequence.js +8 -14
- package/dist/commands/change/get.js +7 -7
- package/dist/commands/change/get.test.js +1 -1
- package/dist/commands/config.js +4 -5
- package/dist/commands/feature/add-child.js +18 -19
- package/dist/commands/feature/check.js +11 -11
- package/dist/commands/feature/copy.js +12 -14
- package/dist/commands/feature/delete.js +13 -19
- package/dist/commands/feature/edit-attribute.js +18 -11
- package/dist/commands/feature/edit-coords.js +36 -21
- package/dist/commands/feature/edit-type.js +7 -11
- package/dist/commands/feature/edit.js +5 -6
- package/dist/commands/feature/get-id.js +5 -6
- package/dist/commands/feature/get.js +3 -4
- package/dist/commands/feature/import.d.ts +2 -2
- package/dist/commands/feature/import.js +26 -39
- package/dist/commands/feature/search.js +7 -7
- package/dist/commands/file/delete.d.ts +13 -0
- package/dist/commands/file/delete.js +58 -0
- package/dist/commands/file/download.d.ts +14 -0
- package/dist/commands/file/download.js +45 -0
- package/dist/commands/file/get.d.ts +13 -0
- package/dist/commands/file/get.js +38 -0
- package/dist/commands/file/upload.d.ts +16 -0
- package/dist/commands/file/upload.js +88 -0
- package/dist/commands/jbrowse/get-config.d.ts +10 -0
- package/dist/commands/jbrowse/get-config.js +21 -0
- package/dist/commands/jbrowse/set-config.d.ts +13 -0
- package/dist/commands/jbrowse/set-config.js +51 -0
- package/dist/commands/login.js +12 -16
- package/dist/commands/logout.js +3 -3
- package/dist/commands/{assembly/add-fasta.d.ts → refseq/add-alias.d.ts} +3 -4
- package/dist/commands/refseq/add-alias.js +72 -0
- package/dist/commands/refseq/get.js +8 -8
- package/dist/commands/status.js +5 -4
- package/dist/commands/user/get.js +3 -3
- package/dist/commands/user/get.test.js +1 -1
- package/dist/fileCommand.d.ts +5 -0
- package/dist/fileCommand.js +76 -0
- package/dist/test/fixtures.js +2 -2
- package/dist/utils.d.ts +20 -9
- package/dist/utils.js +33 -80
- package/oclif.manifest.json +495 -58
- package/package.json +56 -42
- 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
package/dist/ApolloConf.js
CHANGED
package/dist/baseCommand.d.ts
CHANGED
|
@@ -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(
|
|
13
|
+
getAccess(): Promise<{
|
|
14
14
|
address: string;
|
|
15
15
|
accessToken: string;
|
|
16
16
|
}>;
|
package/dist/baseCommand.js
CHANGED
|
@@ -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.
|
|
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(
|
|
35
|
+
async getAccess() {
|
|
36
|
+
const { 'config-file': configFile, profile } = this.flags;
|
|
36
37
|
const config = this.getConfig(configFile);
|
|
37
|
-
|
|
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
|
-
|
|
44
|
-
|
|
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 {
|
|
2
|
-
export default class AddGff extends
|
|
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 {
|
|
6
|
-
import {
|
|
7
|
-
export default class AddGff extends
|
|
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 =
|
|
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 %>
|
|
17
|
+
command: '<%= config.bin %> <%= command.id %> genome.gff -a myAssembly -o',
|
|
18
18
|
},
|
|
19
19
|
];
|
|
20
|
-
static
|
|
21
|
-
'input-file':
|
|
22
|
-
|
|
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(
|
|
42
|
-
this.error(`File ${
|
|
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(
|
|
45
|
-
const fileId = await uploadFile(access.address, access.accessToken,
|
|
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(
|
|
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
|
|
58
|
-
|
|
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,
|
|
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 =
|
|
58
|
-
|
|
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(
|
|
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
|
|
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,
|
|
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 =
|
|
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(
|
|
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
|
|
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 =
|
|
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(
|
|
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.
|
|
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,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,
|
|
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
|
-
|
|
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 =
|
|
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(
|
|
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
|
|
91
|
-
const rname = x
|
|
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
|
|
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 =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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(
|
|
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.
|
|
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
|
@@ -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
|
|
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 =
|
|
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.
|
|
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);
|