Skip to content

Commit

Permalink
Start using TypeScript
Browse files Browse the repository at this point in the history
  • Loading branch information
dittos committed Feb 5, 2019
1 parent 8213c8b commit 22aa252
Show file tree
Hide file tree
Showing 18 changed files with 391 additions and 140 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
root = true

[*.{js,css}]
[*.{js,css,ts,tsx}]
indent_style = space
indent_size = 2
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
"private": true,
"dependencies": {
"@blueprintjs/core": "^1.35.7",
"@types/jest": "^24.0.0",
"@types/node": "^10.12.21",
"@types/react": "^16.8.1",
"@types/react-dom": "^16.0.11",
"diff2html": "^2.3.3",
"firebase": "^4.11.0",
"fuzzaldrin-plus": "^0.6.0",
Expand All @@ -19,7 +23,8 @@
"react-router-dom": "^4.2.2",
"redux": "^3.7.2",
"redux-observable": "^0.18.0",
"rxjs": "^5.5.7"
"rxjs": "^5.5.7",
"typescript": "3.3.1"
},
"devDependencies": {
"react-scripts": "2.1.3",
Expand Down
2 changes: 1 addition & 1 deletion src/config.js.sample
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
export default {
// Public URL of your installation
url: 'https://diff.sapzil.org/',

Expand Down
26 changes: 0 additions & 26 deletions src/lib/Database.js

This file was deleted.

33 changes: 33 additions & 0 deletions src/lib/Database.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import * as firebase from 'firebase';
import { Observable } from 'rxjs/Observable';

function getFirebaseUid(): string | null {
const user = firebase.auth().currentUser;
return user && user.uid;
}

function refValues<T>(ref: firebase.database.Reference): Observable<T> {
return Observable.create((obs: any) => {
const callback = (snapshot: firebase.database.DataSnapshot | null, err: string | null | undefined) => {
if (err) {
obs.error(err);
return;
}
obs.next(snapshot!.val());
};
ref.on('value', callback);
return () => ref.off('value', callback);
});
}

function reviewStatesRef(pullRequestId: number): firebase.database.Reference {
return firebase.database().ref(`reviewStates/${pullRequestId}/${getFirebaseUid()}`);
}

export function observeReviewStates(pullRequestId: number): Observable<{[fileId: string]: boolean}> {
return refValues(reviewStatesRef(pullRequestId));
}

export function setReviewState(pullRequestId: number, fileId: string, reviewState: boolean): Promise<any> {
return reviewStatesRef(pullRequestId).child(fileId).set(reviewState);
}
107 changes: 84 additions & 23 deletions src/lib/Github.js → src/lib/Github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'rxjs/add/operator/map';
import 'rxjs/add/operator/exhaustMap';
import LinkHeader from 'http-link-header';
import { getAccessToken } from './GithubAuth';
import { AjaxRequest, AjaxResponse } from 'rxjs/observable/dom/AjaxObservable';

const BASE_URL = 'https://api.github.com';

Expand All @@ -17,14 +18,18 @@ export const PullRequestReviewState = {
DISMISSED: 'DISMISSED',
};

export type PullRequestReviewStateType = keyof (typeof PullRequestReviewState);

export const PullRequestReviewEvent = {
PENDING: null,
COMMENT: 'COMMENT',
APPROVE: 'APPROVE',
REQUEST_CHANGES: 'REQUEST_CHANGES',
COMMENT: 'COMMENT' as PullRequestReviewEventInput,
APPROVE: 'APPROVE' as PullRequestReviewEventInput,
REQUEST_CHANGES: 'REQUEST_CHANGES' as PullRequestReviewEventInput,
DISMISS: 'DISMISS',
};

export type PullRequestReviewEventInput = null | 'COMMENT' | 'APPROVE' | 'REQUEST_CHANGES';

export const pullRequestReviewFragment = `
id
state
Expand All @@ -45,26 +50,76 @@ export const pullRequestReviewCommentRestLikeFragment = `
position
`;

function ajax(request) {
export interface PullRequestDTO {
id: number;
node_id: string;
url: string;
base: {
sha: string;
repo: {
url: string;
};
};
head: {
sha: string;
repo: {
url: string;
};
};
body: string;
}

export interface PullRequestCommentDTO {
id: number;
node_id: string;
user: {
html_url: string;
login: string;
};
body: string;
path: string;
position: number;
}

export interface PullRequestReviewCommentsConnection {
nodes: PullRequestCommentDTO[];
pageInfo: {
hasPreviousPage: boolean;
startCursor: string;
};
}

export interface PullRequestReviewDTO {
id: string;
state: PullRequestReviewStateType;
comments?: PullRequestReviewCommentsConnection;
}

function ajax(request: AjaxRequest): Observable<AjaxResponse> {
if (!request.responseType)
request.responseType = 'json';
if (!request.headers)
request.headers = {};
const headers: any = request.headers;
// https://developer.github.com/v3/#graphql-global-relay-ids
if (!request.headers['Accept'])
request.headers['Accept'] = 'application/vnd.github.jean-grey-preview+json';
if (!headers['Accept'])
headers['Accept'] = 'application/vnd.github.jean-grey-preview+json';

const token = getAccessToken();
if (token)
request.headers['Authorization'] = `token ${token}`;
headers['Authorization'] = `token ${token}`;
return Observable.ajax(request);
}

export function graphql(query, variables) {
export interface GraphQLError {
type: 'NOT_FOUND';
}

export function graphql(query: string, variables: {[key: string]: any}): Observable<any> {
const request = {
url: `${BASE_URL}/graphql`,
method: 'post',
headers: {
headers: <any>{
'Content-Type': 'application/json',
},
responseType: 'json',
Expand All @@ -80,18 +135,18 @@ export function graphql(query, variables) {
Observable.of(resp.response.data));
}

function pullRequestUrl(owner, repo, number) {
function pullRequestUrl(owner: string, repo: string, number: number): string {
return `${BASE_URL}/repos/${owner}/${repo}/pulls/${number}`;
}

export function getPullRequest(owner, repo, number) {
export function getPullRequest(owner: string, repo: string, number: number): Observable<PullRequestDTO> {
return ajax({
url: pullRequestUrl(owner, repo, number),
method: 'get',
}).map(resp => resp.response);
}

function paginated(obs) {
function paginated<T>(obs: Observable<AjaxResponse>): Observable<T[]> {
return obs.exhaustMap(resp => {
const link = LinkHeader.parse(resp.xhr.getResponseHeader('Link') || '');
const next = link.rel('next');
Expand All @@ -103,7 +158,7 @@ function paginated(obs) {
});
}

export function getPullRequestAsDiff(owner, repo, number) {
export function getPullRequestAsDiff(owner: string, repo: string, number: number): Observable<string> {
return ajax({
// Append query string to prevent interfering caches
url: `${pullRequestUrl(owner, repo, number)}?.diff`,
Expand All @@ -115,14 +170,14 @@ export function getPullRequestAsDiff(owner, repo, number) {
}).map(resp => resp.response);
}

export function getPullRequestComments(pullRequest) {
export function getPullRequestComments(pullRequest: PullRequestDTO): Observable<PullRequestCommentDTO[]> {
return paginated(ajax({
url: `${pullRequest.url}/comments`,
method: 'get',
}));
}

export function getPullRequestFromGraphQL(owner, repo, number, author, fragment) {
export function getPullRequestFromGraphQL(owner: string, repo: string, number: number, author: string, fragment: string): Observable<PullRequestDTO> {
return graphql(`
query($owner: String!, $repo: String!, $number: Int!, $author: String!) {
repository(owner: $owner, name: $repo) {
Expand All @@ -135,14 +190,14 @@ export function getPullRequestFromGraphQL(owner, repo, number, author, fragment)
.map(resp => resp.repository.pullRequest);
}

export function getAuthenticatedUser() {
export function getAuthenticatedUser(): Observable<any> {
return ajax({
url: `${BASE_URL}/user`,
method: 'get',
}).map(resp => resp.response);
}

export function getPullRequestReviewComments(pullRequest, reviewId, startCursor) {
export function getPullRequestReviewComments(pullRequest: PullRequestDTO, reviewId: string, startCursor: string): Observable<PullRequestCommentDTO[]> {
return graphql(`
query($reviewId: ID!, $startCursor: String) {
node(id: $reviewId) {
Expand Down Expand Up @@ -170,7 +225,13 @@ export function getPullRequestReviewComments(pullRequest, reviewId, startCursor)
});
}

export function addPullRequestReview(pullRequestId, commitId, event, comments = []) {
export interface AddPullRequestReviewInputComment {
body: string;
position: number;
path: string;
}

export function addPullRequestReview(pullRequestId: string, commitId: string, event: PullRequestReviewEventInput, comments: AddPullRequestReviewInputComment[] = []): Observable<PullRequestReviewDTO> {
return graphql(`
mutation($input: AddPullRequestReviewInput!, $commentCount: Int) {
addPullRequestReview(input: $input) {
Expand All @@ -195,7 +256,7 @@ export function addPullRequestReview(pullRequestId, commitId, event, comments =
}).map(resp => resp.addPullRequestReview.pullRequestReview);
}

export function submitPullRequestReview(pullRequestReviewId, event) {
export function submitPullRequestReview(pullRequestReviewId: string, event: PullRequestReviewEventInput): Observable<PullRequestReviewDTO> {
return graphql(`
mutation($input: SubmitPullRequestReviewInput!) {
submitPullRequestReview(input: $input) {
Expand All @@ -212,7 +273,7 @@ export function submitPullRequestReview(pullRequestReviewId, event) {
}).map(resp => resp.submitPullRequestReview.pullRequestReview);
}

export function addPullRequestReviewCommentOnReview(reviewId, commitId, body, path, position) {
export function addPullRequestReviewCommentOnReview(reviewId: string, commitId: string, body: string, path: string, position: number): Observable<PullRequestCommentDTO> {
return graphql(`
mutation($input: AddPullRequestReviewCommentInput!) {
addPullRequestReviewComment(input: $input) {
Expand All @@ -232,14 +293,14 @@ export function addPullRequestReviewCommentOnReview(reviewId, commitId, body, pa
}).map(resp => resp.addPullRequestReviewComment.comment);
}

export function deletePullRequestReviewComment(pullRequest, commentId) {
export function deletePullRequestReviewComment(pullRequest: PullRequestDTO, commentId: number): Observable<any> {
return ajax({
url: `${pullRequest.base.repo.url}/pulls/comments/${commentId}`,
method: 'DELETE',
});
}

export function editPullRequestReviewComment(pullRequest, commentId, { body }) {
export function editPullRequestReviewComment(pullRequest: PullRequestDTO, commentId: number, { body }: { body: string }): Observable<PullRequestCommentDTO> {
return ajax({
url: `${pullRequest.base.repo.url}/pulls/comments/${commentId}`,
method: 'PATCH',
Expand All @@ -250,7 +311,7 @@ export function editPullRequestReviewComment(pullRequest, commentId, { body }) {
}).map(resp => resp.response);
}

export function editPullRequestReviewCommentViaGraphQL(commentNodeId, { body }) {
export function editPullRequestReviewCommentViaGraphQL(commentNodeId: string, { body }: { body: string }): Observable<PullRequestCommentDTO> {
return graphql(`
mutation($input: UpdatePullRequestReviewCommentInput!) {
updatePullRequestReviewComment(input: $input) {
Expand Down
9 changes: 9 additions & 0 deletions src/react-app-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/// <reference types="react-scripts" />

declare module 'http-link-header' {
declare function parse(link: string);
}

declare module 'marked' {
export default function(markdown: string, options: any);
}
Loading

0 comments on commit 22aa252

Please sign in to comment.