tdk-api-wrapper 1.5.0 → 1.5.1
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/{chunk-7KJHYRJZ.mjs → chunk-NEC5MIQM.mjs} +311 -12
- package/dist/cli.js +316 -13
- package/dist/cli.mjs +6 -2
- package/dist/index.js +311 -12
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/src/cli.ts +6 -1
- package/src/morphology.ts +9 -0
- package/src/tdk.ts +344 -37
- package/test/proofread.test.js +28 -0
package/dist/index.js
CHANGED
|
@@ -584,6 +584,13 @@ function getStemCandidates(word, minStemLength = 2, maxDepth = 4) {
|
|
|
584
584
|
seen.add(apostropheStem);
|
|
585
585
|
}
|
|
586
586
|
}
|
|
587
|
+
const bareInfinitives = restoreInfinitive(normalized);
|
|
588
|
+
for (const inf of bareInfinitives) {
|
|
589
|
+
if (!seen.has(inf) && inf !== normalized) {
|
|
590
|
+
seen.add(inf);
|
|
591
|
+
candidatesWithWeight.push({ candidate: inf, baseLength: normalized.length });
|
|
592
|
+
}
|
|
593
|
+
}
|
|
587
594
|
let frontier = [normalized];
|
|
588
595
|
for (let depth = 0; depth < maxDepth; depth++) {
|
|
589
596
|
const nextFrontier = [];
|
|
@@ -633,6 +640,159 @@ var path = __toESM(require("path"));
|
|
|
633
640
|
var os = __toESM(require("os"));
|
|
634
641
|
var https = __toESM(require("https"));
|
|
635
642
|
var tls = __toESM(require("tls"));
|
|
643
|
+
var COMMON_MISSPELLINGS = {
|
|
644
|
+
// -şey ile biten ve ayrı yazılması zorunlu söz öbekleri
|
|
645
|
+
her\u015Fey: "her \u015Fey",
|
|
646
|
+
hersey: "her \u015Fey",
|
|
647
|
+
bir\u015Fey: "bir \u015Fey",
|
|
648
|
+
birsey: "bir \u015Fey",
|
|
649
|
+
hi\u00E7bir\u015Fey: "hi\xE7bir \u015Fey",
|
|
650
|
+
hicbirsey: "hi\xE7bir \u015Fey",
|
|
651
|
+
\u00E7ok\u015Fey: "\xE7ok \u015Fey",
|
|
652
|
+
coksey: "\xE7ok \u015Fey",
|
|
653
|
+
\u015Feyler: "\u015Feyler",
|
|
654
|
+
seyler: "\u015Feyler",
|
|
655
|
+
herhangibir\u015Fey: "herhangi bir \u015Fey",
|
|
656
|
+
herhangibirsey: "herhangi bir \u015Fey",
|
|
657
|
+
// Sıkça birleşik yazılan ama ayrı yazılması gereken sözler
|
|
658
|
+
herg\u00FCn: "her g\xFCn",
|
|
659
|
+
hergun: "her g\xFCn",
|
|
660
|
+
herzaman: "her zaman",
|
|
661
|
+
heran: "her an",
|
|
662
|
+
heryer: "her yer",
|
|
663
|
+
herbiri: "her biri",
|
|
664
|
+
pek\u00E7ok: "pek \xE7ok",
|
|
665
|
+
pekcok: "pek \xE7ok",
|
|
666
|
+
pekaz: "pek az",
|
|
667
|
+
yada: "ya da",
|
|
668
|
+
tabiki: "tabii ki",
|
|
669
|
+
tabiiki: "tabii ki",
|
|
670
|
+
sa\u011Fol: "sa\u011F ol",
|
|
671
|
+
sagol: "sa\u011F ol",
|
|
672
|
+
sa\u011Folun: "sa\u011F olun",
|
|
673
|
+
sagolun: "sa\u011F olun",
|
|
674
|
+
ho\u015F\u00E7akal: "ho\u015F\xE7a kal",
|
|
675
|
+
hoscakal: "ho\u015F\xE7a kal",
|
|
676
|
+
ho\u015Fgeldin: "ho\u015F geldin",
|
|
677
|
+
hosgeldin: "ho\u015F geldin",
|
|
678
|
+
ho\u015Fgeldiniz: "ho\u015F geldiniz",
|
|
679
|
+
hosgeldiniz: "ho\u015F geldiniz",
|
|
680
|
+
ho\u015Fbulduk: "ho\u015F bulduk",
|
|
681
|
+
hosbulduk: "ho\u015F bulduk",
|
|
682
|
+
yan\u0131s\u0131ra: "yan\u0131 s\u0131ra",
|
|
683
|
+
yanisira: "yan\u0131 s\u0131ra",
|
|
684
|
+
pe\u015Fis\u0131ra: "pe\u015Fi s\u0131ra",
|
|
685
|
+
pesisira: "pe\u015Fi s\u0131ra",
|
|
686
|
+
ard\u0131s\u0131ra: "ard\u0131 s\u0131ra",
|
|
687
|
+
ardisira: "ard\u0131 s\u0131ra",
|
|
688
|
+
artarda: "art arda",
|
|
689
|
+
y\u00FCzy\u00FCze: "y\xFCz y\xFCze",
|
|
690
|
+
yuzyuze: "y\xFCz y\xFCze",
|
|
691
|
+
elele: "el ele",
|
|
692
|
+
g\u00F6zg\u00F6ze: "g\xF6z g\xF6ze",
|
|
693
|
+
ba\u015Fba\u015Fa: "ba\u015F ba\u015Fa",
|
|
694
|
+
basbasa: "ba\u015F ba\u015Fa",
|
|
695
|
+
yanyana: "yan yana",
|
|
696
|
+
i\u00E7i\u00E7e: "i\xE7 i\xE7e",
|
|
697
|
+
icice: "i\xE7 i\xE7e",
|
|
698
|
+
\u00FCst\u00FCste: "\xFCst \xFCste",
|
|
699
|
+
ustuste: "\xFCst \xFCste",
|
|
700
|
+
altalta: "alt alta",
|
|
701
|
+
\u00F6ns\u00F6z: "\xF6n s\xF6z",
|
|
702
|
+
onsoz: "\xF6n s\xF6z",
|
|
703
|
+
\u00F6nyarg\u0131: "\xF6n yarg\u0131",
|
|
704
|
+
onyargi: "\xF6n yarg\u0131",
|
|
705
|
+
farketmek: "fark etmek",
|
|
706
|
+
farketti: "fark etti",
|
|
707
|
+
farkettim: "fark ettim",
|
|
708
|
+
farkeder: "fark eder",
|
|
709
|
+
farketmez: "fark etmez",
|
|
710
|
+
terketmek: "terk etmek",
|
|
711
|
+
terketti: "terk etti",
|
|
712
|
+
ay\u0131rdetmek: "ay\u0131rt etmek",
|
|
713
|
+
ay\u0131rtetmek: "ay\u0131rt etmek",
|
|
714
|
+
arzetmek: "arz etmek",
|
|
715
|
+
arzederim: "arz ederim",
|
|
716
|
+
varolmak: "var olmak",
|
|
717
|
+
yokolmak: "yok olmak",
|
|
718
|
+
haketmek: "hak etmek",
|
|
719
|
+
haketti: "hak etti",
|
|
720
|
+
hakkaten: "hakikaten",
|
|
721
|
+
hi\u00E7kimse: "hi\xE7 kimse",
|
|
722
|
+
hickimse: "hi\xE7 kimse",
|
|
723
|
+
// Ünlü düşmesi yapılmaması gereken yer bildiren sözler (TDK Kural 15)
|
|
724
|
+
burda: "burada",
|
|
725
|
+
burdan: "buradan",
|
|
726
|
+
\u015Furda: "\u015Furada",
|
|
727
|
+
surda: "\u015Furada",
|
|
728
|
+
\u015Furdan: "\u015Furadan",
|
|
729
|
+
surdan: "\u015Furadan",
|
|
730
|
+
orda: "orada",
|
|
731
|
+
ordan: "oradan",
|
|
732
|
+
i\u00E7erde: "i\xE7eride",
|
|
733
|
+
icerde: "i\xE7eride",
|
|
734
|
+
i\u00E7erden: "i\xE7eriden",
|
|
735
|
+
icerden: "i\xE7eriden",
|
|
736
|
+
d\u0131\u015Farda: "d\u0131\u015Far\u0131da",
|
|
737
|
+
disarda: "d\u0131\u015Far\u0131da",
|
|
738
|
+
d\u0131\u015Fardan: "d\u0131\u015Far\u0131dan",
|
|
739
|
+
disardan: "d\u0131\u015Far\u0131dan",
|
|
740
|
+
yukarda: "yukar\u0131da",
|
|
741
|
+
yukardan: "yukar\u0131dan",
|
|
742
|
+
// Sıkça yanlış yazılan sözcükler
|
|
743
|
+
herkez: "herkes",
|
|
744
|
+
yanl\u0131z: "yaln\u0131z",
|
|
745
|
+
yaln\u0131\u015F: "yanl\u0131\u015F",
|
|
746
|
+
orjinal: "orijinal",
|
|
747
|
+
labaratuar: "laboratuvar",
|
|
748
|
+
laboratuar: "laboratuvar",
|
|
749
|
+
\u015F\u00F6f\u00F6r: "\u015Fof\xF6r",
|
|
750
|
+
sofor: "\u015Fof\xF6r",
|
|
751
|
+
egzos: "egzoz",
|
|
752
|
+
eksoz: "egzoz",
|
|
753
|
+
ekzoz: "egzoz",
|
|
754
|
+
kiprik: "kirpik",
|
|
755
|
+
kirbit: "kibrit",
|
|
756
|
+
klavuz: "k\u0131lavuz",
|
|
757
|
+
k\u0131ravat: "kravat",
|
|
758
|
+
s\u00FCpriz: "s\xFCrpriz",
|
|
759
|
+
supriz: "s\xFCrpriz",
|
|
760
|
+
raslant\u0131: "rastlant\u0131",
|
|
761
|
+
hastahane: "hastane",
|
|
762
|
+
pastahane: "pastane",
|
|
763
|
+
postahane: "postane",
|
|
764
|
+
eczahane: "eczane",
|
|
765
|
+
meyva: "meyve",
|
|
766
|
+
sarm\u0131sak: "sar\u0131msak",
|
|
767
|
+
dinazor: "dinozor",
|
|
768
|
+
pantalon: "pantolon",
|
|
769
|
+
tesbih: "tespih",
|
|
770
|
+
ah\u00E7\u0131: "a\u015F\xE7\u0131",
|
|
771
|
+
matba: "matbaa",
|
|
772
|
+
idda: "iddia",
|
|
773
|
+
iddaa: "iddia",
|
|
774
|
+
muhattap: "muhatap",
|
|
775
|
+
tra\u015F: "t\u0131ra\u015F",
|
|
776
|
+
karn\u0131bahar: "karnabahar",
|
|
777
|
+
kareografi: "koreografi",
|
|
778
|
+
poa\u00E7a: "po\u011Fa\xE7a",
|
|
779
|
+
poha\u00E7a: "po\u011Fa\xE7a",
|
|
780
|
+
\u015Farz: "\u015Farj",
|
|
781
|
+
sarj: "\u015Farj",
|
|
782
|
+
makina: "makine",
|
|
783
|
+
m\u00FCsade: "m\xFCsaade",
|
|
784
|
+
entellekt\u00FCel: "entelekt\xFCel",
|
|
785
|
+
inisiyatif: "inisiyatif",
|
|
786
|
+
insiyatif: "inisiyatif",
|
|
787
|
+
sezeryan: "sezaryen",
|
|
788
|
+
dok\u00FCman: "dok\xFCman",
|
|
789
|
+
d\u00F6k\u00FCman: "dok\xFCman",
|
|
790
|
+
erozyon: "erozyon",
|
|
791
|
+
erizyon: "erozyon",
|
|
792
|
+
anane: "anneanne",
|
|
793
|
+
babaanne: "babaanne"
|
|
794
|
+
};
|
|
795
|
+
var SEY_EXCEPTIONS = /* @__PURE__ */ new Set(["d\xFC\u015Fey", "e\u015Fey", "konsey", "jersey", "\u015Fey"]);
|
|
636
796
|
var TDK = class {
|
|
637
797
|
static BASE_URL = "https://sozluk.gov.tr";
|
|
638
798
|
static AUDIO_API_HOST = "api.sozluk.gov.tr";
|
|
@@ -1196,25 +1356,45 @@ yDFx8r7i9vIJU5HS3moZLkYWAOilMaV9N56A9Bgb6dNcHkvg3NoaYA==
|
|
|
1196
1356
|
* Checks spelling and returns suggestions if wrong.
|
|
1197
1357
|
*/
|
|
1198
1358
|
static async checkSpelling(word) {
|
|
1359
|
+
if (!word || word.trim() === "") {
|
|
1360
|
+
return { isCorrect: false, word };
|
|
1361
|
+
}
|
|
1362
|
+
const cleanWord = word.trim().toLocaleLowerCase("tr-TR");
|
|
1199
1363
|
const results = await this.getWord(word);
|
|
1200
1364
|
if (results.length > 0) {
|
|
1201
1365
|
return { isCorrect: true, word };
|
|
1202
1366
|
}
|
|
1367
|
+
if (COMMON_MISSPELLINGS[cleanWord]) {
|
|
1368
|
+
return { isCorrect: false, word, suggestion: COMMON_MISSPELLINGS[cleanWord] };
|
|
1369
|
+
}
|
|
1370
|
+
const seyMatch = cleanWord.match(/^(.+?)(?:şey|sey)([ıiuaeüodekmnl]+)?$/);
|
|
1371
|
+
if (seyMatch && !SEY_EXCEPTIONS.has(cleanWord)) {
|
|
1372
|
+
let prefix = seyMatch[1];
|
|
1373
|
+
const suffix = seyMatch[2] || "";
|
|
1374
|
+
if (prefix === "hicbir")
|
|
1375
|
+
prefix = "hi\xE7bir";
|
|
1376
|
+
if (prefix === "cok")
|
|
1377
|
+
prefix = "\xE7ok";
|
|
1378
|
+
return {
|
|
1379
|
+
isCorrect: false,
|
|
1380
|
+
word,
|
|
1381
|
+
suggestion: `${prefix} \u015Fey${suffix}`
|
|
1382
|
+
};
|
|
1383
|
+
}
|
|
1203
1384
|
const daily = await this.getDailyContent();
|
|
1204
1385
|
if (daily) {
|
|
1205
|
-
const syydMatch = daily.syyd.find((s) => s.yanliskelime.toLocaleLowerCase("tr-TR") ===
|
|
1386
|
+
const syydMatch = daily.syyd.find((s) => s.yanliskelime.toLocaleLowerCase("tr-TR") === cleanWord);
|
|
1206
1387
|
if (syydMatch) {
|
|
1207
1388
|
return { isCorrect: false, word, suggestion: syydMatch.dogrukelime };
|
|
1208
1389
|
}
|
|
1209
|
-
const mixMatch = daily.karistirma.find((s) => s.yanlis.toLocaleLowerCase("tr-TR") ===
|
|
1390
|
+
const mixMatch = daily.karistirma.find((s) => s.yanlis.toLocaleLowerCase("tr-TR") === cleanWord);
|
|
1210
1391
|
if (mixMatch) {
|
|
1211
1392
|
return { isCorrect: false, word, suggestion: mixMatch.dogru };
|
|
1212
1393
|
}
|
|
1213
1394
|
}
|
|
1214
1395
|
const root = await this.findRoot(word);
|
|
1215
1396
|
if (root) {
|
|
1216
|
-
const
|
|
1217
|
-
const isInflected = root !== cleanWord2;
|
|
1397
|
+
const isInflected = root !== cleanWord;
|
|
1218
1398
|
return {
|
|
1219
1399
|
isCorrect: true,
|
|
1220
1400
|
word,
|
|
@@ -1225,24 +1405,32 @@ yDFx8r7i9vIJU5HS3moZLkYWAOilMaV9N56A9Bgb6dNcHkvg3NoaYA==
|
|
|
1225
1405
|
if (this.autocompleteCache.length === 0) {
|
|
1226
1406
|
this.autocompleteCache = await this.fetchAutocompleteData();
|
|
1227
1407
|
}
|
|
1228
|
-
const
|
|
1408
|
+
for (const candidate of this.autocompleteCache) {
|
|
1409
|
+
if (candidate.includes(" ")) {
|
|
1410
|
+
const candidateNoSpace = candidate.replace(/\s+/g, "").toLocaleLowerCase("tr-TR");
|
|
1411
|
+
if (candidateNoSpace === cleanWord) {
|
|
1412
|
+
return { isCorrect: false, word, suggestion: candidate };
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1229
1416
|
let best = null;
|
|
1230
1417
|
for (const candidate of this.autocompleteCache) {
|
|
1231
1418
|
if (candidate.includes(" ") || candidate !== candidate.toLocaleLowerCase("tr-TR"))
|
|
1232
1419
|
continue;
|
|
1233
1420
|
if (Math.abs(candidate.length - cleanWord.length) > 2)
|
|
1234
1421
|
continue;
|
|
1235
|
-
const
|
|
1236
|
-
if (
|
|
1422
|
+
const rawDist = this.damerauLevenshtein(cleanWord, candidate);
|
|
1423
|
+
if (rawDist === 0)
|
|
1237
1424
|
continue;
|
|
1238
1425
|
const firstMismatch = candidate[0] === cleanWord[0] ? 0 : 1;
|
|
1239
1426
|
const lengthMismatch = candidate.length === cleanWord.length ? 0 : 1;
|
|
1427
|
+
const distance = rawDist + (firstMismatch > 0 ? 1.2 : 0);
|
|
1240
1428
|
const better = !best || distance < best.distance || distance === best.distance && firstMismatch < best.firstMismatch || distance === best.distance && firstMismatch === best.firstMismatch && lengthMismatch < best.lengthMismatch;
|
|
1241
1429
|
if (better) {
|
|
1242
|
-
best = { candidate, distance, firstMismatch, lengthMismatch };
|
|
1430
|
+
best = { candidate, distance, rawDist, firstMismatch, lengthMismatch };
|
|
1243
1431
|
}
|
|
1244
1432
|
}
|
|
1245
|
-
if (best && best.
|
|
1433
|
+
if (best && best.rawDist <= 2 && (best.firstMismatch === 0 || best.rawDist <= 1)) {
|
|
1246
1434
|
return { isCorrect: false, word, suggestion: best.candidate };
|
|
1247
1435
|
}
|
|
1248
1436
|
return { isCorrect: false, word };
|
|
@@ -1995,6 +2183,73 @@ yDFx8r7i9vIJU5HS3moZLkYWAOilMaV9N56A9Bgb6dNcHkvg3NoaYA==
|
|
|
1995
2183
|
"me\u011Ferki",
|
|
1996
2184
|
"illaki"
|
|
1997
2185
|
]);
|
|
2186
|
+
const PHRASE_MISTAKES = [
|
|
2187
|
+
{
|
|
2188
|
+
regex: /\bhiç\s+bir\b/gi,
|
|
2189
|
+
suggestion: "hi\xE7bir",
|
|
2190
|
+
message: "'hi\xE7bir' belgisiz s\u0131fat\u0131 biti\u015Fik yaz\u0131lmal\u0131d\u0131r.",
|
|
2191
|
+
type: "spelling"
|
|
2192
|
+
},
|
|
2193
|
+
{
|
|
2194
|
+
regex: /\bbir\s+çok\b/gi,
|
|
2195
|
+
suggestion: "bir\xE7ok",
|
|
2196
|
+
message: "'bir\xE7ok' belgisiz s\u0131fat\u0131/zamiri biti\u015Fik yaz\u0131lmal\u0131d\u0131r.",
|
|
2197
|
+
type: "spelling"
|
|
2198
|
+
},
|
|
2199
|
+
{
|
|
2200
|
+
regex: /\bbir\s+kaç\b/gi,
|
|
2201
|
+
suggestion: "birka\xE7",
|
|
2202
|
+
message: "'birka\xE7' belgisiz s\u0131fat\u0131/zamiri biti\u015Fik yaz\u0131lmal\u0131d\u0131r.",
|
|
2203
|
+
type: "spelling"
|
|
2204
|
+
},
|
|
2205
|
+
{
|
|
2206
|
+
regex: /\bbir\s+az\b/gi,
|
|
2207
|
+
suggestion: "biraz",
|
|
2208
|
+
message: "'biraz' s\xF6zc\xFC\u011F\xFC biti\u015Fik yaz\u0131lmal\u0131d\u0131r.",
|
|
2209
|
+
type: "spelling"
|
|
2210
|
+
},
|
|
2211
|
+
{
|
|
2212
|
+
regex: /\bher\s+hangi\b/gi,
|
|
2213
|
+
suggestion: "herhangi",
|
|
2214
|
+
message: "'herhangi' s\xF6zc\xFC\u011F\xFC biti\u015Fik yaz\u0131lmal\u0131d\u0131r.",
|
|
2215
|
+
type: "spelling"
|
|
2216
|
+
},
|
|
2217
|
+
{
|
|
2218
|
+
regex: /\bgit\s+gide\b/gi,
|
|
2219
|
+
suggestion: "gitgide",
|
|
2220
|
+
message: "'gitgide' zarf\u0131 biti\u015Fik yaz\u0131lmal\u0131d\u0131r.",
|
|
2221
|
+
type: "spelling"
|
|
2222
|
+
},
|
|
2223
|
+
{
|
|
2224
|
+
regex: /\bbirden\s+bire\b/gi,
|
|
2225
|
+
suggestion: "birdenbire",
|
|
2226
|
+
message: "'birdenbire' zarf\u0131 biti\u015Fik yaz\u0131lmal\u0131d\u0131r.",
|
|
2227
|
+
type: "spelling"
|
|
2228
|
+
},
|
|
2229
|
+
{
|
|
2230
|
+
regex: /\brast\s+gele\b/gi,
|
|
2231
|
+
suggestion: "rastgele",
|
|
2232
|
+
message: "'rastgele' zarf\u0131 biti\u015Fik yaz\u0131lmal\u0131d\u0131r.",
|
|
2233
|
+
type: "spelling"
|
|
2234
|
+
}
|
|
2235
|
+
];
|
|
2236
|
+
const coveredRanges = [];
|
|
2237
|
+
for (const pm of PHRASE_MISTAKES) {
|
|
2238
|
+
let pmMatch;
|
|
2239
|
+
while ((pmMatch = pm.regex.exec(text)) !== null) {
|
|
2240
|
+
const start = pmMatch.index;
|
|
2241
|
+
const end = start + pmMatch[0].length;
|
|
2242
|
+
coveredRanges.push({ start, end });
|
|
2243
|
+
issues.push({
|
|
2244
|
+
type: pm.type,
|
|
2245
|
+
word: pmMatch[0],
|
|
2246
|
+
startIndex: start,
|
|
2247
|
+
endIndex: end,
|
|
2248
|
+
suggestion: pm.suggestion,
|
|
2249
|
+
message: pm.message
|
|
2250
|
+
});
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
1998
2253
|
const tokenRegex = /[\p{L}0-9'’]+/gu;
|
|
1999
2254
|
let match;
|
|
2000
2255
|
while ((match = tokenRegex.exec(text)) !== null) {
|
|
@@ -2004,6 +2259,8 @@ yDFx8r7i9vIJU5HS3moZLkYWAOilMaV9N56A9Bgb6dNcHkvg3NoaYA==
|
|
|
2004
2259
|
const lower = rawWord.toLocaleLowerCase("tr-TR");
|
|
2005
2260
|
if (/^\d+$/.test(lower))
|
|
2006
2261
|
continue;
|
|
2262
|
+
if (coveredRanges.some((r) => startIndex >= r.start && endIndex <= r.end))
|
|
2263
|
+
continue;
|
|
2007
2264
|
let flagged = false;
|
|
2008
2265
|
const questionMatch = lower.match(/^(.+?)(m[ıiuü](?:sin|sın|sun|sün|siniz|sınız|sunuz|sünüz|yiz|yız|yuz|yüz|m|k)?)$/);
|
|
2009
2266
|
if (questionMatch) {
|
|
@@ -2029,7 +2286,7 @@ yDFx8r7i9vIJU5HS3moZLkYWAOilMaV9N56A9Bgb6dNcHkvg3NoaYA==
|
|
|
2029
2286
|
if (!SOMBAHCEMI.has(lower)) {
|
|
2030
2287
|
if (!await this.isHeadword(lower)) {
|
|
2031
2288
|
const root = await this.findRoot(base);
|
|
2032
|
-
const isVerb =
|
|
2289
|
+
const isVerb = (base === "demek" || base === "kald\u0131" || base === "yeter" || base === "bilmem" || VERB_CONJUGATION_REGEX.test(base)) && (root ? root.endsWith("mek") || root.endsWith("mak") : true);
|
|
2033
2290
|
if (isVerb) {
|
|
2034
2291
|
issues.push({
|
|
2035
2292
|
type: "conjunction_ki",
|
|
@@ -2049,7 +2306,7 @@ yDFx8r7i9vIJU5HS3moZLkYWAOilMaV9N56A9Bgb6dNcHkvg3NoaYA==
|
|
|
2049
2306
|
const ending = lower.slice(-2);
|
|
2050
2307
|
if (!await this.isHeadword(lower)) {
|
|
2051
2308
|
const root = await this.findRoot(base);
|
|
2052
|
-
const isVerb =
|
|
2309
|
+
const isVerb = VERB_CONJUGATION_REGEX.test(base) && (root ? root.endsWith("mek") || root.endsWith("mak") : false);
|
|
2053
2310
|
if (isVerb) {
|
|
2054
2311
|
const correctEnding = ending.startsWith("t") ? ending === "te" ? "de" : "da" : ending;
|
|
2055
2312
|
issues.push({
|
|
@@ -2064,6 +2321,47 @@ yDFx8r7i9vIJU5HS3moZLkYWAOilMaV9N56A9Bgb6dNcHkvg3NoaYA==
|
|
|
2064
2321
|
}
|
|
2065
2322
|
}
|
|
2066
2323
|
}
|
|
2324
|
+
const seyMatch = lower.match(/^(.+?)(?:şey|sey)([ıiuaeüodekmnl]+)?$/);
|
|
2325
|
+
if (!flagged && seyMatch && !SEY_EXCEPTIONS.has(lower)) {
|
|
2326
|
+
let prefix = seyMatch[1];
|
|
2327
|
+
const suffix = seyMatch[2] || "";
|
|
2328
|
+
if (prefix === "hicbir")
|
|
2329
|
+
prefix = "hi\xE7bir";
|
|
2330
|
+
if (prefix === "cok")
|
|
2331
|
+
prefix = "\xE7ok";
|
|
2332
|
+
issues.push({
|
|
2333
|
+
type: "spelling",
|
|
2334
|
+
word: rawWord,
|
|
2335
|
+
startIndex,
|
|
2336
|
+
endIndex,
|
|
2337
|
+
suggestion: `${prefix} \u015Fey${suffix}`,
|
|
2338
|
+
message: "'\u015Fey' s\xF6zc\xFC\u011F\xFC kendinden \xF6nceki kelimeden ayr\u0131 yaz\u0131lmal\u0131d\u0131r."
|
|
2339
|
+
});
|
|
2340
|
+
flagged = true;
|
|
2341
|
+
}
|
|
2342
|
+
if (!flagged && lower === "yada") {
|
|
2343
|
+
issues.push({
|
|
2344
|
+
type: "spelling",
|
|
2345
|
+
word: rawWord,
|
|
2346
|
+
startIndex,
|
|
2347
|
+
endIndex,
|
|
2348
|
+
suggestion: "ya da",
|
|
2349
|
+
message: "'ya da' ba\u011Flac\u0131 her zaman ayr\u0131 yaz\u0131l\u0131r."
|
|
2350
|
+
});
|
|
2351
|
+
flagged = true;
|
|
2352
|
+
}
|
|
2353
|
+
if (!flagged && (lower === "burda" || lower === "\u015Furda" || lower === "surda" || lower === "orda" || lower === "i\xE7erde" || lower === "icerde" || lower === "d\u0131\u015Farda" || lower === "disarda" || lower === "yukarda")) {
|
|
2354
|
+
const correct = COMMON_MISSPELLINGS[lower] || lower;
|
|
2355
|
+
issues.push({
|
|
2356
|
+
type: "spelling",
|
|
2357
|
+
word: rawWord,
|
|
2358
|
+
startIndex,
|
|
2359
|
+
endIndex,
|
|
2360
|
+
suggestion: correct,
|
|
2361
|
+
message: `'${rawWord}' s\xF6zc\xFC\u011F\xFCnde \xFCnl\xFC d\xFC\u015Fmesi yap\u0131lmaz.`
|
|
2362
|
+
});
|
|
2363
|
+
flagged = true;
|
|
2364
|
+
}
|
|
2067
2365
|
if (!flagged) {
|
|
2068
2366
|
const check = await this.checkSpelling(rawWord);
|
|
2069
2367
|
if (!check.isCorrect) {
|
|
@@ -2073,11 +2371,12 @@ yDFx8r7i9vIJU5HS3moZLkYWAOilMaV9N56A9Bgb6dNcHkvg3NoaYA==
|
|
|
2073
2371
|
startIndex,
|
|
2074
2372
|
endIndex,
|
|
2075
2373
|
suggestion: check.suggestion,
|
|
2076
|
-
message: check.suggestion ? `'${rawWord}' yanl\u0131\u015F yaz\u0131lm\u0131\u015F olabilir
|
|
2374
|
+
message: check.suggestion ? `'${rawWord}' yanl\u0131\u015F yaz\u0131lm\u0131\u015F olabilir.` : `'${rawWord}' s\xF6zl\xFCkte bulunamad\u0131.`
|
|
2077
2375
|
});
|
|
2078
2376
|
}
|
|
2079
2377
|
}
|
|
2080
2378
|
}
|
|
2379
|
+
issues.sort((a, b) => a.startIndex - b.startIndex);
|
|
2081
2380
|
return {
|
|
2082
2381
|
text,
|
|
2083
2382
|
issues,
|
package/dist/index.mjs
CHANGED
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -53,7 +53,7 @@ const KNOWN_COMMANDS = new Set([
|
|
|
53
53
|
let command = args[0];
|
|
54
54
|
let word = args.slice(1).join(" ");
|
|
55
55
|
|
|
56
|
-
if (command && !KNOWN_COMMANDS.has(command) && command !== "--help" && command !== "-h") {
|
|
56
|
+
if (command && !KNOWN_COMMANDS.has(command) && command !== "--help" && command !== "-h" && command !== "--version" && command !== "-v") {
|
|
57
57
|
word = args.join(" ");
|
|
58
58
|
command = "anlam";
|
|
59
59
|
}
|
|
@@ -153,6 +153,11 @@ async function run() {
|
|
|
153
153
|
process.exit(1);
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
if (command === "--version" || command === "-v") {
|
|
157
|
+
console.log("tdk-api-wrapper v1.5.1");
|
|
158
|
+
process.exit(0);
|
|
159
|
+
}
|
|
160
|
+
|
|
156
161
|
if (command === "--help" || command === "-h") {
|
|
157
162
|
console.log("Kullanım: tdk [komut] <kelime> [--json]");
|
|
158
163
|
console.log(
|
package/src/morphology.ts
CHANGED
|
@@ -230,6 +230,15 @@ export function getStemCandidates(
|
|
|
230
230
|
}
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
+
// Bare verb imperative candidates (e.g. "söyle" -> "söylemek", "oku" -> "okumak")
|
|
234
|
+
const bareInfinitives = restoreInfinitive(normalized);
|
|
235
|
+
for (const inf of bareInfinitives) {
|
|
236
|
+
if (!seen.has(inf) && inf !== normalized) {
|
|
237
|
+
seen.add(inf);
|
|
238
|
+
candidatesWithWeight.push({ candidate: inf, baseLength: normalized.length });
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
233
242
|
let frontier = [normalized];
|
|
234
243
|
|
|
235
244
|
for (let depth = 0; depth < maxDepth; depth++) {
|