@sjcrh/proteinpaint-server 2.84.0 → 2.85.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/package.json +4 -5
  2. package/routes/_template_.js +14 -11
  3. package/routes/brainImaging.js +5 -14
  4. package/routes/brainImagingSamples.js +3 -3
  5. package/routes/burden.js +27 -59
  6. package/routes/dataset.js +9 -17
  7. package/routes/dsdata.js +11 -14
  8. package/routes/dzimages.js +11 -16
  9. package/routes/gdc.maf.js +8 -23
  10. package/routes/gdc.mafBuild.js +9 -9
  11. package/routes/gdc.topMutatedGenes.js +7 -7
  12. package/routes/genelookup.js +16 -34
  13. package/routes/genesetEnrichment.js +18 -14
  14. package/routes/genesetOverrepresentation.js +9 -14
  15. package/routes/healthcheck.js +26 -32
  16. package/routes/hicdata.js +7 -28
  17. package/routes/hicgenome.js +6 -27
  18. package/routes/hicstat.js +4 -22
  19. package/routes/isoformlst.js +8 -11
  20. package/routes/ntseq.js +8 -11
  21. package/routes/pdomain.js +8 -11
  22. package/routes/sampledzimages.js +12 -12
  23. package/routes/samplewsimages.js +6 -10
  24. package/routes/snp.js +8 -10
  25. package/routes/termdb.DE.js +8 -10
  26. package/routes/termdb.boxplot.js +8 -9
  27. package/routes/termdb.categories.js +4 -45
  28. package/routes/termdb.cluster.js +9 -9
  29. package/routes/termdb.cohort.summary.js +5 -8
  30. package/routes/termdb.cohorts.js +3 -7
  31. package/routes/{termdb.getdescrstats.js → termdb.descrstats.js} +8 -45
  32. package/routes/termdb.numericcategories.js +51 -0
  33. package/routes/{termdb.getpercentile.js → termdb.percentile.js} +4 -46
  34. package/routes/{termdb.getrootterm.js → termdb.rootterm.js} +4 -24
  35. package/routes/{termdb.getSampleImages.js → termdb.sampleImages.js} +9 -9
  36. package/routes/termdb.singleSampleMutation.js +3 -7
  37. package/routes/termdb.singlecellDEgenes.js +8 -8
  38. package/routes/termdb.singlecellData.js +4 -8
  39. package/routes/termdb.singlecellSamples.js +8 -8
  40. package/routes/{termdb.gettermchildren.js → termdb.termchildren.js} +8 -28
  41. package/routes/termdb.termsbyids.js +9 -16
  42. package/routes/{termdb.getTopTermsByType.js → termdb.topTermsByType.js} +9 -10
  43. package/routes/termdb.topVariablyExpressedGenes.js +8 -8
  44. package/routes/termdb.violin.js +8 -46
  45. package/routes/tileserver.js +5 -10
  46. package/routes/wsimages.js +10 -9
  47. package/src/app.js +1286 -2148
  48. package/routes/termdb.getnumericcategories.js +0 -91
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjcrh/proteinpaint-server",
3
- "version": "2.84.0",
3
+ "version": "2.85.1",
4
4
  "type": "module",
5
5
  "description": "a genomics visualization tool for exploring a cohort's genotype and phenotype data",
6
6
  "main": "src/app.js",
@@ -28,7 +28,6 @@
28
28
  "dedup": "./dedupjs.sh",
29
29
  "//todo": "refactor or deprecate the scripts below",
30
30
  "pretest": "tsc && ./test/pretest.js",
31
- "prepare": "ts-patch install",
32
31
  "pretest:type": "npm run checkers",
33
32
  "pretest:integration": "tsc",
34
33
  "test:integration": "echo 'TODO: server integration tests'",
@@ -43,7 +42,6 @@
43
42
  "@babel/preset-env": "^7.9.6",
44
43
  "@babel/preset-typescript": "^7.21.4",
45
44
  "@babel/register": "^7.14.5",
46
- "@sjcrh/proteinpaint-types": "2.84.0",
47
45
  "@types/node": "^20.11.24",
48
46
  "@types/tough-cookie": "^4.0.5",
49
47
  "@typescript-eslint/eslint-plugin": "^5.60.0",
@@ -63,9 +61,10 @@
63
61
  "typia": "^4.1.14"
64
62
  },
65
63
  "dependencies": {
66
- "@sjcrh/augen": "2.46.0",
64
+ "@sjcrh/augen": "2.85.0",
67
65
  "@sjcrh/proteinpaint-rust": "2.84.0",
68
- "@sjcrh/proteinpaint-shared": "2.83.0",
66
+ "@sjcrh/proteinpaint-shared": "2.85.0",
67
+ "@sjcrh/proteinpaint-types": "2.85.0",
69
68
  "better-sqlite3": "^9.4.1",
70
69
  "body-parser": "^1.15.2",
71
70
  "canvas": "~2.11.2",
@@ -1,28 +1,31 @@
1
+ import { snpPayload } from "#types";
1
2
  const api = {
2
3
  // route endpoint
3
4
  // - no need for trailing slash
4
- // - should be a noun (method is based on HTTP GET, POST, etc)
5
+ // - should be a noun
5
6
  // - don't add 'Data' as response is assumed to be data
6
- endpoint: "...",
7
+ // - don't prefix with `get`, such as `/getmyroute`, the method is already indicated via HTTP GET
8
+ endpoint: "/myroute",
7
9
  methods: {
8
10
  get: {
9
- init,
10
- request: {
11
- typeId: "any"
12
- },
13
- response: {
14
- typeId: "any"
15
- }
11
+ ...snpPayload,
12
+ // this would "spread"/copy-over payload key-values from snpPayload, such as {request: {typeId}, examples: []}
13
+ init
16
14
  },
17
15
  post: {
18
- alternativeFor: "get",
16
+ ...snpPayload,
17
+ // repeat for post method, since PP routes are mostly read-only and POST can handle bigger payloads
19
18
  init
20
19
  }
20
+ // !!! DO NOT USE expressjs 'all' method shortcut !!!
21
+ // it will initialize 20+ methods includng HEAD which can break expected HTTP response
21
22
  }
22
23
  };
23
24
  function init({ genomes }) {
24
25
  return async function(req, res) {
25
- console.log(genomes, req, res);
26
+ const q = req.query;
27
+ console.log(genomes[q.genome]);
28
+ res.send({});
26
29
  };
27
30
  }
28
31
  export {
@@ -1,28 +1,19 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
3
  import serverconfig from "#src/serverconfig.js";
4
+ import { brainImagingPayload } from "#types";
4
5
  import { spawn } from "child_process";
5
6
  import { getData } from "../src/termdb.matrix.js";
6
7
  const api = {
7
8
  endpoint: "brainImaging",
8
9
  methods: {
9
10
  get: {
10
- init,
11
- request: {
12
- typeId: "GetBrainImagingRequest"
13
- },
14
- response: {
15
- typeId: "GetBrainImagingResponse"
16
- }
11
+ ...brainImagingPayload,
12
+ init
17
13
  },
18
14
  post: {
19
- init,
20
- request: {
21
- typeId: "GetBrainImagingRequest"
22
- },
23
- response: {
24
- typeId: "GetBrainImagingResponse"
25
- }
15
+ ...brainImagingPayload,
16
+ init
26
17
  }
27
18
  }
28
19
  };
@@ -8,10 +8,10 @@ const api = {
8
8
  get: {
9
9
  init,
10
10
  request: {
11
- typeId: "GetBrainImagingSamplesRequest"
11
+ typeId: "BrainImagingSamplesRequest"
12
12
  },
13
13
  response: {
14
- typeId: "GetBrainImagingSamplesResponse"
14
+ typeId: "BrainImagingSamplesResponse"
15
15
  }
16
16
  }
17
17
  }
@@ -62,7 +62,7 @@ async function getBrainImageSamples(query, genomes) {
62
62
  throw "no reference or sample files";
63
63
  }
64
64
  }
65
- async function validate_query_NIdata(ds, genome) {
65
+ async function validate_query_NIdata(ds) {
66
66
  const q = ds.queries.NIdata;
67
67
  if (!q || !serverconfig.features?.showBrainImaging)
68
68
  return;
package/routes/burden.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { burdenPayload } from "#types";
1
2
  import run_R from "#src/run_R.js";
2
3
  import path from "path";
3
4
  import serverconfig from "#src/serverconfig.js";
@@ -5,68 +6,35 @@ const api = {
5
6
  endpoint: "burden",
6
7
  methods: {
7
8
  get: {
8
- init({ genomes }) {
9
- return async (req, res) => {
10
- try {
11
- const genome = genomes[req.query.genome];
12
- if (!genome)
13
- throw `invalid q.genome=${req.query.genome}`;
14
- const q = req.query;
15
- const ds = genome.datasets[q.dslabel];
16
- if (!ds)
17
- throw `invalid q.genome=${req.query.dslabel}`;
18
- if (!ds.cohort.cumburden?.files)
19
- throw `missing ds.cohort.cumburden.files`;
20
- const estimates = await getBurdenEstimates(req, ds);
21
- const { keys, rows } = formatPayload(estimates);
22
- res.send({ status: "ok", keys, rows });
23
- } catch (e) {
24
- res.send({ status: "error", error: e.message || e });
25
- }
26
- };
27
- },
28
- request: {
29
- typeId: "BurdenRequest"
30
- },
31
- response: {
32
- typeId: "BurdenResponse"
33
- },
34
- examples: [
35
- {
36
- request: {
37
- body: {
38
- genome: "hg38",
39
- // TODO: !!! use hg38-test and TermdbTest !!!
40
- dslabel: "SJLife",
41
- diaggrp: 5,
42
- sex: 1,
43
- white: 1,
44
- agedx: 1,
45
- bleo: 0,
46
- etop: 0,
47
- cisp: 0,
48
- carbo: 0,
49
- steriod: 0,
50
- vcr: 0,
51
- hdmtx: 0,
52
- itmt: 0,
53
- ced: 0,
54
- dox: 0,
55
- heart: 0,
56
- brain: 0,
57
- abd: 0,
58
- pelvis: 0,
59
- chest: 0
60
- }
61
- },
62
- response: {
63
- header: { status: 200 }
64
- }
65
- }
66
- ]
9
+ init,
10
+ ...burdenPayload
11
+ },
12
+ post: {
13
+ init,
14
+ ...burdenPayload
67
15
  }
68
16
  }
69
17
  };
18
+ function init({ genomes }) {
19
+ return async function handler(req, res) {
20
+ try {
21
+ const genome = genomes[req.query.genome];
22
+ if (!genome)
23
+ throw `invalid q.genome=${req.query.genome}`;
24
+ const q = req.query;
25
+ const ds = genome.datasets[q.dslabel];
26
+ if (!ds)
27
+ throw `invalid q.genome=${req.query.dslabel}`;
28
+ if (!ds.cohort.cumburden?.files)
29
+ throw `missing ds.cohort.cumburden.files`;
30
+ const estimates = await getBurdenEstimates(req, ds);
31
+ const { keys, rows } = formatPayload(estimates);
32
+ res.send({ status: "ok", keys, rows });
33
+ } catch (e) {
34
+ res.send({ status: "error", error: e.message || e });
35
+ }
36
+ };
37
+ }
70
38
  async function getBurdenEstimates(q, ds) {
71
39
  for (const k in q.query) {
72
40
  q.query[k] = Number(q.query[k]);
package/routes/dataset.js CHANGED
@@ -1,49 +1,41 @@
1
1
  import * as mds2_init from "#src/mds2.init.js";
2
2
  import * as mds3_init from "#src/mds3.init.js";
3
3
  import * as common from "#shared/common.js";
4
+ import { datasetPayload } from "#types";
4
5
  const api = {
5
6
  endpoint: "getDataset",
6
7
  // should rename to simply 'dataset', method is based on HTTP method
7
8
  methods: {
8
9
  get: {
9
10
  init,
10
- request: {
11
- typeId: "any"
12
- },
13
- response: {
14
- typeId: "any"
15
- }
11
+ ...datasetPayload
16
12
  },
17
13
  post: {
18
- alternativeFor: "get",
19
- init
14
+ init,
15
+ ...datasetPayload
20
16
  }
21
17
  }
22
18
  };
23
19
  function init({ genomes }) {
24
20
  return function(req, res) {
25
21
  try {
26
- const genome = genomes[req.query.genome];
22
+ const q = req.query;
23
+ const genome = genomes[q.genome];
27
24
  if (!genome)
28
25
  throw "unknown genome";
29
26
  if (!genome.datasets)
30
27
  throw "genomeobj.datasets{} missing";
31
28
  let ds;
32
29
  for (const k in genome.datasets) {
33
- if (k.toLowerCase() == req.query.dsname.toLowerCase()) {
30
+ if (k.toLowerCase() == q.dsname.toLowerCase()) {
34
31
  ds = genome.datasets[k];
35
32
  break;
36
33
  }
37
34
  }
38
35
  if (!ds)
39
36
  throw "invalid dsname";
40
- if (ds.isMds3) {
41
- return res.send({ ds: mds3_init.client_copy(ds) });
42
- }
43
- if (ds.isMds) {
44
- return res.send({ ds: mds_clientcopy(ds) });
45
- }
46
- return res.send({ ds: copy_legacyDataset(ds) });
37
+ const copy = ds.isMds3 ? mds3_init.client_copy(ds) : ds.isMds ? mds_clientcopy(ds) : copy_legacyDataset(ds);
38
+ return res.send({ ds: copy });
47
39
  } catch (e) {
48
40
  res.send({ error: e.message || e });
49
41
  }
package/routes/dsdata.js CHANGED
@@ -2,6 +2,7 @@ import path from "path";
2
2
  import { spawn } from "child_process";
3
3
  import serverconfig from "#src/serverconfig.js";
4
4
  import * as common from "#shared/common.js";
5
+ import { dsDataPayload } from "#types";
5
6
  const api = {
6
7
  // route endpoint
7
8
  // - no need for trailing slash
@@ -10,16 +11,11 @@ const api = {
10
11
  endpoint: "dsdata",
11
12
  methods: {
12
13
  get: {
13
- init,
14
- request: {
15
- typeId: "any"
16
- },
17
- response: {
18
- typeId: "any"
19
- }
14
+ ...dsDataPayload,
15
+ init
20
16
  },
21
17
  post: {
22
- alternativeFor: "get",
18
+ ...dsDataPayload,
23
19
  init
24
20
  }
25
21
  }
@@ -27,19 +23,20 @@ const api = {
27
23
  function init({ genomes }) {
28
24
  return async function handle_dsdata(req, res) {
29
25
  try {
30
- if (!genomes[req.query.genome])
26
+ const q = req.query;
27
+ if (!genomes[q.genome])
31
28
  throw "invalid genome";
32
- if (!req.query.dsname)
29
+ if (!q.dsname)
33
30
  throw ".dsname missing";
34
- const ds = genomes[req.query.genome].datasets[req.query.dsname];
31
+ const ds = genomes[q.genome].datasets[q.dsname];
35
32
  if (!ds)
36
33
  throw "invalid dsname";
37
34
  const data = [];
38
35
  for (const query of ds.queries) {
39
- if (req.query.expressiononly && !query.isgeneexpression) {
36
+ if (q.expressiononly && !query.isgeneexpression) {
40
37
  continue;
41
38
  }
42
- if (req.query.noexpression && query.isgeneexpression) {
39
+ if (q.noexpression && query.isgeneexpression) {
43
40
  continue;
44
41
  }
45
42
  if (query.dsblocktracklst) {
@@ -110,7 +107,7 @@ function handle_dsdata_vcf(query, req) {
110
107
  const out = [], out2 = [];
111
108
  ps.stdout.on("data", (i) => out.push(i));
112
109
  ps.stderr.on("data", (i) => out2.push(i));
113
- ps.on("close", (code) => {
110
+ ps.on("close", () => {
114
111
  const e = out2.join("").trim();
115
112
  if (e != "")
116
113
  reject("error querying vcf file");
@@ -1,47 +1,42 @@
1
1
  import path from "path";
2
2
  import serverconfig from "#src/serverconfig.js";
3
3
  import { illegalpath } from "#src/utils.js";
4
- const routePath = "dzimages";
4
+ import { dzImagesPayload } from "#types";
5
5
  const api = {
6
- endpoint: `${routePath}/:sampleId`,
6
+ endpoint: `dzimages/:sampleId`,
7
7
  methods: {
8
8
  get: {
9
- init,
10
- request: {
11
- typeId: "any"
12
- },
13
- response: {
14
- typeId: "any"
15
- }
9
+ ...dzImagesPayload,
10
+ init
16
11
  },
17
12
  post: {
18
- alternativeFor: "get",
13
+ ...dzImagesPayload,
19
14
  init
20
15
  }
21
16
  }
22
17
  };
23
18
  function init({ genomes }) {
24
19
  return async (req, res) => {
25
- let imagePath;
26
20
  try {
27
- const g = genomes[req.query.genome];
21
+ const q = req.query;
22
+ const g = genomes[q.genome];
28
23
  if (!g)
29
24
  throw "invalid genome name";
30
- const ds = g.datasets[req.query.dslabel];
25
+ const ds = g.datasets[q.dslabel];
31
26
  if (!ds)
32
27
  throw "invalid dataset name";
33
- const sampleId = req.params.sampleId;
28
+ const sampleId = q.sampleId;
34
29
  if (!sampleId)
35
30
  throw "invalid sampleId";
36
31
  if (illegalpath(req.query.file))
37
32
  throw `illegalpath filepath`;
38
- const filename = path.basename(req.query.file);
33
+ const filename = path.basename(q.file);
39
34
  const allowedExtensions = [".dzi", ".jpeg", ".png"];
40
35
  const extension = path.extname(filename);
41
36
  if (!allowedExtensions.includes(extension)) {
42
37
  throw `Invalid file extension. Allowed extensions are ${allowedExtensions.join(", ")}`;
43
38
  }
44
- imagePath = path.join(
39
+ const imagePath = path.join(
45
40
  `${serverconfig.tpmasterdir}/${ds.queries.DZImages.imageBySampleFolder}`,
46
41
  `${sampleId}/${req.query.file}`
47
42
  );
package/routes/gdc.maf.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { gdcMafPayload } from "#types";
1
2
  import path from "path";
2
3
  import got from "got";
3
4
  import serverconfig from "#src/serverconfig.js";
@@ -7,29 +8,13 @@ const maxTotalSizeCompressed = serverconfig.features.gdcMafMaxFileSize || 4e8;
7
8
  const api = {
8
9
  endpoint: "gdc/maf",
9
10
  methods: {
10
- all: {
11
- init,
12
- request: {
13
- typeId: "GdcMafRequest"
14
- },
15
- response: {
16
- typeId: "GdcMafResponse"
17
- // will combine this with type checker
18
- //valid: (t) => {}
19
- },
20
- examples: [
21
- {
22
- request: {
23
- body: {
24
- experimentalStrategy: "WXS",
25
- embedder: "localhost"
26
- }
27
- },
28
- response: {
29
- header: { status: 200 }
30
- }
31
- }
32
- ]
11
+ get: {
12
+ ...gdcMafPayload,
13
+ init
14
+ },
15
+ post: {
16
+ ...gdcMafPayload,
17
+ init
33
18
  }
34
19
  }
35
20
  };
@@ -2,32 +2,32 @@ import got from "got";
2
2
  import path from "path";
3
3
  import { run_rust_stream } from "@sjcrh/proteinpaint-rust";
4
4
  import serverconfig from "#src/serverconfig.js";
5
+ import { gdcMafPayload } from "#types";
5
6
  import { maxTotalSizeCompressed } from "./gdc.maf.ts";
6
7
  const api = {
7
8
  endpoint: "gdc/mafBuild",
8
9
  methods: {
9
- all: {
10
+ get: {
10
11
  init,
11
- request: {
12
- typeId: "GdcMafBuildRequest"
13
- },
14
- response: {
15
- typeId: null
16
- // 'GdcMafBuildResponse'
17
- }
12
+ ...gdcMafPayload
13
+ },
14
+ post: {
15
+ init,
16
+ ...gdcMafPayload
18
17
  }
19
18
  }
20
19
  };
21
20
  function init({ genomes }) {
22
21
  return async (req, res) => {
23
22
  try {
23
+ const q = req.query;
24
24
  const g = genomes.hg38;
25
25
  if (!g)
26
26
  throw "hg38 missing";
27
27
  const ds = g.datasets.GDC;
28
28
  if (!ds)
29
29
  throw "hg38 GDC missing";
30
- await buildMaf(req.query, res, ds);
30
+ await buildMaf(q, res, ds);
31
31
  } catch (e) {
32
32
  if (e.stack)
33
33
  console.log(e.stack);
@@ -1,16 +1,16 @@
1
+ import { gdcTopMutatedGenePayload } from "#types";
1
2
  import { mclasscnvgain, mclasscnvloss, dtsnvindel } from "#shared/common.js";
2
3
  import ky from "ky";
3
4
  const api = {
4
5
  endpoint: "gdc/topMutatedGenes",
5
6
  methods: {
6
- all: {
7
+ get: {
7
8
  init,
8
- request: {
9
- typeId: "GdcTopMutatedGeneRequest"
10
- },
11
- response: {
12
- typeId: "GdcTopMutatedGeneResponse"
13
- }
9
+ ...gdcTopMutatedGenePayload
10
+ },
11
+ post: {
12
+ init,
13
+ ...gdcTopMutatedGenePayload
14
14
  }
15
15
  }
16
16
  };
@@ -1,12 +1,26 @@
1
1
  import { getResult } from "#src/gene.js";
2
+ import { geneLookupPayload } from "#types";
3
+ const api = {
4
+ endpoint: "genelookup",
5
+ methods: {
6
+ get: {
7
+ init,
8
+ ...geneLookupPayload
9
+ },
10
+ post: {
11
+ init,
12
+ ...geneLookupPayload
13
+ }
14
+ }
15
+ };
2
16
  function init({ genomes }) {
3
17
  return (req, res) => {
4
18
  try {
5
19
  const q = req.query;
6
- const g = genomes[req.query.genome];
20
+ const g = genomes[q.genome];
7
21
  if (!g)
8
22
  throw "invalid genome name";
9
- const result = getResult(g, req.query);
23
+ const result = getResult(g, q);
10
24
  res.send(result);
11
25
  } catch (e) {
12
26
  res.send({ error: e.message || e });
@@ -15,38 +29,6 @@ function init({ genomes }) {
15
29
  }
16
30
  };
17
31
  }
18
- const api = {
19
- endpoint: "genelookup",
20
- methods: {
21
- get: {
22
- init,
23
- request: {
24
- typeId: "GeneLookupRequest"
25
- //valid: default to type checker
26
- },
27
- response: {
28
- typeId: "GeneLookupResponse"
29
- // will combine this with type checker
30
- //valid: (t) => {}
31
- },
32
- examples: [
33
- {
34
- request: {
35
- body: { input: "kr", genome: "hg38-test" }
36
- },
37
- response: {
38
- header: { status: 200 },
39
- body: { hits: ["KRAS"] }
40
- }
41
- }
42
- ]
43
- },
44
- post: {
45
- alternativeFor: "get",
46
- init
47
- }
48
- }
49
- };
50
32
  export {
51
33
  api
52
34
  };
@@ -1,3 +1,4 @@
1
+ import { genesetEnrichmentPayload } from "#types";
1
2
  import fs from "fs";
2
3
  import path from "path";
3
4
  import { spawn } from "child_process";
@@ -6,26 +7,27 @@ import serverconfig from "#src/serverconfig.js";
6
7
  const api = {
7
8
  endpoint: "genesetEnrichment",
8
9
  methods: {
9
- all: {
10
- init,
11
- request: {
12
- typeId: "genesetEnrichmentRequest"
13
- },
14
- response: {
15
- typeId: "genesetEnrichmentResponse"
16
- // will combine this with type checker
17
- //valid: (t) => {}
18
- }
10
+ get: {
11
+ ...genesetEnrichmentPayload,
12
+ init
13
+ },
14
+ post: {
15
+ ...genesetEnrichmentPayload,
16
+ init
19
17
  }
20
18
  }
21
19
  };
22
20
  function init({ genomes }) {
23
21
  return async (req, res) => {
24
22
  try {
25
- const results = await run_genesetEnrichment_analysis(req.query, genomes);
26
- if (!req.query.geneset_name) {
27
- res.send(results);
28
- } else {
23
+ const q = req.query;
24
+ const results = await run_genesetEnrichment_analysis(q, genomes);
25
+ if (!q.geneset_name) {
26
+ if (typeof results != "string")
27
+ res.send(results);
28
+ else
29
+ throw `invalid results type when !req.query.geneset_name`;
30
+ } else if (typeof results == "string") {
29
31
  res.sendFile(results, (err) => {
30
32
  fs.unlink(results, (del_err) => {
31
33
  if (del_err) {
@@ -79,6 +81,8 @@ async function run_genesetEnrichment_analysis(q, genomes) {
79
81
  } else if (image_found) {
80
82
  const imagePath = path.join(serverconfig.cachedir, result.image_file);
81
83
  return imagePath;
84
+ } else {
85
+ throw ``;
82
86
  }
83
87
  }
84
88
  async function run_gsea(path2, data) {