@lunanoir/dep-lens 0.1.1 → 0.1.3

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/args.js CHANGED
@@ -16,6 +16,8 @@ OPTIONS:
16
16
  --tr Turkish UI (Turkce arayuz)
17
17
  --test Run a self-check: verify the scanner binary and
18
18
  report which ecosystems it detects in --path
19
+ --setup Re-run the interactive setup wizard (language,
20
+ PATH check) even outside of npm install
19
21
  --help Show this help
20
22
  --version Show version
21
23
 
@@ -49,6 +51,7 @@ export function parseArgs(argv) {
49
51
  help: false,
50
52
  version: false,
51
53
  test: false,
54
+ setup: false,
52
55
  };
53
56
  for (let i = 0; i < argv.length; i += 1) {
54
57
  const arg = argv[i];
@@ -98,6 +101,9 @@ export function parseArgs(argv) {
98
101
  case '--test':
99
102
  options.test = true;
100
103
  break;
104
+ case '--setup':
105
+ options.setup = true;
106
+ break;
101
107
  case '--help':
102
108
  case '-h':
103
109
  options.help = true;
package/dist/cli.js CHANGED
@@ -7,6 +7,7 @@ import { parseArgs, USAGE } from './args.js';
7
7
  import { renderCsv, renderHtml, renderMarkdown, runScan } from './bridge.js';
8
8
  import { readConfig } from './config.js';
9
9
  import { runSelfTest } from './selftest.js';
10
+ import { runFirstRunSetup, runWizard } from './setup.js';
10
11
  import { violations } from './utils.js';
11
12
  import { Root } from './ui/Root.js';
12
13
  function packageVersion() {
@@ -46,6 +47,11 @@ async function main() {
46
47
  process.stdout.write(`dep-lens ${packageVersion()}\n`);
47
48
  return;
48
49
  }
50
+ if (options.setup) {
51
+ await runWizard(true);
52
+ return;
53
+ }
54
+ await runFirstRunSetup();
49
55
  if (!options.localeExplicit) {
50
56
  const config = await readConfig();
51
57
  if (config.locale !== undefined) {
package/dist/config.js CHANGED
@@ -22,6 +22,9 @@ export async function readConfig() {
22
22
  if (record['locale'] === 'en' || record['locale'] === 'tr') {
23
23
  config.locale = record['locale'];
24
24
  }
25
+ if (typeof record['setupDone'] === 'boolean') {
26
+ config.setupDone = record['setupDone'];
27
+ }
25
28
  return config;
26
29
  }
27
30
  catch {
@@ -1,13 +1,12 @@
1
- #!/usr/bin/env node
2
1
  /**
3
- * Postinstall setup wizard. Runs once after `npm install`, detects the
4
- * caller's project ecosystems, asks for a default UI language, and checks
5
- * whether the global npm bin directory (where the `dep-lens` launcher
6
- * lands) is on PATH.
2
+ * Interactive setup wizard. Detects the project's ecosystems, asks for a
3
+ * default UI language, and checks whether the global npm bin directory
4
+ * (where the `dep-lens` launcher lands) is on PATH.
7
5
  *
8
- * Skips entirely in non-interactive environments (CI, piped installs, or
9
- * when npm doesn't attach a TTY to lifecycle scripts) so it never blocks an
10
- * install.
6
+ * Runs automatically the first time `dep-lens` is invoked (not as an npm
7
+ * `postinstall` script - npm 11's install-script policy and the lack of a
8
+ * TTY on lifecycle scripts make that unreliable), and any time via
9
+ * `dep-lens --setup`.
11
10
  */
12
11
  import { execFile } from 'node:child_process';
13
12
  import { createInterface } from 'node:readline';
@@ -69,18 +68,20 @@ function pathContains(dir) {
69
68
  const sep = process.platform === 'win32' ? ';' : ':';
70
69
  return pathEnv.split(sep).some((entry) => entry.replace(/[/\\]+$/, '') === dir.replace(/[/\\]+$/, ''));
71
70
  }
72
- async function main() {
73
- // Always print a one-line banner so even non-interactive installs show
74
- // something useful, but never prompt unless we have a real TTY.
75
- const cwd = process.env['INIT_CWD'] ?? process.cwd();
71
+ /**
72
+ * Run the setup wizard. `force` skips the TTY/CI checks (used by
73
+ * `dep-lens --setup`, where the user explicitly asked for it).
74
+ */
75
+ export async function runWizard(force = false) {
76
+ const cwd = process.cwd();
76
77
  const detected = detectEcosystems(cwd);
77
- process.stdout.write(`\n${bold(brand('dep-lens'))} installed.\n`);
78
+ process.stdout.write(`\n${bold(brand('dep-lens'))} setup\n`);
78
79
  if (detected.length > 0) {
79
80
  const labels = detected.map((eco) => eco.label).join(', ');
80
81
  process.stdout.write(`${dim('detected in this project:')} ${good(labels)}\n`);
81
82
  }
82
- if (!isInteractive()) {
83
- process.stdout.write(`${dim('run')} dep-lens ${dim('to scan, or')} dep-lens --help\n\n`);
83
+ if (!force && !isInteractive()) {
84
+ process.stdout.write(`${dim('run')} dep-lens --setup ${dim('for language and PATH setup.')}\n\n`);
84
85
  return;
85
86
  }
86
87
  process.stdout.write(`\n${bold('Quick setup')} ${dim('(press enter to accept defaults)')}\n`);
@@ -126,13 +127,29 @@ async function appendToShellProfile(binDir) {
126
127
  process.stdout.write(`${dim('already present in')} ${rcFile}\n`);
127
128
  return;
128
129
  }
129
- await appendFile(rcFile, `\n# added by dep-lens postinstall\n${line}\n`);
130
+ await appendFile(rcFile, `\n# added by dep-lens setup\n${line}\n`);
130
131
  process.stdout.write(`${good('added to')} ${rcFile}${dim(' - open a new terminal to apply.')}\n`);
131
132
  }
132
133
  catch {
133
134
  process.stdout.write(`${dim('could not update shell profile, add manually:')} ${line}\n`);
134
135
  }
135
136
  }
136
- main().catch(() => {
137
- // Never fail the install over the setup wizard.
138
- });
137
+ /**
138
+ * Run the wizard once, the first time `dep-lens` is ever invoked. No-op on
139
+ * every later run (tracked via `setupDone` in the user config).
140
+ */
141
+ export async function runFirstRunSetup() {
142
+ // Avoid writing wizard banners into piped/redirected output (e.g.
143
+ // `dep-lens --json | jq`), where stdout isn't a terminal at all.
144
+ if (process.stdout.isTTY !== true) {
145
+ return;
146
+ }
147
+ const config = await readConfig();
148
+ if (config.setupDone === true) {
149
+ return;
150
+ }
151
+ await runWizard(false);
152
+ const finalConfig = await readConfig();
153
+ finalConfig.setupDone = true;
154
+ await writeConfig(finalConfig);
155
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunanoir/dep-lens",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Dependency license scanner across npm, Cargo, Go, Python, Ruby, PHP, Java, Dart, and C/C++ with commercial risk reporting",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -32,8 +32,7 @@
32
32
  ],
33
33
  "scripts": {
34
34
  "build": "tsc",
35
- "test": "tsc && node --test \"dist/test/**/*.test.js\"",
36
- "postinstall": "node dist/postinstall.js"
35
+ "test": "tsc && node --test \"dist/test/**/*.test.js\""
37
36
  },
38
37
  "dependencies": {
39
38
  "ink": "^5.2.1",