Skip to content

Commit

Permalink
feat: add unwrapData request option
Browse files Browse the repository at this point in the history
  • Loading branch information
Yukaii committed Feb 14, 2023
1 parent 7b045e1 commit 7e8c915
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 44 deletions.
1 change: 1 addition & 0 deletions nodejs/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const customJestConfig: JestConfigWithTsJest = {
testEnvironment: "node",
transformIgnorePatterns: ["<rootDir>/node_modules/"],
extensionsToTreatAsEsm: [".ts"],
setupFiles: ["dotenv/config"],
}

export default customJestConfig
16 changes: 16 additions & 0 deletions nodejs/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions nodejs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"@types/node": "^13.11.1",
"@typescript-eslint/eslint-plugin": "^5.52.0",
"@typescript-eslint/parser": "^5.52.0",
"dotenv": "^16.0.3",
"eslint": "^8.9.0",
"jest": "^29.4.2",
"json-server": "^0.17.1",
Expand Down
120 changes: 83 additions & 37 deletions nodejs/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import axios, { AxiosInstance, AxiosRequestConfig, AxiosError, AxiosResponse } from 'axios'
import { User, Note, Team, CreateNoteOptions, GetMe, GetUserHistory, GetUserNotes, GetUserNote, CreateUserNote, GetUserTeams, GetTeamNotes, CreateTeamNote, DeleteUserNote, DeleteTeamNote, UpdateUserNote, SingleNote, UpdateTeamNote } from './type'
import { User, Note, Team, CreateNoteOptions, GetMe, GetUserHistory, GetUserNotes, GetUserNote, CreateUserNote, GetUserTeams, GetTeamNotes, CreateTeamNote, SingleNote } from './type'
import * as HackMDErrors from './error'

export default class API {
export type RequestOptions = {
unwrapData?: boolean
}

const defaultOption: RequestOptions = {
unwrapData: true,
}

export class API {
private axios: AxiosInstance

constructor (readonly accessToken: string, public hackmdAPIEndpointURL: string = "https://api.hackmd.io/v1") {
Expand Down Expand Up @@ -53,67 +61,105 @@ export default class API {
)
}

async getMe (): Promise<GetMe> {
const { data } = await this.axios.get<User>("me")
return data
async getMe (option = defaultOption) {
if (option.unwrapData) {
return this.axios.get<User>("me").then(response => response.data) as Promise<GetMe>
} else {
return this.axios.get<GetMe>("me")
}
}

async getHistory (): Promise<GetUserHistory> {
const { data } = await this.axios.get<Note[]>("history")
return data
async getHistory (options = defaultOption) {
if (options.unwrapData) {
return this.axios.get<Note[]>("history").then(response => response.data) as Promise<GetUserHistory>
} else {
return this.axios.get<GetUserHistory>("history")
}
}

async getNoteList (): Promise<GetUserNotes> {
const { data } = await this.axios.get<Note[]>("notes")
return data
async getNoteList (options = defaultOption) {
if (options.unwrapData) {
return this.axios.get<Note[]>("notes").then(response => response.data) as Promise<GetUserNotes>
} else {
return this.axios.get<GetUserNotes>("notes")
}
}

async getNote (noteId: string): Promise<GetUserNote> {
const { data } = await this.axios.get<SingleNote>(`notes/${noteId}`)
return data
async getNote (noteId: string, options = defaultOption) {
if (options.unwrapData) {
return this.axios.get<SingleNote>(`notes/${noteId}`).then(response => response.data) as Promise<GetUserNote>
} else {
return this.axios.get<GetUserNote>(`notes/${noteId}`)
}
}

async createNote (options: CreateNoteOptions): Promise<CreateUserNote> {
const { data } = await this.axios.post<SingleNote>("notes", options)
return data
async createNote (payload: CreateNoteOptions, options = defaultOption) {
if (options.unwrapData) {
return this.axios.post<SingleNote>("notes", payload).then(response => response.data) as Promise<CreateUserNote>
} else {
return this.axios.post<CreateUserNote>("notes", payload)
}
}

async updateNoteContent (noteId: string, content?: string): Promise<UpdateUserNote> {
await this.axios.patch<AxiosResponse>(`notes/${noteId}`, { content })
async updateNoteContent (noteId: string, content?: string, options = defaultOption) {
if (options.unwrapData) {
return this.axios.patch<SingleNote>(`notes/${noteId}`, { content }).then(response => response.data)
} else {
return this.axios.patch<SingleNote>(`notes/${noteId}`, { content })
}
}

async updateNote (noteId: string, options: Partial<Pick<SingleNote, 'content' | 'readPermission' | 'writePermission' | 'permalink'>>): Promise<AxiosResponse> {
return await this.axios.patch<AxiosResponse>(`notes/${noteId}`, options)
async updateNote (noteId: string, payload: Partial<Pick<SingleNote, 'content' | 'readPermission' | 'writePermission' | 'permalink'>>, options = defaultOption) {
if (options.unwrapData) {
return this.axios.patch<SingleNote>(`notes/${noteId}`, payload).then(response => response.data)
} else {
return this.axios.patch<SingleNote>(`notes/${noteId}`, payload)
}
}

async deleteNote (noteId: string): Promise<DeleteUserNote> {
await this.axios.delete<AxiosResponse>(`notes/${noteId}`)
async deleteNote (noteId: string, options = defaultOption) {
if (options.unwrapData) {
return this.axios.delete<SingleNote>(`notes/${noteId}`).then(response => response.data)
} else {
return this.axios.delete<SingleNote>(`notes/${noteId}`)
}
}

async getTeams (): Promise<GetUserTeams> {
const { data } = await this.axios.get<Team[]>("teams")
return data
async getTeams (options = defaultOption) {
if (options.unwrapData) {
return this.axios.get<Team[]>("teams").then(response => response.data) as Promise<GetUserTeams>
} else {
return this.axios.get<GetUserTeams>("teams")
}
}

async getTeamNotes (teamPath: string): Promise<GetTeamNotes> {
const { data } = await this.axios.get<Note[]>(`teams/${teamPath}/notes`)
return data
async getTeamNotes (teamPath: string, options = defaultOption) {
if (options.unwrapData) {
return this.axios.get<Note[]>(`teams/${teamPath}/notes`).then(response => response.data) as Promise<GetTeamNotes>
} else {
return this.axios.get<GetTeamNotes>(`teams/${teamPath}/notes`)
}
}

async createTeamNote (teamPath: string, options: CreateNoteOptions): Promise<CreateTeamNote> {
const { data } = await this.axios.post<SingleNote>(`teams/${teamPath}/notes`, options)
return data
async createTeamNote (teamPath: string, payload: CreateNoteOptions, options = defaultOption) {
if (options.unwrapData) {
return this.axios.post<SingleNote>(`teams/${teamPath}/notes`, payload).then(response => response.data) as Promise<CreateTeamNote>
} else {
return this.axios.post<CreateTeamNote>(`teams/${teamPath}/notes`, payload)
}
}

async updateTeamNoteContent (teamPath: string, noteId: string, content?: string): Promise<UpdateTeamNote> {
await this.axios.patch<AxiosResponse>(`teams/${teamPath}/notes/${noteId}`, { content })
async updateTeamNoteContent (teamPath: string, noteId: string, content?: string): Promise<AxiosResponse> {
return this.axios.patch<AxiosResponse>(`teams/${teamPath}/notes/${noteId}`, { content })
}

async updateTeamNote (teamPath: string, noteId: string, options: Partial<Pick<SingleNote, 'content' | 'readPermission' | 'writePermission' | 'permalink'>>): Promise<AxiosResponse> {
return await this.axios.patch<AxiosResponse>(`teams/${teamPath}/notes/${noteId}`, options)
return this.axios.patch<AxiosResponse>(`teams/${teamPath}/notes/${noteId}`, options)
}

async deleteTeamNote (teamPath: string, noteId: string): Promise<DeleteTeamNote> {
await this.axios.delete<AxiosResponse>(`teams/${teamPath}/notes/${noteId}`)
async deleteTeamNote (teamPath: string, noteId: string): Promise<AxiosResponse> {
return this.axios.delete<AxiosResponse>(`teams/${teamPath}/notes/${noteId}`)
}
}

export default API
27 changes: 20 additions & 7 deletions nodejs/tests/api.spec.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
import { startServer, stopServer } from './server'
// import { startServer, stopServer } from './server'
import { API } from '../src'

let address: Awaited<ReturnType<typeof startServer>>
// let address: Awaited<ReturnType<typeof startServer>>
let client: API

beforeAll(async () => {
address = await startServer()
// address = await startServer()

console.log(address)
client = new API(process.env.HACKMD_ACCESS_TOKEN!, 'http://localhost:3000/api/openAPI/v1/')

// console.log(address)
})

afterAll(async () => {
await stopServer()
// await stopServer()
})

test('it should respond with a 200 status code', async () => {
expect(200).toBe(200)
test('getMe', async () => {
const response = await client.getMe({ unwrapData: false })

expect(response).toHaveProperty('status', 200)
expect(response).toHaveProperty('headers')
})

test('getMe unwrapped', async () => {
const response = await client.getMe()

expect(typeof response).toBe('object')
})

0 comments on commit 7e8c915

Please sign in to comment.