Skip to content

Commit

Permalink
feat: rewrite with more modularity
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrekwitkowski committed Apr 25, 2022
1 parent b7ec465 commit 0e80387
Show file tree
Hide file tree
Showing 13 changed files with 260 additions and 133 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"/dist/*"
],
"scripts": {
"build": "rm -f dist/* && tsc",
"build": "rm -rf dist/* && tsc",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
Expand Down
67 changes: 14 additions & 53 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,57 +1,18 @@
import axios, { AxiosRequestConfig } from 'axios';
import {
AddPeopleToAThreadRequest,
AddPeopleToAThreadResponse,
CopyADocumentOrTemplateV2Request,
CopyADocumentOrTemplateV2Response,
GetMembersV2Response,
GetThreadHtmlV2Response,
GetUserByIdResponse,
GetUserResponse,
} from './types';
import axios from 'axios';

export class Client {
private axiosConfig: AxiosRequestConfig;
private urlBase: string;
import { getThreadsMethods, EditADocumentLocation } from "./threads";
import { getUsersMethods } from "./users";

constructor(accessToken: string, urlBase?: string) {
this.axiosConfig = { headers: { Authorization: 'Bearer ' + accessToken } };
this.urlBase = urlBase || 'https://platform.quip.com/';
}
export const getQuipClient = (accessToken: string, urlBase = 'https://platform.quip.com/') => {
const axiosConfig = { headers: { Authorization: 'Bearer ' + accessToken } };
const get = <T>(path: string) => axios.get<T>(urlBase + path, axiosConfig).then(response => response.data);
const post = <T>(path: string, data: any) => axios.post<T>(urlBase + path, data, axiosConfig).then(response => response.data);

private get<T>(path: string) {
return axios.get<T>(this.urlBase + path, this.axiosConfig)
.then(response => response.data);
}
return ({
threads: getThreadsMethods(get, post),
users: getUsersMethods(get),
});
};

private post<T, D>(path: string, data: D) {
return axios.post<T>(this.urlBase + path, data, this.axiosConfig)
.then(response => response.data);
}

addPeopleToAThread(threadId: string, memberIds: string[]) {
const data = { 'thread_id': threadId, 'member_ids': memberIds.join(',') };
return this.post<AddPeopleToAThreadResponse, AddPeopleToAThreadRequest>(`1/threads/add-members`, data);
}

copyADocumentOrTemplateV2(threadIdOrSecretPath: string, body: CopyADocumentOrTemplateV2Request) {
return this.post<CopyADocumentOrTemplateV2Response, CopyADocumentOrTemplateV2Request>(`2/threads/${threadIdOrSecretPath}/copy`, body)
.then(response => response.thread);
}

getThreadMembersV2(threadIdOrSecretPath: string) {
return this.get<GetMembersV2Response>(`2/threads/${threadIdOrSecretPath}/members`);
}

getThreadHtmlV2(id: string) {
return this.get<GetThreadHtmlV2Response>(`2/threads/${id}/html`);
}

getUserByEmail(email: string) {
return this.get<GetUserResponse>(`1/users/${email}`);
}

getUserById(id: string) {
return this.get<GetUserByIdResponse>(`1/users/${id}`);
}
}
// re-export enums
export { EditADocumentLocation };
26 changes: 26 additions & 0 deletions src/threads/addMembersToThreadOrAddThreadToFolders.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Post } from "../types";
import { Thread } from ".";

export interface AddPeopleToAThreadRequestProps {
body: {
thread_id: string;
member_ids: string;
}
}

export interface AddPeopleToAThreadResponse {
thread: Thread;
user_ids: string[];
shared_folder_ids: string[];
expanded_user_ids: string[];
invited_user_emails: string[];
access_levels: Record<string, { access_level: string }>;
html: string;
}

// https://quip.com/dev/automation/documentation/current#operation/addMembersToThreadOrAddThreadToFolders
export const addMembersToThreadOrAddThreadToFolders = (post: Post) => (props: AddPeopleToAThreadRequestProps) => {
// REQUEST BODY SCHEMA: application/x-www-form-urlencoded
const { body } = props;
return post<AddPeopleToAThreadResponse>(`1/threads/add-members`, new URLSearchParams(body));
}
33 changes: 33 additions & 0 deletions src/threads/copyADocumentOrTemplateV2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Post } from "../types";

export interface CopyADocumentOrTemplateV2RequestProps {
threadIdOrSecretPath: string;
body?: {
title?: string;
folder_id?: string;
mail_merge_values?: object;
copy_annotations?: boolean;
}
}

export interface CopyADocumentOrTemplateV2Response {
thread: {
author_id: string;
created_usec: number;
id: string;
is_template: boolean;
link: string;
owning_company_id: string;
secret_path: string;
title: string;
type: string;
updated_usec: number;
}
}

// https://quip.com/dev/automation/documentation/current#operation/copyDocumentV2
export const copyADocumentOrTemplateV2 = (post: Post) => (props: CopyADocumentOrTemplateV2RequestProps) => {
// REQUEST BODY SCHEMA: application/json
const { threadIdOrSecretPath, body } = props;
return post<CopyADocumentOrTemplateV2Response>(`2/threads/${threadIdOrSecretPath}/copy`, body)
}
19 changes: 19 additions & 0 deletions src/threads/createADocumentOrSpreadsheet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Post } from "../types";

export interface createADocumentOrSpreadsheetRequestProps {
body: {
content: string;
format?: 'html' | 'markdown';
title?: string;
member_ids?: string;
type?: 'document' | 'spreadsheet' | 'slides';
}
}

// https://quip.com/dev/automation/documentation/current#operation/createDocument
export const createADocumentOrSpreadsheet = (post: Post) => (props: createADocumentOrSpreadsheetRequestProps) => {
// REQUEST BODY SCHEMA: application/x-www-form-urlencoded
const { body } = props;

return post(`1/threads/new-document`, new URLSearchParams(body));
}
45 changes: 45 additions & 0 deletions src/threads/editADocument.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Post } from "../types";
import { Thread } from ".";

export const enum EditADocumentLocation {
APPEND = '0',
PREPEND = '1',
AFTER_SECTION = '2',
BEFORE_SECTION = '3',
REPLACE_SECTION = '4',
DELETE_SECTION = '5',
AFTER_DOCUMENT_RANGE = '6',
BEFORE_DOCUMENT_RANGE = '7',
REPLACE_DOCUMENT_RANGE = '8',
DELETE_DOCUMENT_RANGE = '9',
}

export interface EditADocumentRequestProps {
body: {
thread_id: string;
format?: 'html' | 'markdown';
content?: string;
section_id?: string;
documentRange?: string;
location?: EditADocumentLocation;
}
}

export interface EditADocumentResponse {
thread: Thread;
user_ids: string[];
shared_folder_ids: string[];
expanded_user_ids: string[];
invited_user_emails: string[];
markdown?: string;
access_levels?: Record<string, { access_level: string }>;
html?: string;
section_ids?: string[];
}

// https://quip.com/dev/automation/documentation/current#operation/editDocument
export const editADocument = (post: Post) => (props: EditADocumentRequestProps) => {
// REQUEST BODY SCHEMA: application/x-www-form-urlencoded
const { body } = props;
return post<EditADocumentResponse>(`1/threads/edit-document`, new URLSearchParams(body));
}
19 changes: 19 additions & 0 deletions src/threads/getThreadHtmlV2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

import { Get, ResponseMetadata } from "../types";


export interface GetThreadHtmlV2RequestProps {
id: string;
}

export interface GetThreadHtmlV2Response {
html: string;
response_metadata: ResponseMetadata;
}

// https://quip.com/dev/automation/documentation/current#operation/getThreadHtmlV2
export const getThreadHtmlV2 = (get: Get) => (props: GetThreadHtmlV2RequestProps) => {
const { id } = props;

return get<GetThreadHtmlV2Response>(`2/threads/${id}/html`);
}
21 changes: 21 additions & 0 deletions src/threads/getThreadMembersV2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

import { Get, MembersEntity, ResponseMetadata } from "../types";

export interface GetThreadMembersV2RequestProps {
threadIdOrSecretPath: string;
// TODO: implement query parameters
// cursor?: string;
// limit: number
}

export interface GetThreadMembersV2Response {
members: MembersEntity[];
response_metadata: ResponseMetadata;
}

// https://quip.com/dev/automation/documentation/current#operation/getThreadMembersV2
export const getThreadMembersV2 = (get: Get) => (props: GetThreadMembersV2RequestProps) => {
const { threadIdOrSecretPath } = props;
// TODO: implement query parameters
return get<GetThreadMembersV2Response>(`2/threads/${threadIdOrSecretPath}/members`);
}
37 changes: 37 additions & 0 deletions src/threads/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Get, Post } from "../types";

import { addMembersToThreadOrAddThreadToFolders } from "./addMembersToThreadOrAddThreadToFolders";
import { copyADocumentOrTemplateV2 } from "./copyADocumentOrTemplateV2";
import { createADocumentOrSpreadsheet } from "./createADocumentOrSpreadsheet";
import { editADocument, EditADocumentLocation } from "./editADocument";
import { getThreadHtmlV2 } from "./getThreadHtmlV2";
import { getThreadMembersV2 } from "./getThreadMembersV2";

export const getThreadsMethods = (get: Get, post: Post) => ({
addMembersToThreadOrAddThreadToFolders: addMembersToThreadOrAddThreadToFolders(post),
copyADocumentOrTemplateV2: copyADocumentOrTemplateV2(post),
createADocumentOrSpreadsheet: createADocumentOrSpreadsheet(post),
editADocument: editADocument(post),
getThreadHtmlV2: getThreadHtmlV2(get),
getThreadMembersV2: getThreadMembersV2(get),
});

export interface Thread {
id: string;
created_usec: number;
updated_usec: number;
thread_class: string;
owning_company_id: string;
author_id?: string;
title?: string;
is_deleted?: boolean;
is_template?: boolean;
document_id?: string;
link: string;
type: "document" | "spreadsheet" | "slides" | "chat";
snippet_user_id: string;
snippet_message: string;
sharing: object;
};

export { EditADocumentLocation }
82 changes: 4 additions & 78 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,85 +1,11 @@
export interface CopyADocumentOrTemplateV2Request {
title?: string;
folder_id?: string;
mail_merge_values?: Record<string, string>;
copy_annotations?: boolean;
}

export interface CopyADocumentOrTemplateV2Response {
thread: CopiedThread;
}

export interface CopiedThread extends Thread {
secret_path: string;
}

interface Thread {
author_id: string;
created_usec: number;
id: string;
is_template: boolean;
link: string;
owning_company_id: string;
title: string;
type: string;
updated_usec: number;
}
export type Get = <T>(path: string) => Promise<T>;
export type Post = <T>(path: string, data: any) => Promise<T>;

export interface GetThreadHtmlV2Response {
html: string;
response_metadata: ResponseMetadata;
}

export interface GetMembersV2Response {
members: MembersEntity[];
response_metadata: ResponseMetadata;
export interface ResponseMetadata {
next_cursor: string;
}

export interface MembersEntity {
user_id: string;
access_level: string;
}

export interface ResponseMetadata {
next_cursor: string;
}

export type GetUserResponse = {
id: string;
name: string;
is_robot: boolean;
affinity: number;
profile_picture_url?: string;
}

export interface GetUserByIdResponse extends GetUserResponse {
emails: Emails[];
}

export interface Emails {
address: string;
added_usec: number;
verified_company_id: string;
send_notifications?: boolean | null;
}

export interface AddPeopleToAThreadRequest {
thread_id: string;
member_ids: string;
}

export interface AddPeopleToAThreadResponse {
thread: SharedThread;
user_ids: string[];
shared_folder_ids: string[];
expanded_user_ids: string[];
invited_user_emails: string[];
access_levels: Record<string, { access_level: string }>;
html: string;
}

export interface SharedThread extends Thread {
thread_class: string;
document_id: string;
is_deleted: boolean;
}
Loading

0 comments on commit 0e80387

Please sign in to comment.