@jbrowse/core
Version:
JBrowse 2 core libraries used by plugins
103 lines (102 loc) • 4.06 kB
JavaScript
import isNode from 'detect-node';
import { BlobFile, LocalFile } from 'generic-filehandle2';
import { RemoteFileWithRangeCache } from "./RemoteFileWithRangeCache.js";
import { isElectron } from "../index.js";
import { getBlob, getFileFromCache } from "../tracks.js";
import { AuthNeededError, isRootModelWithInternetAccounts, isUriLocation, } from "../types/index.js";
function isLocalPathLocation(location) {
return 'localPath' in location;
}
function isBlobLocation(location) {
return 'blobId' in location;
}
function isFileHandleLocationLocal(location) {
return 'handleId' in location;
}
export function resolveUriLocation(location) {
return location.baseUri
? { ...location, uri: new URL(location.uri, location.baseUri).href }
: location;
}
export function openLocation(location, pluginManager) {
if (isLocalPathLocation(location)) {
if (!location.localPath) {
throw new Error('No local path provided');
}
if (isNode || isElectron) {
return new LocalFile(location.localPath);
}
else {
throw new Error("can't use local files in the browser");
}
}
if (isBlobLocation(location)) {
const blob = getBlob(location.blobId);
if (!blob) {
throw new Error(`file ("${location.name}") was opened locally from a previous session. To restore it, go to track settings and reopen the file`);
}
return new BlobFile(blob);
}
if (isFileHandleLocationLocal(location)) {
const file = getFileFromCache(location.handleId);
if (!file) {
throw new Error(`file ("${location.name}") requires permission. Please reopen the file from track settings`);
}
return new BlobFile(file);
}
if (isUriLocation(location)) {
if (!location.uri) {
throw new Error('No URI provided');
}
const absoluteLocation = resolveUriLocation(location);
if (pluginManager) {
const internetAccount = getInternetAccount(location, pluginManager);
if (internetAccount) {
return internetAccount.openLocation(absoluteLocation);
}
}
return new RemoteFileWithRangeCache(absoluteLocation.uri, {
fetch: checkAuthNeededFetch,
});
}
throw new Error('invalid fileLocation');
}
export function getFetcher(location, pluginManager) {
if (!isUriLocation(location)) {
throw new Error(`Not a valid UriLocation: ${JSON.stringify(location)}`);
}
if (pluginManager) {
const internetAccount = getInternetAccount(location, pluginManager);
if (internetAccount) {
return internetAccount.getFetcher(location);
}
}
return checkAuthNeededFetch;
}
function getInternetAccount(location, pluginManager) {
const { rootModel } = pluginManager;
if (rootModel && isRootModelWithInternetAccounts(rootModel)) {
return rootModel.findAppropriateInternetAccount(location);
}
if (location.internetAccountPreAuthorization) {
if (!location.internetAccountPreAuthorization.authInfo.token) {
throw new Error('Failed to obtain token from internet account. Try reloading the page');
}
return pluginManager
.getInternetAccountType(location.internetAccountPreAuthorization.internetAccountType)
.stateModel.create({
type: location.internetAccountPreAuthorization.internetAccountType,
configuration: location.internetAccountPreAuthorization.authInfo.configuration,
});
}
return undefined;
}
async function checkAuthNeededFetch(url, opts) {
const response = await fetch(url, opts);
if (response.status === 401 &&
response.headers.get('WWW-Authenticate')?.includes('Basic')) {
throw new AuthNeededError('Accessing HTTPBasic resource without authentication', url.toString());
}
return response;
}
export { RemoteFileWithRangeCache } from "./RemoteFileWithRangeCache.js";