@lunanoir/dep-lens 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dep-lens contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # dep-lens
2
+
3
+ Scan the licenses of your npm/yarn/pnpm and Cargo dependencies and report
4
+ commercial-use risk, in an interactive terminal UI or as JSON/HTML for CI.
5
+
6
+ ```sh
7
+ npm install -g dep-lens
8
+
9
+ dep-lens # interactive TUI
10
+ dep-lens --json # raw JSON to stdout
11
+ dep-lens --html report.html # standalone HTML report
12
+ dep-lens --fail-on gpl # exit 1 when strong copyleft is found (CI gate)
13
+ dep-lens --path ../my-app --ignore left-pad
14
+ ```
15
+
16
+ Full documentation: https://github.com/dep-lens/dep-lens
17
+
18
+ This package contains the CLI and TUI; the native scanner binary is delivered
19
+ through a platform-specific optional dependency (Linux x64, macOS x64/arm64,
20
+ Windows x64).
21
+
22
+ License: MIT
package/dist/args.js ADDED
@@ -0,0 +1,113 @@
1
+ export const USAGE = `dep-lens: scan dependencies for license risk
2
+
3
+ USAGE:
4
+ dep-lens [OPTIONS]
5
+
6
+ OPTIONS:
7
+ --json Print the raw JSON report to stdout (no TUI)
8
+ --html <FILE> Write an HTML report to FILE (no TUI)
9
+ --csv <FILE> Write a CSV report to FILE (no TUI)
10
+ --md <FILE> Write a Markdown report to FILE (no TUI)
11
+ --fail-on <KIND> Exit with code 1 when matching licenses are found.
12
+ KIND is "gpl" (any strong copyleft: GPL, AGPL) or
13
+ "agpl" (AGPL only). Intended for CI/CD pipelines.
14
+ --path <DIR> Project directory to scan (default: current directory)
15
+ --ignore <NAMES> Comma-separated package names to exclude (repeatable)
16
+ --tr Turkish UI (Turkce arayuz)
17
+ --help Show this help
18
+ --version Show version
19
+
20
+ KEYS (interactive TUI):
21
+ up/down Move selection (pgup/pgdn jump 10, g/G top/bottom)
22
+ enter Open package detail pane
23
+ f Filter by package name, license, or category
24
+ 1 / 2 / 3 / 4 Quick filter: Permissive / Weak / Strong / Unknown
25
+ 0 Clear all filters
26
+ s Cycle sort column
27
+ r Reverse sort direction
28
+ e Export menu (JSON / HTML)
29
+ h Help overlay
30
+ q Quit
31
+ `;
32
+ /**
33
+ * Parse CLI arguments. Throws an Error with a user-facing message on
34
+ * unknown flags, missing values, or invalid --fail-on kinds.
35
+ */
36
+ export function parseArgs(argv) {
37
+ const options = {
38
+ json: false,
39
+ html: null,
40
+ csv: null,
41
+ markdown: null,
42
+ failOn: null,
43
+ path: '.',
44
+ ignore: [],
45
+ locale: 'en',
46
+ help: false,
47
+ version: false,
48
+ };
49
+ for (let i = 0; i < argv.length; i += 1) {
50
+ const arg = argv[i];
51
+ switch (arg) {
52
+ case '--json':
53
+ options.json = true;
54
+ break;
55
+ case '--html':
56
+ options.html = requireValue(argv, i, '--html');
57
+ i += 1;
58
+ break;
59
+ case '--csv':
60
+ options.csv = requireValue(argv, i, '--csv');
61
+ i += 1;
62
+ break;
63
+ case '--md':
64
+ case '--markdown':
65
+ options.markdown = requireValue(argv, i, '--md');
66
+ i += 1;
67
+ break;
68
+ case '--fail-on': {
69
+ const value = requireValue(argv, i, '--fail-on');
70
+ i += 1;
71
+ if (value !== 'gpl' && value !== 'agpl') {
72
+ throw new Error(`--fail-on must be "gpl" or "agpl", got "${value}"`);
73
+ }
74
+ options.failOn = value;
75
+ break;
76
+ }
77
+ case '--path':
78
+ options.path = requireValue(argv, i, '--path');
79
+ i += 1;
80
+ break;
81
+ case '--ignore': {
82
+ const value = requireValue(argv, i, '--ignore');
83
+ i += 1;
84
+ options.ignore.push(...value
85
+ .split(',')
86
+ .map((name) => name.trim())
87
+ .filter((name) => name.length > 0));
88
+ break;
89
+ }
90
+ case '--tr':
91
+ options.locale = 'tr';
92
+ break;
93
+ case '--help':
94
+ case '-h':
95
+ options.help = true;
96
+ break;
97
+ case '--version':
98
+ case '-V':
99
+ options.version = true;
100
+ break;
101
+ default:
102
+ throw new Error(`unknown argument: ${String(arg)}`);
103
+ }
104
+ }
105
+ return options;
106
+ }
107
+ function requireValue(argv, index, flag) {
108
+ const value = argv[index + 1];
109
+ if (value === undefined || value.startsWith('--')) {
110
+ throw new Error(`${flag} requires a value`);
111
+ }
112
+ return value;
113
+ }
package/dist/bridge.js ADDED
@@ -0,0 +1,117 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { existsSync } from 'node:fs';
3
+ import { createRequire } from 'node:module';
4
+ import path from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { promisify } from 'node:util';
7
+ const execFileAsync = promisify(execFile);
8
+ const PLATFORM_PACKAGES = {
9
+ 'linux-x64': '@lunanoir/dep-lens-linux-x64',
10
+ 'darwin-arm64': '@lunanoir/dep-lens-darwin-arm64',
11
+ 'darwin-x64': '@lunanoir/dep-lens-darwin-x64',
12
+ 'win32-x64': '@lunanoir/dep-lens-win32-x64',
13
+ };
14
+ function binaryName() {
15
+ return process.platform === 'win32' ? 'dep-lens-core.exe' : 'dep-lens-core';
16
+ }
17
+ /**
18
+ * Locate the dep-lens-core binary. Resolution order:
19
+ * 1. DEP_LENS_BINARY environment variable (explicit override)
20
+ * 2. The platform-specific optional dependency (normal installs)
21
+ * 3. The Cargo target directory of this repository (development)
22
+ */
23
+ export function resolveBinaryPath() {
24
+ const override = process.env['DEP_LENS_BINARY'];
25
+ if (override !== undefined && override.length > 0) {
26
+ return override;
27
+ }
28
+ const platformKey = `${process.platform}-${process.arch}`;
29
+ const packageName = PLATFORM_PACKAGES[platformKey];
30
+ if (packageName !== undefined) {
31
+ try {
32
+ const require = createRequire(import.meta.url);
33
+ return require.resolve(`${packageName}/bin/${binaryName()}`);
34
+ }
35
+ catch {
36
+ // Platform package not installed; fall through to development paths.
37
+ }
38
+ }
39
+ const here = path.dirname(fileURLToPath(import.meta.url));
40
+ for (const profile of ['release', 'debug']) {
41
+ const candidate = path.resolve(here, '..', '..', '..', 'target', profile, binaryName());
42
+ if (existsSync(candidate)) {
43
+ return candidate;
44
+ }
45
+ }
46
+ throw new Error(`no native binary available for ${platformKey}. ` +
47
+ 'Reinstall dep-lens so the platform package is picked up, or set DEP_LENS_BINARY.');
48
+ }
49
+ function scanArgs(options) {
50
+ const args = ['--path', options.path];
51
+ for (const name of options.ignore) {
52
+ args.push('--ignore', name);
53
+ }
54
+ if (options.locale) {
55
+ args.push('--lang', options.locale);
56
+ }
57
+ return args;
58
+ }
59
+ async function runCore(args) {
60
+ const binary = resolveBinaryPath();
61
+ try {
62
+ const { stdout } = await execFileAsync(binary, [...args], {
63
+ maxBuffer: 64 * 1024 * 1024,
64
+ });
65
+ return stdout;
66
+ }
67
+ catch (error) {
68
+ const stderr = typeof error === 'object' && error !== null && 'stderr' in error
69
+ ? String(error.stderr).trim()
70
+ : '';
71
+ throw new Error(`core scanner failed${stderr.length > 0 ? `: ${stderr}` : ''}`);
72
+ }
73
+ }
74
+ /** Structural validation of the core binary's JSON output. */
75
+ export function validateReport(value) {
76
+ if (typeof value !== 'object' || value === null) {
77
+ throw new Error('core output is not a JSON object');
78
+ }
79
+ const record = value;
80
+ for (const field of ['project', 'scannedAt', 'path']) {
81
+ if (typeof record[field] !== 'string') {
82
+ throw new Error(`core output is missing string field "${field}"`);
83
+ }
84
+ }
85
+ const summary = record['summary'];
86
+ if (typeof summary !== 'object' || summary === null) {
87
+ throw new Error('core output is missing "summary"');
88
+ }
89
+ if (!Array.isArray(record['packages'])) {
90
+ throw new Error('core output is missing "packages" array');
91
+ }
92
+ return value;
93
+ }
94
+ /** Run a scan and return the parsed report. */
95
+ export async function runScan(options) {
96
+ const stdout = await runCore([...scanArgs(options), '--format', 'json']);
97
+ let parsed;
98
+ try {
99
+ parsed = JSON.parse(stdout);
100
+ }
101
+ catch {
102
+ throw new Error('core output is not valid JSON');
103
+ }
104
+ return validateReport(parsed);
105
+ }
106
+ /** Run a scan and return the standalone HTML report. */
107
+ export async function renderHtml(options) {
108
+ return runCore([...scanArgs(options), '--format', 'html']);
109
+ }
110
+ /** Run a scan and return the CSV report. */
111
+ export async function renderCsv(options) {
112
+ return runCore([...scanArgs(options), '--format', 'csv']);
113
+ }
114
+ /** Run a scan and return the Markdown report. */
115
+ export async function renderMarkdown(options) {
116
+ return runCore([...scanArgs(options), '--format', 'markdown']);
117
+ }
package/dist/cli.js ADDED
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env node
2
+ import { writeFile } from 'node:fs/promises';
3
+ import { createRequire } from 'node:module';
4
+ import React from 'react';
5
+ import { render } from 'ink';
6
+ import { parseArgs, USAGE } from './args.js';
7
+ import { renderCsv, renderHtml, renderMarkdown, runScan } from './bridge.js';
8
+ import { violations } from './utils.js';
9
+ import { Root } from './ui/Root.js';
10
+ function packageVersion() {
11
+ const require = createRequire(import.meta.url);
12
+ const manifest = require('../package.json');
13
+ return manifest.version;
14
+ }
15
+ function applyFailOn(report, options) {
16
+ if (options.failOn === null) {
17
+ return;
18
+ }
19
+ const offenders = violations(report, options.failOn);
20
+ if (offenders.length > 0) {
21
+ process.stderr.write(`dep-lens: --fail-on ${options.failOn} matched ${offenders.length} package(s):\n`);
22
+ for (const pkg of offenders) {
23
+ process.stderr.write(` ${pkg.name}@${pkg.version} (${pkg.license})\n`);
24
+ }
25
+ process.exitCode = 1;
26
+ }
27
+ }
28
+ async function main() {
29
+ let options;
30
+ try {
31
+ options = parseArgs(process.argv.slice(2));
32
+ }
33
+ catch (error) {
34
+ process.stderr.write(`dep-lens: ${error instanceof Error ? error.message : String(error)}\n`);
35
+ process.stderr.write('Run dep-lens --help for usage.\n');
36
+ process.exitCode = 2;
37
+ return;
38
+ }
39
+ if (options.help) {
40
+ process.stdout.write(USAGE);
41
+ return;
42
+ }
43
+ if (options.version) {
44
+ process.stdout.write(`dep-lens ${packageVersion()}\n`);
45
+ return;
46
+ }
47
+ const scanOptions = { path: options.path, ignore: options.ignore, locale: options.locale };
48
+ if (options.json) {
49
+ const report = await runScan(scanOptions);
50
+ process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
51
+ applyFailOn(report, options);
52
+ return;
53
+ }
54
+ if (options.html !== null) {
55
+ const report = await runScan(scanOptions);
56
+ const html = await renderHtml(scanOptions);
57
+ await writeFile(options.html, html);
58
+ process.stderr.write(`dep-lens: HTML report written to ${options.html}\n`);
59
+ applyFailOn(report, options);
60
+ return;
61
+ }
62
+ if (options.csv !== null) {
63
+ const report = await runScan(scanOptions);
64
+ const csv = await renderCsv(scanOptions);
65
+ await writeFile(options.csv, csv);
66
+ process.stderr.write(`dep-lens: CSV report written to ${options.csv}\n`);
67
+ applyFailOn(report, options);
68
+ return;
69
+ }
70
+ if (options.markdown !== null) {
71
+ const report = await runScan(scanOptions);
72
+ const md = await renderMarkdown(scanOptions);
73
+ await writeFile(options.markdown, md);
74
+ process.stderr.write(`dep-lens: Markdown report written to ${options.markdown}\n`);
75
+ applyFailOn(report, options);
76
+ return;
77
+ }
78
+ if (process.stdout.isTTY !== true) {
79
+ // Piped or redirected output: emit JSON instead of starting the TUI.
80
+ const report = await runScan(scanOptions);
81
+ process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
82
+ applyFailOn(report, options);
83
+ return;
84
+ }
85
+ // Interactive TUI: the scan runs inside the UI behind an animated
86
+ // progress screen; the report is captured for the --fail-on gate.
87
+ const captured = { report: null };
88
+ const app = render(React.createElement(Root, {
89
+ locale: options.locale,
90
+ version: packageVersion(),
91
+ scan: () => runScan(scanOptions),
92
+ getHtml: () => renderHtml(scanOptions),
93
+ onReport: (report) => {
94
+ captured.report = report;
95
+ },
96
+ onError: () => {
97
+ process.exitCode = 2;
98
+ },
99
+ }));
100
+ await app.waitUntilExit();
101
+ if (captured.report !== null) {
102
+ applyFailOn(captured.report, options);
103
+ }
104
+ }
105
+ main().catch((error) => {
106
+ process.stderr.write(`dep-lens: ${error instanceof Error ? error.message : String(error)}\n`);
107
+ process.exitCode = 2;
108
+ });
package/dist/i18n.js ADDED
@@ -0,0 +1,231 @@
1
+ /** Replace `{name}` placeholders in a catalog template. */
2
+ export function format(template, values) {
3
+ return template.replace(/\{(\w+)\}/g, (match, key) => key in values ? String(values[key]) : match);
4
+ }
5
+ export const EN = {
6
+ header: {
7
+ scanned: 'scanned',
8
+ packages: 'packages',
9
+ health: {
10
+ good: 'good',
11
+ ok: 'needs attention',
12
+ poor: 'at risk',
13
+ },
14
+ },
15
+ categories: {
16
+ Permissive: 'Permissive',
17
+ WeakCopyleft: 'Weak Copyleft',
18
+ StrongCopyleft: 'Strong Copyleft',
19
+ Unknown: 'Unknown',
20
+ },
21
+ summaryShort: {
22
+ Permissive: 'Permissive',
23
+ WeakCopyleft: 'Weak',
24
+ StrongCopyleft: 'Strong',
25
+ Unknown: 'Unknown',
26
+ },
27
+ riskLevels: {
28
+ low: 'low',
29
+ medium: 'medium',
30
+ high: 'high',
31
+ },
32
+ commercial: {
33
+ yes: 'yes',
34
+ caution: 'caution',
35
+ restricted: 'restricted',
36
+ review: 'review',
37
+ },
38
+ sources: {
39
+ declared: 'declared in manifest',
40
+ licenseFile: 'detected from LICENSE file',
41
+ none: 'not found',
42
+ },
43
+ types: {
44
+ direct: 'direct',
45
+ transitive: 'transitive',
46
+ },
47
+ advice: {
48
+ Permissive: 'Safe for commercial use. Keep the copyright notice.',
49
+ WeakCopyleft: 'Commercial use is fine; modifications to this library itself must stay open.',
50
+ StrongCopyleft: 'Copyleft terms can extend to derivative works. Legal review required.',
51
+ Unknown: 'License could not be identified. Review this package manually.',
52
+ },
53
+ table: {
54
+ package: 'PACKAGE',
55
+ version: 'VERSION',
56
+ license: 'LICENSE',
57
+ category: 'CATEGORY',
58
+ type: 'TYPE',
59
+ risk: 'RISK',
60
+ commercial: 'COMMERCIAL',
61
+ empty: 'No packages match the current filter.',
62
+ rows: 'rows {start}-{end} of {total}',
63
+ },
64
+ footer: 'arrows enter detail f filter 1-4 cat s sort e export h help q quit',
65
+ filtersLabel: 'filters: {list}',
66
+ filterText: 'text "{query}"',
67
+ filterCategory: 'category {category}',
68
+ filterBar: {
69
+ label: 'filter: ',
70
+ hint: ' (enter apply, esc clear)',
71
+ },
72
+ exportMenu: {
73
+ title: 'export (enter select, esc cancel)',
74
+ json: 'Export JSON (dep-lens-report.json)',
75
+ html: 'Export HTML (dep-lens-report.html)',
76
+ cancel: 'Cancel',
77
+ writing: 'writing {file} ...',
78
+ wrote: 'wrote {file}',
79
+ failed: 'export failed: {error}',
80
+ },
81
+ detail: {
82
+ hint: '(enter/esc close)',
83
+ ecosystem: 'ecosystem',
84
+ license: 'license',
85
+ category: 'category',
86
+ risk: 'risk',
87
+ commercial: 'commercial',
88
+ advice: 'advice',
89
+ riskValue: '{score}/100 ({level})',
90
+ },
91
+ help: {
92
+ title: 'keys (h or esc to close)',
93
+ bindings: [
94
+ ['up/down', 'move selection'],
95
+ ['pgup/pgdn', 'jump 10 rows'],
96
+ ['g / G', 'jump to top / bottom'],
97
+ ['enter', 'open package detail'],
98
+ ['f', 'free-text filter (name, license, category)'],
99
+ ['1 / 2 / 3 / 4', 'quick filter: Permissive / Weak / Strong / Unknown'],
100
+ ['0', 'clear all filters'],
101
+ ['s', 'cycle sort column'],
102
+ ['r', 'reverse sort direction'],
103
+ ['e', 'export menu (JSON / HTML)'],
104
+ ['h', 'toggle this help'],
105
+ ['q', 'quit'],
106
+ ],
107
+ },
108
+ scanning: {
109
+ title: 'scanning dependencies',
110
+ elapsed: '{seconds}s elapsed',
111
+ },
112
+ error: {
113
+ title: 'scan failed',
114
+ hint: 'press q to quit',
115
+ },
116
+ };
117
+ export const TR = {
118
+ header: {
119
+ scanned: 'tarandı',
120
+ packages: 'paket',
121
+ health: {
122
+ good: 'iyi',
123
+ ok: 'dikkat gerekli',
124
+ poor: 'riskli',
125
+ },
126
+ },
127
+ categories: {
128
+ Permissive: 'İzinli',
129
+ WeakCopyleft: 'Zayıf Copyleft',
130
+ StrongCopyleft: 'Güçlü Copyleft',
131
+ Unknown: 'Bilinmeyen',
132
+ },
133
+ summaryShort: {
134
+ Permissive: 'İzinli',
135
+ WeakCopyleft: 'Zayıf',
136
+ StrongCopyleft: 'Güçlü',
137
+ Unknown: 'Bilinmeyen',
138
+ },
139
+ riskLevels: {
140
+ low: 'düşük',
141
+ medium: 'orta',
142
+ high: 'yüksek',
143
+ },
144
+ commercial: {
145
+ yes: 'evet',
146
+ caution: 'dikkat',
147
+ restricted: 'kısıtlı',
148
+ review: 'incele',
149
+ },
150
+ sources: {
151
+ declared: 'manifestte bildirilmiş',
152
+ licenseFile: 'LICENSE dosyasından tespit edildi',
153
+ none: 'bulunamadı',
154
+ },
155
+ types: {
156
+ direct: 'doğrudan',
157
+ transitive: 'dolaylı',
158
+ },
159
+ advice: {
160
+ Permissive: 'Ticari kullanım için güvenli. Telif bildirimini koruyun.',
161
+ WeakCopyleft: 'Ticari kullanım uygundur; bu kütüphanede yapılan değişiklikler açık kalmalıdır.',
162
+ StrongCopyleft: 'Copyleft şartları türev çalışmalara yayılabilir. Hukuki inceleme gerekir.',
163
+ Unknown: 'Lisans tespit edilemedi. Bu paketi elle inceleyin.',
164
+ },
165
+ table: {
166
+ package: 'PAKET',
167
+ version: 'SÜRÜM',
168
+ license: 'LİSANS',
169
+ category: 'KATEGORİ',
170
+ type: 'TÜR',
171
+ risk: 'RİSK',
172
+ commercial: 'TİCARİ',
173
+ empty: 'Filtreyle eşleşen paket yok.',
174
+ rows: 'satır {start}-{end} / {total}',
175
+ },
176
+ footer: 'oklar enter detay f filtre 1-4 kategori s sırala e aktar h yardım q çıkış',
177
+ filtersLabel: 'filtreler: {list}',
178
+ filterText: 'metin "{query}"',
179
+ filterCategory: 'kategori {category}',
180
+ filterBar: {
181
+ label: 'filtre: ',
182
+ hint: ' (enter uygula, esc temizle)',
183
+ },
184
+ exportMenu: {
185
+ title: 'dışa aktar (enter seç, esc iptal)',
186
+ json: 'JSON aktar (dep-lens-report.json)',
187
+ html: 'HTML aktar (dep-lens-report.html)',
188
+ cancel: 'İptal',
189
+ writing: '{file} yazılıyor ...',
190
+ wrote: '{file} yazıldı',
191
+ failed: 'dışa aktarma başarısız: {error}',
192
+ },
193
+ detail: {
194
+ hint: '(enter/esc kapat)',
195
+ ecosystem: 'ekosistem',
196
+ license: 'lisans',
197
+ category: 'kategori',
198
+ risk: 'risk',
199
+ commercial: 'ticari',
200
+ advice: 'tavsiye',
201
+ riskValue: '{score}/100 ({level})',
202
+ },
203
+ help: {
204
+ title: 'tuşlar (kapatmak için h veya esc)',
205
+ bindings: [
206
+ ['yukarı/aşağı', 'seçimi taşı'],
207
+ ['pgup/pgdn', '10 satır atla'],
208
+ ['g / G', 'başa / sona git'],
209
+ ['enter', 'paket detayını aç'],
210
+ ['f', 'serbest metin filtresi (ad, lisans, kategori)'],
211
+ ['1 / 2 / 3 / 4', 'hızlı filtre: İzinli / Zayıf / Güçlü / Bilinmeyen'],
212
+ ['0', 'tüm filtreleri temizle'],
213
+ ['s', 'sıralama sütununu değiştir'],
214
+ ['r', 'sıralama yönünü ters çevir'],
215
+ ['e', 'dışa aktarma menüsü (JSON / HTML)'],
216
+ ['h', 'bu yardımı aç/kapat'],
217
+ ['q', 'çıkış'],
218
+ ],
219
+ },
220
+ scanning: {
221
+ title: 'bağımlılıklar taranıyor',
222
+ elapsed: '{seconds}sn geçti',
223
+ },
224
+ error: {
225
+ title: 'tarama başarısız',
226
+ hint: 'çıkmak için q',
227
+ },
228
+ };
229
+ export function getMessages(locale) {
230
+ return locale === 'tr' ? TR : EN;
231
+ }
package/dist/types.js ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * TypeScript mirror of the JSON contract emitted by the dep-lens-core binary.
3
+ * Field names and enum string values must stay in sync with
4
+ * crates/dep-lens-core/src/model.rs.
5
+ */
6
+ export {};