Skip to content

Commit

Permalink
Write initial github backend
Browse files Browse the repository at this point in the history
  • Loading branch information
njgheorghita committed Dec 16, 2019
1 parent 9c54a70 commit a3a9f40
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 16 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"json-stable-stringify": "^1.0.1",
"module-alias": "^2.1.0",
"original-require": "^1.0.1",
"request-promise": "^4.2.4",
"source-map-support": "^0.5.9",
"web3": "^1.0.0-beta.36"
},
Expand Down
46 changes: 32 additions & 14 deletions src/storage/github/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,40 @@

import * as config from "ethpm/config";
import * as storage from "ethpm/storage";
import * as t from "io-ts";
import { Maybe } from "ethpm/types";
import { URL } from "url";
import { isValidGithubUri } from "./validation";

import request = require("request-promise");
export { isValidGithubUri } from "./validation";

async function makeGithubRequest(blobUri: URL): Promise<string> {
let response: any = {};
const options = {
uri: blobUri,
json: true,
headers: { "user-agent": "node.js" }
};

await request
.get(options)
.then(body => {
const decoded = new Buffer(body.content, "base64");
response = decoded.toString("ascii");
})
.catch(err => {
response = err.toString();
});
return response;
}

export class GithubService implements storage.Service {
async read(uri: URL): Promise<Maybe<string>> {

// validate uri
// fetch contents
// validate fetched contents
if (!isValidGithubUri(uri)) {
throw new TypeError(uri + "is not a valid content addressed Github uri.");
}
let base64Contents = await makeGithubRequest(uri);
return base64Contents;
}
}

export default class GithubConnector extends config.Connector<storage.Service> {
/**
* Construct GithubService and load with specified contents
*/
async init(): Promise<GithubService> {
const service = new GithubService();
return service;
}
}
14 changes: 14 additions & 0 deletions src/storage/github/test/integration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { GithubService } from "ethpm/storage/github";
import { URL } from "url";
import examples from "test/examples/manifests";

describe("Github service returns URI contents", () => {
it("with valid blob URI", async () => {
const ownedBlobUri = new URL(
"https://api.github.com/repos/ethpm/ethpm-spec/git/blobs/8f9dc767d4c8b31fec4a08d9c0858d4f37b83180"
);
const service = new GithubService();
const actualContents = await service.read(ownedBlobUri);
expect(actualContents).toBe(examples.owned);
});
});
36 changes: 36 additions & 0 deletions src/storage/github/test/validation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { isValidGithubUri } from "ethpm/storage/github";
import { URL } from "url";

const invalidUris = [
// http is not valid protocol
"http://api.github.com/repos/ethpm/ethpm-spec/git/blobs/123",
// www.github.com is not valid hostname
"https://www.github.com/repos/ethpm/ethpm-spec/git/blobs/123",
// path doesn't contain 'repos' & 'git' & 'blobs'
"https://api.github.com/ethpm/ethpm-spec/git/blobs/123",
"https://api.github.com/repos/ethpm/ethpm-spec/blobs/123",
"https://api.github.com/repos/ethpm/ethpm-spec/git/123"
];

const validUris = [
"https://api.github.com/repos/ethpm/ethpm-spec/git/blobs/123",
"https://api.github.com/repos/other/repository/git/blobs/123"
];

invalidUris.forEach(uri => {
describe("Github uri validator invalidates", () => {
it(uri, () => {
const result = isValidGithubUri(new URL(uri));
expect(result).toBe(false);
});
});
});

validUris.forEach(uri => {
describe("Github uri validator validates", () => {
it(uri, () => {
const result = isValidGithubUri(new URL(uri));
expect(result).toBe(true);
});
});
});
23 changes: 21 additions & 2 deletions src/storage/github/validation.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
/**
* @module "ethpm/storage/github"
* @module "ethpm/storage/github/validation"
*/

export default function isValidGithubUri(uri: URL): boolean {
import { URL } from "url";

/**
* Returns a bool indicating whether the given uri conforms to this scheme.
* https://api.github.com/repos/:owner/:repo/git/blobs/:file_sha
*/
export function isValidGithubUri(uri: URL): boolean {
if (uri.hostname != "api.github.com") {
return false;
}
if (uri.protocol != "https:") {
return false;
}
if (
!uri.pathname.includes("/repos/") ||
!uri.pathname.includes("/git/") ||
!uri.pathname.includes("/blobs/")
) {
return false;
}
return true;
}

0 comments on commit a3a9f40

Please sign in to comment.