@vltpkg/run 0.0.0-8 → 1.0.0-rc.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/README.md CHANGED
@@ -1,7 +1,7 @@
1
- ![run](https://github.com/user-attachments/assets/7546e081-c35c-44ac-a4bc-05caf88b7a2b)
2
-
3
1
  # @vltpkg/run
4
2
 
3
+ ![run](https://github.com/user-attachments/assets/7546e081-c35c-44ac-a4bc-05caf88b7a2b)
4
+
5
5
  Run a script defined in a `package.json` file (eg, `vlt run` and
6
6
  lifecycle scripts), or an arbitrary command as if it was (eg,
7
7
  `vlt exec`).
@@ -62,3 +62,98 @@ const execResult = await exec({
62
62
  // other arguments all the same.
63
63
  })
64
64
  ```
65
+
66
+ ## Node-gyp Shimming
67
+
68
+ The `@vltpkg/run` package automatically provides node-gyp shimming for
69
+ commands that contain `node-gyp` references. This allows packages that
70
+ expect `node-gyp` to be available to work seamlessly with vlt's
71
+ package management system.
72
+
73
+ ### How it works
74
+
75
+ When executing commands that contain references to `node-gyp`, the
76
+ package will:
77
+
78
+ 1. Create a `node-gyp` shim file in the XDG runtime directory
79
+ (typically `~/.run/vlt/run/node-gyp` on Unix or
80
+ `%TEMP%\xdg.run\vlt\run\node-gyp.cmd` on Windows)
81
+ 2. Inject the shim directory into the command's `PATH` environment
82
+ variable
83
+ 3. The shim redirects all `node-gyp` calls to `vlx node-gyp@latest`
84
+
85
+ The shim is created once per session and cached in memory for
86
+ performance. It works for both simple commands like `node-gyp rebuild`
87
+ and complex commands with shell operators like
88
+ `echo "before" && node-gyp rebuild && echo "after"`.
89
+
90
+ ### Cross-platform support
91
+
92
+ The shimming system is fully cross-platform:
93
+
94
+ - **Unix/Linux/macOS**: Creates an executable shell script with
95
+ shebang (`#!/bin/sh`)
96
+ - **Windows**: Creates a batch file (`.cmd`) that forwards arguments
97
+
98
+ ### Examples
99
+
100
+ ```js
101
+ // These commands will automatically use the node-gyp shim:
102
+ await run({
103
+ cwd: '/path/to/pkg',
104
+ arg0: 'build', // where build script is: "node-gyp rebuild"
105
+ projectRoot: '/path/to/pkg',
106
+ })
107
+
108
+ await exec({
109
+ arg0: 'echo "before" && node-gyp rebuild && echo "after"',
110
+ cwd: '/path/to/pkg',
111
+ projectRoot: '/path/to/pkg',
112
+ 'script-shell': true,
113
+ })
114
+
115
+ await exec({
116
+ arg0: 'node-gyp',
117
+ args: ['configure', '--debug'],
118
+ cwd: '/path/to/pkg',
119
+ projectRoot: '/path/to/pkg',
120
+ })
121
+
122
+ // These commands will NOT use the shim:
123
+ await exec({
124
+ arg0: 'echo "hello"', // No node-gyp reference
125
+ cwd: '/path/to/pkg',
126
+ projectRoot: '/path/to/pkg',
127
+ })
128
+ ```
129
+
130
+ ### How to verify the shim
131
+
132
+ You can access the shim utilities to inspect or verify the setup:
133
+
134
+ ```js
135
+ import {
136
+ getNodeGypShim,
137
+ getNodeGypShimDir,
138
+ hasNodeGypReference,
139
+ } from '@vltpkg/run'
140
+
141
+ // Get the path to the shim file
142
+ const shimPath = await getNodeGypShim()
143
+ // e.g., '/home/user/.run/vlt/run/node-gyp'
144
+
145
+ // Get the directory containing the shim (for PATH injection)
146
+ const shimDir = await getNodeGypShimDir()
147
+ // e.g., '/home/user/.run/vlt/run'
148
+
149
+ // Check if a command contains node-gyp references
150
+ const needsShim = hasNodeGypReference('node-gyp rebuild')
151
+ // true
152
+ ```
153
+
154
+ ### Fallback behavior
155
+
156
+ If the shim cannot be created (e.g., due to filesystem permissions),
157
+ the error is silently caught and the command executes normally. This
158
+ ensures the command fails naturally if `node-gyp` is actually needed
159
+ but not available, providing clear error messages to the user.
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Get or create the node-gyp shim file path
3
+ * The shim redirects node-gyp calls to vlx node-gyp@latest
4
+ */
5
+ export declare function getNodeGypShim(): Promise<string>;
6
+ /**
7
+ * Get the directory containing the node-gyp shim
8
+ * This can be prepended to PATH to make the shim available
9
+ */
10
+ export declare function getNodeGypShimDir(): Promise<string>;
11
+ /**
12
+ * Check if a command contains node-gyp references
13
+ */
14
+ export declare function hasNodeGypReference(command: string): boolean;
15
+ //# sourceMappingURL=aliasRunner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aliasRunner.d.ts","sourceRoot":"","sources":["../../src/aliasRunner.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAsCtD;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,CAGzD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE5D"}
@@ -0,0 +1,57 @@
1
+ import { XDG } from '@vltpkg/xdg';
2
+ import { chmod, mkdir, stat, writeFile } from 'node:fs/promises';
3
+ import { dirname, join } from 'node:path';
4
+ const xdg = new XDG('vlt');
5
+ let shimPath;
6
+ /**
7
+ * Get or create the node-gyp shim file path
8
+ * The shim redirects node-gyp calls to vlx node-gyp@latest
9
+ */
10
+ export async function getNodeGypShim() {
11
+ if (shimPath)
12
+ return shimPath;
13
+ const runtimeDir = xdg.runtime('run');
14
+ const shimFile = join(runtimeDir, 'node-gyp');
15
+ // Check if shim already exists
16
+ try {
17
+ await stat(shimFile);
18
+ /* c8 ignore next 2 - hard to test */
19
+ shimPath = shimFile;
20
+ return shimPath;
21
+ }
22
+ catch {
23
+ // Shim doesn't exist, create it
24
+ }
25
+ // Create runtime directory if needed
26
+ await mkdir(runtimeDir, { recursive: true });
27
+ // Create shim that calls vlx
28
+ /* c8 ignore start - ignore platform-dependent coverage */
29
+ const shimContent = process.platform === 'win32' ?
30
+ `@echo off\nvlx node-gyp@latest %*\n`
31
+ : `#!/bin/sh\nexec vlx node-gyp@latest "$@"\n`;
32
+ /* c8 ignore stop */
33
+ await writeFile(shimFile, shimContent, 'utf8');
34
+ // Make executable on Unix systems
35
+ /* c8 ignore start - unix-only */
36
+ if (process.platform !== 'win32') {
37
+ await chmod(shimFile, 0o755);
38
+ }
39
+ /* c8 ignore stop */
40
+ shimPath = shimFile;
41
+ return shimPath;
42
+ }
43
+ /**
44
+ * Get the directory containing the node-gyp shim
45
+ * This can be prepended to PATH to make the shim available
46
+ */
47
+ export async function getNodeGypShimDir() {
48
+ const shim = await getNodeGypShim();
49
+ return dirname(shim);
50
+ }
51
+ /**
52
+ * Check if a command contains node-gyp references
53
+ */
54
+ export function hasNodeGypReference(command) {
55
+ return command.includes('node-gyp');
56
+ }
57
+ //# sourceMappingURL=aliasRunner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aliasRunner.js","sourceRoot":"","sources":["../../src/aliasRunner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AACjC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAChE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEzC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAA;AAC1B,IAAI,QAA4B,CAAA;AAEhC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAA;IAE7B,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAA;IAE7C,+BAA+B;IAC/B,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAA;QACpB,qCAAqC;QACrC,QAAQ,GAAG,QAAQ,CAAA;QACnB,OAAO,QAAQ,CAAA;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,gCAAgC;IAClC,CAAC;IAED,qCAAqC;IACrC,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAE5C,6BAA6B;IAC7B,0DAA0D;IAC1D,MAAM,WAAW,GACf,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;QAC5B,qCAAqC;QACvC,CAAC,CAAC,4CAA4C,CAAA;IAChD,oBAAoB;IAEpB,MAAM,SAAS,CAAC,QAAQ,EAAE,WAAW,EAAE,MAAM,CAAC,CAAA;IAE9C,kCAAkC;IAClC,iCAAiC;IACjC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;IAC9B,CAAC;IACD,oBAAoB;IAEpB,QAAQ,GAAG,QAAQ,CAAA;IACnB,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,IAAI,GAAG,MAAM,cAAc,EAAE,CAAA;IACnC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAA;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,OAAO,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;AACrC,CAAC","sourcesContent":["import { XDG } from '@vltpkg/xdg'\nimport { chmod, mkdir, stat, writeFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\n\nconst xdg = new XDG('vlt')\nlet shimPath: string | undefined\n\n/**\n * Get or create the node-gyp shim file path\n * The shim redirects node-gyp calls to vlx node-gyp@latest\n */\nexport async function getNodeGypShim(): Promise<string> {\n if (shimPath) return shimPath\n\n const runtimeDir = xdg.runtime('run')\n const shimFile = join(runtimeDir, 'node-gyp')\n\n // Check if shim already exists\n try {\n await stat(shimFile)\n /* c8 ignore next 2 - hard to test */\n shimPath = shimFile\n return shimPath\n } catch {\n // Shim doesn't exist, create it\n }\n\n // Create runtime directory if needed\n await mkdir(runtimeDir, { recursive: true })\n\n // Create shim that calls vlx\n /* c8 ignore start - ignore platform-dependent coverage */\n const shimContent =\n process.platform === 'win32' ?\n `@echo off\\nvlx node-gyp@latest %*\\n`\n : `#!/bin/sh\\nexec vlx node-gyp@latest \"$@\"\\n`\n /* c8 ignore stop */\n\n await writeFile(shimFile, shimContent, 'utf8')\n\n // Make executable on Unix systems\n /* c8 ignore start - unix-only */\n if (process.platform !== 'win32') {\n await chmod(shimFile, 0o755)\n }\n /* c8 ignore stop */\n\n shimPath = shimFile\n return shimPath\n}\n\n/**\n * Get the directory containing the node-gyp shim\n * This can be prepended to PATH to make the shim available\n */\nexport async function getNodeGypShimDir(): Promise<string> {\n const shim = await getNodeGypShim()\n return dirname(shim)\n}\n\n/**\n * Check if a command contains node-gyp references\n */\nexport function hasNodeGypReference(command: string): boolean {\n return command.includes('node-gyp')\n}\n"]}
@@ -25,6 +25,12 @@ export type SharedOptions = PromiseSpawnOptions & {
25
25
  * platform-specific shell will be used.
26
26
  */
27
27
  'script-shell'?: boolean | string;
28
+ /**
29
+ * If true, then `FORCE_COLOR=1` will be set in the environment so that
30
+ * scripts will typically have colored output enablled, even if the output
31
+ * is not a tty.
32
+ */
33
+ color?: boolean;
28
34
  };
29
35
  /**
30
36
  * Options for run() and runFG()
@@ -41,7 +47,7 @@ export type RunOptions = SharedOptions & {
41
47
  /**
42
48
  * Pass in a manifest to avoid having to read it at all
43
49
  */
44
- manifest?: Manifest;
50
+ manifest?: Pick<Manifest, 'scripts' | 'gypfile'>;
45
51
  /**
46
52
  * if the script is not defined in package.json#scripts, just ignore it and
47
53
  * treat as success. Otherwise, treat as an error. Default false.
@@ -121,4 +127,5 @@ export declare const runExec: (options: RunExecOptions) => Promise<RunResult | S
121
127
  * execFG()
122
128
  */
123
129
  export declare const runExecFG: (options: RunExecOptions) => Promise<RunFGResult | SpawnResultNoStdio>;
130
+ export { getNodeGypShim, getNodeGypShimDir, hasNodeGypReference, } from './aliasRunner.ts';
124
131
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAElD,OAAO,KAAK,EACV,mBAAmB,EACnB,kBAAkB,EAClB,uBAAuB,EACxB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAiD7C,yCAAyC;AACzC,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG;IAChD,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAA;IAEnB,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAA;IACX;;;;;;;;;OASG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;CAClC,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,aAAa,GAAG;IACvC,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAA;IACZ;;;;OAIG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;IAEzB;;OAEG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAA;IAEnB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IAEvB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG;IACxC,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG;IAC3C;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ;;;;OAIG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,GAAG,YAAmB,UAAU,KAAG,OAAO,CAAC,SAAS,CACrC,CAAA;AAE5B;;GAEG;AACH,eAAO,MAAM,KAAK,YACP,UAAU,KAClB,OAAO,CAAC,WAAW,CAAmC,CAAA;AAEzD,iCAAiC;AACjC,MAAM,MAAM,SAAS,GAAG,uBAAuB,GAAG;IAChD,GAAG,CAAC,EAAE,uBAAuB,CAAA;IAC7B,IAAI,CAAC,EAAE,uBAAuB,CAAA;CAC/B,CAAA;AAED,mCAAmC;AACnC,MAAM,MAAM,WAAW,GAAG,kBAAkB,GAAG;IAC7C,GAAG,CAAC,EAAE,kBAAkB,CAAA;IACxB,IAAI,CAAC,EAAE,kBAAkB,CAAA;CAC1B,CAAA;AAED,eAAO,MAAM,WAAW,MAAO,OAAO,KAAG,CAAC,IAAI,SAO/B,CAAA;AAEf;;;;GAIG;AACH,MAAM,MAAM,aAAa,CACvB,CAAC,SAAS,kBAAkB,GAAG,uBAAuB,IACpD,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,CAAC,CAAA;CAAE,CAAA;AAkH7B;;GAEG;AACH,eAAO,MAAM,IAAI,YACN,WAAW,KACnB,OAAO,CAAC,uBAAuB,CAyBjC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,YACR,WAAW,KACnB,OAAO,CAAC,kBAAkB,CAsC5B,CAAA;AAoBD;;GAEG;AACH,eAAO,MAAM,OAAO,YACT,cAAc,KACtB,OAAO,CAAC,SAAS,GAAG,uBAAuB,CACY,CAAA;AAE1D;;;GAGG;AACH,eAAO,MAAM,SAAS,YACX,cAAc,KACtB,OAAO,CAAC,WAAW,GAAG,kBAAkB,CACc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EACV,mBAAmB,EACnB,kBAAkB,EAClB,uBAAuB,EACxB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAiF7C,yCAAyC;AACzC,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG;IAChD,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAA;IAEnB,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAA;IACX;;;;;;;;;OASG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IAEjC;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,aAAa,GAAG;IACvC,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAA;IACZ;;;;OAIG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;IAEzB;;OAEG;IACH,QAAQ,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,GAAG,SAAS,CAAC,CAAA;IAEhD;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IAEvB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG;IACxC,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG;IAC3C;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ;;;;OAIG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,GAAG,YAAmB,UAAU,KAAG,OAAO,CAAC,SAAS,CACrC,CAAA;AAE5B;;GAEG;AACH,eAAO,MAAM,KAAK,YACP,UAAU,KAClB,OAAO,CAAC,WAAW,CAAmC,CAAA;AAEzD,iCAAiC;AACjC,MAAM,MAAM,SAAS,GAAG,uBAAuB,GAAG;IAChD,GAAG,CAAC,EAAE,uBAAuB,CAAA;IAC7B,IAAI,CAAC,EAAE,uBAAuB,CAAA;CAC/B,CAAA;AAED,mCAAmC;AACnC,MAAM,MAAM,WAAW,GAAG,kBAAkB,GAAG;IAC7C,GAAG,CAAC,EAAE,kBAAkB,CAAA;IACxB,IAAI,CAAC,EAAE,kBAAkB,CAAA;CAC1B,CAAA;AAED,eAAO,MAAM,WAAW,MAAO,OAAO,KAAG,CAAC,IAAI,SAO/B,CAAA;AAEf;;;;GAIG;AACH,MAAM,MAAM,aAAa,CACvB,CAAC,SAAS,kBAAkB,GAAG,uBAAuB,IACpD,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,CAAC,CAAA;CAAE,CAAA;AAsH7B;;GAEG;AACH,eAAO,MAAM,IAAI,YACN,WAAW,KACnB,OAAO,CAAC,uBAAuB,CAiCjC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,YACR,WAAW,KACnB,OAAO,CAAC,kBAAkB,CAgD5B,CAAA;AAoBD;;GAEG;AACH,eAAO,MAAM,OAAO,YACT,cAAc,KACtB,OAAO,CAAC,SAAS,GAAG,uBAAuB,CACY,CAAA;AAE1D;;;GAGG;AACH,eAAO,MAAM,SAAS,YACX,cAAc,KACtB,OAAO,CAAC,WAAW,GAAG,kBAAkB,CACc,CAAA;AAGzD,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,kBAAkB,CAAA"}
package/dist/esm/index.js CHANGED
@@ -4,8 +4,9 @@ import { promiseSpawn } from '@vltpkg/promise-spawn';
4
4
  import { foregroundChild } from 'foreground-child';
5
5
  import { proxySignals } from 'foreground-child/proxy-signals';
6
6
  import { statSync } from 'node:fs';
7
- import { delimiter, resolve } from 'node:path';
7
+ import { delimiter, resolve, sep } from 'node:path';
8
8
  import { walkUp } from 'walk-up-path';
9
+ import { getNodeGypShimDir, hasNodeGypReference, } from "./aliasRunner.js";
9
10
  /** map of which node_modules/.bin folders exist */
10
11
  const dotBins = new Map();
11
12
  /** Check if a directory exists, and cache result */
@@ -23,14 +24,26 @@ const dirExists = (p) => {
23
24
  return false;
24
25
  }
25
26
  };
27
+ const nmBin = `${sep}node_modules${sep}.bin`;
26
28
  /**
27
- * Add all exsting `node_modules/.bin` folders to the PATH that
29
+ * Add all existing `node_modules/.bin` folders to the PATH that
28
30
  * exist between the cwd and the projectRoot, so dependency bins
29
31
  * are found, with closer paths higher priority.
32
+ *
33
+ * If command contains node-gyp reference, also inject the shim directory
34
+ * as a fallback (after all existing PATH entries).
30
35
  */
31
- const addPaths = (projectRoot, cwd, env) => {
36
+ const addPaths = async (projectRoot, cwd, env, command) => {
32
37
  const { PATH = '' } = env;
38
+ const PATHsplit = PATH.split(delimiter);
33
39
  const paths = new Set();
40
+ // anything in the PATH that already has node_modules/.bin is a thing
41
+ // we put there, perhaps for the vlx exec cache usage
42
+ for (const p of PATHsplit) {
43
+ if (p.endsWith(nmBin)) {
44
+ paths.add(p);
45
+ }
46
+ }
34
47
  for (const p of walkUp(cwd)) {
35
48
  const dotBin = resolve(p, 'node_modules/.bin');
36
49
  if (dirExists(dotBin))
@@ -43,6 +56,18 @@ const addPaths = (projectRoot, cwd, env) => {
43
56
  if (p)
44
57
  paths.add(p);
45
58
  }
59
+ // If command has node-gyp, inject shim directory as fallback (last)
60
+ if (command && hasNodeGypReference(command)) {
61
+ try {
62
+ const shimDir = await getNodeGypShimDir();
63
+ paths.add(shimDir);
64
+ /* c8 ignore start */
65
+ }
66
+ catch {
67
+ // Ignore shim creation errors, command will fail naturally if node-gyp is needed
68
+ }
69
+ /* c8 ignore stop */
70
+ }
46
71
  env.PATH = [...paths].join(delimiter);
47
72
  return env;
48
73
  };
@@ -65,7 +90,7 @@ export const isRunResult = (v) => !!v &&
65
90
  * Internal implementation of run() and runFG(), since they're mostly identical
66
91
  */
67
92
  const runImpl = async (options, execImpl, empty) => {
68
- const { arg0, packageJson = new PackageJson(), ignoreMissing = false, manifest, ...execArgs } = options;
93
+ const { arg0, packageJson = new PackageJson(), ignoreMissing = false, manifest, 'script-shell': shell = true, ...execArgs } = options;
69
94
  const pjPath = resolve(options.cwd, 'package.json');
70
95
  // npm adds a `"install": "node-gyp rebuild"` if a binding.gyp
71
96
  // is present at the time of publish, EVEN IF it's not included
@@ -106,6 +131,7 @@ const runImpl = async (options, execImpl, empty) => {
106
131
  await execImpl({
107
132
  arg0: precommand,
108
133
  ...execArgs,
134
+ 'script-shell': shell,
109
135
  args: [],
110
136
  env: {
111
137
  ...execArgs.env,
@@ -121,6 +147,7 @@ const runImpl = async (options, execImpl, empty) => {
121
147
  const result = await execImpl({
122
148
  arg0: command,
123
149
  ...execArgs,
150
+ 'script-shell': shell,
124
151
  env: {
125
152
  ...execArgs.env,
126
153
  npm_package_json: pjPath,
@@ -138,6 +165,7 @@ const runImpl = async (options, execImpl, empty) => {
138
165
  const post = await execImpl({
139
166
  arg0: postcommand,
140
167
  ...execArgs,
168
+ 'script-shell': shell,
141
169
  args: [],
142
170
  env: {
143
171
  ...execArgs.env,
@@ -157,17 +185,18 @@ const runImpl = async (options, execImpl, empty) => {
157
185
  * Execute an arbitrary command in the background
158
186
  */
159
187
  export const exec = async (options) => {
160
- const { arg0, args = [], cwd, env = {}, projectRoot, 'script-shell': shell = true, ...spawnOptions } = options;
188
+ const { arg0, args = [], cwd, env = {}, projectRoot, 'script-shell': shell = false, color = false, signal, ...spawnOptions } = options;
161
189
  const p = promiseSpawn(arg0, args, {
162
190
  ...spawnOptions,
163
191
  shell,
164
192
  stdio: 'pipe',
165
193
  stdioString: true,
166
194
  cwd,
167
- env: addPaths(projectRoot, cwd, {
195
+ env: await addPaths(projectRoot, cwd, {
168
196
  ...process.env,
169
197
  ...env,
170
- }),
198
+ FORCE_COLOR: color ? '1' : '0',
199
+ }, arg0),
171
200
  windowsHide: true,
172
201
  });
173
202
  proxySignals(p.process);
@@ -177,16 +206,18 @@ export const exec = async (options) => {
177
206
  * Execute an arbitrary command in the foreground
178
207
  */
179
208
  export const execFG = async (options) => {
180
- const { arg0, args = [], cwd, projectRoot, env = {}, 'script-shell': shell = true, ...spawnOptions } = options;
209
+ const { arg0, args = [], cwd, projectRoot, env = {}, 'script-shell': shell = false, color = true, signal, ...spawnOptions } = options;
210
+ const processEnv = await addPaths(projectRoot, cwd, {
211
+ ...process.env,
212
+ ...env,
213
+ FORCE_COLOR: color ? '1' : '0',
214
+ }, arg0);
181
215
  return new Promise(res => {
182
216
  foregroundChild(arg0, args, {
183
217
  ...spawnOptions,
184
218
  shell,
185
219
  cwd,
186
- env: addPaths(projectRoot, cwd, {
187
- ...process.env,
188
- ...env,
189
- }),
220
+ env: processEnv,
190
221
  }, (status, signal) => {
191
222
  res({
192
223
  command: arg0,
@@ -222,4 +253,6 @@ export const runExec = async (options) => runExecImpl(options, run, exec);
222
253
  * execFG()
223
254
  */
224
255
  export const runExecFG = async (options) => runExecImpl(options, runFG, execFG);
256
+ // Export shim utilities
257
+ export { getNodeGypShim, getNodeGypShimDir, hasNodeGypReference, } from "./aliasRunner.js";
225
258
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { error } from '@vltpkg/error-cause'\nimport { PackageJson } from '@vltpkg/package-json'\nimport { promiseSpawn } from '@vltpkg/promise-spawn'\nimport type {\n PromiseSpawnOptions,\n SpawnResultNoStdio,\n SpawnResultStdioStrings,\n} from '@vltpkg/promise-spawn'\nimport type { Manifest } from '@vltpkg/types'\nimport { foregroundChild } from 'foreground-child'\nimport { proxySignals } from 'foreground-child/proxy-signals'\nimport { statSync } from 'node:fs'\nimport { delimiter, resolve } from 'node:path'\nimport { walkUp } from 'walk-up-path'\n\n/** map of which node_modules/.bin folders exist */\nconst dotBins = new Map<string, boolean>()\n\n/** Check if a directory exists, and cache result */\nconst dirExists = (p: string) => {\n const cached = dotBins.get(p)\n if (cached !== undefined) return cached\n try {\n const isDir = statSync(p).isDirectory()\n dotBins.set(p, isDir)\n return isDir\n } catch {\n dotBins.set(p, false)\n return false\n }\n}\n\n/**\n * Add all exsting `node_modules/.bin` folders to the PATH that\n * exist between the cwd and the projectRoot, so dependency bins\n * are found, with closer paths higher priority.\n */\nconst addPaths = (\n projectRoot: string,\n cwd: string,\n env: NodeJS.ProcessEnv,\n): NodeJS.ProcessEnv => {\n const { PATH = '' } = env\n const paths = new Set<string>()\n for (const p of walkUp(cwd)) {\n const dotBin = resolve(p, 'node_modules/.bin')\n if (dirExists(dotBin)) paths.add(dotBin)\n if (p === projectRoot) break\n }\n for (const p of PATH.split(delimiter)) {\n /* c8 ignore next - pretty rare to have an empty entry */\n if (p) paths.add(p)\n }\n env.PATH = [...paths].join(delimiter)\n return env\n}\n\n/** options shared by run() and exec() */\nexport type SharedOptions = PromiseSpawnOptions & {\n /** additional arguments to pass to the command */\n args?: string[]\n /** the root of the project, which we don't walk up past */\n projectRoot: string\n\n /** the directory where the package.json lives and the script runs */\n cwd: string\n /**\n * environment variables to set. `process.env` is always included,\n * to omit fields, set them explicitly to undefined.\n *\n * vlt will add some of its own, as well:\n * - npm_lifecycle_event: the event name\n * - npm_lifecycle_script: the command in package.json#scripts\n * - npm_package_json: path to the package.json file\n * - VLT_* envs for all vlt configuration values that are set\n */\n env?: NodeJS.ProcessEnv\n /**\n * the shell to run the script in. If not set, then the default\n * platform-specific shell will be used.\n */\n 'script-shell'?: boolean | string\n}\n\n/**\n * Options for run() and runFG()\n */\nexport type RunOptions = SharedOptions & {\n /** the name of the thing in package.json#scripts */\n arg0: string\n /**\n * pass in a @vltpkg/package-json.PackageJson instance, and\n * it'll be used for reading the package.json file. Optional,\n * may improve performance somewhat.\n */\n packageJson?: PackageJson\n\n /**\n * Pass in a manifest to avoid having to read it at all\n */\n manifest?: Manifest\n\n /**\n * if the script is not defined in package.json#scripts, just ignore it and\n * treat as success. Otherwise, treat as an error. Default false.\n */\n ignoreMissing?: boolean\n\n /**\n * skip the pre/post commands, just run the one specified.\n * This can be used to run JUST the specified script, without any\n * pre/post commands.\n */\n ignorePrePost?: boolean\n}\n\n/**\n * Options for exec() and execFG()\n */\nexport type ExecOptions = SharedOptions & {\n /** the command to execute */\n arg0: string\n}\n\n/**\n * Options for runExec() and runExecFG()\n */\nexport type RunExecOptions = SharedOptions & {\n /**\n * Either the command to be executed, or the event to be run\n */\n arg0: string\n /**\n * pass in a @vltpkg/package-json.PackageJson instance, and\n * it'll be used for reading the package.json file. Optional,\n * may improve performance somewhat.\n */\n packageJson?: PackageJson\n}\n\n/**\n * Run a package.json#scripts event in the background\n */\nexport const run = async (options: RunOptions): Promise<RunResult> =>\n runImpl(options, exec, '')\n\n/**\n * Run a package.json#scripts event in the foreground\n */\nexport const runFG = async (\n options: RunOptions,\n): Promise<RunFGResult> => runImpl(options, execFG, null)\n\n/** Return type of {@link run} */\nexport type RunResult = SpawnResultStdioStrings & {\n pre?: SpawnResultStdioStrings\n post?: SpawnResultStdioStrings\n}\n\n/** Return type of {@link runFG} */\nexport type RunFGResult = SpawnResultNoStdio & {\n pre?: SpawnResultNoStdio\n post?: SpawnResultNoStdio\n}\n\nexport const isRunResult = (v: unknown): v is RunResult =>\n !!v &&\n typeof v === 'object' &&\n !Array.isArray(v) &&\n 'stdout' in v &&\n 'stderr' in v &&\n 'status' in v &&\n 'signal' in v\n\n/**\n * Return type of {@link run} or {@link runFG}, as determined by their base\n * type\n * @internal\n */\nexport type RunImplResult<\n R extends SpawnResultNoStdio | SpawnResultStdioStrings,\n> = R & { pre?: R; post?: R }\n\n/**\n * Internal implementation of run() and runFG(), since they're mostly identical\n */\nconst runImpl = async <\n R extends SpawnResultNoStdio | SpawnResultStdioStrings,\n>(\n options: RunOptions,\n execImpl: (options: ExecOptions) => Promise<R>,\n empty: R['stdout'],\n): Promise<RunImplResult<R>> => {\n const {\n arg0,\n packageJson = new PackageJson(),\n ignoreMissing = false,\n manifest,\n ...execArgs\n } = options\n const pjPath = resolve(options.cwd, 'package.json')\n // npm adds a `\"install\": \"node-gyp rebuild\"` if a binding.gyp\n // is present at the time of publish, EVEN IF it's not included\n // in the package. So, we need to read the actual package.json\n // in those cases.\n const untrustworthy = !!(\n manifest?.gypfile &&\n arg0 === 'install' &&\n manifest.scripts?.install === 'node-gyp rebuild'\n )\n const pj =\n (untrustworthy ? undefined : manifest) ??\n packageJson.read(options.cwd)\n const { scripts } = pj\n const command = scripts?.[arg0]\n if (!command) {\n if (ignoreMissing) {\n return {\n command: '',\n /* c8 ignore next */\n args: execArgs.args ?? [],\n cwd: options.cwd,\n status: 0,\n signal: null,\n stdout: empty,\n stderr: empty,\n // `as` to workaround \"could be instantiated with arbitrary type\".\n // it's private and used in 2 places, we know that it isn't.\n } as R\n }\n throw error('Script not defined in package.json', {\n name: arg0,\n cwd: options.cwd,\n args: options.args,\n path: pjPath,\n manifest: pj,\n })\n }\n\n const precommand = !options.ignorePrePost && scripts[`pre${arg0}`]\n const pre =\n precommand ?\n await execImpl({\n arg0: precommand,\n ...execArgs,\n args: [],\n env: {\n ...execArgs.env,\n npm_package_json: pjPath,\n npm_lifecycle_event: `pre${arg0}`,\n npm_lifecycle_script: precommand,\n },\n })\n : undefined\n if (pre && (pre.status || pre.signal)) {\n return pre as RunImplResult<R>\n }\n const result: RunImplResult<R> = await execImpl({\n arg0: command,\n ...execArgs,\n env: {\n ...execArgs.env,\n npm_package_json: pjPath,\n npm_lifecycle_event: arg0,\n npm_lifecycle_script: command,\n },\n })\n result.pre = pre\n if (result.signal || result.status) {\n return result\n }\n\n const postcommand = !options.ignorePrePost && scripts[`post${arg0}`]\n if (!postcommand) return result\n\n const post = await execImpl({\n arg0: postcommand,\n ...execArgs,\n args: [],\n env: {\n ...execArgs.env,\n npm_package_json: pjPath,\n npm_lifecycle_event: `post${arg0}`,\n npm_lifecycle_script: postcommand,\n },\n })\n\n if (post.status || post.signal) {\n const { status, signal } = post\n return Object.assign(result, { post, status, signal })\n }\n result.post = post\n return result\n}\n\n/**\n * Execute an arbitrary command in the background\n */\nexport const exec = async (\n options: ExecOptions,\n): Promise<SpawnResultStdioStrings> => {\n const {\n arg0,\n args = [],\n cwd,\n env = {},\n projectRoot,\n 'script-shell': shell = true,\n ...spawnOptions\n } = options\n\n const p = promiseSpawn(arg0, args, {\n ...spawnOptions,\n shell,\n stdio: 'pipe',\n stdioString: true,\n cwd,\n env: addPaths(projectRoot, cwd, {\n ...process.env,\n ...env,\n }),\n windowsHide: true,\n })\n proxySignals(p.process)\n return await p\n}\n\n/**\n * Execute an arbitrary command in the foreground\n */\nexport const execFG = async (\n options: ExecOptions,\n): Promise<SpawnResultNoStdio> => {\n const {\n arg0,\n args = [],\n cwd,\n projectRoot,\n env = {},\n 'script-shell': shell = true,\n ...spawnOptions\n } = options\n\n return new Promise<SpawnResultNoStdio>(res => {\n foregroundChild(\n arg0,\n args,\n {\n ...spawnOptions,\n shell,\n cwd,\n env: addPaths(projectRoot, cwd, {\n ...process.env,\n ...env,\n }),\n },\n (status, signal) => {\n res({\n command: arg0,\n args,\n cwd,\n stdout: null,\n stderr: null,\n status,\n signal,\n })\n return false\n },\n )\n })\n}\n\nconst runExecImpl = async <\n R extends SpawnResultNoStdio | SpawnResultStdioStrings,\n>(\n options: RunExecOptions,\n runImpl: (options: RunOptions) => Promise<RunImplResult<R>>,\n execImpl: (options: ExecOptions) => Promise<R>,\n): Promise<R | RunImplResult<R>> => {\n const { arg0, packageJson = new PackageJson(), ...args } = options\n const pj = packageJson.read(options.cwd)\n const { scripts } = pj\n const command = scripts?.[arg0]\n if (command) {\n return runImpl({ ...args, packageJson, arg0 })\n } else {\n return execImpl({ ...args, arg0 })\n }\n}\n\n/**\n * If the arg0 is a defined package.json script, then run(), otherwise exec()\n */\nexport const runExec = async (\n options: RunExecOptions,\n): Promise<RunResult | SpawnResultStdioStrings> =>\n runExecImpl<SpawnResultStdioStrings>(options, run, exec)\n\n/**\n * If the arg0 is a defined package.json script, then runFG(), otherwise\n * execFG()\n */\nexport const runExecFG = async (\n options: RunExecOptions,\n): Promise<RunFGResult | SpawnResultNoStdio> =>\n runExecImpl<SpawnResultNoStdio>(options, runFG, execFG)\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { error } from '@vltpkg/error-cause'\nimport { PackageJson } from '@vltpkg/package-json'\nimport type {\n PromiseSpawnOptions,\n SpawnResultNoStdio,\n SpawnResultStdioStrings,\n} from '@vltpkg/promise-spawn'\nimport { promiseSpawn } from '@vltpkg/promise-spawn'\nimport type { Manifest } from '@vltpkg/types'\nimport { foregroundChild } from 'foreground-child'\nimport { proxySignals } from 'foreground-child/proxy-signals'\nimport { statSync } from 'node:fs'\nimport { delimiter, resolve, sep } from 'node:path'\nimport { walkUp } from 'walk-up-path'\nimport {\n getNodeGypShimDir,\n hasNodeGypReference,\n} from './aliasRunner.ts'\n\n/** map of which node_modules/.bin folders exist */\nconst dotBins = new Map<string, boolean>()\n\n/** Check if a directory exists, and cache result */\nconst dirExists = (p: string) => {\n const cached = dotBins.get(p)\n if (cached !== undefined) return cached\n try {\n const isDir = statSync(p).isDirectory()\n dotBins.set(p, isDir)\n return isDir\n } catch {\n dotBins.set(p, false)\n return false\n }\n}\n\nconst nmBin = `${sep}node_modules${sep}.bin`\n\n/**\n * Add all existing `node_modules/.bin` folders to the PATH that\n * exist between the cwd and the projectRoot, so dependency bins\n * are found, with closer paths higher priority.\n *\n * If command contains node-gyp reference, also inject the shim directory\n * as a fallback (after all existing PATH entries).\n */\nconst addPaths = async (\n projectRoot: string,\n cwd: string,\n env: NodeJS.ProcessEnv,\n command?: string,\n): Promise<NodeJS.ProcessEnv> => {\n const { PATH = '' } = env\n const PATHsplit = PATH.split(delimiter)\n const paths = new Set<string>()\n\n // anything in the PATH that already has node_modules/.bin is a thing\n // we put there, perhaps for the vlx exec cache usage\n for (const p of PATHsplit) {\n if (p.endsWith(nmBin)) {\n paths.add(p)\n }\n }\n for (const p of walkUp(cwd)) {\n const dotBin = resolve(p, 'node_modules/.bin')\n if (dirExists(dotBin)) paths.add(dotBin)\n if (p === projectRoot) break\n }\n for (const p of PATH.split(delimiter)) {\n /* c8 ignore next - pretty rare to have an empty entry */\n if (p) paths.add(p)\n }\n\n // If command has node-gyp, inject shim directory as fallback (last)\n if (command && hasNodeGypReference(command)) {\n try {\n const shimDir = await getNodeGypShimDir()\n paths.add(shimDir)\n /* c8 ignore start */\n } catch {\n // Ignore shim creation errors, command will fail naturally if node-gyp is needed\n }\n /* c8 ignore stop */\n }\n\n env.PATH = [...paths].join(delimiter)\n return env\n}\n\n/** options shared by run() and exec() */\nexport type SharedOptions = PromiseSpawnOptions & {\n /** additional arguments to pass to the command */\n args?: string[]\n /** the root of the project, which we don't walk up past */\n projectRoot: string\n\n /** the directory where the package.json lives and the script runs */\n cwd: string\n /**\n * environment variables to set. `process.env` is always included,\n * to omit fields, set them explicitly to undefined.\n *\n * vlt will add some of its own, as well:\n * - npm_lifecycle_event: the event name\n * - npm_lifecycle_script: the command in package.json#scripts\n * - npm_package_json: path to the package.json file\n * - VLT_* envs for all vlt configuration values that are set\n */\n env?: NodeJS.ProcessEnv\n /**\n * the shell to run the script in. If not set, then the default\n * platform-specific shell will be used.\n */\n 'script-shell'?: boolean | string\n\n /**\n * If true, then `FORCE_COLOR=1` will be set in the environment so that\n * scripts will typically have colored output enablled, even if the output\n * is not a tty.\n */\n color?: boolean\n}\n\n/**\n * Options for run() and runFG()\n */\nexport type RunOptions = SharedOptions & {\n /** the name of the thing in package.json#scripts */\n arg0: string\n /**\n * pass in a @vltpkg/package-json.PackageJson instance, and\n * it'll be used for reading the package.json file. Optional,\n * may improve performance somewhat.\n */\n packageJson?: PackageJson\n\n /**\n * Pass in a manifest to avoid having to read it at all\n */\n manifest?: Pick<Manifest, 'scripts' | 'gypfile'>\n\n /**\n * if the script is not defined in package.json#scripts, just ignore it and\n * treat as success. Otherwise, treat as an error. Default false.\n */\n ignoreMissing?: boolean\n\n /**\n * skip the pre/post commands, just run the one specified.\n * This can be used to run JUST the specified script, without any\n * pre/post commands.\n */\n ignorePrePost?: boolean\n}\n\n/**\n * Options for exec() and execFG()\n */\nexport type ExecOptions = SharedOptions & {\n /** the command to execute */\n arg0: string\n}\n\n/**\n * Options for runExec() and runExecFG()\n */\nexport type RunExecOptions = SharedOptions & {\n /**\n * Either the command to be executed, or the event to be run\n */\n arg0: string\n /**\n * pass in a @vltpkg/package-json.PackageJson instance, and\n * it'll be used for reading the package.json file. Optional,\n * may improve performance somewhat.\n */\n packageJson?: PackageJson\n}\n\n/**\n * Run a package.json#scripts event in the background\n */\nexport const run = async (options: RunOptions): Promise<RunResult> =>\n runImpl(options, exec, '')\n\n/**\n * Run a package.json#scripts event in the foreground\n */\nexport const runFG = async (\n options: RunOptions,\n): Promise<RunFGResult> => runImpl(options, execFG, null)\n\n/** Return type of {@link run} */\nexport type RunResult = SpawnResultStdioStrings & {\n pre?: SpawnResultStdioStrings\n post?: SpawnResultStdioStrings\n}\n\n/** Return type of {@link runFG} */\nexport type RunFGResult = SpawnResultNoStdio & {\n pre?: SpawnResultNoStdio\n post?: SpawnResultNoStdio\n}\n\nexport const isRunResult = (v: unknown): v is RunResult =>\n !!v &&\n typeof v === 'object' &&\n !Array.isArray(v) &&\n 'stdout' in v &&\n 'stderr' in v &&\n 'status' in v &&\n 'signal' in v\n\n/**\n * Return type of {@link run} or {@link runFG}, as determined by their base\n * type\n * @internal\n */\nexport type RunImplResult<\n R extends SpawnResultNoStdio | SpawnResultStdioStrings,\n> = R & { pre?: R; post?: R }\n\n/**\n * Internal implementation of run() and runFG(), since they're mostly identical\n */\nconst runImpl = async <\n R extends SpawnResultNoStdio | SpawnResultStdioStrings,\n>(\n options: RunOptions,\n execImpl: (options: ExecOptions) => Promise<R>,\n empty: R['stdout'],\n): Promise<RunImplResult<R>> => {\n const {\n arg0,\n packageJson = new PackageJson(),\n ignoreMissing = false,\n manifest,\n 'script-shell': shell = true,\n ...execArgs\n } = options\n const pjPath = resolve(options.cwd, 'package.json')\n // npm adds a `\"install\": \"node-gyp rebuild\"` if a binding.gyp\n // is present at the time of publish, EVEN IF it's not included\n // in the package. So, we need to read the actual package.json\n // in those cases.\n const untrustworthy = !!(\n manifest?.gypfile &&\n arg0 === 'install' &&\n manifest.scripts?.install === 'node-gyp rebuild'\n )\n const pj =\n (untrustworthy ? undefined : manifest) ??\n packageJson.read(options.cwd)\n const { scripts } = pj\n const command = scripts?.[arg0]\n if (!command) {\n if (ignoreMissing) {\n return {\n command: '',\n /* c8 ignore next */\n args: execArgs.args ?? [],\n cwd: options.cwd,\n status: 0,\n signal: null,\n stdout: empty,\n stderr: empty,\n // `as` to workaround \"could be instantiated with arbitrary type\".\n // it's private and used in 2 places, we know that it isn't.\n } as R\n }\n throw error('Script not defined in package.json', {\n name: arg0,\n cwd: options.cwd,\n args: options.args,\n path: pjPath,\n manifest: pj,\n })\n }\n\n const precommand = !options.ignorePrePost && scripts[`pre${arg0}`]\n const pre =\n precommand ?\n await execImpl({\n arg0: precommand,\n ...execArgs,\n 'script-shell': shell,\n args: [],\n env: {\n ...execArgs.env,\n npm_package_json: pjPath,\n npm_lifecycle_event: `pre${arg0}`,\n npm_lifecycle_script: precommand,\n },\n })\n : undefined\n if (pre && (pre.status || pre.signal)) {\n return pre as RunImplResult<R>\n }\n const result: RunImplResult<R> = await execImpl({\n arg0: command,\n ...execArgs,\n 'script-shell': shell,\n env: {\n ...execArgs.env,\n npm_package_json: pjPath,\n npm_lifecycle_event: arg0,\n npm_lifecycle_script: command,\n },\n })\n result.pre = pre\n if (result.signal || result.status) {\n return result\n }\n\n const postcommand = !options.ignorePrePost && scripts[`post${arg0}`]\n if (!postcommand) return result\n\n const post = await execImpl({\n arg0: postcommand,\n ...execArgs,\n 'script-shell': shell,\n args: [],\n env: {\n ...execArgs.env,\n npm_package_json: pjPath,\n npm_lifecycle_event: `post${arg0}`,\n npm_lifecycle_script: postcommand,\n },\n })\n\n if (post.status || post.signal) {\n const { status, signal } = post\n return Object.assign(result, { post, status, signal })\n }\n result.post = post\n return result\n}\n\n/**\n * Execute an arbitrary command in the background\n */\nexport const exec = async (\n options: ExecOptions,\n): Promise<SpawnResultStdioStrings> => {\n const {\n arg0,\n args = [],\n cwd,\n env = {},\n projectRoot,\n 'script-shell': shell = false,\n color = false,\n signal,\n ...spawnOptions\n } = options\n\n const p = promiseSpawn(arg0, args, {\n ...spawnOptions,\n shell,\n stdio: 'pipe',\n stdioString: true,\n cwd,\n env: await addPaths(\n projectRoot,\n cwd,\n {\n ...process.env,\n ...env,\n FORCE_COLOR: color ? '1' : '0',\n },\n arg0,\n ),\n windowsHide: true,\n })\n proxySignals(p.process)\n return await p\n}\n\n/**\n * Execute an arbitrary command in the foreground\n */\nexport const execFG = async (\n options: ExecOptions,\n): Promise<SpawnResultNoStdio> => {\n const {\n arg0,\n args = [],\n cwd,\n projectRoot,\n env = {},\n 'script-shell': shell = false,\n color = true,\n signal,\n ...spawnOptions\n } = options\n\n const processEnv = await addPaths(\n projectRoot,\n cwd,\n {\n ...process.env,\n ...env,\n FORCE_COLOR: color ? '1' : '0',\n },\n arg0,\n )\n\n return new Promise<SpawnResultNoStdio>(res => {\n foregroundChild(\n arg0,\n args,\n {\n ...spawnOptions,\n shell,\n cwd,\n env: processEnv,\n },\n (status, signal) => {\n res({\n command: arg0,\n args,\n cwd,\n stdout: null,\n stderr: null,\n status,\n signal,\n })\n return false\n },\n )\n })\n}\n\nconst runExecImpl = async <\n R extends SpawnResultNoStdio | SpawnResultStdioStrings,\n>(\n options: RunExecOptions,\n runImpl: (options: RunOptions) => Promise<RunImplResult<R>>,\n execImpl: (options: ExecOptions) => Promise<R>,\n): Promise<R | RunImplResult<R>> => {\n const { arg0, packageJson = new PackageJson(), ...args } = options\n const pj = packageJson.read(options.cwd)\n const { scripts } = pj\n const command = scripts?.[arg0]\n if (command) {\n return runImpl({ ...args, packageJson, arg0 })\n } else {\n return execImpl({ ...args, arg0 })\n }\n}\n\n/**\n * If the arg0 is a defined package.json script, then run(), otherwise exec()\n */\nexport const runExec = async (\n options: RunExecOptions,\n): Promise<RunResult | SpawnResultStdioStrings> =>\n runExecImpl<SpawnResultStdioStrings>(options, run, exec)\n\n/**\n * If the arg0 is a defined package.json script, then runFG(), otherwise\n * execFG()\n */\nexport const runExecFG = async (\n options: RunExecOptions,\n): Promise<RunFGResult | SpawnResultNoStdio> =>\n runExecImpl<SpawnResultNoStdio>(options, runFG, execFG)\n\n// Export shim utilities\nexport {\n getNodeGypShim,\n getNodeGypShimDir,\n hasNodeGypReference,\n} from './aliasRunner.ts'\n"]}
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@vltpkg/run",
3
3
  "description": "Run package.json scripts and execute commands",
4
- "version": "0.0.0-8",
4
+ "version": "1.0.0-rc.1",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/vltpkg/vltpkg.git",
8
8
  "directory": "src/run"
9
9
  },
10
+ "author": "vlt technology inc. <support@vlt.sh> (http://vlt.sh)",
10
11
  "tshy": {
11
12
  "selfLink": false,
12
13
  "liveDev": true,
@@ -19,24 +20,24 @@
19
20
  }
20
21
  },
21
22
  "dependencies": {
22
- "foreground-child": "^3.2.0",
23
+ "foreground-child": "^3.3.1",
23
24
  "walk-up-path": "^4.0.0",
24
- "@vltpkg/error-cause": "0.0.0-8",
25
- "@vltpkg/package-json": "0.0.0-8",
26
- "@vltpkg/promise-spawn": "0.0.0-8",
27
- "@vltpkg/types": "0.0.0-8"
25
+ "@vltpkg/error-cause": "1.0.0-rc.1",
26
+ "@vltpkg/types": "1.0.0-rc.1",
27
+ "@vltpkg/xdg": "1.0.0-rc.1",
28
+ "@vltpkg/promise-spawn": "1.0.0-rc.1",
29
+ "@vltpkg/package-json": "1.0.0-rc.1"
28
30
  },
29
31
  "devDependencies": {
30
- "@eslint/js": "^9.20.0",
31
- "@types/eslint__js": "^8.42.3",
32
- "@types/node": "^22.13.1",
33
- "eslint": "^9.20.0",
34
- "prettier": "^3.4.2",
32
+ "@eslint/js": "^9.34.0",
33
+ "@types/node": "^22.17.2",
34
+ "eslint": "^9.34.0",
35
+ "prettier": "^3.6.2",
35
36
  "tap": "^21.1.0",
36
37
  "tshy": "^3.0.2",
37
- "typedoc": "0.27.6",
38
+ "typedoc": "~0.27.9",
38
39
  "typescript": "5.7.3",
39
- "typescript-eslint": "^8.23.0"
40
+ "typescript-eslint": "^8.40.0"
40
41
  },
41
42
  "license": "BSD-2-Clause-Patent",
42
43
  "engines": {
@@ -68,6 +69,7 @@
68
69
  "snap": "tap",
69
70
  "test": "tap",
70
71
  "posttest": "tsc --noEmit",
72
+ "tshy": "tshy",
71
73
  "typecheck": "tsc --noEmit"
72
74
  }
73
75
  }