tdk-api-wrapper 1.3.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -15
- package/dist/{chunk-ACMGCL7T.mjs → chunk-7KJHYRJZ.mjs} +1041 -16
- package/dist/cli.js +1205 -21
- package/dist/cli.mjs +219 -7
- package/dist/index.d.mts +206 -1
- package/dist/index.d.ts +206 -1
- package/dist/index.js +1052 -17
- package/dist/index.mjs +23 -3
- package/package.json +3 -2
- package/src/cli.ts +224 -6
- package/src/index.ts +2 -1
- package/src/morphology.ts +324 -0
- package/src/tdk.ts +560 -15
- package/src/types.ts +49 -0
- package/test/grammar.test.js +52 -0
- package/test/morphology.test.js +129 -0
- package/test/proofread.test.js +60 -0
- package/test/tools.test.js +51 -0
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,32 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TDK,
|
|
3
|
+
TDKClient,
|
|
3
4
|
TDKError,
|
|
4
5
|
TDKNetworkError,
|
|
5
|
-
TDKValidationError
|
|
6
|
-
|
|
6
|
+
TDKValidationError,
|
|
7
|
+
TURKISH_SUFFIXES,
|
|
8
|
+
TURKISH_VOWELS,
|
|
9
|
+
getStemCandidates,
|
|
10
|
+
isVowel,
|
|
11
|
+
restoreConsonantSoftening,
|
|
12
|
+
restoreGemination,
|
|
13
|
+
restoreInfinitive,
|
|
14
|
+
restoreVowelDrop,
|
|
15
|
+
restoreVowelNarrowing
|
|
16
|
+
} from "./chunk-7KJHYRJZ.mjs";
|
|
7
17
|
export {
|
|
8
18
|
TDK,
|
|
19
|
+
TDKClient,
|
|
9
20
|
TDKError,
|
|
10
21
|
TDKNetworkError,
|
|
11
|
-
TDKValidationError
|
|
22
|
+
TDKValidationError,
|
|
23
|
+
TURKISH_SUFFIXES,
|
|
24
|
+
TURKISH_VOWELS,
|
|
25
|
+
getStemCandidates,
|
|
26
|
+
isVowel,
|
|
27
|
+
restoreConsonantSoftening,
|
|
28
|
+
restoreGemination,
|
|
29
|
+
restoreInfinitive,
|
|
30
|
+
restoreVowelDrop,
|
|
31
|
+
restoreVowelNarrowing
|
|
12
32
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tdk-api-wrapper",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "TDK (Türk Dil Kurumu) unofficial live data API wrapper for Node.js",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
18
|
"scripts": {
|
|
19
|
-
"build": "tsup src/index.ts src/cli.ts --format cjs,esm --dts --clean --shims"
|
|
19
|
+
"build": "tsup src/index.ts src/cli.ts --format cjs,esm --dts --clean --shims",
|
|
20
|
+
"test": "node test/morphology.test.js && node test/grammar.test.js && node test/proofread.test.js && node test/tools.test.js"
|
|
20
21
|
},
|
|
21
22
|
"keywords": [
|
|
22
23
|
"tdk",
|
package/src/cli.ts
CHANGED
|
@@ -4,6 +4,17 @@ import { TDK } from "./tdk";
|
|
|
4
4
|
const rawArgs = process.argv.slice(2);
|
|
5
5
|
const jsonMode = rawArgs.includes("--json");
|
|
6
6
|
const args = rawArgs.filter((a) => a !== "--json");
|
|
7
|
+
|
|
8
|
+
const isColor = !jsonMode && Boolean(process.stdout.isTTY);
|
|
9
|
+
const c = {
|
|
10
|
+
bold: (s: string) => (isColor ? `\x1b[1m${s}\x1b[0m` : s),
|
|
11
|
+
dim: (s: string) => (isColor ? `\x1b[2m${s}\x1b[0m` : s),
|
|
12
|
+
green: (s: string) => (isColor ? `\x1b[32m${s}\x1b[0m` : s),
|
|
13
|
+
yellow: (s: string) => (isColor ? `\x1b[33m${s}\x1b[0m` : s),
|
|
14
|
+
cyan: (s: string) => (isColor ? `\x1b[36m${s}\x1b[0m` : s),
|
|
15
|
+
red: (s: string) => (isColor ? `\x1b[31m${s}\x1b[0m` : s),
|
|
16
|
+
};
|
|
17
|
+
|
|
7
18
|
const KNOWN_COMMANDS = new Set([
|
|
8
19
|
"ara",
|
|
9
20
|
"anlam",
|
|
@@ -11,7 +22,11 @@ const KNOWN_COMMANDS = new Set([
|
|
|
11
22
|
"ornek",
|
|
12
23
|
"hece",
|
|
13
24
|
"uyum",
|
|
25
|
+
"kucukuyum",
|
|
14
26
|
"yazim",
|
|
27
|
+
"kok",
|
|
28
|
+
"stem",
|
|
29
|
+
"deyim",
|
|
15
30
|
"gunun",
|
|
16
31
|
"rastgele",
|
|
17
32
|
"esanlam",
|
|
@@ -22,6 +37,14 @@ const KNOWN_COMMANDS = new Set([
|
|
|
22
37
|
"karsilastir",
|
|
23
38
|
"analiz",
|
|
24
39
|
"oneri",
|
|
40
|
+
"bulmaca",
|
|
41
|
+
"pattern",
|
|
42
|
+
"anagram",
|
|
43
|
+
"kafiye",
|
|
44
|
+
"rhyme",
|
|
45
|
+
"denetle",
|
|
46
|
+
"proofread",
|
|
47
|
+
"repl",
|
|
25
48
|
"kubbealti",
|
|
26
49
|
"nisanyan",
|
|
27
50
|
"viki",
|
|
@@ -47,18 +70,96 @@ function printError(message: string) {
|
|
|
47
70
|
if (jsonMode) {
|
|
48
71
|
console.log(JSON.stringify({ error: message }));
|
|
49
72
|
} else {
|
|
50
|
-
console.log(`Hata: ${message}`);
|
|
73
|
+
console.log(c.red(`Hata: ${message}`));
|
|
51
74
|
}
|
|
52
75
|
}
|
|
53
76
|
|
|
77
|
+
async function startRepl() {
|
|
78
|
+
const readline = await import("node:readline");
|
|
79
|
+
const rl = readline.createInterface({
|
|
80
|
+
input: process.stdin,
|
|
81
|
+
output: process.stdout,
|
|
82
|
+
prompt: c.cyan("tdk> "),
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
console.log(c.bold("TDK İnteraktif Sözlük Kabuğu (Çıkmak için 'exit' veya Ctrl+C)"));
|
|
86
|
+
console.log(c.dim("Komutlar: ara <kelime>, hece <kelime>, bulmaca <desen>, denetle <metin> veya doğrudan kelime"));
|
|
87
|
+
rl.prompt();
|
|
88
|
+
|
|
89
|
+
rl.on("line", async (line) => {
|
|
90
|
+
const trimmed = line.trim();
|
|
91
|
+
if (!trimmed) {
|
|
92
|
+
rl.prompt();
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (trimmed === "exit" || trimmed === "quit" || trimmed === ".exit") {
|
|
96
|
+
rl.close();
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const parts = trimmed.split(/\s+/);
|
|
101
|
+
let subCmd = parts[0].toLowerCase();
|
|
102
|
+
let subArg = parts.slice(1).join(" ");
|
|
103
|
+
if (!KNOWN_COMMANDS.has(subCmd)) {
|
|
104
|
+
subArg = trimmed;
|
|
105
|
+
subCmd = "anlam";
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
if (subCmd === "ara" || subCmd === "anlam") {
|
|
110
|
+
const meanings = await TDK.getMeanings(subArg);
|
|
111
|
+
if (meanings.length === 0) console.log(c.dim("Sonuç bulunamadı."));
|
|
112
|
+
else meanings.forEach((m, i) => console.log(`${i + 1}. ${c.green(m)}`));
|
|
113
|
+
} else if (subCmd === "koken") {
|
|
114
|
+
const origin = await TDK.getOrigin(subArg);
|
|
115
|
+
console.log(`Köken: ${c.cyan(origin || "Bilinmiyor")}`);
|
|
116
|
+
} else if (subCmd === "hece") {
|
|
117
|
+
const s = TDK.syllabicate(subArg);
|
|
118
|
+
console.log(`Heceler: ${c.yellow(s.join("-"))}`);
|
|
119
|
+
} else if (subCmd === "uyum") {
|
|
120
|
+
const h = TDK.checkVowelHarmony(subArg);
|
|
121
|
+
console.log(`Büyük Ünlü Uyumu: ${h ? c.green("Uyar") : c.red("Uymaz")}`);
|
|
122
|
+
} else if (subCmd === "kucukuyum") {
|
|
123
|
+
const h = TDK.checkLabialHarmony(subArg);
|
|
124
|
+
console.log(`Küçük Ünlü Uyumu: ${h ? c.green("Uyar") : c.red("Uymaz")}`);
|
|
125
|
+
} else if (subCmd === "bulmaca" || subCmd === "pattern") {
|
|
126
|
+
const matches = await TDK.patternSearch(subArg);
|
|
127
|
+
console.log(matches.slice(0, 15).join(", "));
|
|
128
|
+
} else if (subCmd === "denetle" || subCmd === "proofread") {
|
|
129
|
+
const res = await TDK.proofread(subArg);
|
|
130
|
+
if (res.isCorrect) console.log(c.green("✓ Sorun bulunamadı."));
|
|
131
|
+
else res.issues.forEach((iss) => console.log(`- ${c.yellow(iss.word)}: ${iss.message}${iss.suggestion ? " -> " + c.green(iss.suggestion) : ""}`));
|
|
132
|
+
} else {
|
|
133
|
+
console.log(c.dim("Örnek komutlar: 'ara kalem', 'hece elektrik', 'bulmaca k_l_m', 'denetle Bugün evdeyim'"));
|
|
134
|
+
}
|
|
135
|
+
} catch (e: any) {
|
|
136
|
+
console.log(c.red(`Hata: ${e?.message || e}`));
|
|
137
|
+
}
|
|
138
|
+
rl.prompt();
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
54
142
|
async function run() {
|
|
55
|
-
if (!command
|
|
143
|
+
if (!command) {
|
|
144
|
+
if (process.stdin.isTTY) {
|
|
145
|
+
await startRepl();
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
56
148
|
console.log("Kullanım: tdk [komut] <kelime> [--json]");
|
|
57
149
|
console.log(
|
|
58
|
-
"Komutlar: ara, anlam, koken, ornek, hece, uyum, yazim, gunun, rastgele, esanlam, karsit, yabanci, kurallar, kural, karsilastir, analiz, oneri, kubbealti, nisanyan, viki"
|
|
150
|
+
"Komutlar: ara, anlam, koken, ornek, hece, uyum, kucukuyum, yazim, kok, deyim, gunun, rastgele, esanlam, karsit, yabanci, kurallar, kural, karsilastir, analiz, oneri, bulmaca, anagram, kafiye, denetle, repl, kubbealti, nisanyan, viki"
|
|
59
151
|
);
|
|
60
152
|
console.log("Not: Komut belirtilmezse doğrudan kelime anlamı aranır (örn: tdk selam)");
|
|
61
|
-
process.exit(
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (command === "--help" || command === "-h") {
|
|
157
|
+
console.log("Kullanım: tdk [komut] <kelime> [--json]");
|
|
158
|
+
console.log(
|
|
159
|
+
"Komutlar: ara, anlam, koken, ornek, hece, uyum, kucukuyum, yazim, kok, deyim, gunun, rastgele, esanlam, karsit, yabanci, kurallar, kural, karsilastir, analiz, oneri, bulmaca, anagram, kafiye, denetle, repl, kubbealti, nisanyan, viki"
|
|
160
|
+
);
|
|
161
|
+
console.log("Not: Komut belirtilmezse doğrudan kelime anlamı aranır (örn: tdk selam)");
|
|
162
|
+
process.exit(0);
|
|
62
163
|
}
|
|
63
164
|
|
|
64
165
|
TDK.enableCache(false);
|
|
@@ -118,12 +219,26 @@ async function run() {
|
|
|
118
219
|
break;
|
|
119
220
|
}
|
|
120
221
|
|
|
222
|
+
case "kucukuyum":
|
|
223
|
+
case "labial": {
|
|
224
|
+
if (!word) throw new Error("Kelime belirtmelisiniz.");
|
|
225
|
+
const isHarmony = TDK.checkLabialHarmony(word);
|
|
226
|
+
printResult({ word, labialHarmony: isHarmony }, () =>
|
|
227
|
+
console.log(`Küçük Ünlü Uyumu: ${isHarmony ? "Uyar" : "Uymaz"}`)
|
|
228
|
+
);
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
|
|
121
232
|
case "yazim": {
|
|
122
233
|
if (!word) throw new Error("Kelime belirtmelisiniz.");
|
|
123
234
|
const spellResult = await TDK.checkSpelling(word);
|
|
124
235
|
printResult(spellResult, () => {
|
|
125
236
|
if (spellResult.isCorrect) {
|
|
126
|
-
|
|
237
|
+
if (spellResult.isInflected && spellResult.root) {
|
|
238
|
+
console.log(`Doğru yazım (çekimli biçim, kök: ${spellResult.root}).`);
|
|
239
|
+
} else {
|
|
240
|
+
console.log("Doğru yazım.");
|
|
241
|
+
}
|
|
127
242
|
} else {
|
|
128
243
|
console.log(`Yanlış yazım.${spellResult.suggestion ? " Doğrusu: " + spellResult.suggestion : ""}`);
|
|
129
244
|
}
|
|
@@ -131,6 +246,35 @@ async function run() {
|
|
|
131
246
|
break;
|
|
132
247
|
}
|
|
133
248
|
|
|
249
|
+
case "kok":
|
|
250
|
+
case "stem": {
|
|
251
|
+
if (!word) throw new Error("Kelime belirtmelisiniz.");
|
|
252
|
+
const stemResult = await TDK.stem(word);
|
|
253
|
+
printResult(stemResult, () => {
|
|
254
|
+
if (!stemResult) {
|
|
255
|
+
console.log("Kök bulunamadı.");
|
|
256
|
+
} else if (stemResult.isInflected) {
|
|
257
|
+
console.log(`Kök: ${stemResult.root} (çekimli biçim)`);
|
|
258
|
+
} else {
|
|
259
|
+
console.log(`Kök: ${stemResult.root} (yalın biçim)`);
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
case "deyim": {
|
|
266
|
+
if (!word) throw new Error("Kelime belirtmelisiniz.");
|
|
267
|
+
const proverbs = await TDK.getProverbs(word);
|
|
268
|
+
printResult(proverbs, () => {
|
|
269
|
+
if (proverbs.length === 0) {
|
|
270
|
+
console.log("Atasözü/deyim bulunamadı.");
|
|
271
|
+
} else {
|
|
272
|
+
proverbs.forEach((p, i) => console.log(`${i + 1}. ${p}`));
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
|
|
134
278
|
case "gunun": {
|
|
135
279
|
const wotd = await TDK.getWordOfTheDay();
|
|
136
280
|
printResult(wotd, () => {
|
|
@@ -239,7 +383,8 @@ async function run() {
|
|
|
239
383
|
} else {
|
|
240
384
|
analysis.forEach((a) => {
|
|
241
385
|
if (a.found) {
|
|
242
|
-
|
|
386
|
+
const rootLabel = a.isInflected && a.root ? ` (kök: ${a.root})` : "";
|
|
387
|
+
console.log(`${a.word}${rootLabel}: ${a.meaning ?? "-"} (${a.origin})`);
|
|
243
388
|
} else {
|
|
244
389
|
console.log(`${a.word}: bulunamadı`);
|
|
245
390
|
}
|
|
@@ -262,6 +407,79 @@ async function run() {
|
|
|
262
407
|
break;
|
|
263
408
|
}
|
|
264
409
|
|
|
410
|
+
case "bulmaca":
|
|
411
|
+
case "pattern": {
|
|
412
|
+
if (!word) throw new Error("Desen belirtmelisiniz (örn: k_l_m).");
|
|
413
|
+
const matches = await TDK.patternSearch(word);
|
|
414
|
+
printResult(matches, () => {
|
|
415
|
+
if (matches.length === 0) {
|
|
416
|
+
console.log("Eşleşen kelime bulunamadı.");
|
|
417
|
+
} else {
|
|
418
|
+
console.log(c.bold(`Bulunan Kelimeler (${matches.length}):`));
|
|
419
|
+
matches.forEach((m, i) => console.log(`${i + 1}. ${c.cyan(m)}`));
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
break;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
case "anagram": {
|
|
426
|
+
if (!word) throw new Error("Harfler belirtmelisiniz.");
|
|
427
|
+
const anagrams = await TDK.findAnagrams(word);
|
|
428
|
+
printResult(anagrams, () => {
|
|
429
|
+
if (anagrams.length === 0) {
|
|
430
|
+
console.log("Anagram veya bu harflerle türetilebilecek kelime bulunamadı.");
|
|
431
|
+
} else {
|
|
432
|
+
const clean = word.trim().toLocaleLowerCase("tr-TR").replace(/[^a-zçğıöşüâîû]/gi, "");
|
|
433
|
+
const hasExact = anagrams.some((a) => a.length === clean.length);
|
|
434
|
+
const title = hasExact
|
|
435
|
+
? `Anagramlar (${anagrams.length}):`
|
|
436
|
+
: `Birebir anagram bulunamadı. Bu harflerle türetilen kelimeler (${anagrams.length}):`;
|
|
437
|
+
console.log(c.bold(title));
|
|
438
|
+
anagrams.forEach((a, i) => console.log(`${i + 1}. ${c.green(a)} ${c.dim(`(${a.length} harf)`)}`));
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
break;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
case "kafiye":
|
|
445
|
+
case "rhyme": {
|
|
446
|
+
if (!word) throw new Error("Kelime belirtmelisiniz.");
|
|
447
|
+
const rhymes = await TDK.findRhymes(word);
|
|
448
|
+
printResult(rhymes, () => {
|
|
449
|
+
if (rhymes.length === 0) {
|
|
450
|
+
console.log("Kafiye bulunamadı.");
|
|
451
|
+
} else {
|
|
452
|
+
console.log(c.bold(`Kafiyeli Kelimeler (${rhymes.length}):`));
|
|
453
|
+
rhymes.forEach((r, i) => console.log(`${i + 1}. ${c.yellow(r)}`));
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
break;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
case "denetle":
|
|
460
|
+
case "proofread": {
|
|
461
|
+
if (!word) throw new Error("Metin belirtmelisiniz.");
|
|
462
|
+
const result = await TDK.proofread(word);
|
|
463
|
+
printResult(result, () => {
|
|
464
|
+
if (result.isCorrect) {
|
|
465
|
+
console.log(c.green("✓ Metinde imla veya bağlaç hatası tespit edilmedi."));
|
|
466
|
+
} else {
|
|
467
|
+
console.log(c.bold(c.red(`Metinde ${result.issues.length} olası sorun tespit edildi:`)));
|
|
468
|
+
result.issues.forEach((issue, i) => {
|
|
469
|
+
const label = c.yellow(`[${issue.type}]`);
|
|
470
|
+
const sug = issue.suggestion ? c.green(` -> Öneri: ${issue.suggestion}`) : "";
|
|
471
|
+
console.log(`${i + 1}. ${label} "${c.bold(issue.word)}": ${issue.message}${sug}`);
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
case "repl": {
|
|
479
|
+
await startRepl();
|
|
480
|
+
break;
|
|
481
|
+
}
|
|
482
|
+
|
|
265
483
|
case "kubbealti": {
|
|
266
484
|
if (!word) throw new Error("Kelime belirtmelisiniz.");
|
|
267
485
|
const meanings = await TDK.getKubbealtiMeanings(word);
|
package/src/index.ts
CHANGED