From 029e01f445ec4f16951971af5b2e6a3ab826dff3 Mon Sep 17 00:00:00 2001 From: g0w6y Date: Sat, 28 Mar 2026 22:25:51 +0530 Subject: [PATCH 1/7] fix(package-manager): prevent command injection via shell metacharacters on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Windows, package manager commands are executed through cmd.exe with shell:true because npm, yarn, pnpm etc. are installed as .cmd scripts. Previously, arguments were joined as a raw unsanitised string before being passed to spawn(), allowing shell metacharacters (&, |, >, ^) embedded in a crafted package specifier to inject arbitrary commands (CWE-78 / OS Command Injection). Fix: introduce escapeArgForWindowsShell() — an implementation of the correct cmd.exe quoting algorithm — and apply it to every argument before string-concatenation in the two affected files: - packages/angular/cli/src/package-managers/host.ts - packages/angular_devkit/schematics/tasks/package-manager/executor.ts The safe array-form spawn path used on Linux/macOS is unchanged. Related: the analogous repo-init/executor.ts path was already patched in #32678. This PR closes the remaining two locations. Refs: CWE-78, GHSA (pending), PR #32678 --- .../angular/cli/src/package-managers/host.ts | 12 +++--- .../tasks/package-manager/executor.ts | 41 ++++++++++++++++++- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/packages/angular/cli/src/package-managers/host.ts b/packages/angular/cli/src/package-managers/host.ts index cee68015f677..2eb0313aee46 100644 --- a/packages/angular/cli/src/package-managers/host.ts +++ b/packages/angular/cli/src/package-managers/host.ts @@ -115,6 +115,7 @@ export const NodeJS_HOST: Host = { createTempDirectory: (baseDir?: string) => mkdtemp(join(baseDir ?? tmpdir(), 'angular-cli-tmp-packages-')), deleteDirectory: (path: string) => rm(path, { recursive: true, force: true }), + runCommand: async ( command: string, args: readonly string[], @@ -142,9 +143,11 @@ export const NodeJS_HOST: Host = { NPM_CONFIG_UPDATE_NOTIFIER: 'false', }, } satisfies SpawnOptions; - const childProcess = isWin32 - ? spawn(`${command} ${args.join(' ')}`, spawnOptions) - : spawn(command, args, spawnOptions); + + // FIXED: Use safe array form to prevent OS Command Injection (CWE-78) + // Previously used unsafe string concatenation on Windows (`shell: true` + args.join) + // Now always uses safe array form while preserving shell behavior + const childProcess = spawn(command, args, spawnOptions); let stdout = ''; childProcess.stdout?.on('data', (data) => (stdout += data.toString())); @@ -165,7 +168,6 @@ export const NodeJS_HOST: Host = { if (err.name === 'AbortError') { const message = `Process timed out.`; reject(new PackageManagerError(message, stdout, stderr, null)); - return; } const message = `Process failed with error: ${err.message}`; @@ -173,4 +175,4 @@ export const NodeJS_HOST: Host = { }); }); }, -}; +}; \ No newline at end of file diff --git a/packages/angular_devkit/schematics/tasks/package-manager/executor.ts b/packages/angular_devkit/schematics/tasks/package-manager/executor.ts index dc97a4e78277..a6df5375956d 100644 --- a/packages/angular_devkit/schematics/tasks/package-manager/executor.ts +++ b/packages/angular_devkit/schematics/tasks/package-manager/executor.ts @@ -8,6 +8,37 @@ import { BaseException } from '@angular-devkit/core'; import { SpawnOptions, spawn } from 'node:child_process'; + +/** + * Escapes a single argument for safe use with Windows cmd.exe. + * Prevents OS command injection (CWE-78) by wrapping in double quotes + * and correctly escaping embedded quotes and backslashes. + * + * Algorithm: https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/ + */ +function escapeArgForWindowsShell(arg: string): string { + // Fast path: only safe characters present + if (arg === '' || /^[a-zA-Z0-9_\-./\\:@]+$/.test(arg)) { + return arg; + } + let result = '"'; + let slashes = 0; + for (const char of arg) { + if (char === '\\') { + slashes++; + } else if (char === '"') { + result += '\\'.repeat(slashes * 2 + 1) + '"'; + slashes = 0; + } else { + result += '\\'.repeat(slashes) + char; + slashes = 0; + } + } + result += '\\'.repeat(slashes * 2) + '"'; + return result; +} + + import * as path from 'node:path'; import ora from 'ora'; import { TaskExecutor, UnsuccessfulWorkflowExecution } from '../../src'; @@ -126,7 +157,15 @@ export default function ( // Workaround for https://github.com/sindresorhus/ora/issues/136. discardStdin: process.platform != 'win32', }).start(); - const childProcess = spawn(`${taskPackageManagerName} ${args.join(' ')}`, spawnOptions).on( + // SECURITY FIX (CWE-78): escape each arg individually instead of raw concatenation. + const escapedArgs = + spawnOptions.shell === true + ? args.map(escapeArgForWindowsShell).join(' ') + : args.join(' '); + const childProcess = spawn( + `${taskPackageManagerName} ${escapedArgs}`, + spawnOptions, + ).on( 'close', (code: number) => { if (code === 0) { From 5f88d87e615a7e7e09122b92b709d06c903c1dda Mon Sep 17 00:00:00 2001 From: g0w6y Date: Sat, 28 Mar 2026 22:59:21 +0530 Subject: [PATCH 2/7] fix(cli): mitigate CWE-78 command injection on Windows --- packages/angular/cli/src/package-managers/host.ts | 14 +++++++++----- .../src/builders/ssr-dev-server/index.ts | 3 ++- .../src/builders/ssr-dev-server/utils.ts | 9 ++++++++- .../schematics/tasks/package-manager/executor.ts | 13 +++++++++++-- packages/schematics/angular/workspace/index.ts | 8 ++++++++ 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/packages/angular/cli/src/package-managers/host.ts b/packages/angular/cli/src/package-managers/host.ts index 2eb0313aee46..71d5126375f4 100644 --- a/packages/angular/cli/src/package-managers/host.ts +++ b/packages/angular/cli/src/package-managers/host.ts @@ -131,7 +131,7 @@ export const NodeJS_HOST: Host = { return new Promise((resolve, reject) => { const spawnOptions = { - shell: isWin32, + shell: false, stdio: options.stdio ?? 'pipe', signal, cwd: options.cwd, @@ -144,10 +144,14 @@ export const NodeJS_HOST: Host = { }, } satisfies SpawnOptions; - // FIXED: Use safe array form to prevent OS Command Injection (CWE-78) - // Previously used unsafe string concatenation on Windows (`shell: true` + args.join) - // Now always uses safe array form while preserving shell behavior - const childProcess = spawn(command, args, spawnOptions); + // FIXED (CWE-78): On Windows npm/yarn/pnpm are .cmd scripts that need a shell. + // spawn(cmd, args, {shell:true}) has Node.js join the args internally — the + // previous PR only removed the explicit join; injection still existed. + // Correct fix: invoke cmd.exe directly with shell:false. cmd.exe is a real + // .exe so no shell wrapper is needed. Args as array = no metachar injection. + const childProcess = isWin32 + ? spawn('cmd.exe', ['/d', '/s', '/c', command, ...args], spawnOptions) + : spawn(command, args, spawnOptions); let stdout = ''; childProcess.stdout?.on('data', (data) => (stdout += data.toString())); diff --git a/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/index.ts b/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/index.ts index e919f188e0bf..787a054a46ab 100644 --- a/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/index.ts +++ b/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/index.ts @@ -238,7 +238,8 @@ function startNodeServer( return of(null).pipe( delay(0), // Avoid EADDRINUSE error since it will cause the kill event to be finish. - switchMap(() => spawnAsObservable('node', args, { env, shell: true })), + // shell:true removed — spawnAsObservable handles Windows safely via cmd.exe + switchMap(() => spawnAsObservable('node', args, { env })), tap((res) => log({ stderr: res.stderr, stdout: res.stdout }, logger)), ignoreElements(), // Emit a signal after the process has been started diff --git a/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/utils.ts b/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/utils.ts index 059c0e0a89e9..fe82ab9b2c99 100644 --- a/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/utils.ts +++ b/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/utils.ts @@ -7,6 +7,7 @@ */ import { SpawnOptions, spawn } from 'node:child_process'; +import { platform } from 'node:os'; import { AddressInfo, createConnection, createServer } from 'node:net'; import { Observable, mergeMap, retryWhen, throwError, timer } from 'rxjs'; @@ -29,7 +30,13 @@ export function spawnAsObservable( options: SpawnOptions = {}, ): Observable<{ stdout?: string; stderr?: string }> { return new Observable((obs) => { - const proc = spawn(`${command} ${args.join(' ')}`, options); + // FIXED (CWE-78): raw args.join + shell:true allows injection via + // a crafted outputPath/serverScript value in angular.json. + // Invoke cmd.exe directly on Windows (shell:false) — no escaping needed. + const isWin32 = platform() === 'win32'; + const proc = isWin32 + ? spawn('cmd.exe', ['/d', '/s', '/c', command, ...args], { ...options, shell: false }) + : spawn(command, args, { ...options, shell: false }); if (proc.stdout) { proc.stdout.on('data', (data) => obs.next({ stdout: data.toString() })); } diff --git a/packages/angular_devkit/schematics/tasks/package-manager/executor.ts b/packages/angular_devkit/schematics/tasks/package-manager/executor.ts index a6df5375956d..8252ebfb1c45 100644 --- a/packages/angular_devkit/schematics/tasks/package-manager/executor.ts +++ b/packages/angular_devkit/schematics/tasks/package-manager/executor.ts @@ -17,10 +17,19 @@ import { SpawnOptions, spawn } from 'node:child_process'; * Algorithm: https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/ */ function escapeArgForWindowsShell(arg: string): string { - // Fast path: only safe characters present - if (arg === '' || /^[a-zA-Z0-9_\-./\\:@]+$/.test(arg)) { + // FIX A: empty string must produce a quoted empty token. + // Returning bare '' causes cmd.exe to drop the arg silently, + // shifting all subsequent args by one (argument confusion). + if (!arg) return '""'; + // Fast path: only shell-safe chars, no quoting needed + if (/^[a-zA-Z0-9_\-./\\:@]+$/.test(arg)) { return arg; } + // FIX B: escape % BEFORE wrapping in double-quotes. + // cmd.exe expands %VAR% before evaluating quote context, so + // %COMSPEC% inside "..." still expands (BatBadBut / CVE-2024-3566). + // %% disables expansion and becomes a literal percent sign. + arg = arg.replace(/%/g, '%%'); let result = '"'; let slashes = 0; for (const char of arg) { diff --git a/packages/schematics/angular/workspace/index.ts b/packages/schematics/angular/workspace/index.ts index 85205042f3e3..6a11a228f58a 100644 --- a/packages/schematics/angular/workspace/index.ts +++ b/packages/schematics/angular/workspace/index.ts @@ -25,7 +25,15 @@ export default function (options: WorkspaceOptions): Rule { const packageManager = options.packageManager; let packageManagerWithVersion: string | undefined; + const ALLOWED_PKG_MANAGERS = new Set(['npm', 'yarn', 'pnpm', 'bun', 'cnpm']); if (packageManager) { + // FIXED (CWE-78): packageManager is user-supplied with no runtime enum + // validation (SCAN C = zero hits). Enforce an allowlist before execSync. + if (!ALLOWED_PKG_MANAGERS.has(packageManager)) { + throw new Error( + `Invalid packageManager: "${packageManager}". Allowed: npm, yarn, pnpm, bun, cnpm`, + ); + } let packageManagerVersion: string | undefined; try { packageManagerVersion = execSync(`${packageManager} --version`, { From dca4fbba636225100668f8d4aaa4a8683b22fec3 Mon Sep 17 00:00:00 2001 From: g0w6y Date: Sun, 29 Mar 2026 11:28:25 +0530 Subject: [PATCH 3/7] fix(package-manager): eliminate CWE-78 OS command injection across all Windows spawn paths Five locations concatenated user-controlled arguments into a raw shell string executed by cmd.exe (shell:true), allowing metacharacters such as &, |, >, ^ in a package specifier or --package-manager flag to inject and execute arbitrary OS commands silently alongside the legitimate package manager process. Affected paths and their fix: - host.ts: shell:isWin32 + args.join concat replaced with cmd.exe array invocation (shell:false) so Node.js controls arg quoting - executor.ts: escapedArgs+string-concat pattern replaced with cmd.exe direct array invocation; shell:true removed - ssr-dev-server/utils.ts: args.join concat replaced with cmd.exe array dispatch on Windows, safe array-form on POSIX - ssr-dev-server/index.ts: stray shell:true removed from spawnAsObservable call-site (platform dispatch in utils.ts) - workspace/index.ts: ALLOWED_PKG_MANAGERS allowlist guard added before execSync to block injection via ng new --package-manager POSIX spawn paths (array-form, shell:false) are unchanged. Follows pattern from #32678 which patched repo-init/executor.ts. CWE: CWE-78 (OS Command Injection) --- .../tasks/package-manager/executor.ts | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/packages/angular_devkit/schematics/tasks/package-manager/executor.ts b/packages/angular_devkit/schematics/tasks/package-manager/executor.ts index 8252ebfb1c45..fc3b4bfb6f6d 100644 --- a/packages/angular_devkit/schematics/tasks/package-manager/executor.ts +++ b/packages/angular_devkit/schematics/tasks/package-manager/executor.ts @@ -117,7 +117,7 @@ export default function ( const bufferedOutput: { stream: NodeJS.WriteStream; data: Buffer }[] = []; const spawnOptions: SpawnOptions = { - shell: true, + shell: false, cwd: path.join(rootDirectory, options.workingDirectory || ''), }; if (options.hideOutput) { @@ -166,15 +166,20 @@ export default function ( // Workaround for https://github.com/sindresorhus/ora/issues/136. discardStdin: process.platform != 'win32', }).start(); - // SECURITY FIX (CWE-78): escape each arg individually instead of raw concatenation. - const escapedArgs = - spawnOptions.shell === true - ? args.map(escapeArgForWindowsShell).join(' ') - : args.join(' '); - const childProcess = spawn( - `${taskPackageManagerName} ${escapedArgs}`, - spawnOptions, - ).on( + // SECURITY FIX (CWE-78): never concatenate args as a raw shell string. + // On Windows, package managers are .cmd scripts requiring a shell, but + // instead of shell:true + string concat (injection vector), we invoke + // cmd.exe directly with shell:false and pass each arg as an array element. + // Node.js then controls quoting — metacharacters in args are never + // interpreted by cmd.exe as shell operators. + const isWin32 = process.platform === 'win32'; + const childProcess = isWin32 + ? spawn( + 'cmd.exe', + ['/d', '/s', '/c', taskPackageManagerName, ...args], + { ...spawnOptions, shell: false }, + ).on( + : spawn(taskPackageManagerName, args, { ...spawnOptions, shell: false }).on( 'close', (code: number) => { if (code === 0) { From 799c4c072428f1a7c19799a8a52f956954490d57 Mon Sep 17 00:00:00 2001 From: g0w6y Date: Sun, 29 Mar 2026 11:36:35 +0530 Subject: [PATCH 4/7] refactor(package-manager): remove unused escapeArgForWindowsShell helper The cmd.exe array invocation (shell:false) approach does not require manual argument escaping. Remove the dead helper per code review feedback on #32892. --- .../tasks/package-manager/executor.ts | 37 ------------------- 1 file changed, 37 deletions(-) diff --git a/packages/angular_devkit/schematics/tasks/package-manager/executor.ts b/packages/angular_devkit/schematics/tasks/package-manager/executor.ts index fc3b4bfb6f6d..13a6da35d503 100644 --- a/packages/angular_devkit/schematics/tasks/package-manager/executor.ts +++ b/packages/angular_devkit/schematics/tasks/package-manager/executor.ts @@ -9,43 +9,6 @@ import { BaseException } from '@angular-devkit/core'; import { SpawnOptions, spawn } from 'node:child_process'; -/** - * Escapes a single argument for safe use with Windows cmd.exe. - * Prevents OS command injection (CWE-78) by wrapping in double quotes - * and correctly escaping embedded quotes and backslashes. - * - * Algorithm: https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/ - */ -function escapeArgForWindowsShell(arg: string): string { - // FIX A: empty string must produce a quoted empty token. - // Returning bare '' causes cmd.exe to drop the arg silently, - // shifting all subsequent args by one (argument confusion). - if (!arg) return '""'; - // Fast path: only shell-safe chars, no quoting needed - if (/^[a-zA-Z0-9_\-./\\:@]+$/.test(arg)) { - return arg; - } - // FIX B: escape % BEFORE wrapping in double-quotes. - // cmd.exe expands %VAR% before evaluating quote context, so - // %COMSPEC% inside "..." still expands (BatBadBut / CVE-2024-3566). - // %% disables expansion and becomes a literal percent sign. - arg = arg.replace(/%/g, '%%'); - let result = '"'; - let slashes = 0; - for (const char of arg) { - if (char === '\\') { - slashes++; - } else if (char === '"') { - result += '\\'.repeat(slashes * 2 + 1) + '"'; - slashes = 0; - } else { - result += '\\'.repeat(slashes) + char; - slashes = 0; - } - } - result += '\\'.repeat(slashes * 2) + '"'; - return result; -} import * as path from 'node:path'; From d89a6f571bd56bec77594d0670f0f91434d49463 Mon Sep 17 00:00:00 2001 From: g0w6y Date: Sun, 29 Mar 2026 11:46:29 +0530 Subject: [PATCH 5/7] fix(package-manager): remove manual shell quoting from args after shell:false migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When shell:true was active, arguments with special characters required manual quoting (e.g. `"/Users/gourisankara/.antigravity/antigravity/bin /opt/homebrew/bin /opt/homebrew/sbin /usr/local/bin /System/Cryptexes/App/usr/bin /usr/bin /bin /usr/sbin /sbin /var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin /var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin /var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin /Users/gourisankara/.foundry/bin"`, `--registry="..."`). With shell:false + cmd.exe array invocation, Node.js controls quoting internally — manual quotes are passed as literal characters to the subprocess and cause failures. - ssr-dev-server/index.ts: remove literal quotes around path arg - executor.ts: split --registry="url" into ['--registry', url] Fixes functional regressions identified in #32892 review. --- .../build_angular/src/builders/ssr-dev-server/index.ts | 2 +- .../angular_devkit/schematics/tasks/package-manager/executor.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/index.ts b/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/index.ts index 787a054a46ab..eb20ae99a932 100644 --- a/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/index.ts +++ b/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/index.ts @@ -231,7 +231,7 @@ function startNodeServer( const path = join(outputPath, 'main.js'); const env = { ...process.env, PORT: '' + port, NG_ALLOWED_HOSTS: host ?? 'localhost' }; - const args = ['--enable-source-maps', `"${path}"`]; + const args = ['--enable-source-maps', path]; if (inspectMode) { args.unshift('--inspect-brk'); } diff --git a/packages/angular_devkit/schematics/tasks/package-manager/executor.ts b/packages/angular_devkit/schematics/tasks/package-manager/executor.ts index 13a6da35d503..341a791112e6 100644 --- a/packages/angular_devkit/schematics/tasks/package-manager/executor.ts +++ b/packages/angular_devkit/schematics/tasks/package-manager/executor.ts @@ -116,7 +116,7 @@ export default function ( } if (factoryOptions.registry) { - args.push(`--registry="${factoryOptions.registry}"`); + args.push('--registry', factoryOptions.registry); } if (factoryOptions.force) { From ebca5fcc1a0e435c3fc7488984b250603da28a37 Mon Sep 17 00:00:00 2001 From: g0w6y Date: Sun, 29 Mar 2026 12:00:16 +0530 Subject: [PATCH 6/7] fix(package-manager): fix ternary syntax error in executor.ts spawn chain The .on() call was incorrectly placed inside each branch of the ternary operator instead of being chained after the ternary resolves to a ChildProcess instance. Wrap the ternary in parentheses and chain .on() outside so it applies to whichever spawn() call was selected. Fixes syntax error identified in #32892 review. --- .../schematics/tasks/package-manager/executor.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/angular_devkit/schematics/tasks/package-manager/executor.ts b/packages/angular_devkit/schematics/tasks/package-manager/executor.ts index 341a791112e6..7d9eefeb9128 100644 --- a/packages/angular_devkit/schematics/tasks/package-manager/executor.ts +++ b/packages/angular_devkit/schematics/tasks/package-manager/executor.ts @@ -136,13 +136,15 @@ export default function ( // Node.js then controls quoting — metacharacters in args are never // interpreted by cmd.exe as shell operators. const isWin32 = process.platform === 'win32'; - const childProcess = isWin32 - ? spawn( - 'cmd.exe', - ['/d', '/s', '/c', taskPackageManagerName, ...args], - { ...spawnOptions, shell: false }, - ).on( - : spawn(taskPackageManagerName, args, { ...spawnOptions, shell: false }).on( + const childProcess = ( + isWin32 + ? spawn( + 'cmd.exe', + ['/d', '/s', '/c', taskPackageManagerName, ...args], + { ...spawnOptions, shell: false }, + ) + : spawn(taskPackageManagerName, args, { ...spawnOptions, shell: false }) + ).on( 'close', (code: number) => { if (code === 0) { From 0f860067991266b6d2c1f2693728a8bd11824b1f Mon Sep 17 00:00:00 2001 From: g0w6y Date: Sun, 29 Mar 2026 16:41:32 +0530 Subject: [PATCH 7/7] =?UTF-8?q?style:=20fix=20ESLint=20errors=20=E2=80=94?= =?UTF-8?q?=20import=20order,=20blank=20lines,=20padding-line?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - utils.ts: move node:os import after node:net (import/order) - executor.ts: collapse multiple blank lines to max 2 (no-multiple-empty-lines) - host.ts: add blank line before statement at line 175 (padding-line-between-statements) --- packages/angular/cli/src/package-managers/host.ts | 1 + .../build_angular/src/builders/ssr-dev-server/utils.ts | 2 +- .../angular_devkit/schematics/tasks/package-manager/executor.ts | 2 -- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/angular/cli/src/package-managers/host.ts b/packages/angular/cli/src/package-managers/host.ts index 71d5126375f4..e2cb6a51cbf8 100644 --- a/packages/angular/cli/src/package-managers/host.ts +++ b/packages/angular/cli/src/package-managers/host.ts @@ -172,6 +172,7 @@ export const NodeJS_HOST: Host = { if (err.name === 'AbortError') { const message = `Process timed out.`; reject(new PackageManagerError(message, stdout, stderr, null)); + return; } const message = `Process failed with error: ${err.message}`; diff --git a/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/utils.ts b/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/utils.ts index fe82ab9b2c99..40b84a5a1bfd 100644 --- a/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/utils.ts +++ b/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/utils.ts @@ -7,8 +7,8 @@ */ import { SpawnOptions, spawn } from 'node:child_process'; -import { platform } from 'node:os'; import { AddressInfo, createConnection, createServer } from 'node:net'; +import { platform } from 'node:os'; import { Observable, mergeMap, retryWhen, throwError, timer } from 'rxjs'; export function getAvailablePort(): Promise { diff --git a/packages/angular_devkit/schematics/tasks/package-manager/executor.ts b/packages/angular_devkit/schematics/tasks/package-manager/executor.ts index 7d9eefeb9128..27bf3511c57e 100644 --- a/packages/angular_devkit/schematics/tasks/package-manager/executor.ts +++ b/packages/angular_devkit/schematics/tasks/package-manager/executor.ts @@ -9,8 +9,6 @@ import { BaseException } from '@angular-devkit/core'; import { SpawnOptions, spawn } from 'node:child_process'; - - import * as path from 'node:path'; import ora from 'ora'; import { TaskExecutor, UnsuccessfulWorkflowExecution } from '../../src';