From c859be922395ea4d68ac192fac32cc3bd08684ec Mon Sep 17 00:00:00 2001 From: Hamed Mohamed Date: Sun, 1 Feb 2026 02:04:14 +0300 Subject: [PATCH 1/2] feat(i18n): add support for Arabic and Turkish languages --- .changeset/add-arabic-turkish-languages.md | 5 +++ workspaces/i18n/src/constants.ts | 2 +- workspaces/i18n/src/languages/arabic.ts | 44 ++++++++++++++++++++++ workspaces/i18n/src/languages/index.ts | 6 ++- workspaces/i18n/src/languages/turkish.ts | 44 ++++++++++++++++++++++ 5 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 .changeset/add-arabic-turkish-languages.md create mode 100644 workspaces/i18n/src/languages/arabic.ts create mode 100644 workspaces/i18n/src/languages/turkish.ts diff --git a/.changeset/add-arabic-turkish-languages.md b/.changeset/add-arabic-turkish-languages.md new file mode 100644 index 00000000..92fcfb14 --- /dev/null +++ b/.changeset/add-arabic-turkish-languages.md @@ -0,0 +1,5 @@ +--- +"@nodesecure/i18n": minor +--- + +feat: add support for Arabic and Turkish languages diff --git a/workspaces/i18n/src/constants.ts b/workspaces/i18n/src/constants.ts index 0bb82a73..32039d6a 100644 --- a/workspaces/i18n/src/constants.ts +++ b/workspaces/i18n/src/constants.ts @@ -2,7 +2,7 @@ import os from "node:os"; import path from "node:path"; -export type Languages = "french" | "english" | (string & {}); +export type Languages = "french" | "english" | "arabic" | "turkish" | (string & {}); export const CACHE_PATH = path.join(os.tmpdir(), "nsecure-cli"); export const CURRENT_LANG: Languages = "english"; diff --git a/workspaces/i18n/src/languages/arabic.ts b/workspaces/i18n/src/languages/arabic.ts new file mode 100644 index 00000000..27be22c7 --- /dev/null +++ b/workspaces/i18n/src/languages/arabic.ts @@ -0,0 +1,44 @@ +// Require Internal Dependencies +import { taggedString as tS } from "../utils.ts"; + +const lang = "ar"; + +const depWalker = { + dep_tree: "شجرة الاعتمادات", + fetch_and_walk_deps: "جاري جلب وفحص جميع الاعتمادات...", + fetch_on_registry: "في انتظار جلب الحزم من سجل npm...", + waiting_tarball: "في انتظار تحليل ملفات الحزم (tarballs)...", + fetch_metadata: "تم جلب البيانات الوصفية للحزمة:", + analyzed_tarball: "تم تحليل ملفات npm:", + success_fetch_deptree: tS`تم تصفح ${0} بنجاح خلال ${1}`, + success_tarball: tS`تم تحليل ${0} ملف حزمة بنجاح خلال ${1}`, + success_registry_metadata: "تم جلب البيانات الوصفية المطلوبة لجميع الحزم بنجاح!", + failed_rmdir: tS`فشل حذف الدليل ${0}!` +}; + +const warnings = { + disable_scarf: "هذا الاعتماد قد يقوم بجمع بيانات عنك، لتعطيله استخدم متغير البيئة: (SCARF_ANALYTICS)", + keylogging: "هذا الاعتماد يمكنه تسجيل مدخلاتك (Keylogging). قد يُستخدم في هجمات خبيثة." +}; + +const sast_warnings = { + parsing_error: "فشل تحليل كود JavaScript. التحويل إلى AST لم ينجح (meriyah). يرجى فتح issue.", + unsafe_import: "تعذر تتبع جملة استيراد (require / require.resolve).", + unsafe_regex: "تم اكتشاف تعبير نمطي غير آمن (ReDoS Attack).", + unsafe_stmt: "استخدام لجملة خطيرة: eval() أو Function(\"\").", + unsafe_assign: "تعيين قيمة لمتغير محمي: process أو require.", + encoded_literal: "تم اكتشاف نص مشفر (Hex, Unicode, Base64, etc).", + suspicious_file: "ملف مشبوه (يحتوي على أكثر من 10 نصوص مشفرة).", + short_identifiers: "المعرفات قصيرة جداً (أقل من 1.5). ملف مشبوه.", + suspicious_literal: "مجموع النقاط المشبوهة للنصوص (Literals) أكبر من 3.", + obfuscated_code: "احتمالية عالية أن الكود مموه (Obfuscated).", + weak_crypto: "خوارزمية تشفير ضعيفة (md5, sha1, ...).", + shady_link: "رابط بامتداد مشبوه داخل النص.", + zero_semver: "إصدار غير مستقر (0.x) - Semantic Versioning.", + empty_package: "الحزمة فارغة (تحتوي فقط على package.json).", + unsafe_command: "أمر child_process مشبوه: spawn() أو exec().", + serialize_environment: "محاولة تسريب متغيرات البيئة (process.env serialization).", + synchronous_io: "عمليات I/O متزامنة قد تبطئ التطبيق (Sync I/O)." +}; + +export const arabic = { lang, depWalker, warnings, sast_warnings }; diff --git a/workspaces/i18n/src/languages/index.ts b/workspaces/i18n/src/languages/index.ts index 590f1281..cbe2545e 100644 --- a/workspaces/i18n/src/languages/index.ts +++ b/workspaces/i18n/src/languages/index.ts @@ -1,7 +1,11 @@ import { english } from "./english.ts"; import { french } from "./french.ts"; +import { arabic } from "./arabic.ts"; +import { turkish } from "./turkish.ts"; export const languages: Record = { english, - french + french, + arabic, + turkish }; diff --git a/workspaces/i18n/src/languages/turkish.ts b/workspaces/i18n/src/languages/turkish.ts new file mode 100644 index 00000000..28beb6e7 --- /dev/null +++ b/workspaces/i18n/src/languages/turkish.ts @@ -0,0 +1,44 @@ +// Require Internal Dependencies +import { taggedString as tS } from "../utils.ts"; + +const lang = "tr"; + +const depWalker = { + dep_tree: "bağımlılık ağacı", + fetch_and_walk_deps: "Tüm bağımlılıklar getiriliyor ve taranıyor...", + fetch_on_registry: "Paketlerin npm kayıt defterinden (registry) getirilmesi bekleniyor...", + waiting_tarball: "Paket dosyalarının (tarball) analiz edilmesi bekleniyor...", + fetch_metadata: "Paket meta verileri getirildi:", + analyzed_tarball: "Analiz edilen npm paket dosyaları:", + success_fetch_deptree: tS`${0} başarıyla ${1} içinde tarandı`, + success_tarball: tS`${0} paket dosyası ${1} içinde başarıyla analiz edildi`, + success_registry_metadata: "Tüm paketler için gerekli meta veriler başarıyla getirildi!", + failed_rmdir: tS`${0} dizini silinemedi!` +}; + +const warnings = { + disable_scarf: "Bu bağımlılık izniniz olmadan veri toplayabilir, SCARF_ANALYTICS ortam değişkeni ile devre dışı bırakmayı düşünün.", + keylogging: "Bu bağımlılık klavye ve fare girişlerinizi alabilir. 'Keylogging' saldırıları/kötü amaçlı yazılımları için kullanılabilir." +}; + +const sast_warnings = { + parsing_error: "JavaScript kodu meriyah ile ayrıştırılırken bir hata oluştu. Bu, metinden AST'ye dönüşümün başarısız olduğu anlamına gelir. Böyle bir hatayla karşılaşırsanız, lütfen bir issue açın.", + unsafe_import: "Bir içe aktarma (require, require.resolve) ifadesi/deyimi takip edilemiyor.", + unsafe_regex: "Güvensiz bir RegEx (Düzenli İfade) tespit edildi ve ReDoS saldırısı için kullanılabilir.", + unsafe_stmt: "eval() veya Function(\"\") gibi tehlikeli ifadelerin kullanımı.", + unsafe_assign: "process veya require gibi korumalı bir global değişkene atama yapılması.", + encoded_literal: "Kodlanmış bir değişmez değer (literal) tespit edildi (onaltılık değer, unicode dizisi, base64 dizesi vb. olabilir).", + suspicious_file: "İçinde ondan fazla kodlanmış değişmez değer (literal) bulunan şüpheli dosya.", + short_identifiers: "Tanımlayıcıların ortalama uzunluğu 1.5'in altında. Sadece dosya 5'ten fazla tanımlayıcı içeriyorsa mümkündür.", + suspicious_literal: "Tüm değişmez değerlerin (literals) şüpheli puanlarının toplamı 3'ten büyük.", + obfuscated_code: "Kodun gizlenmiş/karartılmış (obfuscated) olma ihtimali çok yüksek...", + weak_crypto: "Kod muhtemelen zayıf bir şifreleme algoritması içeriyor (md5, sha1...)", + shady_link: "Bir değişmez değer (string), şüpheli uzantıya sahip bir alan adına (domain) URL içeriyor.", + zero_semver: "0.x ile başlayan anlamsal sürüm (kararsız proje veya ciddi sürümleme yapılmamış).", + empty_package: "Paket dosyası (tarball) sadece package.json dosyası içeriyor.", + unsafe_command: "spawn() veya exec() gibi şüpheli child_process komutlarının kullanımı.", + serialize_environment: "Kod process.env'yi serileştirmeye çalışıyor, bu da ortam değişkenlerinin sızmasına yol açabilir.", + synchronous_io: "Kod, olay döngüsünü (event loop) engelleyebilecek ve performansı düşürebilecek senkron G/Ç (I/O) işlemleri içeriyor." +}; + +export const turkish = { lang, depWalker, warnings, sast_warnings }; From 4a74a703d788748ac91ab3f5f7b8b1d3c6acc2d5 Mon Sep 17 00:00:00 2001 From: Hamed Mohamed Date: Sun, 1 Feb 2026 02:17:50 +0300 Subject: [PATCH 2/2] fix(test): update language count assertion to 4 --- workspaces/i18n/test/i18n.spec.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/workspaces/i18n/test/i18n.spec.ts b/workspaces/i18n/test/i18n.spec.ts index 1a1c68f2..cbe6df00 100644 --- a/workspaces/i18n/test/i18n.spec.ts +++ b/workspaces/i18n/test/i18n.spec.ts @@ -39,9 +39,11 @@ describe("getLocalLang/setLocalLang", () => { await i18n.setLocalLang("french"); const languages = await i18n.getLanguages(); - assert.strictEqual(languages.length, 2); + assert.strictEqual(languages.length, 4); assert.strictEqual(languages[0], "french"); - assert.strictEqual(languages[1], "english"); + assert.ok(languages.includes("english")); + assert.ok(languages.includes("arabic")); + assert.ok(languages.includes("turkish")); }); it("setLocalLang with force option returns language and updates LANG_UPDATED", async() => {