Skip to content

Commit fb436fa

Browse files
authored
feat: add custom npm registry when installing dependencies (google#994)
1 parent 7c08fe0 commit fb436fa

File tree

4 files changed

+51
-12
lines changed

4 files changed

+51
-12
lines changed

man/zx.1

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ evaluate script
2525
default extension
2626
.SS --install, -i
2727
install dependencies
28+
.SS --registry<URL>
29+
npm registry, defaults to https://registry.npmjs.org/
2830
.SS --repl
2931
start repl
3032
.SS --version, -v

src/cli.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export function printUsage() {
6060
--eval=<js>, -e evaluate script
6161
--ext=<.mjs> default extension
6262
--install, -i install dependencies
63+
--registry=<URL> npm registry, defaults to https://registry.npmjs.org/
6364
--version, -v print current zx version
6465
--help, -h print help
6566
--repl start repl
@@ -70,7 +71,7 @@ export function printUsage() {
7071
}
7172

7273
export const argv: minimist.ParsedArgs = minimist(process.argv.slice(2), {
73-
string: ['shell', 'prefix', 'postfix', 'eval', 'cwd', 'ext'],
74+
string: ['shell', 'prefix', 'postfix', 'eval', 'cwd', 'ext', 'registry'],
7475
boolean: [
7576
'version',
7677
'help',
@@ -206,8 +207,9 @@ export async function importPath(
206207
}
207208
if (argv.install) {
208209
const deps = parseDeps(await fs.readFile(filepath))
209-
await installDeps(deps, dir)
210+
await installDeps(deps, dir, argv.registry)
210211
}
212+
211213
injectGlobalRequire(origin)
212214
// TODO: fix unanalyzable-dynamic-import to work correctly with jsr.io
213215
await import(url.pathToFileURL(filepath).toString())

src/deps.ts

+12-4
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,27 @@ import { $ } from './core.js'
1616
import { spinner } from './goods.js'
1717
import { depseek } from './vendor.js'
1818

19+
/**
20+
* Install npm dependencies
21+
* @param dependencies object of dependencies
22+
* @param prefix path to the directory where npm should install the dependencies
23+
* @param registry custom npm registry URL when installing dependencies
24+
*/
1925
export async function installDeps(
2026
dependencies: Record<string, string>,
21-
prefix?: string
22-
) {
23-
const flags = prefix ? `--prefix=${prefix}` : ''
27+
prefix?: string,
28+
registry?: string
29+
): Promise<void> {
30+
const prefixFlag = prefix ? `--prefix=${prefix}` : ''
31+
const registryFlag = registry ? `--registry=${registry}` : ''
2432
const packages = Object.entries(dependencies).map(
2533
([name, version]) => `${name}@${version}`
2634
)
2735
if (packages.length === 0) {
2836
return
2937
}
3038
await spinner(`npm i ${packages.join(' ')}`, () =>
31-
$`npm install --no-save --no-audit --no-fund ${flags} ${packages}`.nothrow()
39+
$`npm install --no-save --no-audit --no-fund ${registryFlag} ${prefixFlag} ${packages}`.nothrow()
3240
)
3341
}
3442

test/deps.test.js

+33-6
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
// limitations under the License.
1414

1515
import assert from 'node:assert'
16-
import { test, describe, before, beforeEach } from 'node:test'
17-
import { $ } from '../build/index.js'
16+
import { test, describe } from 'node:test'
17+
import { $, tmpfile, fs } from '../build/index.js'
1818
import { installDeps, parseDeps } from '../build/deps.js'
1919

2020
describe('deps', () => {
@@ -27,12 +27,39 @@ describe('deps', () => {
2727
assert((await import('lodash-es')).pick instanceof Function)
2828
})
2929

30+
test('installDeps() loader works via JS API with custom npm registry URL', async () => {
31+
await installDeps(
32+
{
33+
'@jsr/std__internal': '1.0.5',
34+
},
35+
undefined,
36+
'https://npm.jsr.io'
37+
)
38+
39+
assert((await import('@jsr/std__internal')).diff instanceof Function)
40+
})
41+
3042
test('installDeps() loader works via CLI', async () => {
3143
const out =
3244
await $`node build/cli.js --install <<< 'import _ from "lodash" /* @4.17.15 */; console.log(_.VERSION)'`
3345
assert.match(out.stdout, /4.17.15/)
3446
})
3547

48+
test('installDeps() loader works via CLI with custom npm registry URL', async () => {
49+
const code =
50+
'import { diff } from "@jsr/std__internal";console.log(diff instanceof Function)'
51+
const file = tmpfile('index.mjs', code)
52+
53+
let out =
54+
await $`node build/cli.js --i --registry=https://npm.jsr.io ${file}`
55+
fs.remove(file)
56+
assert.match(out.stdout, /true/)
57+
58+
out =
59+
await $`node build/cli.js -i --registry=https://npm.jsr.io <<< ${code}`
60+
assert.match(out.stdout, /true/)
61+
})
62+
3663
test('parseDeps(): import or require', async () => {
3764
;[
3865
[`import "foo"`, { foo: 'latest' }],
@@ -82,11 +109,11 @@ describe('deps', () => {
82109
require('a') // @1.0.0
83110
const b =require('b') /* @2.0.0 */
84111
const c = {
85-
c:require('c') /* @3.0.0 */,
86-
d: await import('d') /* @4.0.0 */,
112+
c:require('c') /* @3.0.0 */,
113+
d: await import('d') /* @4.0.0 */,
87114
...require('e') /* @5.0.0 */
88115
}
89-
const f = [...require('f') /* @6.0.0 */]
116+
const f = [...require('f') /* @6.0.0 */]
90117
;require('g'); // @7.0.0
91118
const h = 1 *require('h') // @8.0.0
92119
{require('i') /* @9.0.0 */}
@@ -96,7 +123,7 @@ describe('deps', () => {
96123
import path from 'path'
97124
import foo from "foo"
98125
// import aaa from 'a'
99-
/* import bbb from 'b' */
126+
/* import bbb from 'b' */
100127
import bar from "bar" /* @1.0.0 */
101128
import baz from "baz" // @^2.0
102129
import qux from "@qux/pkg/entry" // @^3.0

0 commit comments

Comments
 (0)