forked from nqthqn/obsidian-wordy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDatamuseApi.ts
126 lines (116 loc) · 3.37 KB
/
DatamuseApi.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
export type SimilarWords = {
relatedWords: string[];
};
// This uses WordNet and RhymeZone
// https://www.datamuse.com/api/
type QueryParam =
| "rel_rhy" // Rhymes spade → aid
| "rel_nry" // Approximate rhymes forest → chorus
| "rel_hom" // Homophones (sound-alike words) course → coarse
| "rel_cns" // Consonant match sample → simple
| "rel_ant" // Antonyms late → early
| "rel_syn" // Synonyms ocean → sea
| "rel_spc" // "More general than" (direct hyponyms) boat → gondola
| "rel_gen" // "More general than" (direct hyponyms) boat → gondola
| "rel_com" // "Comprises" (direct holonyms) car → accelerator
| "rel_par"; //"Part of" (direct meronyms) trunk → tree
export class DatamuseApi {
baseUrl = new URL("https://api.datamuse.com/words");
async wordsSimilarTo(rootWord: string, extra = false): Promise<string[]> {
const results: string[] = [];
const urls: QueryParam[] = [
"rel_syn",
"rel_spc",
"rel_gen",
"rel_com",
"rel_par",
];
await Promise.all(
urls.map(async (queryParam: QueryParam) => {
results.push(
...(await this.relatedWords(queryParam, rootWord))
);
})
);
if (extra) {
const extraResults: string[] = [];
await Promise.all(
results.map(async (similiarWord: string) => {
extraResults.push(
...(await this.relatedWords("rel_syn", similiarWord))
);
})
);
results.push(...extraResults);
}
return results;
}
async wordsOppositeTo(rootWord: string, extra = false): Promise<string[]> {
const results: string[] = [];
results.push(...(await this.relatedWords("rel_ant", rootWord)));
// Get antonyms for synonyms as well
const syns = await this.relatedWords("rel_syn", rootWord);
Promise.all(
syns.map(async (wordLikeRootWord: string) => {
const data = await this.relatedWords(
"rel_ant",
wordLikeRootWord
);
results.push(...data);
})
);
if (extra) {
// Get antonyms for each synonym
const extraResults: string[] = [];
const synonyms = [...(await this.wordsSimilarTo(rootWord))];
await Promise.all(
synonyms.map(async (similiarWord: string) => {
const antonyms = await this.relatedWords(
"rel_ant",
similiarWord
);
extraResults.push(...antonyms);
})
);
results.push(...extraResults);
}
return this.cleanUp(results);
}
async wordsThatRhymeWith(rootWord: string): Promise<string[]> {
const results: string[] = [];
const urls: QueryParam[] = ["rel_rhy", "rel_nry", "rel_hom", "rel_cns"];
await Promise.all(
urls.map(async (queryParam: QueryParam) => {
results.push(
...(await this.relatedWords(queryParam, rootWord))
);
})
);
return this.cleanUp(results);
}
async alliterativeSynonyms(
priorWord: string,
rootWord: string
): Promise<string[]> {
const data = await this.wordsSimilarTo(rootWord, true);
return [
...data
.filter((w) => w.startsWith(priorWord[0]))
.map((syn) => `${priorWord} ${syn}`),
];
}
private cleanUp(results: string[]) {
return [...new Set(results.filter((el) => !!el))];
}
private async relatedWords(
queryParam: QueryParam,
rootWord: string
): Promise<string[]> {
const results = [];
const url = `${this.baseUrl}?${queryParam}=${rootWord}`;
const resp = await fetch(url);
const data = await resp.json();
results.push(...data.map((o: any) => o.word));
return results;
}
}