Skip to content

Commit 53741e8

Browse files
committed
feat: type hacking
1 parent c5590d0 commit 53741e8

File tree

1 file changed

+33
-67
lines changed

1 file changed

+33
-67
lines changed

nodejs/src/index.ts

Lines changed: 33 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import axios, { AxiosInstance, AxiosRequestConfig, AxiosError, AxiosResponse } from 'axios'
2-
import { User, Note, Team, CreateNoteOptions, GetMe, GetUserHistory, GetUserNotes, GetUserNote, CreateUserNote, GetUserTeams, GetTeamNotes, CreateTeamNote, SingleNote } from './type'
2+
import { CreateNoteOptions, GetMe, GetUserHistory, GetUserNotes, GetUserNote, CreateUserNote, GetUserTeams, GetTeamNotes, CreateTeamNote, SingleNote } from './type'
33
import * as HackMDErrors from './error'
44

55
export type RequestOptions = {
@@ -10,6 +10,8 @@ const defaultOption: RequestOptions = {
1010
unwrapData: true,
1111
}
1212

13+
type OptionReturnType<Opt, T> = Opt extends { unwrapData: false } ? AxiosResponse<T> : Opt extends { unwrapData: true } ? T : T
14+
1315
export class API {
1416
private axios: AxiosInstance
1517

@@ -61,92 +63,48 @@ export class API {
6163
)
6264
}
6365

64-
async getMe (option = defaultOption) {
65-
if (option.unwrapData) {
66-
return this.axios.get<User>("me").then(response => response.data) as Promise<GetMe>
67-
} else {
68-
return this.axios.get<GetMe>("me")
69-
}
66+
async getMe<Opt extends RequestOptions> (options = defaultOption as Opt): Promise<OptionReturnType<Opt, GetMe>> {
67+
return this.unwrapData(this.axios.get<GetMe>("me"), options.unwrapData) as unknown as OptionReturnType<Opt, GetMe>
7068
}
7169

72-
async getHistory (options = defaultOption) {
73-
if (options.unwrapData) {
74-
return this.axios.get<Note[]>("history").then(response => response.data) as Promise<GetUserHistory>
75-
} else {
76-
return this.axios.get<GetUserHistory>("history")
77-
}
70+
async getHistory<Opt extends RequestOptions> (options = defaultOption as Opt): Promise<OptionReturnType<Opt, GetUserHistory>> {
71+
return this.unwrapData(this.axios.get<GetUserHistory>("history"), options.unwrapData) as unknown as OptionReturnType<Opt, GetUserHistory>
7872
}
7973

80-
async getNoteList (options = defaultOption) {
81-
if (options.unwrapData) {
82-
return this.axios.get<Note[]>("notes").then(response => response.data) as Promise<GetUserNotes>
83-
} else {
84-
return this.axios.get<GetUserNotes>("notes")
85-
}
74+
async getNoteList<Opt extends RequestOptions> (options = defaultOption as Opt): Promise<OptionReturnType<Opt, GetUserNotes>> {
75+
return this.unwrapData(this.axios.get<GetUserNotes>("notes"), options.unwrapData) as unknown as OptionReturnType<Opt, GetUserNotes>
8676
}
8777

88-
async getNote (noteId: string, options = defaultOption) {
89-
if (options.unwrapData) {
90-
return this.axios.get<SingleNote>(`notes/${noteId}`).then(response => response.data) as Promise<GetUserNote>
91-
} else {
92-
return this.axios.get<GetUserNote>(`notes/${noteId}`)
93-
}
78+
async getNote<Opt extends RequestOptions> (noteId: string, options = defaultOption as Opt): Promise<OptionReturnType<Opt, GetUserNote>> {
79+
return this.unwrapData(this.axios.get<GetUserNote>(`notes/${noteId}`), options.unwrapData) as unknown as OptionReturnType<Opt, GetUserNote>
9480
}
9581

96-
async createNote (payload: CreateNoteOptions, options = defaultOption) {
97-
if (options.unwrapData) {
98-
return this.axios.post<SingleNote>("notes", payload).then(response => response.data) as Promise<CreateUserNote>
99-
} else {
100-
return this.axios.post<CreateUserNote>("notes", payload)
101-
}
82+
async createNote<Opt extends RequestOptions> (payload: CreateNoteOptions, options = defaultOption as Opt): Promise<OptionReturnType<Opt, CreateUserNote>> {
83+
return this.unwrapData(this.axios.post<CreateUserNote>("notes", payload), options.unwrapData) as unknown as OptionReturnType<Opt, CreateUserNote>
10284
}
10385

104-
async updateNoteContent (noteId: string, content?: string, options = defaultOption) {
105-
if (options.unwrapData) {
106-
return this.axios.patch<SingleNote>(`notes/${noteId}`, { content }).then(response => response.data)
107-
} else {
108-
return this.axios.patch<SingleNote>(`notes/${noteId}`, { content })
109-
}
86+
async updateNoteContent<Opt extends RequestOptions> (noteId: string, content?: string, options = defaultOption as Opt): Promise<OptionReturnType<Opt, SingleNote>> {
87+
return this.unwrapData(this.axios.patch<SingleNote>(`notes/${noteId}`, { content }), options.unwrapData) as unknown as OptionReturnType<Opt, SingleNote>
11088
}
11189

112-
async updateNote (noteId: string, payload: Partial<Pick<SingleNote, 'content' | 'readPermission' | 'writePermission' | 'permalink'>>, options = defaultOption) {
113-
if (options.unwrapData) {
114-
return this.axios.patch<SingleNote>(`notes/${noteId}`, payload).then(response => response.data)
115-
} else {
116-
return this.axios.patch<SingleNote>(`notes/${noteId}`, payload)
117-
}
90+
async updateNote<Opt extends RequestOptions> (noteId: string, payload: Partial<Pick<SingleNote, 'content' | 'readPermission' | 'writePermission' | 'permalink'>>, options = defaultOption as Opt): Promise<OptionReturnType<Opt, SingleNote>> {
91+
return this.unwrapData(this.axios.patch<SingleNote>(`notes/${noteId}`, payload), options.unwrapData) as unknown as OptionReturnType<Opt, SingleNote>
11892
}
11993

120-
async deleteNote (noteId: string, options = defaultOption) {
121-
if (options.unwrapData) {
122-
return this.axios.delete<SingleNote>(`notes/${noteId}`).then(response => response.data)
123-
} else {
124-
return this.axios.delete<SingleNote>(`notes/${noteId}`)
125-
}
94+
async deleteNote<Opt extends RequestOptions> (noteId: string, options = defaultOption as Opt): Promise<OptionReturnType<Opt, SingleNote>> {
95+
return this.unwrapData(this.axios.delete<SingleNote>(`notes/${noteId}`), options.unwrapData) as unknown as OptionReturnType<Opt, SingleNote>
12696
}
12797

128-
async getTeams (options = defaultOption) {
129-
if (options.unwrapData) {
130-
return this.axios.get<Team[]>("teams").then(response => response.data) as Promise<GetUserTeams>
131-
} else {
132-
return this.axios.get<GetUserTeams>("teams")
133-
}
98+
async getTeams<Opt extends RequestOptions> (options = defaultOption as Opt): Promise<OptionReturnType<Opt, GetUserTeams>> {
99+
return this.unwrapData(this.axios.get<GetUserTeams>("teams"), options.unwrapData) as unknown as OptionReturnType<Opt, GetUserTeams>
134100
}
135101

136-
async getTeamNotes (teamPath: string, options = defaultOption) {
137-
if (options.unwrapData) {
138-
return this.axios.get<Note[]>(`teams/${teamPath}/notes`).then(response => response.data) as Promise<GetTeamNotes>
139-
} else {
140-
return this.axios.get<GetTeamNotes>(`teams/${teamPath}/notes`)
141-
}
102+
async getTeamNotes<Opt extends RequestOptions> (teamPath: string, options = defaultOption as Opt): Promise<OptionReturnType<Opt, GetTeamNotes>> {
103+
return this.unwrapData(this.axios.get<GetTeamNotes>(`teams/${teamPath}/notes`), options.unwrapData) as unknown as OptionReturnType<Opt, GetTeamNotes>
142104
}
143105

144-
async createTeamNote (teamPath: string, payload: CreateNoteOptions, options = defaultOption) {
145-
if (options.unwrapData) {
146-
return this.axios.post<SingleNote>(`teams/${teamPath}/notes`, payload).then(response => response.data) as Promise<CreateTeamNote>
147-
} else {
148-
return this.axios.post<CreateTeamNote>(`teams/${teamPath}/notes`, payload)
149-
}
106+
async createTeamNote<Opt extends RequestOptions> (teamPath: string, payload: CreateNoteOptions, options = defaultOption as Opt): Promise<OptionReturnType<Opt, CreateTeamNote>> {
107+
return this.unwrapData(this.axios.post<CreateTeamNote>(`teams/${teamPath}/notes`, payload), options.unwrapData) as unknown as OptionReturnType<Opt, CreateTeamNote>
150108
}
151109

152110
async updateTeamNoteContent (teamPath: string, noteId: string, content?: string): Promise<AxiosResponse> {
@@ -160,6 +118,14 @@ export class API {
160118
async deleteTeamNote (teamPath: string, noteId: string): Promise<AxiosResponse> {
161119
return this.axios.delete<AxiosResponse>(`teams/${teamPath}/notes/${noteId}`)
162120
}
121+
122+
private unwrapData<T> (reqP: Promise<AxiosResponse<T>>, unwrap = true) {
123+
if (unwrap) {
124+
return reqP.then(response => response.data)
125+
} else {
126+
return reqP
127+
}
128+
}
163129
}
164130

165131
export default API

0 commit comments

Comments
 (0)