@apollo-annotation/cli 0.1.19 → 0.1.21
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 +297 -115
- package/dist/baseCommand.d.ts +1 -1
- package/dist/baseCommand.js +3 -4
- package/dist/commands/assembly/add-from-fasta.d.ts +22 -0
- package/dist/commands/assembly/add-from-fasta.js +157 -0
- package/dist/commands/assembly/{add-gff.d.ts → add-from-gff.d.ts} +5 -3
- package/dist/commands/assembly/add-from-gff.js +64 -0
- 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/sequence.js +4 -4
- package/dist/commands/change/get.js +7 -7
- package/dist/commands/config.js +4 -6
- package/dist/commands/feature/add-child.js +6 -5
- package/dist/commands/feature/check.js +6 -6
- package/dist/commands/feature/copy.js +5 -4
- package/dist/commands/feature/delete.js +4 -4
- package/dist/commands/feature/edit-attribute.js +6 -5
- package/dist/commands/feature/edit-coords.js +5 -5
- package/dist/commands/feature/edit-type.js +5 -5
- package/dist/commands/feature/edit.js +5 -5
- package/dist/commands/feature/get-id.js +5 -5
- package/dist/commands/feature/get.js +3 -3
- package/dist/commands/feature/import.d.ts +5 -3
- package/dist/commands/feature/import.js +15 -14
- package/dist/commands/feature/search.js +6 -6
- 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 +18 -0
- package/dist/commands/file/upload.js +89 -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 +11 -15
- package/dist/commands/logout.js +2 -2
- package/dist/commands/refseq/add-alias.d.ts +3 -1
- package/dist/commands/refseq/add-alias.js +13 -12
- package/dist/commands/refseq/get.js +8 -8
- package/dist/commands/status.js +4 -3
- package/dist/commands/user/get.js +3 -3
- package/dist/fileCommand.d.ts +5 -0
- package/dist/fileCommand.js +76 -0
- package/dist/utils.d.ts +7 -21
- package/dist/utils.js +37 -109
- package/oclif.manifest.json +449 -90
- package/package.json +50 -43
- package/dist/commands/assembly/add-fasta.d.ts +0 -15
- package/dist/commands/assembly/add-fasta.js +0 -87
- package/dist/commands/assembly/add-gff.js +0 -63
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
|
@@ -32,11 +32,10 @@ export class BaseCommand extends Command {
|
|
|
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) {
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
force: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
15
|
+
editable: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
16
|
+
fai: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
17
|
+
gzi: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
18
|
+
gzip: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
19
|
+
decompressed: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
20
|
+
};
|
|
21
|
+
run(): Promise<void>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
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 \
|
|
27
|
+
file. For local or remote files, it is assumed the file is bgzip'd with \
|
|
28
|
+
`bgzip` and indexed with `samtools faidx`. The indexes are assumed to be at \
|
|
29
|
+
<my.fasta.gz>.fai and <my.fasta.gz>.gzi unless the options --fai and --gzi are \
|
|
30
|
+
provided.",
|
|
31
|
+
required: true,
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
static flags = {
|
|
35
|
+
assembly: Flags.string({
|
|
36
|
+
char: 'a',
|
|
37
|
+
description: 'Name for this assembly. Use the file name if omitted',
|
|
38
|
+
}),
|
|
39
|
+
force: Flags.boolean({
|
|
40
|
+
char: 'f',
|
|
41
|
+
description: 'Delete existing assembly, if it exists',
|
|
42
|
+
}),
|
|
43
|
+
editable: Flags.boolean({
|
|
44
|
+
char: 'e',
|
|
45
|
+
description: 'Instead of using indexed fasta lookup, the sequence is loaded into \
|
|
46
|
+
the Apollo database and is editable. Use with caution, as editing the sequence \
|
|
47
|
+
often has unintended side effects.',
|
|
48
|
+
}),
|
|
49
|
+
fai: Flags.string({
|
|
50
|
+
description: 'Fasta index of the (not-editable) fasta file',
|
|
51
|
+
}),
|
|
52
|
+
gzi: Flags.string({
|
|
53
|
+
description: 'Gzi index of the (not-editable) fasta file',
|
|
54
|
+
}),
|
|
55
|
+
gzip: Flags.boolean({
|
|
56
|
+
char: 'z',
|
|
57
|
+
description: 'For local file input: Override autodetection and instruct that input is gzip compressed',
|
|
58
|
+
exclusive: ['decompressed'],
|
|
59
|
+
}),
|
|
60
|
+
decompressed: Flags.boolean({
|
|
61
|
+
char: 'd',
|
|
62
|
+
description: 'For local file input: Override autodetection and instruct that input is decompressed',
|
|
63
|
+
exclusive: ['gzip'],
|
|
64
|
+
}),
|
|
65
|
+
};
|
|
66
|
+
async run() {
|
|
67
|
+
const { args, flags } = await this.parse(AddFasta);
|
|
68
|
+
const access = await this.getAccess();
|
|
69
|
+
const assemblyName = flags.assembly ?? path.basename(args.input);
|
|
70
|
+
const fastaIsFileId = await isFileId(args.input, access.address, access.accessToken);
|
|
71
|
+
const isExternal = isValidHttpUrl(args.input);
|
|
72
|
+
let body;
|
|
73
|
+
if (isExternal) {
|
|
74
|
+
const fai = flags.fai ?? `${args.input}.fai`;
|
|
75
|
+
const gzi = flags.gzi ?? `${args.input}.gzi`;
|
|
76
|
+
body = {
|
|
77
|
+
assemblyName,
|
|
78
|
+
typeName: 'AddAssemblyFromExternalChange',
|
|
79
|
+
externalLocation: { fa: args.input, fai, gzi },
|
|
80
|
+
assembly: new ObjectId().toHexString(),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
else if (flags.editable) {
|
|
84
|
+
if (!isExternal && !fs.existsSync(args.input) && !fastaIsFileId) {
|
|
85
|
+
this.error(`Input "${args.input}" is not valid`);
|
|
86
|
+
}
|
|
87
|
+
let isGzip = args.input.endsWith('.gz');
|
|
88
|
+
if (flags.gzip) {
|
|
89
|
+
isGzip = true;
|
|
90
|
+
}
|
|
91
|
+
if (flags.decompressed) {
|
|
92
|
+
isGzip = false;
|
|
93
|
+
}
|
|
94
|
+
const fileId = fastaIsFileId
|
|
95
|
+
? args.input
|
|
96
|
+
: await this.uploadFile(access.address, access.accessToken, args.input, 'text/x-fasta', isGzip);
|
|
97
|
+
body = {
|
|
98
|
+
assemblyName,
|
|
99
|
+
fileIds: { fa: fileId },
|
|
100
|
+
typeName: 'AddAssemblyFromFileChange',
|
|
101
|
+
assembly: new ObjectId().toHexString(),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
const gzi = flags.gzi ?? `${args.input}.gzi`;
|
|
106
|
+
const fai = flags.fai ?? `${args.input}.fai`;
|
|
107
|
+
const gziIsFileId = await isFileId(gzi, access.address, access.accessToken);
|
|
108
|
+
const faiIsFileId = await isFileId(fai, access.address, access.accessToken);
|
|
109
|
+
if (!fs.existsSync(gzi) && !gziIsFileId) {
|
|
110
|
+
this.error(`Only bgzip'd and indexed fasta files are supported at the moment. "${gzi}" is neither a file or a file id`);
|
|
111
|
+
}
|
|
112
|
+
if (!fs.existsSync(fai) && !faiIsFileId) {
|
|
113
|
+
this.error(`Only bgzip'd and indexed fasta files are supported at the moment. "${fai}" is neither a file or a file id`);
|
|
114
|
+
}
|
|
115
|
+
const faId = fastaIsFileId
|
|
116
|
+
? args.input
|
|
117
|
+
: await this.uploadFile(access.address, access.accessToken, args.input, 'application/x-bgzip-fasta', true);
|
|
118
|
+
const faiId = faiIsFileId
|
|
119
|
+
? fai
|
|
120
|
+
: await this.uploadFile(access.address, access.accessToken, fai, 'text/x-fai', false);
|
|
121
|
+
const gziId = gziIsFileId
|
|
122
|
+
? gzi
|
|
123
|
+
: await this.uploadFile(access.address, access.accessToken, gzi, 'application/x-gzi', false);
|
|
124
|
+
body = {
|
|
125
|
+
assemblyName,
|
|
126
|
+
typeName: 'AddAssemblyFromFileChange',
|
|
127
|
+
fileIds: { fa: faId, fai: faiId, gzi: gziId },
|
|
128
|
+
assembly: new ObjectId().toHexString(),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
const rec = await submitAssembly(access.address, access.accessToken, body, flags.force);
|
|
132
|
+
this.log(JSON.stringify(rec, null, 2));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function isValidHttpUrl(x) {
|
|
136
|
+
let url;
|
|
137
|
+
try {
|
|
138
|
+
url = new URL(x);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
return url.protocol === 'http:' || url.protocol === 'https:';
|
|
144
|
+
}
|
|
145
|
+
async function isFileId(x, address, accessToken) {
|
|
146
|
+
if (x.length != 24) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
const files = await queryApollo(address, accessToken, 'files');
|
|
150
|
+
const json = (await files.json());
|
|
151
|
+
for (const fileDoc of json) {
|
|
152
|
+
if (fileDoc['_id'] === x) {
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
@@ -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>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { Args, Flags } from '@oclif/core';
|
|
4
|
+
import { ObjectId } from 'bson';
|
|
5
|
+
import { FileCommand } from '../../fileCommand.js';
|
|
6
|
+
import { submitAssembly } from '../../utils.js';
|
|
7
|
+
export default class AddGff extends FileCommand {
|
|
8
|
+
static summary = 'Add new assembly from gff or gft file';
|
|
9
|
+
static description = 'The gff file is expected to contain sequences as per gff specifications. Features are also imported by default.';
|
|
10
|
+
static examples = [
|
|
11
|
+
{
|
|
12
|
+
description: 'Import sequences and features:',
|
|
13
|
+
command: '<%= config.bin %> <%= command.id %> genome.gff -a myAssembly',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
description: 'Import sequences only:',
|
|
17
|
+
command: '<%= config.bin %> <%= command.id %> genome.gff -a myAssembly -o',
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
static args = {
|
|
21
|
+
'input-file': Args.string({
|
|
22
|
+
description: 'Input gff file',
|
|
23
|
+
required: true,
|
|
24
|
+
}),
|
|
25
|
+
};
|
|
26
|
+
static flags = {
|
|
27
|
+
assembly: Flags.string({
|
|
28
|
+
char: 'a',
|
|
29
|
+
description: 'Name for this assembly. Use the file name if omitted',
|
|
30
|
+
}),
|
|
31
|
+
'omit-features': Flags.boolean({
|
|
32
|
+
char: 'o',
|
|
33
|
+
description: 'Do not import features, only upload the sequences',
|
|
34
|
+
}),
|
|
35
|
+
force: Flags.boolean({
|
|
36
|
+
char: 'f',
|
|
37
|
+
description: 'Delete existing assembly, if it exists',
|
|
38
|
+
}),
|
|
39
|
+
};
|
|
40
|
+
async run() {
|
|
41
|
+
const { args, flags } = await this.parse(AddGff);
|
|
42
|
+
if (!fs.existsSync(args['input-file'])) {
|
|
43
|
+
this.error(`File ${args['input-file']} does not exist`);
|
|
44
|
+
}
|
|
45
|
+
const access = await this.getAccess();
|
|
46
|
+
const fileId = await this.uploadFile(access.address, access.accessToken, args['input-file'], 'text/x-gff3', args['input-file'].endsWith('.gz'));
|
|
47
|
+
const assemblyName = flags.assembly ?? path.basename(args['input-file']);
|
|
48
|
+
const body = flags['omit-features']
|
|
49
|
+
? {
|
|
50
|
+
assemblyName,
|
|
51
|
+
fileIds: { fa: fileId },
|
|
52
|
+
typeName: 'AddAssemblyFromFileChange',
|
|
53
|
+
assembly: new ObjectId().toHexString(),
|
|
54
|
+
}
|
|
55
|
+
: {
|
|
56
|
+
assemblyName,
|
|
57
|
+
fileIds: { fa: fileId },
|
|
58
|
+
typeName: 'AddAssemblyAndFeaturesFromFileChange',
|
|
59
|
+
assembly: new ObjectId().toHexString(),
|
|
60
|
+
};
|
|
61
|
+
const rec = await submitAssembly(access.address, access.accessToken, body, flags.force);
|
|
62
|
+
this.log(JSON.stringify(rec, null, 2));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -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());
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Flags } from '@oclif/core';
|
|
3
3
|
import { Agent, fetch } from 'undici';
|
|
4
4
|
import { BaseCommand } from '../../baseCommand.js';
|
|
5
|
-
import { createFetchErrorMessage, getRefseqId, idReader, localhostToAddress, queryApollo,
|
|
5
|
+
import { createFetchErrorMessage, getRefseqId, idReader, localhostToAddress, queryApollo, } from '../../utils.js';
|
|
6
6
|
async function getSequence(address, accessToken, refSeq, start, end) {
|
|
7
7
|
const url = new URL(localhostToAddress(`${address}/sequence`));
|
|
8
8
|
const searchParams = new URLSearchParams({
|
|
@@ -27,7 +27,7 @@ async function getSequence(address, accessToken, refSeq, start, end) {
|
|
|
27
27
|
}
|
|
28
28
|
export default class ApolloCmd extends BaseCommand {
|
|
29
29
|
static summary = 'Get reference sequence in fasta format';
|
|
30
|
-
static description =
|
|
30
|
+
static description = 'Return the reference sequence for a given assembly and coordinates';
|
|
31
31
|
static examples = [
|
|
32
32
|
{
|
|
33
33
|
description: 'Get all sequences in myAssembly:',
|
|
@@ -63,11 +63,11 @@ export default class ApolloCmd extends BaseCommand {
|
|
|
63
63
|
if (flags.start <= 0 || endCoord <= 0) {
|
|
64
64
|
this.error('Start and end coordinates must be greater than 0.');
|
|
65
65
|
}
|
|
66
|
-
const access = await this.getAccess(
|
|
66
|
+
const access = await this.getAccess();
|
|
67
67
|
let assembly = undefined;
|
|
68
68
|
if (flags.assembly !== undefined) {
|
|
69
69
|
;
|
|
70
|
-
[assembly] = idReader([flags.assembly]);
|
|
70
|
+
[assembly] = await idReader([flags.assembly]);
|
|
71
71
|
}
|
|
72
72
|
let refseqIds = [];
|
|
73
73
|
refseqIds = await getRefseqId(access.address, access.accessToken, flags.refseq, assembly);
|
|
@@ -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'])) {
|
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',
|
|
@@ -48,8 +47,7 @@ export default class ApolloConfig extends BaseCommand {
|
|
|
48
47
|
},
|
|
49
48
|
];
|
|
50
49
|
async run() {
|
|
51
|
-
const { args } = await this.parse(ApolloConfig);
|
|
52
|
-
const { flags } = await this.parse(ApolloConfig);
|
|
50
|
+
const { args, flags } = await this.parse(ApolloConfig);
|
|
53
51
|
let configFile = flags['config-file'];
|
|
54
52
|
configFile =
|
|
55
53
|
configFile === undefined
|
|
@@ -4,14 +4,15 @@ import { Flags } from '@oclif/core';
|
|
|
4
4
|
import { ObjectId } from 'bson';
|
|
5
5
|
import { fetch } from 'undici';
|
|
6
6
|
import { BaseCommand } from '../../baseCommand.js';
|
|
7
|
-
import { createFetchErrorMessage, getFeatureById, idReader, localhostToAddress, queryApollo,
|
|
7
|
+
import { createFetchErrorMessage, getFeatureById, idReader, localhostToAddress, queryApollo, } from '../../utils.js';
|
|
8
8
|
export default class Get extends BaseCommand {
|
|
9
9
|
static summary = 'Add a child feature (e.g. add an exon to an mRNA)';
|
|
10
|
-
static description =
|
|
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.';
|
|
11
12
|
static examples = [
|
|
12
13
|
{
|
|
13
14
|
description: 'Add an exon at genomic coordinates 10..20 to this feature ID:',
|
|
14
|
-
command: '<%= config.bin %> <%= command.id %> -i
|
|
15
|
+
command: '<%= config.bin %> <%= command.id %> -i 660...73f -t exon -s 10 -e 20',
|
|
15
16
|
},
|
|
16
17
|
];
|
|
17
18
|
static flags = {
|
|
@@ -44,12 +45,12 @@ export default class Get extends BaseCommand {
|
|
|
44
45
|
if (flags.start <= 0) {
|
|
45
46
|
this.error('Coordinates must be greater than 0');
|
|
46
47
|
}
|
|
47
|
-
const ff = idReader([flags['feature-id']]);
|
|
48
|
+
const ff = await idReader([flags['feature-id']]);
|
|
48
49
|
if (ff.length !== 1) {
|
|
49
50
|
this.error(`Expected only one feature identifier. Got ${ff.length}`);
|
|
50
51
|
}
|
|
51
52
|
const [featureId] = ff;
|
|
52
|
-
const access = await this.getAccess(
|
|
53
|
+
const access = await this.getAccess();
|
|
53
54
|
const res = await getFeatureById(access.address, access.accessToken, featureId);
|
|
54
55
|
if (!res.ok) {
|
|
55
56
|
const errorMessage = await createFetchErrorMessage(res, 'getFeatureById failed');
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Flags } from '@oclif/core';
|
|
2
2
|
import { fetch } from 'undici';
|
|
3
3
|
import { BaseCommand } from '../../baseCommand.js';
|
|
4
|
-
import { convertAssemblyNameToId, createFetchErrorMessage, idReader, localhostToAddress, queryApollo,
|
|
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 =
|
|
8
|
-
|
|
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(
|
|
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');
|
|
@@ -75,7 +75,7 @@ async function keepAssemblies(address, accessToken, assembly) {
|
|
|
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,
|
|
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 =
|
|
9
|
-
|
|
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(
|
|
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');
|
|
@@ -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, getFeatureById, idReader, localhostToAddress,
|
|
4
|
+
import { createFetchErrorMessage, getFeatureById, idReader, localhostToAddress, } from '../../utils.js';
|
|
5
5
|
async function deleteFeature(address, accessToken, feature) {
|
|
6
6
|
const changeJson = {
|
|
7
7
|
typeName: 'DeleteFeatureChange',
|
|
@@ -34,7 +34,7 @@ async function deleteFeature(address, accessToken, feature) {
|
|
|
34
34
|
}
|
|
35
35
|
export default class Delete extends BaseCommand {
|
|
36
36
|
static summary = 'Delete one or more features by ID';
|
|
37
|
-
static description =
|
|
37
|
+
static description = 'Note that deleting a child feature after deleting its parent will result in an error unless you set -f/--force.';
|
|
38
38
|
static flags = {
|
|
39
39
|
'feature-id': Flags.string({
|
|
40
40
|
char: 'i',
|
|
@@ -53,12 +53,12 @@ export default class Delete extends BaseCommand {
|
|
|
53
53
|
};
|
|
54
54
|
async run() {
|
|
55
55
|
const { flags } = await this.parse(Delete);
|
|
56
|
-
const tmpIds = idReader(flags['feature-id']);
|
|
56
|
+
const tmpIds = await idReader(flags['feature-id']);
|
|
57
57
|
const featureIds = new Set();
|
|
58
58
|
for (const x of tmpIds) {
|
|
59
59
|
featureIds.add(x);
|
|
60
60
|
}
|
|
61
|
-
const access = await this.getAccess(
|
|
61
|
+
const access = await this.getAccess();
|
|
62
62
|
for (const featureId of featureIds) {
|
|
63
63
|
const res = await getFeatureById(access.address, access.accessToken, featureId);
|
|
64
64
|
if (res.status === 404 && flags.force) {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Flags } from '@oclif/core';
|
|
2
2
|
import { fetch } from 'undici';
|
|
3
3
|
import { BaseCommand } from '../../baseCommand.js';
|
|
4
|
-
import { createFetchErrorMessage, getAssemblyFromRefseq, getFeatureById, idReader, localhostToAddress,
|
|
4
|
+
import { createFetchErrorMessage, getAssemblyFromRefseq, getFeatureById, idReader, localhostToAddress, } from '../../utils.js';
|
|
5
5
|
export default class EditAttibute extends BaseCommand {
|
|
6
6
|
static summary = 'Add, edit, or view a feature attribute';
|
|
7
|
-
static description =
|
|
8
|
-
|
|
7
|
+
static description = 'Be aware that there is no checking whether attributes names and values are valid. \
|
|
8
|
+
For example, you can create non-unique ID attributes or you can set gene ontology \
|
|
9
|
+
terms to non-existing terms';
|
|
9
10
|
static examples = [
|
|
10
11
|
{
|
|
11
12
|
description: 'Add attribute "domains" with a list of values:',
|
|
@@ -46,12 +47,12 @@ export default class EditAttibute extends BaseCommand {
|
|
|
46
47
|
if (flags.delete && flags.value) {
|
|
47
48
|
this.error('Error: Options --delete and --value are mutually exclusive');
|
|
48
49
|
}
|
|
49
|
-
const ff = idReader([flags['feature-id']]);
|
|
50
|
+
const ff = await idReader([flags['feature-id']]);
|
|
50
51
|
if (ff.length !== 1) {
|
|
51
52
|
this.error(`Expected only one feature identifier. Got ${ff.length}`);
|
|
52
53
|
}
|
|
53
54
|
const [featureId] = ff;
|
|
54
|
-
const access = await this.getAccess(
|
|
55
|
+
const access = await this.getAccess();
|
|
55
56
|
const response = await getFeatureById(access.address, access.accessToken, featureId);
|
|
56
57
|
if (!response.ok) {
|
|
57
58
|
const errorMessage = await createFetchErrorMessage(response, 'getFeatureById failed');
|