forked from
npmx.dev/npmx.dev
[READ-ONLY]
a fast, modern browser for the npm registry
1import { describe, expect, it } from 'vitest'
2import {
3 extractInstallScriptsInfo,
4 getInstallScriptFilePath,
5 parseNodeScript,
6} from '../../../../app/utils/install-scripts'
7
8describe('extractInstallScriptsInfo', () => {
9 it('returns null when no install scripts exist', () => {
10 expect(extractInstallScriptsInfo(undefined)).toBeNull()
11 expect(extractInstallScriptsInfo({})).toBeNull()
12 expect(extractInstallScriptsInfo({ build: 'vite build', test: 'vitest' })).toBeNull()
13 })
14
15 it('detects all install script types with content', () => {
16 const scripts = {
17 preinstall: 'node check.js',
18 install: 'node-gyp rebuild',
19 postinstall: 'node setup.js',
20 build: 'vite build', // should be ignored
21 }
22 const result = extractInstallScriptsInfo(scripts)
23 expect(result).toEqual({
24 scripts: ['preinstall', 'install', 'postinstall'],
25 content: {
26 preinstall: 'node check.js',
27 install: 'node-gyp rebuild',
28 postinstall: 'node setup.js',
29 },
30 npxDependencies: {},
31 })
32 })
33
34 it('extracts npx packages with versions and flags', () => {
35 const scripts = {
36 preinstall: 'npx only-allow pnpm',
37 postinstall: 'npx -y prisma@5.0.0 generate && npx --yes @scope/pkg db push',
38 }
39 const result = extractInstallScriptsInfo(scripts)
40 expect(result).toEqual({
41 scripts: ['preinstall', 'postinstall'],
42 content: {
43 preinstall: 'npx only-allow pnpm',
44 postinstall: 'npx -y prisma@5.0.0 generate && npx --yes @scope/pkg db push',
45 },
46 npxDependencies: {
47 'only-allow': 'latest',
48 'prisma': '5.0.0',
49 '@scope/pkg': 'latest',
50 },
51 })
52 })
53
54 it('ignores npx in non-install scripts and built-in commands', () => {
55 const scripts = {
56 prepare: 'npx husky install', // ignored - not install script
57 postinstall: 'npx node script.js', // node is filtered as builtin
58 }
59 const result = extractInstallScriptsInfo(scripts)
60 expect(result).toEqual({
61 scripts: ['postinstall'],
62 content: { postinstall: 'npx node script.js' },
63 npxDependencies: {},
64 })
65 })
66
67 it('extracts npx packages with dots in names', () => {
68 const scripts = {
69 postinstall: 'npx vue.js@3.0.0 && npx @scope/pkg.name generate',
70 }
71 const result = extractInstallScriptsInfo(scripts)
72 expect(result).toEqual({
73 scripts: ['postinstall'],
74 content: { postinstall: 'npx vue.js@3.0.0 && npx @scope/pkg.name generate' },
75 npxDependencies: {
76 'vue.js': '3.0.0',
77 '@scope/pkg.name': 'latest',
78 },
79 })
80 })
81})
82
83describe('getInstallScriptFilePath', () => {
84 it('returns file path when script is `node <file-path>`', () => {
85 expect(getInstallScriptFilePath('node scripts/postinstall.js')).toBe('scripts/postinstall.js')
86 })
87
88 it('returns package.json when script is not a simple node command', () => {
89 expect(getInstallScriptFilePath('npx prisma generate')).toBe('package.json')
90 })
91
92 it('strips leading ./ from relative paths', () => {
93 expect(getInstallScriptFilePath('node ./scripts/setup.js')).toBe('scripts/setup.js')
94 })
95
96 it('falls back to package.json for parent directory references', () => {
97 expect(getInstallScriptFilePath('node ../scripts/setup.js')).toBe('package.json')
98 expect(getInstallScriptFilePath('node ./scripts/../lib/setup.js')).toBe('package.json')
99 })
100
101 it('returns package.json for bare node command without arguments', () => {
102 expect(getInstallScriptFilePath('node')).toBe('package.json')
103 expect(getInstallScriptFilePath('node ')).toBe('package.json')
104 })
105})
106
107describe('parseNodeScript', () => {
108 it('returns prefix and filePath for node scripts', () => {
109 expect(parseNodeScript('node scripts/postinstall.js')).toEqual({
110 prefix: 'node ',
111 filePath: 'scripts/postinstall.js',
112 })
113 })
114
115 it('strips leading ./ from file path', () => {
116 expect(parseNodeScript('node ./scripts/setup.js')).toEqual({
117 prefix: 'node ',
118 filePath: 'scripts/setup.js',
119 })
120 })
121
122 it('returns null for non-node scripts', () => {
123 expect(parseNodeScript('npx prisma generate')).toBeNull()
124 })
125
126 it('returns null for bare node command', () => {
127 expect(parseNodeScript('node')).toBeNull()
128 expect(parseNodeScript('node ')).toBeNull()
129 })
130
131 it('returns null for parent directory references', () => {
132 expect(parseNodeScript('node ../scripts/setup.js')).toBeNull()
133 })
134})