@lunanoir/dep-lens 0.1.2 → 1.0.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/cli.js CHANGED
@@ -6,8 +6,8 @@ import { render } from 'ink';
6
6
  import { parseArgs, USAGE } from './args.js';
7
7
  import { renderCsv, renderHtml, renderMarkdown, runScan } from './bridge.js';
8
8
  import { readConfig } from './config.js';
9
- import { main as runSetupWizard } from './postinstall.js';
10
9
  import { runSelfTest } from './selftest.js';
10
+ import { runFirstRunSetup, runWizard } from './setup.js';
11
11
  import { violations } from './utils.js';
12
12
  import { Root } from './ui/Root.js';
13
13
  function packageVersion() {
@@ -47,16 +47,17 @@ async function main() {
47
47
  process.stdout.write(`dep-lens ${packageVersion()}\n`);
48
48
  return;
49
49
  }
50
+ if (options.setup) {
51
+ await runWizard(true);
52
+ return;
53
+ }
54
+ await runFirstRunSetup();
50
55
  if (!options.localeExplicit) {
51
56
  const config = await readConfig();
52
57
  if (config.locale !== undefined) {
53
58
  options.locale = config.locale;
54
59
  }
55
60
  }
56
- if (options.setup) {
57
- await runSetupWizard(true);
58
- return;
59
- }
60
61
  const scanOptions = { path: options.path, ignore: options.ignore, locale: options.locale };
61
62
  if (options.test) {
62
63
  process.exitCode = await runSelfTest(scanOptions);
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';
@@ -73,18 +72,16 @@ function pathContains(dir) {
73
72
  * Run the setup wizard. `force` skips the TTY/CI checks (used by
74
73
  * `dep-lens --setup`, where the user explicitly asked for it).
75
74
  */
76
- export async function main(force = false) {
77
- // Always print a one-line banner so even non-interactive installs show
78
- // something useful, but never prompt unless we have a real TTY.
79
- const cwd = process.env['INIT_CWD'] ?? process.cwd();
75
+ export async function runWizard(force = false) {
76
+ const cwd = process.cwd();
80
77
  const detected = detectEcosystems(cwd);
81
- process.stdout.write(`\n${bold(brand('dep-lens'))} installed.\n`);
78
+ process.stdout.write(`\n${bold(brand('dep-lens'))} setup\n`);
82
79
  if (detected.length > 0) {
83
80
  const labels = detected.map((eco) => eco.label).join(', ');
84
81
  process.stdout.write(`${dim('detected in this project:')} ${good(labels)}\n`);
85
82
  }
86
83
  if (!force && !isInteractive()) {
87
- process.stdout.write(`${dim('run')} dep-lens ${dim('to scan, or')} dep-lens --help\n\n`);
84
+ process.stdout.write(`${dim('run')} dep-lens --setup ${dim('for language and PATH setup.')}\n\n`);
88
85
  return;
89
86
  }
90
87
  process.stdout.write(`\n${bold('Quick setup')} ${dim('(press enter to accept defaults)')}\n`);
@@ -130,17 +127,29 @@ async function appendToShellProfile(binDir) {
130
127
  process.stdout.write(`${dim('already present in')} ${rcFile}\n`);
131
128
  return;
132
129
  }
133
- 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`);
134
131
  process.stdout.write(`${good('added to')} ${rcFile}${dim(' - open a new terminal to apply.')}\n`);
135
132
  }
136
133
  catch {
137
134
  process.stdout.write(`${dim('could not update shell profile, add manually:')} ${line}\n`);
138
135
  }
139
136
  }
140
- // Only auto-run when invoked directly as the postinstall script, not when
141
- // imported by `dep-lens --setup`.
142
- if (process.argv[1]?.endsWith('postinstall.js')) {
143
- main().catch(() => {
144
- // Never fail the install over the setup wizard.
145
- });
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);
146
155
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunanoir/dep-lens",
3
- "version": "0.1.2",
3
+ "version": "1.0.0",
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,18 +32,17 @@
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",
40
39
  "react": "^18.3.1"
41
40
  },
42
41
  "optionalDependencies": {
43
- "@lunanoir/dep-lens-darwin-arm64": "0.1.0",
44
- "@lunanoir/dep-lens-darwin-x64": "0.1.0",
45
- "@lunanoir/dep-lens-linux-x64": "0.1.1",
46
- "@lunanoir/dep-lens-win32-x64": "0.1.0"
42
+ "@lunanoir/dep-lens-darwin-arm64": "1.0.0",
43
+ "@lunanoir/dep-lens-darwin-x64": "1.0.0",
44
+ "@lunanoir/dep-lens-linux-x64": "1.0.0",
45
+ "@lunanoir/dep-lens-win32-x64": "1.0.0"
47
46
  },
48
47
  "devDependencies": {
49
48
  "@types/node": "^20.14.0",