/
mod.ts
216 lines (199 loc) · 5.89 KB
/
mod.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
const MODULE_NAME = "dad_jokes";
const BASE_URL = "https://icanhazdadjoke.com";
let USER_AGENT =
"dad_jokes Deno module by Carter Snook (https://deno.land/x/dad_jokes)";
const DEFAULT_USER_AGENT = USER_AGENT;
export interface AnyObj {
[key: string]: any;
[key: number]: any;
}
export class Joke {
id?: string;
joke?: string;
constructor(data: AnyObj) {
this.id = data.id;
this.joke = data.joke;
}
}
export class JokeResponse extends Joke {
status: number;
message?: string;
constructor(data: AnyObj) {
super(data);
this.status = data.status;
this.message = data.message;
}
}
export class SlackJokeResponse {
attachments: {
fallback: string;
footer: string;
text: string;
}[];
response_type: string;
username: string;
constructor(data: AnyObj) {
this.attachments = data.attachments;
this.response_type = data.response_type;
this.username = data.username;
}
}
export class SearchedJokesResponse {
status: number;
message?: string;
current_page: number;
limit: number;
next_page: number;
results: Joke[];
search_term: string;
total_jokes: number;
total_pages: number;
constructor(data: AnyObj) {
this.status = data.status;
this.message = data.message;
this.current_page = data.current_page;
this.limit = data.limit;
this.next_page = data.next_page;
this.results = data.results;
this.search_term = data.search_term;
this.total_jokes = data.total_jokes;
this.total_pages = data.total_pages;
}
}
/**
* Allows you to set the new user agent that will be used for all dad joke api requests.
* @param newUserAgent the new value of the user agent
*/
export function setDadJokesUserAgent(newUserAgent: string): void {
if (newUserAgent === "") {
console.warn(
`WARNING(${MODULE_NAME}): A user agent should not be an empty string.`
);
}
USER_AGENT = newUserAgent;
}
/**
* Gives you the link for the given joke id on the icanhazdadjoke website. Note that the api is not used for this function.
* @param id the joke id
* @param optional boolean for if the base url should be included in the returned value (default = true)
* @returns the given joke id's url
*/
export function getJokeUrl(id: string, includeBaseUrl: boolean = true): string {
return `${includeBaseUrl ? BASE_URL : ""}/j/${id}`;
}
/**
* Gives you the image link for the given joke id. Note that the api is not used for this function.
* @param the id string of the joke
* @param optional boolean for if the base url should be included in the returned value (default = true)
* @returns the given joke id's url
*/
export function getJokeImageUrl(
id: string,
includeBaseUrl: boolean = true
): string {
return `${getJokeUrl(id, includeBaseUrl)}.png`;
}
/**
* Sends a request to the icanhazdadjoke api.
* @async
* @param endpoint the string endpoint to send the request to
* @returns the response data
*/
export async function fetchDadJokeAPI(endpoint: string): Promise<Response> {
if (USER_AGENT === DEFAULT_USER_AGENT) {
console.warn(
`WARNING(${MODULE_NAME}): Please set a user agent for requests using \`setDadJokesUserAgent\`.`
);
}
return await fetch(`${BASE_URL}${endpoint}`, {
headers: {
Accept: "application/json",
"User-Agent": USER_AGENT,
},
});
}
/**
* Sends a request to the icanhazdadjoke api that is formatted to json.
* @async
* @param endpoint the string endpoint to send the request to
* @returns the response data in json
*/
export async function fetchDadJokeAPIJson(endpoint: string): Promise<AnyObj> {
const res = await fetchDadJokeAPI(endpoint);
return await res.json();
}
/**
* Gives you a random joke.
* @async
* @returns JokeResponse the random Joke
*/
export async function getRandomJoke(): Promise<JokeResponse> {
return new JokeResponse(await fetchDadJokeAPIJson("/"));
}
/**
* Gives you a joke formatted for slack.
* @async
* @returns SlackJokeResponse the slack joke
*/
export async function getRandomSlackJoke(): Promise<SlackJokeResponse> {
return new SlackJokeResponse(await fetchDadJokeAPIJson("/slack"));
}
/**
* Gives you the image link for the given joke id. Note that the api is not used for this function.
* @param id the joke id
* @returns the given joke id's url
*/
export async function getJokeImageByteArray(id: string): Promise<Uint8Array> {
const res = await fetchDadJokeAPI(getJokeImageUrl(id, false));
const data = await res.arrayBuffer();
return new Uint8Array(data);
}
/**
* Gives you a joke with the matching id.
* @async
* @param id the id of the joke to search for
* @returns JokeResponse the Joke that matches the given id
*/
export async function getJoke(id: string): Promise<JokeResponse> {
return new JokeResponse(await fetchDadJokeAPIJson(`/j/${id}`));
}
/**
* Searches the jokes that match your query.
* @async
* @param term the search query
* @param page the page of paginated results to go to (default = 1)
* @param limit the maximum number of jokes to show per page (default = 20)
* @returns SearchedJokesResponse the results from the search query
*/
export async function getSearchedJokes(
term: string,
page: number = 1,
limit: number = 20
): Promise<SearchedJokesResponse> {
const params = new URLSearchParams({
term,
page: page.toString(),
limit: limit.toString(),
});
return new SearchedJokesResponse(
await fetchDadJokeAPIJson(`/search?${params.toString()}`)
);
}
class AllJokesResponse extends SearchedJokesResponse {
constructor(data: AnyObj) {
super(data);
}
}
/**
* Returns all of the paginated jokes.
* @async
* @param page the page of paginated results to go to (default = 1)
* @param limit the maximum number of jokes to show per page (default = 20)
* @returns SearchedJokesResponse the results
*/
export async function getAllJokes(
page: number = 1,
limit: number = 20
): Promise<AllJokesResponse> {
return new AllJokesResponse(await getSearchedJokes("", page, limit));
}