live-plugin-manager
Version:
Install and uninstall any node package at runtime from npm registry
104 lines (80 loc) • 2.62 kB
text/typescript
import * as path from "path";
import * as fs from "./fileSystem";
import {Headers, headersBasicAuth, httpJsonGet} from "./httpUtils";
import Debug from "debug";
import { downloadTarball, extractTarball } from "./tarballUtils";
import { PackageJsonInfo } from "./PackageInfo";
const debug = Debug("live-plugin-manager.BitbucketRegistryClient");
export class BitbucketRegistryClient {
private headers: Headers;
constructor(auth?: BitbucketAuth) {
if (auth) {
debug(`Authenticating Bitbucket api with ${auth.type}...`);
switch (auth.type) {
case "basic":
this.headers = {
...headersBasicAuth(auth.username, auth.password),
"user-agent": "live-plugin-manager"
};
break;
default:
throw new Error("Auth type not supported");
}
} else {
this.headers = {};
}
}
async get(repository: string): Promise<PackageJsonInfo> {
const repoInfo = extractRepositoryInfo(repository);
debug("Repository info: ", repoInfo);
const urlPkg
= `https://api.bitbucket.org/2.0/repositories/${repoInfo.owner}/${repoInfo.repo}/src/${repoInfo.ref}/package.json`;
const pkgContent = await httpJsonGet<PackageJsonInfo>(
urlPkg,
{...this.headers, accept: "application/json"});
if (!pkgContent || !pkgContent.name || !pkgContent.version) {
throw new Error("Invalid plugin Bitbucket repository " + repository);
}
const urlArchiveLink
= `https://bitbucket.org/${repoInfo.owner}/${repoInfo.repo}/get/${repoInfo.ref}.tar.gz`;
pkgContent.dist = { tarball: urlArchiveLink };
return pkgContent;
}
async download(
destinationDirectory: string,
packageInfo: PackageJsonInfo): Promise<string> {
if (!packageInfo.dist || !packageInfo.dist.tarball) {
throw new Error("Invalid dist.tarball property");
}
const tgzFile = await downloadTarball(packageInfo.dist.tarball, this.headers);
const pluginDirectory = path.join(destinationDirectory, packageInfo.name);
try {
await extractTarball(tgzFile, pluginDirectory);
} finally {
await fs.remove(tgzFile);
}
return pluginDirectory;
}
isBitbucketRepo(version: string): boolean {
return version.indexOf("/") > 0;
}
}
function extractRepositoryInfo(repository: string) {
const parts = repository.split("/");
if (parts.length !== 2) {
throw new Error("Invalid repository name");
}
const repoParts = parts[1].split("#");
const repoInfo = {
owner: parts[0],
repo: repoParts[0],
ref: repoParts[1] || "master"
};
return repoInfo;
}
export interface BitbucketAuthBasic {
type: "basic";
username: string;
password: string;
}
export type BitbucketAuth = BitbucketAuthBasic