@jax-data-science/api-clients 0.0.1-0
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 +7 -0
- package/fesm2022/jax-data-science-api-clients.mjs +911 -0
- package/fesm2022/jax-data-science-api-clients.mjs.map +1 -0
- package/index.d.ts +9 -0
- package/lib/asynctask/asynctask.model.d.ts +164 -0
- package/lib/asynctask/asynctask.service.d.ts +60 -0
- package/lib/base.service.d.ts +74 -0
- package/lib/models/base-response.d.ts +4 -0
- package/lib/models/error.d.ts +5 -0
- package/lib/models/paging.d.ts +13 -0
- package/lib/models/response.d.ts +9 -0
- package/lib/mvar/models/response/dtos.d.ts +92 -0
- package/lib/mvar/mvar-client.module.d.ts +9 -0
- package/lib/mvar/mvar.service.d.ts +35 -0
- package/lib/ontology/ontology.model.d.ts +27 -0
- package/lib/ontology/ontology.service.d.ts +56 -0
- package/lib/snp-grid/models/response/dtos.d.ts +95 -0
- package/lib/snp-grid/snp-grid-client.module.d.ts +9 -0
- package/lib/snp-grid/snp-grid.service.d.ts +97 -0
- package/package.json +28 -0
|
@@ -0,0 +1,911 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Injectable, inject, Inject, NgModule } from '@angular/core';
|
|
3
|
+
import { throwError, map, catchError, Observable, BehaviorSubject, combineLatest, tap } from 'rxjs';
|
|
4
|
+
import { fetchEventSource } from '@microsoft/fetch-event-source';
|
|
5
|
+
import * as i1 from '@angular/common/http';
|
|
6
|
+
import { CommonModule } from '@angular/common';
|
|
7
|
+
|
|
8
|
+
class ApiBaseServiceFactory {
|
|
9
|
+
http;
|
|
10
|
+
constructor(http) {
|
|
11
|
+
this.http = http;
|
|
12
|
+
}
|
|
13
|
+
create(baseUrl) {
|
|
14
|
+
return new ApiBaseService(this.http, baseUrl);
|
|
15
|
+
}
|
|
16
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: ApiBaseServiceFactory, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
17
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: ApiBaseServiceFactory, providedIn: 'root' });
|
|
18
|
+
}
|
|
19
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: ApiBaseServiceFactory, decorators: [{
|
|
20
|
+
type: Injectable,
|
|
21
|
+
args: [{
|
|
22
|
+
providedIn: 'root'
|
|
23
|
+
}]
|
|
24
|
+
}], ctorParameters: () => [{ type: i1.HttpClient }] });
|
|
25
|
+
class ApiBaseService {
|
|
26
|
+
http;
|
|
27
|
+
baseUrl;
|
|
28
|
+
constructor(http, baseUrl) {
|
|
29
|
+
this.http = http;
|
|
30
|
+
this.baseUrl = baseUrl;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Handles API response errors and HTTP errors
|
|
34
|
+
* @param response The API response
|
|
35
|
+
* @private
|
|
36
|
+
*/
|
|
37
|
+
handleResponse(response) {
|
|
38
|
+
if (response.errors) {
|
|
39
|
+
// TO-DO: [GIK 6/6/2025] once the API service has the capabilities to respond
|
|
40
|
+
// with meaningful validation and analytical errors, this will need to be
|
|
41
|
+
// updated to typecast these into the ErrorResponse model and rethrow the error object
|
|
42
|
+
throw new Error(response.errors.join(', '));
|
|
43
|
+
}
|
|
44
|
+
return response;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Handles HTTP errors by catching them and rethrowing a consistent
|
|
48
|
+
* error response that contains an error code, numeric code, and
|
|
49
|
+
* a user-friendly message.
|
|
50
|
+
* TO-DO: [GIK 6/10/2025] consider adding error logging capabilities to an external service
|
|
51
|
+
* @param error an error object, typically an HttpErrorResponse
|
|
52
|
+
* @returns an Observable that emits an ErrorResponse object
|
|
53
|
+
*/
|
|
54
|
+
handleHttpError(error) {
|
|
55
|
+
let errorResponse;
|
|
56
|
+
// errors returned on the Observable response stream
|
|
57
|
+
// will be wrapped in an HttpErrorResponse class
|
|
58
|
+
if (error.name === 'HttpErrorResponse') {
|
|
59
|
+
errorResponse = {
|
|
60
|
+
code: error.statusText || 'HTTP_ERROR',
|
|
61
|
+
num_code: error.status,
|
|
62
|
+
message: this.getErrorMessage(error),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
errorResponse = {
|
|
67
|
+
code: 'UNKNOWN_ERROR',
|
|
68
|
+
num_code: 0,
|
|
69
|
+
message: error.message || 'An unknown error occurred',
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return throwError(() => errorResponse);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get a user-friendly error message based on the HTTP status code
|
|
76
|
+
*
|
|
77
|
+
* @param error
|
|
78
|
+
* @return a string containing the error message
|
|
79
|
+
*/
|
|
80
|
+
getErrorMessage(error) {
|
|
81
|
+
switch (error.status) {
|
|
82
|
+
case 400:
|
|
83
|
+
return 'Bad request - malformed request syntax or invalid parameters';
|
|
84
|
+
break;
|
|
85
|
+
case 401:
|
|
86
|
+
return 'Unauthorized - authentication required or invalid credentials';
|
|
87
|
+
break;
|
|
88
|
+
case 403:
|
|
89
|
+
return 'Forbidden - the authenticated user does not have permission to perform the operation';
|
|
90
|
+
break;
|
|
91
|
+
case 404:
|
|
92
|
+
return 'Not found - the requested resource does not exist';
|
|
93
|
+
break;
|
|
94
|
+
case 422:
|
|
95
|
+
return 'Unprocessable content - the request is correctly formed but contained semantic errors';
|
|
96
|
+
break;
|
|
97
|
+
case 500:
|
|
98
|
+
return 'Internal Server Error - generic server-side error';
|
|
99
|
+
break;
|
|
100
|
+
default:
|
|
101
|
+
return `Unexpected error occurred - status code: ${error.status}`;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get a single resource
|
|
106
|
+
* @param url The endpoint URL
|
|
107
|
+
* @param params Optional query parameters
|
|
108
|
+
*/
|
|
109
|
+
get(url, params) {
|
|
110
|
+
return this.http.get(`${this.baseUrl}${url}`, { params }).pipe(map((response) => this.handleResponse(response)), catchError((error) => this.handleHttpError(error)));
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Get a collection of resources
|
|
114
|
+
* @param url The endpoint URL
|
|
115
|
+
* @param params Optional query parameters
|
|
116
|
+
*/
|
|
117
|
+
handleCollectionResponse(response) {
|
|
118
|
+
if (response.errors) {
|
|
119
|
+
throw new Error(response.errors.join(', '));
|
|
120
|
+
}
|
|
121
|
+
return response;
|
|
122
|
+
}
|
|
123
|
+
getCollection(url, params) {
|
|
124
|
+
return this.http
|
|
125
|
+
.get(`${this.baseUrl}${url}`, { params })
|
|
126
|
+
.pipe(map((response) => this.handleCollectionResponse(response)), catchError((error) => this.handleHttpError(error)));
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Create a new resource
|
|
130
|
+
* @param url The endpoint URL
|
|
131
|
+
* @param body The resource to create
|
|
132
|
+
*/
|
|
133
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
134
|
+
post(url, body) {
|
|
135
|
+
return this.http.post(`${this.baseUrl}${url}`, body).pipe(map((response) => this.handleResponse(response)), catchError((error) => this.handleHttpError(error)));
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Update an existing resource
|
|
139
|
+
* @param url The endpoint URL
|
|
140
|
+
* @param body The resource updates
|
|
141
|
+
*/
|
|
142
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
143
|
+
put(url, body) {
|
|
144
|
+
return this.http.put(`${this.baseUrl}${url}`, body).pipe(map((response) => this.handleResponse(response)), catchError((error) => this.handleHttpError(error)));
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Partially update an existing resource
|
|
148
|
+
* @param url The endpoint URL
|
|
149
|
+
* @param body The partial resource updates
|
|
150
|
+
*/
|
|
151
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
152
|
+
patch(url, body) {
|
|
153
|
+
return this.http.patch(`${this.baseUrl}${url}`, body).pipe(map((response) => this.handleResponse(response)), catchError((error) => this.handleHttpError(error)));
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Delete a resource
|
|
157
|
+
* @param url The endpoint URL
|
|
158
|
+
*/
|
|
159
|
+
delete(url) {
|
|
160
|
+
return this.http.delete(`${this.baseUrl}${url}`).pipe(map((response) => this.handleResponse(response)), catchError((error) => this.handleHttpError(error)));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
class AsyncTaskService {
|
|
165
|
+
// TO-DO [GIK 7/9/2025]: move 'https://astra-dev.jax.org' to an environment variable
|
|
166
|
+
apiBaseUrl = '/asynctask/api';
|
|
167
|
+
apiServiceFactory = inject(ApiBaseServiceFactory);
|
|
168
|
+
apiBaseService = this.apiServiceFactory.create(this.apiBaseUrl);
|
|
169
|
+
setApiBaseUrl(baseUrl) {
|
|
170
|
+
this.apiBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
|
|
171
|
+
// ensure the URL ends with '/asynctask/api'
|
|
172
|
+
if (!this.apiBaseUrl.endsWith('asynctask/api')) {
|
|
173
|
+
this.apiBaseUrl = `${this.apiBaseUrl}/asynctask/api`;
|
|
174
|
+
}
|
|
175
|
+
// recreate the apiService
|
|
176
|
+
this.apiBaseService = this.apiServiceFactory.create(this.apiBaseUrl);
|
|
177
|
+
}
|
|
178
|
+
getApiBaseUrl() {
|
|
179
|
+
return this.apiBaseUrl;
|
|
180
|
+
}
|
|
181
|
+
// INPUT
|
|
182
|
+
addInput(inputSubmission) {
|
|
183
|
+
return this.apiBaseService.post('/inputs', inputSubmission);
|
|
184
|
+
}
|
|
185
|
+
getInput(id) {
|
|
186
|
+
return this.apiBaseService.get(`/inputs/${id}`);
|
|
187
|
+
}
|
|
188
|
+
getInputs() {
|
|
189
|
+
return this.apiBaseService.getCollection('/inputs');
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Updates an existing input - only 'name' and 'description' can be updated
|
|
193
|
+
* @param inputId
|
|
194
|
+
* @param name - (optional) name to update
|
|
195
|
+
* @param description - (optional) description to update
|
|
196
|
+
*/
|
|
197
|
+
updateInput(inputId, name, description) {
|
|
198
|
+
let url = `/inputs/${inputId}?`;
|
|
199
|
+
if (name !== undefined) {
|
|
200
|
+
url += `name=${name}&`;
|
|
201
|
+
}
|
|
202
|
+
if (description !== undefined) {
|
|
203
|
+
url += `description=${description}`;
|
|
204
|
+
}
|
|
205
|
+
return this.apiBaseService.patch(url, null);
|
|
206
|
+
}
|
|
207
|
+
// RUN
|
|
208
|
+
createRun(inputId, inputSubmission) {
|
|
209
|
+
const url = inputId ? `/runs?input_id=${inputId}` : '/runs';
|
|
210
|
+
return this.apiBaseService.post(url, inputSubmission || null);
|
|
211
|
+
}
|
|
212
|
+
getRun(id) {
|
|
213
|
+
return this.apiBaseService.get(`/runs/${id}`);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
*
|
|
217
|
+
* @param workflowId - (optional) workflow identifier
|
|
218
|
+
*/
|
|
219
|
+
getRuns(workflowId) {
|
|
220
|
+
const url = (workflowId ? `/runs?workflow_id=${workflowId}` : '/runs');
|
|
221
|
+
return this.apiBaseService.getCollection(url);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Gets the input associated with the specific run ID. One run is associated
|
|
225
|
+
* with only one input, so this function returns a single input object.
|
|
226
|
+
* @param runId
|
|
227
|
+
*/
|
|
228
|
+
getRunInput(runId) {
|
|
229
|
+
return this.apiBaseService.get(`/runs/${runId}/inputs`);
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Gets the result associated with the specific run ID. One run is associated
|
|
233
|
+
* with only one result, so this function returns a single result object.
|
|
234
|
+
* @param runId
|
|
235
|
+
*/
|
|
236
|
+
getRunResult(runId) {
|
|
237
|
+
return this.apiBaseService.get(`/runs/${runId}/results`);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Calls the fetchEventSource() function, which is a wrapper around the native
|
|
241
|
+
* EventSource API. This function is used to establish connection to an API
|
|
242
|
+
* endpoint and listen to event streaming data associated with task runs.
|
|
243
|
+
* TO-DO [GIK 7/9/2025]: needs to add a reconnect logic
|
|
244
|
+
* @return an observable that emits run events
|
|
245
|
+
*/
|
|
246
|
+
getRunEvents(accessToken) {
|
|
247
|
+
const api = this.apiBaseService;
|
|
248
|
+
// observable constructor argument is 'subscribe()' method implementation
|
|
249
|
+
return new Observable((subscriber) => {
|
|
250
|
+
// abort controller to cancel the request (on component destroy)
|
|
251
|
+
const abortController = new AbortController();
|
|
252
|
+
fetchEventSource(`${this.apiBaseUrl}/runs/events`, {
|
|
253
|
+
method: 'GET',
|
|
254
|
+
headers: {
|
|
255
|
+
'Content-Type': 'text/event-stream',
|
|
256
|
+
'Cache-Control': 'no-cache',
|
|
257
|
+
'Authorization': `Bearer ${accessToken}`
|
|
258
|
+
},
|
|
259
|
+
async onopen(response) {
|
|
260
|
+
// SSE media type must be 'text/event-stream'
|
|
261
|
+
const contentType = response.headers.get('content-type');
|
|
262
|
+
if (!contentType?.startsWith('text/event-stream')) {
|
|
263
|
+
const errorResponse = {
|
|
264
|
+
code: 'INVALID_CONTENT_TYPE',
|
|
265
|
+
num_code: response.status,
|
|
266
|
+
message: `Expected content-type to be text/event-stream, but got: ${contentType}`
|
|
267
|
+
};
|
|
268
|
+
throw errorResponse;
|
|
269
|
+
}
|
|
270
|
+
// resolve promise (without returning anything), which indicates that the connection is open
|
|
271
|
+
if (response.ok && response.status === 200)
|
|
272
|
+
return;
|
|
273
|
+
// opening SSE connection failed
|
|
274
|
+
if (response.status >= 400 && response.status < 500 && response.status !== 429) {
|
|
275
|
+
const errorResponse = {
|
|
276
|
+
code: 'RESOURCE_NOT_FOUND',
|
|
277
|
+
num_code: response.status,
|
|
278
|
+
message: 'Resource not found or access denied'
|
|
279
|
+
};
|
|
280
|
+
throw errorResponse;
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
onmessage(event) {
|
|
284
|
+
try {
|
|
285
|
+
const run = JSON.parse(event.data);
|
|
286
|
+
subscriber.next(run);
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
const errorResponse = {
|
|
290
|
+
code: 'PARSE_ERROR',
|
|
291
|
+
num_code: 0,
|
|
292
|
+
message: `Failed to parse event data: ${event.data}`
|
|
293
|
+
};
|
|
294
|
+
throw errorResponse;
|
|
295
|
+
}
|
|
296
|
+
},
|
|
297
|
+
onclose() {
|
|
298
|
+
subscriber.complete();
|
|
299
|
+
},
|
|
300
|
+
onerror(errorRes) {
|
|
301
|
+
// send an error message to subscriber's error handler
|
|
302
|
+
subscriber.error(errorRes);
|
|
303
|
+
// rethrow the error to stop the operation
|
|
304
|
+
throw errorRes;
|
|
305
|
+
},
|
|
306
|
+
signal: abortController.signal
|
|
307
|
+
});
|
|
308
|
+
return () => {
|
|
309
|
+
abortController.abort(); // close connection on unsubscribe
|
|
310
|
+
};
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
// RESULT
|
|
314
|
+
getResult(resId) {
|
|
315
|
+
return this.apiBaseService.get(`/results/${resId}`);
|
|
316
|
+
}
|
|
317
|
+
getResults() {
|
|
318
|
+
return this.apiBaseService.getCollection('/results');
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Updates an existing result record - 'name' and 'description' can be updated
|
|
322
|
+
* @param resId
|
|
323
|
+
* @param name - (optional) result's name to update
|
|
324
|
+
* @param description - (optional) result's description to update
|
|
325
|
+
*/
|
|
326
|
+
updateResult(resId, name, description) {
|
|
327
|
+
let url = `/results/${resId}?`;
|
|
328
|
+
if (name !== undefined) {
|
|
329
|
+
url += `name=${name}&`;
|
|
330
|
+
}
|
|
331
|
+
if (description !== undefined) {
|
|
332
|
+
url += `description=${description}`;
|
|
333
|
+
}
|
|
334
|
+
return this.apiBaseService.patch(url, null);
|
|
335
|
+
}
|
|
336
|
+
// HEALTH CHECK
|
|
337
|
+
// TO-DO [GIK 05/30/2025]: should be moved outside this service
|
|
338
|
+
getHealthCheck() {
|
|
339
|
+
return this.apiBaseService.get('/monitors/servers/health');
|
|
340
|
+
}
|
|
341
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: AsyncTaskService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
342
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: AsyncTaskService, providedIn: 'root' });
|
|
343
|
+
}
|
|
344
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: AsyncTaskService, decorators: [{
|
|
345
|
+
type: Injectable,
|
|
346
|
+
args: [{
|
|
347
|
+
providedIn: 'root'
|
|
348
|
+
}]
|
|
349
|
+
}] });
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* AsyncTask Service Models
|
|
353
|
+
*
|
|
354
|
+
* This module contains TypeScript interfaces for the AsyncTask service API.
|
|
355
|
+
* These models are based on the OpenAPI specification and represent the
|
|
356
|
+
* core entities used in the AsyncTask workflow system.
|
|
357
|
+
*/
|
|
358
|
+
/**
|
|
359
|
+
* Represents the current execution status of a workflow.
|
|
360
|
+
* Based on temporalio.api.enums.v1.WorkflowExecutionStatus
|
|
361
|
+
*/
|
|
362
|
+
var WorkflowExecutionStatus;
|
|
363
|
+
(function (WorkflowExecutionStatus) {
|
|
364
|
+
WorkflowExecutionStatus[WorkflowExecutionStatus["RUNNING"] = 1] = "RUNNING";
|
|
365
|
+
WorkflowExecutionStatus[WorkflowExecutionStatus["COMPLETED"] = 2] = "COMPLETED";
|
|
366
|
+
WorkflowExecutionStatus[WorkflowExecutionStatus["FAILED"] = 3] = "FAILED";
|
|
367
|
+
WorkflowExecutionStatus[WorkflowExecutionStatus["CANCELED"] = 4] = "CANCELED";
|
|
368
|
+
WorkflowExecutionStatus[WorkflowExecutionStatus["TERMINATED"] = 5] = "TERMINATED";
|
|
369
|
+
WorkflowExecutionStatus[WorkflowExecutionStatus["CONTINUED_AS_NEW"] = 6] = "CONTINUED_AS_NEW";
|
|
370
|
+
WorkflowExecutionStatus[WorkflowExecutionStatus["TIMED_OUT"] = 7] = "TIMED_OUT";
|
|
371
|
+
})(WorkflowExecutionStatus || (WorkflowExecutionStatus = {}));
|
|
372
|
+
|
|
373
|
+
var Ontology;
|
|
374
|
+
(function (Ontology) {
|
|
375
|
+
Ontology["HP"] = "HP";
|
|
376
|
+
Ontology["MONDO"] = "MONDO";
|
|
377
|
+
Ontology["MP"] = "MP";
|
|
378
|
+
Ontology["CL"] = "CL";
|
|
379
|
+
Ontology["MAXO"] = "MAXO";
|
|
380
|
+
})(Ontology || (Ontology = {}));
|
|
381
|
+
|
|
382
|
+
class OntologyService {
|
|
383
|
+
httpClient;
|
|
384
|
+
config_location = 'https://raw.githubusercontent.com/TheJacksonLaboratory/ontology-service/refs/heads/main/config/ontologies-internal.json';
|
|
385
|
+
config;
|
|
386
|
+
/**
|
|
387
|
+
* Get the configuration file from the source for the backend api service
|
|
388
|
+
*/
|
|
389
|
+
constructor(httpClient) {
|
|
390
|
+
this.httpClient = httpClient;
|
|
391
|
+
this.httpClient.get(this.config_location).subscribe({
|
|
392
|
+
next: (config) => this.config = config,
|
|
393
|
+
error: () => {
|
|
394
|
+
this.config = [];
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Search for terms in an ontology
|
|
400
|
+
* @param query - the search query
|
|
401
|
+
* @param limit - the number of results to return
|
|
402
|
+
* @param ontology - the ontology to search
|
|
403
|
+
*/
|
|
404
|
+
search(query, limit, ontology) {
|
|
405
|
+
return this.httpClient.get(`${this.ontologyBaseResolver(ontology)}/search?q=${query}&limit=${limit}`);
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Get a term by its ID
|
|
409
|
+
* @param id - the term ID
|
|
410
|
+
*/
|
|
411
|
+
term(id) {
|
|
412
|
+
try {
|
|
413
|
+
const url = `${this.ontologyBaseResolver(this.ontologyFromCurie(id))}/${id}`;
|
|
414
|
+
return this.httpClient.get(url);
|
|
415
|
+
}
|
|
416
|
+
catch (error) {
|
|
417
|
+
return throwError(error);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Get the parents of a term
|
|
422
|
+
* @param id - the term ID
|
|
423
|
+
*/
|
|
424
|
+
parents(id) {
|
|
425
|
+
try {
|
|
426
|
+
const url = `${this.ontologyBaseResolver(this.ontologyFromCurie(id))}/${id}/parents`;
|
|
427
|
+
return this.httpClient.get(url);
|
|
428
|
+
}
|
|
429
|
+
catch (error) {
|
|
430
|
+
return throwError(error);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Get the children of a term
|
|
435
|
+
* @param id - the term ID
|
|
436
|
+
*/
|
|
437
|
+
children(id) {
|
|
438
|
+
try {
|
|
439
|
+
const url = `${this.ontologyBaseResolver(this.ontologyFromCurie(id))}/${id}/children`;
|
|
440
|
+
return this.httpClient.get(url);
|
|
441
|
+
}
|
|
442
|
+
catch (error) {
|
|
443
|
+
return throwError(error);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Get the ancestors of a term
|
|
448
|
+
* @param id - the term ID
|
|
449
|
+
*/
|
|
450
|
+
ancestors(id) {
|
|
451
|
+
try {
|
|
452
|
+
const url = `${this.ontologyBaseResolver(this.ontologyFromCurie(id))}/${id}/ancestors`;
|
|
453
|
+
return this.httpClient.get(url);
|
|
454
|
+
}
|
|
455
|
+
catch (error) {
|
|
456
|
+
return throwError(error);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Get the descendants of a term
|
|
461
|
+
* @param id - the term ID
|
|
462
|
+
*/
|
|
463
|
+
descendants(id) {
|
|
464
|
+
try {
|
|
465
|
+
const url = `${this.ontologyBaseResolver(this.ontologyFromCurie(id))}/${id}/descendants`;
|
|
466
|
+
return this.httpClient.get(url);
|
|
467
|
+
}
|
|
468
|
+
catch (error) {
|
|
469
|
+
return throwError(error);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Get the ontology from curie
|
|
474
|
+
*/
|
|
475
|
+
ontologyFromCurie(curie) {
|
|
476
|
+
return Ontology[curie.split(':')[0]];
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Get the ontology api base url configuration
|
|
480
|
+
**/
|
|
481
|
+
ontologyBaseResolver(ontology) {
|
|
482
|
+
if (!this.config || this.config.length === 0) {
|
|
483
|
+
throw new Error('No ontology configuration found.');
|
|
484
|
+
}
|
|
485
|
+
const ontology_config = this.config.find((config) => config.prefix.toUpperCase() === ontology);
|
|
486
|
+
if (!ontology_config) {
|
|
487
|
+
throw new Error('Ontology not found in configuration.');
|
|
488
|
+
}
|
|
489
|
+
return ontology_config.api.base;
|
|
490
|
+
}
|
|
491
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: OntologyService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
492
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: OntologyService, providedIn: 'root' });
|
|
493
|
+
}
|
|
494
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: OntologyService, decorators: [{
|
|
495
|
+
type: Injectable,
|
|
496
|
+
args: [{
|
|
497
|
+
providedIn: 'root'
|
|
498
|
+
}]
|
|
499
|
+
}], ctorParameters: () => [{ type: i1.HttpClient }] });
|
|
500
|
+
|
|
501
|
+
// TODO - move to constants file/library
|
|
502
|
+
const MUS_CHRS = [
|
|
503
|
+
'1',
|
|
504
|
+
'2',
|
|
505
|
+
'3',
|
|
506
|
+
'4',
|
|
507
|
+
'5',
|
|
508
|
+
'6',
|
|
509
|
+
'7',
|
|
510
|
+
'8',
|
|
511
|
+
'9',
|
|
512
|
+
'10',
|
|
513
|
+
'11',
|
|
514
|
+
'12',
|
|
515
|
+
'13',
|
|
516
|
+
'14',
|
|
517
|
+
'15',
|
|
518
|
+
'16',
|
|
519
|
+
'17',
|
|
520
|
+
'18',
|
|
521
|
+
'19',
|
|
522
|
+
'X',
|
|
523
|
+
'Y',
|
|
524
|
+
];
|
|
525
|
+
|
|
526
|
+
class MVarService {
|
|
527
|
+
http;
|
|
528
|
+
environment;
|
|
529
|
+
api;
|
|
530
|
+
sequenceOntologyMapping = {};
|
|
531
|
+
soTerms = new BehaviorSubject([]);
|
|
532
|
+
soTerms$ = this.soTerms.asObservable();
|
|
533
|
+
constructor(http, environment) {
|
|
534
|
+
this.http = http;
|
|
535
|
+
this.environment = environment;
|
|
536
|
+
this.api = environment.unsecuredURLs.mvar;
|
|
537
|
+
// create a sequence ontology lookup
|
|
538
|
+
this.getSequenceOntologyTerms().subscribe((terms) => {
|
|
539
|
+
terms.forEach((t) => {
|
|
540
|
+
if (t.label) {
|
|
541
|
+
this.sequenceOntologyMapping[t.label] = t;
|
|
542
|
+
}
|
|
543
|
+
});
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Gets Variants from mvar for a given set snp regions
|
|
548
|
+
* @param regions Array of snp regions
|
|
549
|
+
* @param pageStart snp start location
|
|
550
|
+
* @param pageEnd snp end location
|
|
551
|
+
* @param assembly Desired assembly version. Acceptable values are 'mm10' (GRCm38) and 'mm39' (GRCm39)
|
|
552
|
+
*/
|
|
553
|
+
getVariants(regions, pageStart, pageEnd, assembly) {
|
|
554
|
+
return combineLatest(this.getRegionsToRequestVariantsFor(regions, pageStart, pageEnd).map((r) => {
|
|
555
|
+
return this.http.get(`${this.api}/variant/query?chr=${r.chromosome}&startPos=${r.start_position}&endPos=${r.end_position}&max=8000&assembly=${assembly}`);
|
|
556
|
+
})).pipe(map((variants) => {
|
|
557
|
+
const allVariants = variants.map((v) => v.variants).flat();
|
|
558
|
+
allVariants.forEach((variant) => {
|
|
559
|
+
const classCodes = variant.functionalClassCode.split(',')[0];
|
|
560
|
+
// add the ontology term
|
|
561
|
+
variant.functionalClasses = classCodes.split('&').map((c) => this.sequenceOntologyMapping[c]);
|
|
562
|
+
});
|
|
563
|
+
return allVariants;
|
|
564
|
+
}));
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Returns all sequence ontology terms in MVAR
|
|
568
|
+
*/
|
|
569
|
+
getSequenceOntologyTerms() {
|
|
570
|
+
return this.http
|
|
571
|
+
.get(`${this.api}/sequenceOntology/query?max=3000`)
|
|
572
|
+
.pipe(tap((terms) => this.soTerms.next(terms)));
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* Translates the regions requested from MUSter and the regions actually displayed on the current page into
|
|
576
|
+
* regions to request from MVAR
|
|
577
|
+
* @param requestedRegions - regions included in the request to MUSter
|
|
578
|
+
* @param pageStart - first SNP from the sorted results from MUSter to display in the table
|
|
579
|
+
* @param pageEnd - last SNP from the sorted results from MUSter to display in the table
|
|
580
|
+
*/
|
|
581
|
+
getRegionsToRequestVariantsFor(requestedRegions, pageStart, pageEnd) {
|
|
582
|
+
const displayStartBP = pageStart.start_position || 0;
|
|
583
|
+
const displayEndBP = pageEnd.start_position || 0;
|
|
584
|
+
const regionsByChr = {};
|
|
585
|
+
requestedRegions.forEach((r) => {
|
|
586
|
+
if (regionsByChr[r.chromosome]) {
|
|
587
|
+
regionsByChr[r.chromosome].push(r);
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
590
|
+
regionsByChr[r.chromosome] = [r];
|
|
591
|
+
}
|
|
592
|
+
});
|
|
593
|
+
const displayedRegions = [];
|
|
594
|
+
if (pageStart.chr === pageEnd.chr) {
|
|
595
|
+
regionsByChr[pageStart.chr].forEach((r) => {
|
|
596
|
+
if (r.start_position <= displayEndBP && r.end_position >= displayStartBP) {
|
|
597
|
+
displayedRegions.push({
|
|
598
|
+
chromosome: r.chromosome,
|
|
599
|
+
start_position: Math.max(r.start_position, displayStartBP),
|
|
600
|
+
end_position: Math.min(r.end_position, displayEndBP),
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
else {
|
|
606
|
+
const displayedChrs = Object.keys(regionsByChr).filter((r) => MUS_CHRS.indexOf(r) >= MUS_CHRS.indexOf(pageStart.chr) &&
|
|
607
|
+
MUS_CHRS.indexOf(r) <= MUS_CHRS.indexOf(pageEnd.chr));
|
|
608
|
+
displayedChrs.forEach((chr) => {
|
|
609
|
+
regionsByChr[chr].forEach((r) => {
|
|
610
|
+
if (r.end_position >= displayStartBP && chr === pageStart.chr) {
|
|
611
|
+
displayedRegions.push({
|
|
612
|
+
chromosome: r.chromosome,
|
|
613
|
+
start_position: Math.max(r.start_position, displayStartBP),
|
|
614
|
+
end_position: r.end_position,
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
else if (r.start_position <= displayEndBP && chr === pageEnd.chr) {
|
|
618
|
+
displayedRegions.push({
|
|
619
|
+
chromosome: r.chromosome,
|
|
620
|
+
start_position: r.start_position,
|
|
621
|
+
end_position: Math.min(r.end_position, displayEndBP),
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
else if (chr !== pageStart.chr && chr !== pageEnd.chr) {
|
|
625
|
+
displayedRegions.push({
|
|
626
|
+
chromosome: r.chromosome,
|
|
627
|
+
start_position: r.start_position,
|
|
628
|
+
end_position: r.end_position,
|
|
629
|
+
});
|
|
630
|
+
}
|
|
631
|
+
});
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
return displayedRegions;
|
|
635
|
+
}
|
|
636
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: MVarService, deps: [{ token: i1.HttpClient }, { token: 'environment' }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
637
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: MVarService, providedIn: 'root' });
|
|
638
|
+
}
|
|
639
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: MVarService, decorators: [{
|
|
640
|
+
type: Injectable,
|
|
641
|
+
args: [{
|
|
642
|
+
providedIn: 'root'
|
|
643
|
+
}]
|
|
644
|
+
}], ctorParameters: () => [{ type: i1.HttpClient }, { type: undefined, decorators: [{
|
|
645
|
+
type: Inject,
|
|
646
|
+
args: ['environment']
|
|
647
|
+
}] }] });
|
|
648
|
+
|
|
649
|
+
class MvarClientModule {
|
|
650
|
+
static forRoot(environment) {
|
|
651
|
+
return {
|
|
652
|
+
ngModule: MvarClientModule,
|
|
653
|
+
providers: [
|
|
654
|
+
MVarService,
|
|
655
|
+
{
|
|
656
|
+
provide: 'environment', // you can also use InjectionToken
|
|
657
|
+
useValue: environment
|
|
658
|
+
}
|
|
659
|
+
]
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: MvarClientModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
663
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.5", ngImport: i0, type: MvarClientModule, imports: [CommonModule] });
|
|
664
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: MvarClientModule, imports: [CommonModule] });
|
|
665
|
+
}
|
|
666
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: MvarClientModule, decorators: [{
|
|
667
|
+
type: NgModule,
|
|
668
|
+
args: [{
|
|
669
|
+
imports: [CommonModule],
|
|
670
|
+
}]
|
|
671
|
+
}] });
|
|
672
|
+
|
|
673
|
+
class SnpGridService {
|
|
674
|
+
http;
|
|
675
|
+
environment;
|
|
676
|
+
api;
|
|
677
|
+
// default true but becomes false if any of the API calls for general information fails
|
|
678
|
+
apiAvailable = true;
|
|
679
|
+
strains = new BehaviorSubject([]);
|
|
680
|
+
strains$ = this.strains.asObservable();
|
|
681
|
+
constructor(http, environment) {
|
|
682
|
+
this.http = http;
|
|
683
|
+
this.environment = environment;
|
|
684
|
+
this.api = environment.securedURLs.genomeMUSter;
|
|
685
|
+
this.getHealthCheck().subscribe({
|
|
686
|
+
error: () => {
|
|
687
|
+
this.apiAvailable = false;
|
|
688
|
+
},
|
|
689
|
+
});
|
|
690
|
+
this.getStrains().subscribe({
|
|
691
|
+
next: (strains) => {
|
|
692
|
+
this.apiAvailable = Boolean(strains.length);
|
|
693
|
+
},
|
|
694
|
+
error: () => {
|
|
695
|
+
this.apiAvailable = false;
|
|
696
|
+
},
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Returns the result of a health check for the API
|
|
701
|
+
*/
|
|
702
|
+
getHealthCheck() {
|
|
703
|
+
return this.http.get(`${this.api}/healthcheck`);
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Returns the metadata on the MUSter DB
|
|
707
|
+
*/
|
|
708
|
+
getMusterMetadata() {
|
|
709
|
+
return this.http.get(`${this.api}/db_info`).pipe(catchError((err) => {
|
|
710
|
+
this.apiAvailable = false;
|
|
711
|
+
throw err;
|
|
712
|
+
}));
|
|
713
|
+
}
|
|
714
|
+
/**
|
|
715
|
+
* Returns strains available in the API and takes an optional limit; by default the limit is set
|
|
716
|
+
* to 5000 to get all strains
|
|
717
|
+
* @param limit - maximum number of strains to be returned
|
|
718
|
+
*/
|
|
719
|
+
getStrains(limit = 5000) {
|
|
720
|
+
return this.http
|
|
721
|
+
.get(`${this.api}/strains/?limit=${limit}`)
|
|
722
|
+
.pipe(tap((strains) => this.strains.next(strains.filter((s) => s.mpd_strainid))));
|
|
723
|
+
}
|
|
724
|
+
/**
|
|
725
|
+
* Returns a list of known genes whose symbols/coordinates start with the specified value.
|
|
726
|
+
* @param searchValue - value to use for the "starts with" filter
|
|
727
|
+
* @param limit - maximum number of genes to return, default is 20
|
|
728
|
+
*/
|
|
729
|
+
getGenes(searchValue, limit = 20) {
|
|
730
|
+
return this.http.get(`${this.api}/genes/?symbol=${searchValue}%&limit=${limit}`);
|
|
731
|
+
}
|
|
732
|
+
/**
|
|
733
|
+
* Returns the gene that matches the specified gene symbol
|
|
734
|
+
* @param geneSymbol - symbol to use to get the associated gene info
|
|
735
|
+
*/
|
|
736
|
+
getGene(geneSymbol) {
|
|
737
|
+
return this.http
|
|
738
|
+
.get(`${this.api}/genes/?symbol=${geneSymbol}`)
|
|
739
|
+
.pipe(map((genes) => (genes.length ? genes[0] : null)));
|
|
740
|
+
}
|
|
741
|
+
/**
|
|
742
|
+
* Returns true if the specified gene symbol is valid from the perspective of MUSter
|
|
743
|
+
* @param geneSymbol - symbol to use to check the validity of
|
|
744
|
+
*/
|
|
745
|
+
isGeneSymbolValid(geneSymbol) {
|
|
746
|
+
return this.getGene(geneSymbol).pipe(map((g) => g !== null && geneSymbol.toLowerCase() === g.symbol.toLowerCase()));
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Returns list of known reference SNP (RS) data which includes IDs and coordinates
|
|
750
|
+
* @param searchValue - value to use to filter the search results
|
|
751
|
+
* @param limit - maximum number of results to return, default is 20
|
|
752
|
+
*/
|
|
753
|
+
getReferenceSNPs(searchValue, limit = 20) {
|
|
754
|
+
return this.http.get(`${this.api}/rsids/?rsid=${searchValue}%&limit=${limit}`);
|
|
755
|
+
}
|
|
756
|
+
/**
|
|
757
|
+
* Returns the RS info that matches the specified rsID
|
|
758
|
+
* @param rsid - the RSID to use to get the associated RS info
|
|
759
|
+
*/
|
|
760
|
+
getReferenceSNP(rsid) {
|
|
761
|
+
return this.http
|
|
762
|
+
.get(`${this.api}/rsids/?rsid=${rsid}`)
|
|
763
|
+
.pipe(map((rsids) => (rsids.length ? { ...rsids[0], end_position: rsids[0].start_position } : null)));
|
|
764
|
+
}
|
|
765
|
+
/**
|
|
766
|
+
* Returns true if the specified rsID is valid from the perspective of MUSter
|
|
767
|
+
* @param rsid - rsID to use to check the validity of
|
|
768
|
+
*/
|
|
769
|
+
isRSIDValid(rsid) {
|
|
770
|
+
return this.getReferenceSNP(rsid).pipe(map((rs) => rs !== null && rsid.toLowerCase() === rs.rsid.toLowerCase()));
|
|
771
|
+
}
|
|
772
|
+
/**
|
|
773
|
+
* Returns the SNP results generated from the query constructed from the specified parameters and page
|
|
774
|
+
* @param parameters - search properties (strain IDs, regions, assembly version, etc.)
|
|
775
|
+
* @param page - requested page, which is 0-indexed. The 0th page is the initial page
|
|
776
|
+
* @param pageSize - number of records to show per page. Default of 5000
|
|
777
|
+
*/
|
|
778
|
+
getGenotypes(parameters, page = 0, pageSize = 5000) {
|
|
779
|
+
let constructedURL = `${this.api}/snps/?` +
|
|
780
|
+
`assembly=${parameters.assembly}&` +
|
|
781
|
+
`mpd_strain_ids=${parameters.strains.join(',')}&` +
|
|
782
|
+
`limit=${pageSize}`;
|
|
783
|
+
if (parameters.strains_b?.length) {
|
|
784
|
+
constructedURL += `&mpd_strain_ids_b=${parameters.strains_b.join(',')}&strain_limit=${parameters.strains.length + parameters.strains_b.length}`;
|
|
785
|
+
}
|
|
786
|
+
else {
|
|
787
|
+
constructedURL += `&strain_limit=${parameters.strains.length}`;
|
|
788
|
+
}
|
|
789
|
+
if (parameters.rsids?.length) {
|
|
790
|
+
constructedURL += `&rsids=${parameters.rsids.join(',')}`;
|
|
791
|
+
}
|
|
792
|
+
if (parameters.genes?.length) {
|
|
793
|
+
constructedURL += `&genes=${parameters.genes.join(',')}`;
|
|
794
|
+
}
|
|
795
|
+
if (parameters.regions?.length) {
|
|
796
|
+
constructedURL += `®ions=${parameters.regions.join(',')}`;
|
|
797
|
+
}
|
|
798
|
+
if (parameters.dataset_id) {
|
|
799
|
+
constructedURL += `&dataset_id=${parameters.dataset_id}`;
|
|
800
|
+
}
|
|
801
|
+
if (parameters.is_unique_row) {
|
|
802
|
+
constructedURL += `&is_unique_row=${parameters.is_unique_row}`;
|
|
803
|
+
}
|
|
804
|
+
if (page) {
|
|
805
|
+
constructedURL += `&offset=${pageSize * page}`;
|
|
806
|
+
}
|
|
807
|
+
return this.http.get(constructedURL);
|
|
808
|
+
}
|
|
809
|
+
/**
|
|
810
|
+
* Returns the URL that will generate a download (in file form) for the specified strain IDs and regions
|
|
811
|
+
* @param strains - list of mpd_strain_ids to query SNPs for
|
|
812
|
+
* @param regions - list of SNPSearchRegions to query SNPs for (chromosome, start and end)
|
|
813
|
+
* @param dataset_id - ID of the dataset to query SNPs for
|
|
814
|
+
* @param is_unique_row - boolean for polymorphism filtering - true for only rows with polymorphism, false for all
|
|
815
|
+
* @param limit - the limit of the number of result rows to include in the download - you're likely to
|
|
816
|
+
* prefer to pass the total number of rows generated by the query itself, which is included
|
|
817
|
+
* as part of the GenotypeResults returned by getGenotypes()
|
|
818
|
+
*/
|
|
819
|
+
getGenotypeDownloadURLForCurrentData(strains, regions, dataset_id, is_unique_row = false, limit) {
|
|
820
|
+
if (!dataset_id) {
|
|
821
|
+
// default to the GenomeMuster dataset id
|
|
822
|
+
dataset_id = 2;
|
|
823
|
+
}
|
|
824
|
+
const stringifiedRegions = `regions=${regions
|
|
825
|
+
.map((reg) => `${reg.chromosome}:${reg.start_position}-${reg.end_position}`)
|
|
826
|
+
.join(',')}`;
|
|
827
|
+
const stringifiedStrains = `mpd_strain_ids=${strains.join(',')}`;
|
|
828
|
+
return `${this.api}/snps/download?dataset_id=${dataset_id}&${stringifiedStrains}&${stringifiedRegions}&limit=${limit}&is_unique_row=${is_unique_row}`;
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Returns the dataset with the given ID
|
|
832
|
+
* @param id
|
|
833
|
+
*/
|
|
834
|
+
getDataset(id) {
|
|
835
|
+
return this.http.get(`${this.api}/datasets/${id}`);
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
838
|
+
* Returns a list of Datasets that match the given criteria
|
|
839
|
+
* @param status The value of the status to be used for filtering
|
|
840
|
+
* @param limit The maximum number of records to return
|
|
841
|
+
*/
|
|
842
|
+
findDatasets(status, limit = 50) {
|
|
843
|
+
let url = `${this.api}/datasets`;
|
|
844
|
+
url += `/?limit=${limit}`;
|
|
845
|
+
if (status) {
|
|
846
|
+
url += `&status=${status}`;
|
|
847
|
+
}
|
|
848
|
+
return this.http.get(url);
|
|
849
|
+
}
|
|
850
|
+
/**
|
|
851
|
+
* Return a list of strains that match the given criteria
|
|
852
|
+
* @param datasetId The ID of the dataset from which to fetch the strains
|
|
853
|
+
* @param limit The maximum number of records to return
|
|
854
|
+
*/
|
|
855
|
+
datasetStrains(datasetId, limit = 5000) {
|
|
856
|
+
const url = `${this.api}/dataset_strain/?dataset_id=${datasetId}&limit=${limit}`;
|
|
857
|
+
return this.http.get(url);
|
|
858
|
+
}
|
|
859
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: SnpGridService, deps: [{ token: i1.HttpClient }, { token: 'environment' }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
860
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: SnpGridService, providedIn: 'root' });
|
|
861
|
+
}
|
|
862
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: SnpGridService, decorators: [{
|
|
863
|
+
type: Injectable,
|
|
864
|
+
args: [{
|
|
865
|
+
providedIn: 'root'
|
|
866
|
+
}]
|
|
867
|
+
}], ctorParameters: () => [{ type: i1.HttpClient }, { type: undefined, decorators: [{
|
|
868
|
+
type: Inject,
|
|
869
|
+
args: ['environment']
|
|
870
|
+
}] }] });
|
|
871
|
+
|
|
872
|
+
class SnpGridClientModule {
|
|
873
|
+
static forRoot(environment) {
|
|
874
|
+
return {
|
|
875
|
+
ngModule: SnpGridClientModule,
|
|
876
|
+
providers: [
|
|
877
|
+
SnpGridService,
|
|
878
|
+
{
|
|
879
|
+
provide: 'environment', // you can also use InjectionToken
|
|
880
|
+
useValue: environment
|
|
881
|
+
}
|
|
882
|
+
]
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: SnpGridClientModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
886
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.5", ngImport: i0, type: SnpGridClientModule, imports: [CommonModule] });
|
|
887
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: SnpGridClientModule, imports: [CommonModule] });
|
|
888
|
+
}
|
|
889
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: SnpGridClientModule, decorators: [{
|
|
890
|
+
type: NgModule,
|
|
891
|
+
args: [{
|
|
892
|
+
imports: [CommonModule],
|
|
893
|
+
}]
|
|
894
|
+
}] });
|
|
895
|
+
|
|
896
|
+
var DatasetStatus;
|
|
897
|
+
(function (DatasetStatus) {
|
|
898
|
+
DatasetStatus["Queued"] = "queued";
|
|
899
|
+
DatasetStatus["Loading"] = "loading";
|
|
900
|
+
DatasetStatus["Done"] = "done";
|
|
901
|
+
DatasetStatus["Archived"] = "archived";
|
|
902
|
+
})(DatasetStatus || (DatasetStatus = {}));
|
|
903
|
+
|
|
904
|
+
// AsyncTask API client
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* Generated bundle index. Do not edit.
|
|
908
|
+
*/
|
|
909
|
+
|
|
910
|
+
export { AsyncTaskService, DatasetStatus, MUS_CHRS, MVarService, MvarClientModule, OntologyService, SnpGridClientModule, SnpGridService, WorkflowExecutionStatus };
|
|
911
|
+
//# sourceMappingURL=jax-data-science-api-clients.mjs.map
|