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/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
- } from "./chunk-ACMGCL7T.mjs";
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.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 || command === "--help" || command === "-h") {
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(command ? 0 : 1);
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
- console.log("Doğru yazım.");
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
- console.log(`${a.word}: ${a.meaning ?? "-"} (${a.origin})`);
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
@@ -1,3 +1,4 @@
1
- export { TDK } from "./tdk";
1
+ export { TDK, TDKClient } from "./tdk";
2
2
  export * from "./types";
3
3
  export * from "./errors";
4
+ export * from "./morphology";