synapse-react-client
Version:
[](https://travis-ci.com/Sage-Bionetworks/Synapse-React-Client) [](https://badge.fury.io/js/synaps
966 lines • 91.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getWikiAttachmentsFromEvaluation = exports.getWikiAttachmentsFromEntity = exports.getWikiPageKeyForAccessRequirement = exports.getWikiPageKeyForEntity = exports.getTeamList = exports.getUserTeamList = exports.getUserChallenges = exports.removeUserFavorite = exports.getUserFavorites = exports.getEntityWiki = exports.getEntityBundleV2 = exports.deleteEntity = exports.updateEntity = exports.getEntityHeader = exports.getEntityHeaders = exports.getEntityHeadersByIds = exports.getEntity = exports.getBulkFiles = exports.getFiles = exports.lookupChildEntity = exports.getEntityChildren = exports.getUserProfiles = exports.getGroupHeadersBatch = exports.getUserGroupHeaders = exports.getUserBundle = exports.getUserProfileById = exports.getUserProfile = exports.createProject = exports.createEntity = exports.oAuthSessionRequest = exports.oAuthUrlRequest = exports.login = exports.getFullQueryTableResults = exports.getQueryTableResults = exports.getAsyncResultFromJobId = exports.getFileHandleByIdURL = exports.getActualFileHandleByIdURL = exports.getFileHandleById = exports.getDownloadFromTableRequest = exports.addFilesToDownloadList = exports.getVersion = exports.doPut = exports.doDelete = exports.doGet = exports.doPost = exports.delay = exports.getRootURL = exports.SYNAPSE_STORAGE_LOCATION_ID = exports.ACCESS_TOKEN_COOKIE_KEY = exports.IS_OUTSIDE_SYNAPSE_ORG = void 0;
exports.getAccessRequirement = exports.getRestrictionInformation = exports.getProjectStatistics = exports.rejectFormData = exports.acceptFormData = exports.listFormDataAsFormAdmin = exports.listFormData = exports.submitFormData = exports.deleteFormData = exports.updateFormData = exports.createFormData = exports.updateFormACL = exports.getFormACL = exports.createFormGroup = exports.consentToOAuth2Request = exports.getAuthenticatedOn = exports.getOAuth2Client = exports.hasUserAuthorizedOAuthClient = exports.getOAuth2RequestDescription = exports.getEvaluationSubmissions = exports.deleteEvaluationRound = exports.updateEvaluationRound = exports.createEvaluationRound = exports.getEvaluationRoundsList = exports.getEvaluationRound = exports.deleteEvaluation = exports.createEvaluation = exports.updateEvaluation = exports.getEvaluation = exports.getEvaluationPermissions = exports.submitToEvaluation = exports.createACL = exports.addFilesToDownloadListV2 = exports.createManifestFromDownloadListV2 = exports.createPackageFromDownloadListV2 = exports.addFileToDownloadListV2 = exports.getFileResult = exports.getFileHandleContent = exports.getFileHandleContentFromID = exports.startMultipartUpload = exports.checkUploadComplete = exports.uploadFile = exports.signOut = exports.detectSSOCode = exports.getPrincipalAliasRequest = exports.getUseUtcTimeFromCookie = exports.getAccessTokenFromCookie = exports.setAccessTokenCookie = exports.isInSynapseExperimentalMode = exports.getPresignedUrlForWikiAttachment = void 0;
exports.updateEntityJson = exports.getEntityJson = exports.hasAccessToEntity = exports.getValidationSchema = exports.getSchema = exports.getSchemaValidationResults = exports.getSchemaBinding = exports.cancelDataAccessRequest = exports.submitDataAccessRequest = exports.updateDataAccessRequest = exports.getDataAccessRequestForUpdate = exports.getResearchProject = exports.updateResearchProject = exports.removeItemFromDownloadListV2 = exports.getDownloadListActionsRequired = exports.getDownloadListStatistics = exports.getAvailableFilesToDownload = exports.clearDownloadListV2 = exports.searchEntities = exports.getEntityVersions = exports.getEntityPath = exports.getUserProjects = exports.getMyProjects = exports.deletePersonalAccessToken = exports.getPersonalAccessTokenRecords = exports.createPersonalAccessToken = exports.getTransformSqlWithFacetsRequest = exports.updateTable = exports.deleteDownloadList = exports.deleteDownloadListFiles = exports.getAllOfPaginatedService = exports.getDownloadOrder = exports.getDownloadList = exports.postAccessApproval = exports.getAccessApproval = exports.getAllAccessRequirements = exports.getAccessRequirementStatus = exports.getAccessRequirementById = void 0;
var tslib_1 = require("tslib");
var spark_md5_1 = (0, tslib_1.__importDefault)(require("spark-md5"));
var universal_cookie_1 = (0, tslib_1.__importDefault)(require("universal-cookie"));
var _1 = require(".");
var APIConstants_1 = require("./APIConstants");
var dispatchDownloadListChangeEvent_1 = require("./functions/dispatchDownloadListChangeEvent");
var getEndpoint_1 = require("./functions/getEndpoint");
var ObjectUtils_1 = require("./functions/ObjectUtils");
var SynapseConstants_1 = require("./SynapseConstants");
var synapseTypes_1 = require("./synapseTypes/");
var cookies = new universal_cookie_1.default();
// TODO: Create JSON response types for all return types
exports.IS_OUTSIDE_SYNAPSE_ORG = window.location.hostname
.toLowerCase()
.includes('.synapse.org')
? false
: true;
exports.ACCESS_TOKEN_COOKIE_KEY = 'org.sagebionetworks.security.user.login.token';
// Max size file that we will allow the caller to read into memory (5MB)
var MAX_JS_FILE_DOWNLOAD_SIZE = 5242880;
// This corresponds to the Synapse-managed S3 storage location:
exports.SYNAPSE_STORAGE_LOCATION_ID = 1;
var getRootURL = function () {
var portString = window.location.port ? ":" + window.location.port : '';
return window.location.protocol + "//" + window.location.hostname + portString + "/";
};
exports.getRootURL = getRootURL;
/**
* Waits t number of milliseconds
*
* @export
* @param {number} t milliseconds
* @returns after t milliseconds
*/
function delay(t) {
return new Promise(function (resolve) {
setTimeout(resolve.bind(null, {}), t);
});
}
exports.delay = delay;
/*
0 - no internet connection
429 - Too Many Requests
502 - Bad Gateway
503 - Service Unavailable
504 - Gateway Timeout
*/
var RETRY_STATUS_CODES = [0, 429, 502, 503, 504];
var fetchWithExponentialTimeout = function (url, options, delayMs) {
if (delayMs === void 0) { delayMs = 1000; }
return fetch(url, options)
.then(function (resp) {
return resp
.text()
.then(function (text) {
// try to parse it as json
try {
var json = JSON.parse(text);
return resp.ok ? Promise.resolve(json) : Promise.reject(json);
}
catch (error) {
// failed to parse json, return text
return resp.ok ? Promise.resolve(text) : Promise.reject(text);
}
})
.catch(function (error) {
if (resp.ok) {
// possible empty response
return Promise.resolve({
reason: error,
status: resp.status,
});
}
if (error.reason && resp.status) {
// successful return from server but invalid call
return Promise.reject((0, tslib_1.__assign)((0, tslib_1.__assign)({}, error), { status: resp.status }));
}
// This occurs if the response is not ok and does not have json or is empty
return Promise.reject({
reason: error,
status: resp.status,
});
});
})
.catch(function (error) {
if (error.status && RETRY_STATUS_CODES.indexOf(error.status) !== -1) {
return delay(delayMs).then(function () {
return fetchWithExponentialTimeout(url, options, delayMs * 2);
});
}
else {
return Promise.reject(error);
}
});
};
var doPost = function (url, requestJsonObject, accessToken, initCredentials, endpoint) {
var options = {
body: JSON.stringify(requestJsonObject),
headers: {
Accept: '*/*',
'Access-Control-Request-Headers': 'authorization',
'Content-Type': 'application/json',
},
method: 'POST',
mode: 'cors',
credentials: initCredentials,
};
if (accessToken) {
// @ts-ignore
options.headers.authorization = "Bearer " + accessToken;
}
var usedEndpoint = (0, getEndpoint_1.getEndpoint)(endpoint);
return fetchWithExponentialTimeout(usedEndpoint + url, options);
};
exports.doPost = doPost;
var doGet = function (url, accessToken, initCredentials, endpoint) {
var options = {
headers: {
Accept: '*/*',
'Access-Control-Request-Headers': 'authorization',
},
method: 'GET',
mode: 'cors',
credentials: initCredentials,
};
if (accessToken) {
// @ts-ignore
options.headers.authorization = "Bearer " + accessToken;
}
var usedEndpoint = (0, getEndpoint_1.getEndpoint)(endpoint);
return fetchWithExponentialTimeout(usedEndpoint + url, options);
};
exports.doGet = doGet;
var doDelete = function (url, accessToken, initCredentials, endpoint) {
var options = {
headers: {
Accept: '*/*',
'Access-Control-Request-Headers': 'authorization',
},
method: 'DELETE',
mode: 'cors',
credentials: initCredentials,
};
if (accessToken) {
// @ts-ignore
options.headers.authorization = "Bearer " + accessToken;
}
var usedEndpoint = (0, getEndpoint_1.getEndpoint)(endpoint);
return fetchWithExponentialTimeout(usedEndpoint + url, options);
};
exports.doDelete = doDelete;
var doPut = function (url, requestJsonObject, accessToken, initCredentials, endpoint) {
var options = {
body: JSON.stringify(requestJsonObject),
headers: {
Accept: '*/*',
'Access-Control-Request-Headers': 'authorization',
'Content-Type': 'application/json',
},
method: 'PUT',
mode: 'cors',
credentials: initCredentials,
};
if (accessToken) {
// @ts-ignore
options.headers.authorization = "Bearer " + accessToken;
}
var usedEndpoint = (0, getEndpoint_1.getEndpoint)(endpoint);
return fetchWithExponentialTimeout(usedEndpoint + url, options);
};
exports.doPut = doPut;
var getVersion = function () {
return (0, exports.doGet)('/repo/v1/version', undefined, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getVersion = getVersion;
/**
* https://rest-docs.synapse.org/rest/POST/download/list/add/async/start.html
*/
//Start an asynchronous job to add files to a user's download list.
var addFilesToDownloadList = function (request, accessToken, updateParentState) {
return (0, exports.doPost)("/file/v1/download/list/add/async/start", request, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT)
.then(function (resp) {
var requestUrl = "/file/v1/download/list/add/async/get/" + resp.token;
return (0, exports.getAsyncResultFromJobId)(requestUrl, accessToken, updateParentState).then(function (data) {
(0, dispatchDownloadListChangeEvent_1.dispatchDownloadListChangeEvent)(data.downloadList);
return data;
});
})
.catch(function (error) {
throw error;
});
};
exports.addFilesToDownloadList = addFilesToDownloadList;
/**
* https://rest-docs.synapse.org/rest/POST/entity/id/table/download/csv/async/start.html
*/
var getDownloadFromTableRequest = function (request, accessToken, updateParentState) {
if (accessToken === void 0) { accessToken = undefined; }
return (0, exports.doPost)("/repo/v1/entity/" + request.entityId + "/table/download/csv/async/start", request, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT)
.then(function (resp) {
var requestUrl = "/repo/v1/entity/" + request.entityId + "/table/download/csv/async/get/" + resp.token;
return (0, exports.getAsyncResultFromJobId)(requestUrl, accessToken, updateParentState);
})
.catch(function (error) {
throw error;
});
};
exports.getDownloadFromTableRequest = getDownloadFromTableRequest;
/**
* https://rest-docs.synapse.org/rest/GET/fileHandle/handleId.html
* Get a FileHandle using its ID.
* Note: Only the user that created the FileHandle can access it directly.
* @return FileHandle
**/
var getFileHandleById = function (handleId, accessToken) {
if (accessToken === void 0) { accessToken = undefined; }
return (0, exports.doGet)("/file/v1/fileHandle/" + handleId, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getFileHandleById = getFileHandleById;
/**
* http://rest-docs.synapse.org/rest/GET/file/id.html
* Get the actual URL of the file from with an associated object .
* @return a short lived presignedURL to be redirected with
**/
var getActualFileHandleByIdURL = function (handleId, accessToken, fileAssociateType, fileAssociateId, redirect) {
if (accessToken === void 0) { accessToken = undefined; }
if (redirect === void 0) { redirect = true; }
// get the presigned URL for this file handle association.
return (0, exports.doGet)("/file/v1/file/" + handleId + "?fileAssociateType=" + fileAssociateType + "&fileAssociateId=" + fileAssociateId + "&redirect=" + redirect, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getActualFileHandleByIdURL = getActualFileHandleByIdURL;
/**
* https://rest-docs.synapse.org/rest/GET/fileHandle/handleId/url.html
* Note: Only the user that created the FileHandle can use this method for download.
* @return a short lived presignedURL to be redirected with
**/
var getFileHandleByIdURL = function (handleId, accessToken) {
if (accessToken === void 0) { accessToken = undefined; }
// get the presigned URL for this file handle
return (0, exports.doGet)("/file/v1/fileHandle/" + handleId + "/url?redirect=false", accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getFileHandleByIdURL = getFileHandleByIdURL;
var getAsyncResultFromJobId = function (urlRequest, accessToken, updateParentState) {
if (accessToken === void 0) { accessToken = undefined; }
return (0, exports.doGet)(urlRequest, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT)
.then(function (resp) {
// is this the job status?
if (resp.jobState && resp.jobState !== 'FAILED') {
updateParentState &&
updateParentState({
asyncJobStatus: resp,
});
// still processing, wait for a second and try again
return delay(500).then(function () {
return (0, exports.getAsyncResultFromJobId)(urlRequest, accessToken, updateParentState);
});
}
// these must be the query results!
return resp;
})
.catch(function (error) {
throw error;
});
};
exports.getAsyncResultFromJobId = getAsyncResultFromJobId;
/**
* https://rest-docs.synapse.org/rest/POST/entity/id/table/query/nextPage/async/start.html
* @param {*} queryBundleRequest
* @param {*} accessToken
* @param {*} endpoint
*/
var getQueryTableResults = function (queryBundleRequest, accessToken, updateParentState) {
if (accessToken === void 0) { accessToken = undefined; }
return (0, exports.doPost)("/repo/v1/entity/" + queryBundleRequest.entityId + "/table/query/async/start", queryBundleRequest, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT)
.then(function (resp) {
return (0, exports.getAsyncResultFromJobId)("/repo/v1/entity/" + queryBundleRequest.entityId + "/table/query/async/get/" + resp.token, accessToken, updateParentState);
})
.catch(function (error) {
throw error;
});
};
exports.getQueryTableResults = getQueryTableResults;
/**
* Run and return results from queryBundleRequest, queryBundle request must be of the
* form:
* {
* concreteType: String,
* query: {
* sql: String,
* partMask: Number
* }
* }
* @param {*} queryBundleRequest
* @param {*} [accessToken=undefined]
* @param {boolean} [onlyGetFacets=false] Specify if the query only needs facets and no
* data-- (internally this limits the row count to 1 on the request)
* @returns Full dataset from synapse table query
*/
var getFullQueryTableResults = function (queryBundleRequest, accessToken) {
if (accessToken === void 0) { accessToken = undefined; }
return (0, tslib_1.__awaiter)(void 0, void 0, void 0, function () {
var data, offset, query, rest, queryRequest, response, isDone, response_1;
var _a;
return (0, tslib_1.__generator)(this, function (_b) {
switch (_b.label) {
case 0:
offset = 0;
query = queryBundleRequest.query, rest = (0, tslib_1.__rest)(queryBundleRequest, ["query"]);
queryRequest = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, rest), { query: (0, tslib_1.__assign)((0, tslib_1.__assign)({}, query), { offset: offset }), partMask: queryBundleRequest.partMask |
_1.SynapseConstants.BUNDLE_MASK_QUERY_MAX_ROWS_PER_PAGE });
return [4 /*yield*/, (0, exports.getQueryTableResults)(queryRequest, accessToken)];
case 1:
response = _b.sent();
data = response;
isDone = response.queryResult.queryResults.rows.length < data.maxRowsPerPage;
offset += response.queryResult.queryResults.rows.length;
queryRequest.query.limit = data.maxRowsPerPage; // set the limit to the actual max rows per page
_b.label = 2;
case 2:
if (!!isDone) return [3 /*break*/, 4];
queryRequest.query.offset = offset;
return [4 /*yield*/, (0, exports.getQueryTableResults)(queryRequest, accessToken)];
case 3:
response_1 = _b.sent();
(_a = data.queryResult.queryResults.rows).push.apply(_a, response_1.queryResult.queryResults.rows);
isDone =
response_1.queryResult.queryResults.rows.length < queryRequest.query.limit;
offset += response_1.queryResult.queryResults.rows.length;
return [3 /*break*/, 2];
case 4: return [2 /*return*/, data];
}
});
});
};
exports.getFullQueryTableResults = getFullQueryTableResults;
/**
* Log-in using the given username and password. Will return a access token that must be used in
* authenticated requests.
* https://rest-docs.synapse.org/rest/POST/login2.html
*/
var login = function (username, password, authenticationReceipt, endpoint) {
if (endpoint === void 0) { endpoint = getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT; }
return (0, exports.doPost)('/auth/v1/login2', { username: username, password: password, authenticationReceipt: authenticationReceipt }, undefined, undefined, endpoint);
};
exports.login = login;
/**
* Get redirect url
* https://rest-docs.synapse.org/rest/POST/oauth2/authurl.html
* @param {*} provider
* @param {*} redirectUrl
* @param {*} endpoint
*/
var oAuthUrlRequest = function (provider, redirectUrl, endpoint) {
if (endpoint === void 0) { endpoint = getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT; }
return (0, exports.doPost)('/auth/v1/oauth2/authurl', { provider: provider, redirectUrl: redirectUrl }, undefined, undefined, endpoint);
};
exports.oAuthUrlRequest = oAuthUrlRequest;
/**
* Get access token from SSO
* https://rest-docs.synapse.org/rest/POST/oauth2/session2.html
* @param {*} provider
* @param {*} authenticationCode
* @param {*} redirectUrl
* @param {*} endpoint
*/
var oAuthSessionRequest = function (provider, authenticationCode, redirectUrl, endpoint) {
if (endpoint === void 0) { endpoint = getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT; }
return (0, exports.doPost)('/auth/v1/oauth2/session2', { provider: provider, authenticationCode: authenticationCode, redirectUrl: redirectUrl }, undefined, undefined, endpoint);
};
exports.oAuthSessionRequest = oAuthSessionRequest;
/**
* Create an entity (Project, Folder, File, Table, View)
* https://rest-docs.synapse.org/rest/POST/entity.html
*/
var createEntity = function (entity, accessToken) {
return (0, exports.doPost)(APIConstants_1.ENTITY, entity, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.createEntity = createEntity;
/**
* Create a project with the given name.
* https://rest-docs.synapse.org/rest/POST/entity.html
*/
var createProject = function (name, accessToken) {
return (0, exports.createEntity)({
name: name,
concreteType: 'org.sagebionetworks.repo.model.Project',
}, accessToken);
};
exports.createProject = createProject;
/**
* Return this user's UserProfile
* https://rest-docs.synapse.org/rest/GET/userProfile.html
*/
var getUserProfile = function (accessToken) {
return (0, exports.doGet)(APIConstants_1.USER_PROFILE, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getUserProfile = getUserProfile;
/**
* Return any user's UserProfile
* https://rest-docs.synapse.org/rest/GET/userProfile.html
*/
var getUserProfileById = function (accessToken, ownerId) {
return (0, exports.doGet)((0, APIConstants_1.USER_PROFILE_ID)(ownerId), accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getUserProfileById = getUserProfileById;
/**
* Return this user's profile bundle
* https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/UserBundle.html
*/
var getUserBundle = function (id, mask, accessToken) {
return (0, exports.doGet)((0, APIConstants_1.USER_ID_BUNDLE)(id) + "?mask=" + mask, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getUserBundle = getUserBundle;
/**
* Get Users and Groups that match the given prefix.
* http://rest-docs.synapse.org/rest/GET/userGroupHeaders.html
*/
var getUserGroupHeaders = function (prefix, typeFilter, offset, limit) {
if (prefix === void 0) { prefix = ''; }
if (typeFilter === void 0) { typeFilter = 'ALL'; }
if (offset === void 0) { offset = 0; }
if (limit === void 0) { limit = 20; }
return (0, exports.doGet)("/repo/v1/userGroupHeaders?prefix=" + prefix + "&typeFilter=" + typeFilter + "&offset=" + offset + "&limit=" + limit, undefined, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getUserGroupHeaders = getUserGroupHeaders;
/**
* Return batch of user group headers
* https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/UserGroupHeaderResponsePage.html
*/
var getGroupHeadersBatch = function (ids, accessToken) {
return (0, exports.doGet)("/repo/v1/userGroupHeaders/batch?ids=" + ids.join(','), accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getGroupHeadersBatch = getGroupHeadersBatch;
/**
* Return the User Profiles for the given list of user IDs
* https://rest-docs.synapse.org/rest/POST/userProfile.html
*/
var getUserProfiles = function (list, accessToken) {
if (accessToken === void 0) { accessToken = undefined; }
return (0, exports.doPost)(APIConstants_1.USER_PROFILE, { list: list }, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getUserProfiles = getUserProfiles;
/**
* Return the children (Files/Folders) of the given entity (Project or Folder).
* https://rest-docs.synapse.org/rest/POST/entity/children.html
*/
var getEntityChildren = function (request, accessToken) {
if (accessToken === void 0) { accessToken = undefined; }
return (0, exports.doPost)('/repo/v1/entity/children', request, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getEntityChildren = getEntityChildren;
/**
* Retrieve an entityId for a given parent ID and entity name.
* https://rest-docs.synapse.org/rest/POST/entity/child.html
*/
var lookupChildEntity = function (request, accessToken) {
if (accessToken === void 0) { accessToken = undefined; }
return (0, exports.doPost)('/repo/v1/entity/child', request, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.lookupChildEntity = lookupChildEntity;
/**
* Get a batch of pre-signed URLs and/or FileHandles for the given list of FileHandleAssociations.
* https://rest-docs.synapse.org/rest/POST/fileHandle/batch.html
*/
var getFiles = function (request, accessToken) {
if (accessToken === void 0) { accessToken = undefined; }
return (0, exports.doPost)('/file/v1/fileHandle/batch', request, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getFiles = getFiles;
/**
* Get a batch of pre-signed URLs and/or FileHandles for the given list of FileHandleAssociations.
* https://rest-docs.synapse.org/rest/POST/fileHandle/batch.html
*/
var getBulkFiles = function (bulkFileDownloadRequest, accessToken) {
if (accessToken === void 0) { accessToken = undefined; }
return (0, exports.doPost)('/file/v1/file/bulk/async/start', bulkFileDownloadRequest, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT)
.then(function (asyncJobId) {
var urlRequest = "/file/v1/file/bulk/async/get/" + asyncJobId.token;
return (0, exports.getAsyncResultFromJobId)(urlRequest, accessToken);
})
.catch(function (err) {
console.error('Error on getBulkFiles ', err);
throw err;
});
};
exports.getBulkFiles = getBulkFiles;
var getEntity = function (accessToken, entityId, versionNumber) {
if (accessToken === void 0) { accessToken = undefined; }
if (entityId.indexOf('.') > -1) {
// PORTALS-1943: we were given an entity Id with a version!
var entityTokens = entityId.split('.');
entityId = entityTokens[0];
versionNumber = entityTokens[1];
}
var url = versionNumber
? "/repo/v1/entity/" + entityId + "/version/" + versionNumber
: "/repo/v1/entity/" + entityId;
return (0, exports.doGet)(url, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getEntity = getEntity;
/**
* Get a list of entity headers given by entity ids
* http://rest-docs.synapse.org/rest/GET/entity/type.html
*/
var getEntityHeadersByIds = function (entityIds, accessToken) {
return (0, exports.doGet)("/repo/v1/entity/type?batch=" + entityIds.join(','), accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getEntityHeadersByIds = getEntityHeadersByIds;
/**
* Get the EntityHeader for a list of references with a POST.
* If any item in the batch fails (e.g., with a 404) it will be EXCLUDED in the result set.
* https://rest-docs.synapse.org/rest/POST/entity/header.html
*/
var getEntityHeaders = function (references, accessToken) {
// if references contains entity IDs with dot notation, fix the reference object
var fixedReferences = references.map(function (reference) {
if (reference.targetId.indexOf('.') > -1) {
var entityTokens = reference.targetId.split('.');
return {
targetId: entityTokens[0],
version: entityTokens[1],
};
}
else
return reference;
});
return (0, exports.doPost)(APIConstants_1.ENTITY_HEADERS, { references: fixedReferences }, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getEntityHeaders = getEntityHeaders;
/**
* Get the EntityHeader for a single entity
* https://rest-docs.synapse.org/rest/GET/entity/id/type.html
*/
var getEntityHeader = function (entityId, accessToken) {
return (0, exports.doGet)("/repo/v1/entity/" + entityId + "/type", accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getEntityHeader = getEntityHeader;
var updateEntity = function (entity, accessToken) {
if (accessToken === void 0) { accessToken = undefined; }
var url = "/repo/v1/entity/" + entity.id;
return (0, exports.doPut)(url, entity, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.updateEntity = updateEntity;
var deleteEntity = function (accessToken, entityId) {
if (accessToken === void 0) { accessToken = undefined; }
return (0, exports.doDelete)((0, APIConstants_1.ENTITY_ID)(entityId), accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.deleteEntity = deleteEntity;
var getEntityBundleV2 = function (entityId, requestObject, version, accessToken) {
return (0, exports.doPost)((0, APIConstants_1.ENTITY_BUNDLE_V2)(entityId, version), requestObject, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getEntityBundleV2 = getEntityBundleV2;
/**
* Get a corresponding string value of ObjectType:
**/
function getObjectTypeToString(key) {
return synapseTypes_1.ObjectType[key];
}
/**
* Get Wiki page contents, call is of the form:
* https://rest-docs.synapse.org/rest/GET/entity/ownerId/wiki.html
*/
var getEntityWiki = function (accessToken, ownerId, wikiId, objectType) {
if (wikiId === void 0) { wikiId = ''; }
if (objectType === void 0) { objectType = synapseTypes_1.ObjectType.ENTITY; }
var objectTypeString = getObjectTypeToString(objectType);
var url = "/repo/v1/" + (objectTypeString === null || objectTypeString === void 0 ? void 0 : objectTypeString.toLocaleLowerCase()) + "/" + ownerId + "/wiki/" + wikiId;
return (0, exports.doGet)(url, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getEntityWiki = getEntityWiki;
/**
* Returns synapse user favorites list given their access token
* https://rest-docs.synapse.org/rest/GET/favorite.html
*/
var getUserFavorites = function (accessToken, offset, limit) {
if (offset === void 0) { offset = 0; }
if (limit === void 0) { limit = 200; }
// https://sagebionetworks.jira.com/browse/PLFM-6616
var url = APIConstants_1.FAVORITES + "?offset=" + offset + "&limit=" + limit;
return (0, exports.doGet)(url, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getUserFavorites = getUserFavorites;
/**
* Remove a favorite
* http://rest-docs.synapse.org/rest/DELETE/favorite/id.html
*/
var removeUserFavorite = function (entityId, accessToken) {
return (0, exports.doDelete)("/repo/v1/favorite/" + entityId, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.removeUserFavorite = removeUserFavorite;
/**
* Get a list of challenges for which the given user is registered.
* see http://rest-docs.synapse.org/rest/GET/challenge.html
*/
var getUserChallenges = function (accessToken, userId, offset, limit) {
if (offset === void 0) { offset = 0; }
if (limit === void 0) { limit = 200; }
var url = "/repo/v1/challenge?participantId=" + userId + "&offset=" + offset + "&limit=" + limit;
return (0, exports.doGet)(url, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getUserChallenges = getUserChallenges;
/**
* Get the user's list of teams they are on
*
* @param {*} id ownerID of the synapse user see - https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/UserProfile.html
*/
var getUserTeamList = function (accessToken, userId, offset, limit) {
if (offset === void 0) { offset = 0; }
if (limit === void 0) { limit = 200; }
var url = "/repo/v1/user/" + userId + "/team?offset=" + offset + "&limit=" + limit;
return (0, exports.doGet)(url, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getUserTeamList = getUserTeamList;
/**
* Get the user's list of teams they are on
*
* @param {*} id ownerID of the synapse user see -https://rest-docs.synapse.org/rest/GET/teamMembers/id.html
* @param {*} fragment (optional) a prefix of the user's first or last name or email address (optional)
* @param {*} limit (optional) the maximum number of members to return (default 10, max limit 50)
* @param {*} offset (optional) the starting index of the returned results (default 0)
*
*/
var getTeamList = function (accessToken, id, fragment, limit, offset) {
if (fragment === void 0) { fragment = ''; }
if (limit === void 0) { limit = 10; }
if (offset === void 0) { offset = 0; }
var url = "/repo/v1/teamMembers/" + id + "?limit=" + limit + "&offset=" + offset + (fragment ? "&fragment=" + fragment : '');
return (0, exports.doGet)(url, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getTeamList = getTeamList;
/**
* https://rest-docs.synapse.org/rest/GET/entity/ownerId/wikikey.html
* Get the root WikiPageKey for an Entity.
* Note: The caller must be granted the ACCESS_TYPE.READ permission on the owner.
* @return WikiPageKey
**/
var getWikiPageKeyForEntity = function (accessToken, ownerId) {
var url = "/repo/v1/entity/" + ownerId + "/wikikey";
return (0, exports.doGet)(url, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getWikiPageKeyForEntity = getWikiPageKeyForEntity;
/**
* https://rest-docs.synapse.org/rest/GET/access_requirement/ownerId/wikikey.html
* Get the root WikiPageKey for an Access Requirement.
* Note: The caller must be granted the ACCESS_TYPE.READ permission on the owner.
* @return WikiPageKey
**/
var getWikiPageKeyForAccessRequirement = function (accessToken, ownerId) {
var url = "/repo/v1/access_requirement/" + ownerId + "/wikikey";
return (0, exports.doGet)(url, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getWikiPageKeyForAccessRequirement = getWikiPageKeyForAccessRequirement;
var getWikiAttachmentsFromEntity = function (accessToken, id, wikiId, objectType) {
if (objectType === void 0) { objectType = synapseTypes_1.ObjectType.ENTITY; }
var objectTypeString = getObjectTypeToString(objectType);
var url = "/repo/v1/" + objectTypeString.toLocaleLowerCase() + "/" + id + "/wiki2/" + wikiId + "/attachmenthandles";
return (0, exports.doGet)(url, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getWikiAttachmentsFromEntity = getWikiAttachmentsFromEntity;
var getWikiAttachmentsFromEvaluation = function (accessToken, id, wikiId) {
var url = "/repo/v1/evaluation/" + id + "/wiki/" + wikiId + "/attachmenthandles";
return (0, exports.doGet)(url, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getWikiAttachmentsFromEvaluation = getWikiAttachmentsFromEvaluation;
var getPresignedUrlForWikiAttachment = function (accessToken, id, wikiId, fileName, objectType) {
if (objectType === void 0) { objectType = synapseTypes_1.ObjectType.ENTITY; }
var objectTypeString = getObjectTypeToString(objectType);
var url = "/repo/v1/" + objectTypeString.toLocaleLowerCase() + "/" + id + "/wiki2/" + wikiId + "/attachment?fileName=" + fileName + "&redirect=false";
return (0, exports.doGet)(url, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getPresignedUrlForWikiAttachment = getPresignedUrlForWikiAttachment;
var isInSynapseExperimentalMode = function () {
// bang bang, you're a boolean!
return !!cookies.get(_1.SynapseConstants.EXPERIMENTAL_MODE_COOKIE);
};
exports.isInSynapseExperimentalMode = isInSynapseExperimentalMode;
/**
* Set the access token cookie. Note that this will only succeed if your app is running on
* a .synapse.org subdomain.
*
* @param {*} token Access token. If undefined, then call should instruct the browser to delete the cookie.
*/
var setAccessTokenCookie = function (token, sessionCallback) { return (0, tslib_1.__awaiter)(void 0, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
if (!exports.IS_OUTSIDE_SYNAPSE_ORG) return [3 /*break*/, 4];
if (!!token) return [3 /*break*/, 2];
cookies.remove(exports.ACCESS_TOKEN_COOKIE_KEY, { path: '/' });
// See - https://github.com/reactivestack/cookies/issues/189
return [4 /*yield*/, delay(100)];
case 1:
// See - https://github.com/reactivestack/cookies/issues/189
_a.sent();
return [3 /*break*/, 3];
case 2:
// set's cookie in session storage
cookies.set(exports.ACCESS_TOKEN_COOKIE_KEY, token, {
// expires in a day
maxAge: 60 * 60 * 24,
path: '/',
});
_a.label = 3;
case 3:
sessionCallback();
return [3 /*break*/, 5];
case 4:
// will set cookie in the http header
(0, exports.doPost)('Portal/sessioncookie', { sessionToken: token }, undefined, 'include', getEndpoint_1.BackendDestinationEnum.PORTAL_ENDPOINT)
.then(function (_) {
sessionCallback();
})
.catch(function (err) {
console.error('Error on setting access token ', err);
});
_a.label = 5;
case 5: return [2 /*return*/];
}
});
}); };
exports.setAccessTokenCookie = setAccessTokenCookie;
/**
* Get the current access token from a cookie. Note that this will only succeed if your app is running on
* a .synapse.org subdomain.
*/
var getAccessTokenFromCookie = function () { return (0, tslib_1.__awaiter)(void 0, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
if (exports.IS_OUTSIDE_SYNAPSE_ORG) {
return [2 /*return*/, cookies.get(exports.ACCESS_TOKEN_COOKIE_KEY)];
}
return [2 /*return*/, (0, exports.doGet)('Portal/sessioncookie?validate=true', undefined, 'include', getEndpoint_1.BackendDestinationEnum.PORTAL_ENDPOINT)];
});
}); };
exports.getAccessTokenFromCookie = getAccessTokenFromCookie;
var getUseUtcTimeFromCookie = function () {
return cookies.get(SynapseConstants_1.DATETIME_UTC_COOKIE_KEY) === 'true';
};
exports.getUseUtcTimeFromCookie = getUseUtcTimeFromCookie;
var getPrincipalAliasRequest = function (accessToken, alias, type) {
var url = '/repo/v1/principal/alias';
return (0, exports.doPost)(url, { alias: alias, type: type }, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT);
};
exports.getPrincipalAliasRequest = getPrincipalAliasRequest;
/*
During SSO login, the authorization provider (Google) will
send the user back to the portal with an authorization code,
which can be exchanged for a Synapse user session.
This function should be called whenever the root App is initialized
(to look for this code parameter and complete the round-trip).
*/
var detectSSOCode = function () {
var redirectURL = (0, exports.getRootURL)();
// 'code' handling (from SSO) should be preformed on the root page, and then redirect to original route.
var fullUrl = new URL(window.location.href);
// in test environment the searchParams isn't defined
var searchParams = fullUrl.searchParams;
if (!searchParams) {
return;
}
var code = searchParams.get('code');
var provider = searchParams.get('provider');
if (code && provider) {
(0, exports.oAuthSessionRequest)(provider, code, redirectURL + "?provider=" + provider, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT)
.then(function (synToken) {
(0, exports.setAccessTokenCookie)(synToken.accessToken, function () {
// go back to original route after successful SSO login
var originalUrl = localStorage.getItem('after-sso-login-url');
localStorage.removeItem('after-sso-login-url');
if (originalUrl) {
window.location.replace(originalUrl);
}
});
})
.catch(function (err) {
if (err.status === 404) {
// Synapse account not found, send to registration page
window.location.replace(getEndpoint_1.PRODUCTION_ENDPOINT_CONFIG.PORTAL + "#!RegisterAccount:0");
}
console.error('Error on sso sign in ', err);
});
}
};
exports.detectSSOCode = detectSSOCode;
var signOut = function (sessionCallback) { return (0, tslib_1.__awaiter)(void 0, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, (0, exports.setAccessTokenCookie)(undefined, sessionCallback)];
case 1:
_a.sent();
return [2 /*return*/];
}
});
}); };
exports.signOut = signOut;
/**
* Upload file. Note that this currently only supports Synapse storage (Sage s3 bucket)
* @param accessToken
* @param file
* @param endpoint
*/
var uploadFile = function (accessToken, filename, file) {
return new Promise(function (fileUploadResolve, fileUploadReject) {
var partSize = Math.max(5242880, file.size / 10000);
var request = {
contentType: file.type,
fileName: filename,
fileSizeBytes: file.size,
partSizeBytes: partSize,
storageLocationId: exports.SYNAPSE_STORAGE_LOCATION_ID,
};
calculateMd5(file).then(function (md5) {
request.contentMD5Hex = md5;
(0, exports.startMultipartUpload)(accessToken, filename, file, request, fileUploadResolve, fileUploadReject);
});
});
};
exports.uploadFile = uploadFile;
var calculateMd5 = function (fileBlob) {
// code taken from md5 example from library
return new Promise(function (resolve, reject) {
var blobSlice = File.prototype.slice, file = fileBlob, chunkSize = 2097152, // Read in chunks of 2MB
chunks = Math.ceil(file.size / chunkSize), spark = new spark_md5_1.default.ArrayBuffer(), fileReader = new FileReader();
var currentChunk = 0;
fileReader.onload = function (e) {
console.log('read chunk nr', currentChunk + 1, 'of', chunks);
spark.append(fileReader.result); // Append array buffer
currentChunk++;
if (currentChunk < chunks) {
loadNext();
}
else {
console.log('finished loading');
var md5 = spark.end();
console.info('computed hash', md5); // Compute hash
resolve(md5);
}
};
fileReader.onerror = function () {
console.warn('oops, something went wrong.');
reject(fileReader.error);
};
var loadNext = function () {
var start = currentChunk * chunkSize, end = start + chunkSize >= file.size ? file.size : start + chunkSize;
fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
};
loadNext();
});
};
var processFilePart = function (partNumber, multipartUploadStatus, accessToken, fileName, file, request, fileUploadResolve, fileUploadReject) {
if (multipartUploadStatus.clientSidePartsState[partNumber - 1]) {
// no-op. this part has already been processed!
return;
}
var uploadId = multipartUploadStatus.uploadId;
var presignedUploadUrlRequest = {
uploadId: uploadId,
contentType: 'application/octet-stream',
partNumbers: [partNumber],
};
var presignedUrlUrl = "/file/v1/file/multipart/" + uploadId + "/presigned/url/batch";
(0, exports.doPost)(presignedUrlUrl, presignedUploadUrlRequest, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT).then(function (presignedUrlResponse) { return (0, tslib_1.__awaiter)(void 0, void 0, void 0, function () {
var presignedUrl, startByte, endByte, fileSlice;
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
presignedUrl = presignedUrlResponse.partPresignedUrls[0].uploadPresignedUrl;
startByte = (partNumber - 1) * request.partSizeBytes;
endByte = partNumber * request.partSizeBytes - 1;
if (endByte >= request.fileSizeBytes) {
endByte = request.fileSizeBytes - 1;
}
fileSlice = file.slice(startByte, endByte + 1, presignedUploadUrlRequest.contentType);
return [4 /*yield*/, uploadFilePart(presignedUrl, fileSlice, presignedUploadUrlRequest.contentType)
// uploaded the part. calculate md5 of the part and add the part to the upload
];
case 1:
_a.sent();
// uploaded the part. calculate md5 of the part and add the part to the upload
calculateMd5(fileSlice).then(function (md5) {
var addPartUrl = "/file/v1/file/multipart/" + uploadId + "/add/" + partNumber + "?partMD5Hex=" + md5;
(0, exports.doPut)(addPartUrl, undefined, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT).then(function (addPartResponse) {
if (addPartResponse.addPartState === 'ADD_SUCCESS') {
// done with this part!
multipartUploadStatus.clientSidePartsState[partNumber - 1] = true;
(0, exports.checkUploadComplete)(multipartUploadStatus, fileName, accessToken, fileUploadResolve, fileUploadReject);
}
else {
// retry after a brief delay
delay(1000).then(function () {
processFilePart(partNumber, multipartUploadStatus, accessToken, fileName, file, request, fileUploadResolve, fileUploadReject);
});
}
});
});
return [2 /*return*/];
}
});
}); });
};
var checkUploadComplete = function (status, fileHandleName, accessToken, fileUploadResolve, fileUploadReject) {
// if all client-side parts are true (uploaded), then complete the upload and get the file handle!
if (status.clientSidePartsState.every(function (v) {
return v;
})) {
var url = "/file/v1/file/multipart/" + status.uploadId + "/complete";
(0, exports.doPut)(url, undefined, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT)
.then(function (newStatus) {
// success!
fileUploadResolve({
fileHandleId: newStatus.resultFileHandleId,
fileName: fileHandleName,
});
})
.catch(function (error) {
fileUploadReject(error);
});
}
};
exports.checkUploadComplete = checkUploadComplete;
var uploadFilePart = function (presignedUrl, file, contentType) { return (0, tslib_1.__awaiter)(void 0, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
// TODO: could try using axios to get upload progress, then update the client-side part state (change to numbers from 0-1)
// This would give progress for the single file (across all parts).
// The parent would still need to figure out progress (for the total file set).
return [4 /*yield*/, fetch(presignedUrl, {
method: 'PUT',
headers: {
'Content-Type': contentType,
},
body: file,
})];
case 1:
// TODO: could try using axios to get upload progress, then update the client-side part state (change to numbers from 0-1)
// This would give progress for the single file (across all parts).
// The parent would still need to figure out progress (for the total file set).
_a.sent();
return [2 /*return*/];
}
});
}); };
var startMultipartUpload = function (accessToken, fileName, file, request, fileUploadResolve, fileUploadReject) {
var url = '/file/v1/file/multipart';
(0, exports.doPost)(url, request, accessToken, undefined, getEndpoint_1.BackendDestinationEnum.REPO_ENDPOINT)
.then(function (status) { return (0, tslib_1.__awaiter)(void 0, void 0, void 0, function () {
var clientSidePartsState, i;
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
clientSidePartsState = status.partsState
.split('')
.map(function (bit) { return bit === '1'; });
status.clientSidePartsState = clientSidePartsState;
i = 0;
_a.label = 1;
case 1:
if (!(i < clientSidePartsState.length)) return [3 /*break*/, 4];
if (!!clientSidePartsState[i]) return [3 /*break*/, 3];
// upload this part. note that partNumber is always the index+1
return [4 /*yield*/, pro