Skip to content

Commit 9aec1ff

Browse files
committed
fix: respect dev dependencies in install drift checks
Use npm ls with --include=dev so dependency checks stay accurate under NODE_ENV=production, and dismiss stale update toasts when loader data no longer reports updates. Made-with: Cursor
1 parent ccf6c18 commit 9aec1ff

3 files changed

Lines changed: 43 additions & 6 deletions

File tree

packages/workshop-app/app/components/update-repo.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,17 @@ export function UpdateToast({
168168
},
169169
})
170170
updateToastId.current = id
171+
} else {
172+
// Keep UI aligned with latest loader state: if updates are cleared,
173+
// immediately dismiss any previously shown update toast.
174+
if (updateToastId.current) {
175+
toast.dismiss(updateToastId.current)
176+
updateToastId.current = null
177+
}
178+
if (inProgressToastId.current && !updateInProgress.current) {
179+
toast.dismiss(inProgressToastId.current)
180+
inProgressToastId.current = null
181+
}
171182
}
172183
}, [
173184
updatesAvailable,

packages/workshop-utils/src/package-install/package-install-check.server.test.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ describe('getRootPackageInstallStatus', () => {
251251
expect(status.missingDependencies).toEqual(['react-dom'])
252252
expect(execa).toHaveBeenCalledWith(
253253
'npm',
254-
['ls', '--depth=0', '--json', 'react', 'react-dom'],
254+
['ls', '--depth=0', '--json', '--include=dev', 'react', 'react-dom'],
255255
expect.objectContaining({ cwd: tempDir, reject: false }),
256256
)
257257
})
@@ -350,6 +350,29 @@ describe('getRootPackageInstallStatus', () => {
350350
expect(status.missingDependencies).toEqual(['@epic-web/workshop-utils'])
351351
})
352352

353+
test('uses npm include=dev to avoid NODE_ENV production omissions', async () => {
354+
await using temp = await createTempDir()
355+
const tempDir = temp.dir
356+
357+
await writePackageJson(tempDir, {
358+
name: 'test-package',
359+
dependencies: { react: '^18.0.0' },
360+
devDependencies: { typescript: '^5.0.0' },
361+
})
362+
mockNpmLsResult({
363+
exitCode: 0,
364+
dependencies: { react: {}, typescript: {} },
365+
})
366+
367+
await getRootPackageInstallStatus(path.join(tempDir, 'package.json'))
368+
369+
expect(execa).toHaveBeenCalledWith(
370+
'npm',
371+
['ls', '--depth=0', '--json', '--include=dev', 'react', 'typescript'],
372+
expect.objectContaining({ cwd: tempDir, reject: false }),
373+
)
374+
})
375+
353376
test('handles package.json with no dependencies', async () => {
354377
await using temp = await createTempDir()
355378
const tempDir = temp.dir

packages/workshop-utils/src/package-install/package-install-check.server.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,16 @@ async function checkDependenciesWithNpmLs(
164164
// Use the detected package manager, defaulting to npm
165165
// pnpm has compatible ls output format
166166
const command = packageManager === 'pnpm' ? 'pnpm' : 'npm'
167+
const lsArgs =
168+
command === 'npm'
169+
? ['ls', '--depth=0', '--json', '--include=dev', ...expectedDependencies]
170+
: ['ls', '--depth=0', '--json', ...expectedDependencies]
167171

168172
try {
169-
const result = await execa(
170-
command,
171-
['ls', '--depth=0', '--json', ...expectedDependencies],
172-
{ cwd: rootDir, reject: false },
173-
)
173+
const result = await execa(command, lsArgs, {
174+
cwd: rootDir,
175+
reject: false,
176+
})
174177
const output = parseNpmLsOutput(result.stdout)
175178
const failingDependencies = getFailingDependencies(
176179
expectedDependencies,

0 commit comments

Comments
 (0)