From 4b0ee8ad15efcb513ab5d9e38bf9b1e08857e798 Mon Sep 17 00:00:00 2001 From: Andrew Scott Date: Tue, 1 Nov 2022 10:50:41 -0700 Subject: [PATCH 01/17] fix(@schematics/angular): guard schematics should include all guards (CanMatch) The `CanMatch` guard was added in v14.1 but not added to the list of possible interfaces to implement. This commit adds `CanMatch` to the list of possible interfaces to implement. It has the same type imports as the CanLoad interface. (cherry picked from commit f837f6dab46510346964c2ad6be64b68fac32a41) --- .../guard/files/__name@dasherize__.guard.ts.template | 6 +++++- packages/schematics/angular/guard/index.ts | 5 ++++- packages/schematics/angular/guard/index_spec.ts | 10 ++++++++++ packages/schematics/angular/guard/schema.json | 2 +- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/schematics/angular/guard/files/__name@dasherize__.guard.ts.template b/packages/schematics/angular/guard/files/__name@dasherize__.guard.ts.template index 3dc36a017893..8d83bc7498b4 100644 --- a/packages/schematics/angular/guard/files/__name@dasherize__.guard.ts.template +++ b/packages/schematics/angular/guard/files/__name@dasherize__.guard.ts.template @@ -23,7 +23,11 @@ export class <%= classify(name) %>Guard implements <%= implementations %> { nextState?: RouterStateSnapshot): Observable | Promise | boolean | UrlTree { return true; } - <% } %><% if (implements.includes('CanLoad')) { %>canLoad( + <% } %><% if (implements.includes('CanMatch')) { %>canMatch( + route: Route, + segments: UrlSegment[]): Observable | Promise | boolean | UrlTree { + return true; + }<% } %><% if (implements.includes('CanLoad')) { %>canLoad( route: Route, segments: UrlSegment[]): Observable | Promise | boolean | UrlTree { return true; diff --git a/packages/schematics/angular/guard/index.ts b/packages/schematics/angular/guard/index.ts index f8a35b9947bf..efb377216684 100644 --- a/packages/schematics/angular/guard/index.ts +++ b/packages/schematics/angular/guard/index.ts @@ -21,7 +21,10 @@ export default function (options: GuardOptions): Rule { const commonRouterNameImports = ['ActivatedRouteSnapshot', 'RouterStateSnapshot']; const routerNamedImports: string[] = [...options.implements, 'UrlTree']; - if (options.implements.includes(GuardInterface.CanLoad)) { + if ( + options.implements.includes(GuardInterface.CanLoad) || + options.implements.includes(GuardInterface.CanMatch) + ) { routerNamedImports.push('Route', 'UrlSegment'); if (options.implements.length > 1) { diff --git a/packages/schematics/angular/guard/index_spec.ts b/packages/schematics/angular/guard/index_spec.ts index eba8e654982b..45326eba1862 100644 --- a/packages/schematics/angular/guard/index_spec.ts +++ b/packages/schematics/angular/guard/index_spec.ts @@ -126,6 +126,16 @@ describe('Guard Schematic', () => { expect(fileString).toContain(expectedImports); }); + it('should add correct imports based on CanMatch implementation', async () => { + const implementationOptions = ['CanMatch']; + const options = { ...defaultOptions, implements: implementationOptions }; + const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise(); + const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts'); + const expectedImports = `import { CanMatch, Route, UrlSegment, UrlTree } from '@angular/router';`; + + expect(fileString).toContain(expectedImports); + }); + it('should add correct imports based on CanActivate implementation', async () => { const implementationOptions = ['CanActivate']; const options = { ...defaultOptions, implements: implementationOptions }; diff --git a/packages/schematics/angular/guard/schema.json b/packages/schematics/angular/guard/schema.json index f66bdc9428cc..fda5ea7a43a2 100644 --- a/packages/schematics/angular/guard/schema.json +++ b/packages/schematics/angular/guard/schema.json @@ -48,7 +48,7 @@ "uniqueItems": true, "minItems": 1, "items": { - "enum": ["CanActivate", "CanActivateChild", "CanDeactivate", "CanLoad"], + "enum": ["CanActivate", "CanActivateChild", "CanDeactivate", "CanLoad", "CanMatch"], "type": "string" }, "default": ["CanActivate"], From 4f730aa220921a837e1185821a3bb4c8ce629bd3 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 2 Nov 2022 09:32:25 -0700 Subject: [PATCH 02/17] release: cut the v14.2.8 release --- CHANGELOG.md | 16 ++++++++++++++++ package.json | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac496a1bbd9d..3535eea856a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ + + +# 14.2.8 (2022-11-02) + +### @schematics/angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | +| [4b0ee8ad1](https://github.com/angular/angular-cli/commit/4b0ee8ad15efcb513ab5d9e38bf9b1e08857e798) | fix | guard schematics should include all guards (CanMatch) | + +## Special Thanks + +Andrew Scott + + + # 14.2.7 (2022-10-26) diff --git a/package.json b/package.json index a63c86859f5f..bf797d1c6a2d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@angular/devkit-repo", - "version": "14.2.7", + "version": "14.2.8", "private": true, "description": "Software Development Kit for Angular", "bin": { From 12b2dc5a2374f992df151af32cc80e2c2d7c4dee Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Mon, 7 Nov 2022 13:43:24 +0000 Subject: [PATCH 03/17] fix(@angular-devkit/build-angular): isolate zone.js usage when rendering server bundles When generating an app-shell via the app-shell builder, the server application rendering will now take place within a Node.js Worker. Since the rendering requires the presence of Zone.js, this change allows for the Zone.js patching to be isolated from the remainder of the builder and Angular CLI code. This prevents Zone.js from persisting past the needed render operation. This also allows for a workaround to a Zone.js/Node.js v18 problem where the TypeScript dynamic import workaround involving the Function constructor to ensure a native dynamic import expression will cause a failure when running on Node.js v18.10. (cherry picked from commit 484cda5f9ee90ab17807eb7f5cfb4a40ea6cd264) --- .../angular_devkit/build_angular/BUILD.bazel | 1 + .../src/builders/app-shell/index.ts | 104 +++++++++--------- .../src/builders/app-shell/render-worker.ts | 81 ++++++++++++++ 3 files changed, 133 insertions(+), 53 deletions(-) create mode 100644 packages/angular_devkit/build_angular/src/builders/app-shell/render-worker.ts diff --git a/packages/angular_devkit/build_angular/BUILD.bazel b/packages/angular_devkit/build_angular/BUILD.bazel index 4e3af36fcb55..4e412fd0251c 100644 --- a/packages/angular_devkit/build_angular/BUILD.bazel +++ b/packages/angular_devkit/build_angular/BUILD.bazel @@ -106,6 +106,7 @@ ts_library( "@npm//@angular/compiler-cli", "@npm//@angular/core", "@npm//@angular/localize", + "@npm//@angular/platform-server", "@npm//@angular/service-worker", "@npm//@babel/core", "@npm//@babel/generator", diff --git a/packages/angular_devkit/build_angular/src/builders/app-shell/index.ts b/packages/angular_devkit/build_angular/src/builders/app-shell/index.ts index 37b1c7cb29e5..208c3d5c611d 100644 --- a/packages/angular_devkit/build_angular/src/builders/app-shell/index.ts +++ b/packages/angular_devkit/build_angular/src/builders/app-shell/index.ts @@ -15,6 +15,7 @@ import { import { JsonObject } from '@angular-devkit/core'; import * as fs from 'fs'; import * as path from 'path'; +import Piscina from 'piscina'; import { normalizeOptimization } from '../../utils'; import { assertIsError } from '../../utils/error'; import { InlineCriticalCssProcessor } from '../../utils/index-file/inline-critical-css'; @@ -42,10 +43,9 @@ async function _renderUniversal( browserBuilderName, ); - // Initialize zone.js + // Locate zone.js to load in the render worker const root = context.workspaceRoot; const zonePackage = require.resolve('zone.js', { paths: [root] }); - await import(zonePackage); const projectName = context.target && context.target.project; if (!projectName) { @@ -63,65 +63,63 @@ async function _renderUniversal( }) : undefined; - for (const { path: outputPath, baseHref } of browserResult.outputs) { - const localeDirectory = path.relative(browserResult.baseOutputPath, outputPath); - const browserIndexOutputPath = path.join(outputPath, 'index.html'); - const indexHtml = await fs.promises.readFile(browserIndexOutputPath, 'utf8'); - const serverBundlePath = await _getServerModuleBundlePath( - options, - context, - serverResult, - localeDirectory, - ); - - const { AppServerModule, renderModule } = await import(serverBundlePath); - - const renderModuleFn: ((module: unknown, options: {}) => Promise) | undefined = - renderModule; - - if (!(renderModuleFn && AppServerModule)) { - throw new Error( - `renderModule method and/or AppServerModule were not exported from: ${serverBundlePath}.`, + const renderWorker = new Piscina({ + filename: require.resolve('./render-worker'), + maxThreads: 1, + workerData: { zonePackage }, + }); + + try { + for (const { path: outputPath, baseHref } of browserResult.outputs) { + const localeDirectory = path.relative(browserResult.baseOutputPath, outputPath); + const browserIndexOutputPath = path.join(outputPath, 'index.html'); + const indexHtml = await fs.promises.readFile(browserIndexOutputPath, 'utf8'); + const serverBundlePath = await _getServerModuleBundlePath( + options, + context, + serverResult, + localeDirectory, ); - } - // Load platform server module renderer - const renderOpts = { - document: indexHtml, - url: options.route, - }; - - let html = await renderModuleFn(AppServerModule, renderOpts); - // Overwrite the client index file. - const outputIndexPath = options.outputIndexPath - ? path.join(root, options.outputIndexPath) - : browserIndexOutputPath; - - if (inlineCriticalCssProcessor) { - const { content, warnings, errors } = await inlineCriticalCssProcessor.process(html, { - outputPath, + let html: string = await renderWorker.run({ + serverBundlePath, + document: indexHtml, + url: options.route, }); - html = content; - if (warnings.length || errors.length) { - spinner.stop(); - warnings.forEach((m) => context.logger.warn(m)); - errors.forEach((m) => context.logger.error(m)); - spinner.start(); + // Overwrite the client index file. + const outputIndexPath = options.outputIndexPath + ? path.join(root, options.outputIndexPath) + : browserIndexOutputPath; + + if (inlineCriticalCssProcessor) { + const { content, warnings, errors } = await inlineCriticalCssProcessor.process(html, { + outputPath, + }); + html = content; + + if (warnings.length || errors.length) { + spinner.stop(); + warnings.forEach((m) => context.logger.warn(m)); + errors.forEach((m) => context.logger.error(m)); + spinner.start(); + } } - } - await fs.promises.writeFile(outputIndexPath, html); + await fs.promises.writeFile(outputIndexPath, html); - if (browserOptions.serviceWorker) { - await augmentAppWithServiceWorker( - projectRoot, - root, - outputPath, - baseHref ?? '/', - browserOptions.ngswConfigPath, - ); + if (browserOptions.serviceWorker) { + await augmentAppWithServiceWorker( + projectRoot, + root, + outputPath, + baseHref ?? '/', + browserOptions.ngswConfigPath, + ); + } } + } finally { + await renderWorker.destroy(); } return browserResult; diff --git a/packages/angular_devkit/build_angular/src/builders/app-shell/render-worker.ts b/packages/angular_devkit/build_angular/src/builders/app-shell/render-worker.ts new file mode 100644 index 000000000000..e68fa92874ea --- /dev/null +++ b/packages/angular_devkit/build_angular/src/builders/app-shell/render-worker.ts @@ -0,0 +1,81 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import type { Type } from '@angular/core'; +import type * as platformServer from '@angular/platform-server'; +import assert from 'assert'; +import { workerData } from 'worker_threads'; + +/** + * The fully resolved path to the zone.js package that will be loaded during worker initialization. + * This is passed as workerData when setting up the worker via the `piscina` package. + */ +const { zonePackage } = workerData as { + zonePackage: string; +}; + +/** + * A request to render a Server bundle generate by the universal server builder. + */ +interface RenderRequest { + /** + * The path to the server bundle that should be loaded and rendered. + */ + serverBundlePath: string; + /** + * The existing HTML document as a string that will be augmented with the rendered application. + */ + document: string; + /** + * An optional URL path that represents the Angular route that should be rendered. + */ + url: string | undefined; +} + +/** + * Renders an application based on a provided server bundle path, initial document, and optional URL route. + * @param param0 A request to render a server bundle. + * @returns A promise that resolves to the render HTML document for the application. + */ +async function render({ serverBundlePath, document, url }: RenderRequest): Promise { + const { AppServerModule, renderModule } = (await import(serverBundlePath)) as { + renderModule: typeof platformServer.renderModule | undefined; + AppServerModule: Type | undefined; + }; + + assert(renderModule, `renderModule was not exported from: ${serverBundlePath}.`); + assert(AppServerModule, `AppServerModule was not exported from: ${serverBundlePath}.`); + + // Render platform server module + const html = await renderModule(AppServerModule, { + document, + url, + }); + + return html; +} + +/** + * Initializes the worker when it is first created by loading the Zone.js package + * into the worker instance. + * + * @returns A promise resolving to the render function of the worker. + */ +async function initialize() { + // Setup Zone.js + await import(zonePackage); + + // Return the render function for use + return render; +} + +/** + * The default export will be the promise returned by the initialize function. + * This is awaited by piscina prior to using the Worker. + */ +export default initialize(); From e3e78776782da9d933f7b0e4c6bf391a62585bee Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 7 Nov 2022 16:23:00 -0500 Subject: [PATCH 04/17] fix(@angular-devkit/architect): default to failure if no builder result is provided Currently, if an architect builder does not provide any results, the CLI will crash trying to access an error message property on the result. Instead architect will now provide a default failure result `{ success: false }` in the event that the builder exits prior to generating a result. Thrown errors continue to be propagated as before. (cherry picked from commit 774e83df8b6c7d854881519c46458f73994f0dc0) --- packages/angular_devkit/architect/src/create-builder.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/angular_devkit/architect/src/create-builder.ts b/packages/angular_devkit/architect/src/create-builder.ts index 6aa83bd36cab..8bc03daf1921 100644 --- a/packages/angular_devkit/architect/src/create-builder.ts +++ b/packages/angular_devkit/architect/src/create-builder.ts @@ -8,7 +8,7 @@ import { analytics, experimental, json, logging } from '@angular-devkit/core'; import { Observable, Subscription, from, isObservable, of, throwError } from 'rxjs'; -import { mergeMap, tap } from 'rxjs/operators'; +import { defaultIfEmpty, mergeMap, tap } from 'rxjs/operators'; import { BuilderContext, BuilderHandlerFn, @@ -219,6 +219,7 @@ export function createBuilder { progress({ state: BuilderProgressState.Running, current: total }, context); progress({ state: BuilderProgressState.Stopped }, context); From ac3d230cd0dd416b52a2342948a01d1d687eb491 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Wed, 9 Nov 2022 10:33:17 +0000 Subject: [PATCH 05/17] release: cut the v14.2.9 release --- CHANGELOG.md | 22 ++++++++++++++++++++++ package.json | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3535eea856a1..d2cbc2dff61e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,25 @@ + + +# 14.2.9 (2022-11-09) + +### @angular-devkit/architect + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------- | +| [e3e787767](https://github.com/angular/angular-cli/commit/e3e78776782da9d933f7b0e4c6bf391a62585bee) | fix | default to failure if no builder result is provided | + +### @angular-devkit/build-angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------- | +| [12b2dc5a2](https://github.com/angular/angular-cli/commit/12b2dc5a2374f992df151af32cc80e2c2d7c4dee) | fix | isolate zone.js usage when rendering server bundles | + +## Special Thanks + +Alan Agius and Charles Lyding + + + # 14.2.8 (2022-11-02) diff --git a/package.json b/package.json index bf797d1c6a2d..fb1d8654b2ba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@angular/devkit-repo", - "version": "14.2.8", + "version": "14.2.9", "private": true, "description": "Software Development Kit for Angular", "bin": { From 7541e04f36ff32118e93588be38dcbb5cc2c92a9 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Wed, 9 Nov 2022 13:40:43 +0000 Subject: [PATCH 06/17] fix(@angular/cli): respect registry in RC when running update through yarn This commit fixes an issue where when `ng update` was ran using `yarn` (`yarn ng update`) the registry was always being overridden to `https://registry.yarnpkg.com`. This is because yarn will set the `npm_config_registry` env variable to `https://registry.yarnpkg.com` even when an RC file is present with a different repository. (cherry picked from commit 0dcb1998ad970747b7f4d7de1976e6a8ca3c5765) --- .../angular/cli/src/utilities/package-metadata.ts | 12 ++++++++++++ .../e2e/tests/update/update-secure-registry.ts | 13 ++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/angular/cli/src/utilities/package-metadata.ts b/packages/angular/cli/src/utilities/package-metadata.ts index e7a448aa8d61..faded207495f 100644 --- a/packages/angular/cli/src/utilities/package-metadata.ts +++ b/packages/angular/cli/src/utilities/package-metadata.ts @@ -139,6 +139,18 @@ function readOptions( continue; } + if ( + normalizedName === 'registry' && + rcOptions['registry'] && + value === 'https://registry.yarnpkg.com' && + process.env['npm_config_user_agent']?.includes('yarn') + ) { + // When running `ng update` using yarn (`yarn ng update`), yarn will set the `npm_config_registry` env variable to `https://registry.yarnpkg.com` + // even when an RC file is present with a different repository. + // This causes the registry specified in the RC to always be overridden with the below logic. + continue; + } + normalizedName = normalizedName.replace(/(?!^)_/g, '-'); // don't replace _ at the start of the key.s envVariablesOptions[normalizedName] = value; } diff --git a/tests/legacy-cli/e2e/tests/update/update-secure-registry.ts b/tests/legacy-cli/e2e/tests/update/update-secure-registry.ts index 18ab56859984..a06929f22fbd 100644 --- a/tests/legacy-cli/e2e/tests/update/update-secure-registry.ts +++ b/tests/legacy-cli/e2e/tests/update/update-secure-registry.ts @@ -1,7 +1,9 @@ -import { ng } from '../../utils/process'; +import { exec, ng } from '../../utils/process'; import { createNpmConfigForAuthentication } from '../../utils/registry'; import { expectToFail } from '../../utils/utils'; import { isPrereleaseCli } from '../../utils/project'; +import { getActivePackageManager } from '../../utils/packages'; +import assert from 'node:assert'; export default async function () { // The environment variable has priority over the .npmrc @@ -32,4 +34,13 @@ export default async function () { await createNpmConfigForAuthentication(true, true); await expectToFail(() => ng('update', ...extraArgs)); + + if (getActivePackageManager() === 'yarn') { + // When running `ng update` using yarn (`yarn ng update`), yarn will set the `npm_config_registry` env variable to `https://registry.yarnpkg.com` + // Validate the the registry in the RC is used. + await createNpmConfigForAuthentication(true, true); + + const error = await expectToFail(() => exec('yarn', 'ng', 'update', ...extraArgs)); + assert.match(error.message, /not allowed to access package/); + } } From 21cea0b42f08bf56990bdade82e2daa7c33011ed Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Wed, 16 Nov 2022 11:24:22 +0000 Subject: [PATCH 07/17] fix(@angular-devkit/build-angular): update `loader-utils` to `3.2.1` `loader-utils` is vulnerable to Regular Expression Denial of Service (ReDoS) via url variable. See: https://github.com/advisories/GHSA-3rfm-jhwj-7488 Closes #24241 --- package.json | 2 +- packages/angular_devkit/build_angular/package.json | 2 +- yarn.lock | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index fb1d8654b2ba..786fb683cf27 100644 --- a/package.json +++ b/package.json @@ -170,7 +170,7 @@ "less-loader": "11.0.0", "license-checker": "^25.0.0", "license-webpack-plugin": "4.0.2", - "loader-utils": "3.2.0", + "loader-utils": "3.2.1", "magic-string": "0.26.2", "mini-css-extract-plugin": "2.6.1", "minimatch": "5.1.0", diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index dd78c668e02a..ff68b5ad8fc4 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -38,7 +38,7 @@ "less": "4.1.3", "less-loader": "11.0.0", "license-webpack-plugin": "4.0.2", - "loader-utils": "3.2.0", + "loader-utils": "3.2.1", "mini-css-extract-plugin": "2.6.1", "minimatch": "5.1.0", "open": "8.4.0", diff --git a/yarn.lock b/yarn.lock index 5570f36cabd7..12879154c1af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7317,6 +7317,11 @@ loader-utils@3.2.0: resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.2.0.tgz#bcecc51a7898bee7473d4bc6b845b23af8304d4f" integrity sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ== +loader-utils@3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.2.1.tgz#4fb104b599daafd82ef3e1a41fb9265f87e1f576" + integrity sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw== + loader-utils@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129" From 87277d918ce95e05cd2f5eaf07241a4513f7c3e4 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Wed, 16 Nov 2022 12:59:38 +0000 Subject: [PATCH 08/17] test(@angular/cli): update NPM range in npm-7 test With the previous range NPM 9 was being installed which is not compatible with the version of node that Angular version 13 supports. --- tests/legacy-cli/e2e/tests/misc/npm-7.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/legacy-cli/e2e/tests/misc/npm-7.ts b/tests/legacy-cli/e2e/tests/misc/npm-7.ts index 31cf1a3ad668..3417766b329b 100644 --- a/tests/legacy-cli/e2e/tests/misc/npm-7.ts +++ b/tests/legacy-cli/e2e/tests/misc/npm-7.ts @@ -45,8 +45,8 @@ export default async function () { } try { - // Install version >=7.5.6 - await npm('install', '--global', 'npm@>=7.5.6'); + // Install version ^7.5.6 + await npm('install', '--global', 'npm@^7.5.6'); // Ensure `ng update` does not show npm warning const { stderr: stderrUpdate1 } = await ng('update', ...extraArgs); From f1fe0ea9d4c1cd4173f1de681f0bab795d09b586 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Wed, 16 Nov 2022 13:14:54 +0000 Subject: [PATCH 09/17] test(@angular/cli): remove `node:assert` usage. `node:assert` is not available in Node.js version 14.15.5 --- tests/legacy-cli/e2e/tests/update/update-secure-registry.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/legacy-cli/e2e/tests/update/update-secure-registry.ts b/tests/legacy-cli/e2e/tests/update/update-secure-registry.ts index a06929f22fbd..9d0d89d531c5 100644 --- a/tests/legacy-cli/e2e/tests/update/update-secure-registry.ts +++ b/tests/legacy-cli/e2e/tests/update/update-secure-registry.ts @@ -3,7 +3,6 @@ import { createNpmConfigForAuthentication } from '../../utils/registry'; import { expectToFail } from '../../utils/utils'; import { isPrereleaseCli } from '../../utils/project'; import { getActivePackageManager } from '../../utils/packages'; -import assert from 'node:assert'; export default async function () { // The environment variable has priority over the .npmrc @@ -41,6 +40,8 @@ export default async function () { await createNpmConfigForAuthentication(true, true); const error = await expectToFail(() => exec('yarn', 'ng', 'update', ...extraArgs)); - assert.match(error.message, /not allowed to access package/); + if (!/not allowed to access package/.test(error.message)) { + throw new Error('Error did not match not allowed to access package.'); + } } } From 6446091a310f327ceeb68ae85f3673f6e3e83286 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 25 Oct 2022 12:04:25 -0400 Subject: [PATCH 10/17] fix(@angular/cli): exclude `@angular/material@7.x` from ng add package discovery `@angular/material@7.x` uses unbounded ranges for its framework peer dependencies. This can cause `ng add` to pick these versions of the package if the newer versions are not compatible since the peer dependency ranges would match any newer stable framework version. (cherry picked from commit 9260087bf7980fe4e7e216b7ddbadb2344022112) (cherry picked from commit 1a584364e70cafd84770ef45f3da9ad58a46083f) --- packages/angular/cli/src/commands/add/cli.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/angular/cli/src/commands/add/cli.ts b/packages/angular/cli/src/commands/add/cli.ts index d65cd78e4278..1fd2c58f975c 100644 --- a/packages/angular/cli/src/commands/add/cli.ts +++ b/packages/angular/cli/src/commands/add/cli.ts @@ -50,6 +50,8 @@ interface AddCommandArgs extends SchematicsCommandArgs { const packageVersionExclusions: Record = { // @angular/localize@9.x versions do not have peer dependencies setup '@angular/localize': '9.x', + // @angular/material@7.x versions have unbounded peer dependency ranges (>=7.0.0) + '@angular/material': '7.x', }; export class AddCommandModule From 9ce386caf6037f21f422a785fec977634406d208 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Thu, 27 Oct 2022 21:25:15 +0200 Subject: [PATCH 11/17] =?UTF-8?q?fix(@angular/cli):=20exclude=20`@angular/?= =?UTF-8?q?localize@<10.0.0`=20from=20ng=20add=20pa=E2=80=A6=20(#24152)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(@angular/cli): exclude `@angular/localize@<10.0.0` from ng add package discovery `@angular/localize@<10.0.0` has no peer dependencies. This can cause `ng add` to pick these versions of the package if the newer versions. See: https://app.circleci.com/pipelines/github/angular/angular-cli/27402/workflows/faa64532-541a-4bea-b599-3c53afe42019/jobs/364822 ``` Test Process error Error: Process exit error - "ng add @angular/localize --skip-confirmation": 1... STDOUT: STDERR: npm version 7.4.0 detected. When using npm 7 with the Angular CLI, npm version 7.5.6 or higher is recommended. - Determining package manager... ℹ Using package manager: npm - Searching for compatible package version... ✔ Found compatible package version: @angular/localize@10.0.0-next.7. - Loading package information from registry... ✔ Package information loaded. - Installing packages... ✔ Packages successfully installed. NOT SUPPORTED: keyword "id", use "$id" for schema ID ``` * fixup! fix(@angular/cli): exclude `@angular/localize@<10.0.0` from ng add package discovery Co-authored-by: Charles <19598772+clydin@users.noreply.github.com> Co-authored-by: Charles <19598772+clydin@users.noreply.github.com> (cherry picked from commit 65a0983a416067d160103ce244a580cf04929905) (cherry picked from commit 35e5f4278145b7ef55a75f1692c8e92d6bcd59db) --- packages/angular/cli/src/commands/add/cli.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/angular/cli/src/commands/add/cli.ts b/packages/angular/cli/src/commands/add/cli.ts index 1fd2c58f975c..55768138e4f2 100644 --- a/packages/angular/cli/src/commands/add/cli.ts +++ b/packages/angular/cli/src/commands/add/cli.ts @@ -10,7 +10,7 @@ import { analytics, tags } from '@angular-devkit/core'; import { NodePackageDoesNotSupportSchematics } from '@angular-devkit/schematics/tools'; import npa from 'npm-package-arg'; import { dirname, join } from 'path'; -import { compare, intersects, prerelease, satisfies, valid } from 'semver'; +import { Range, compare, intersects, prerelease, satisfies, valid } from 'semver'; import { Argv } from 'yargs'; import { PackageManager } from '../../../lib/config/workspace-schema'; import { isPackageNameSafeForAnalytics } from '../../analytics/analytics'; @@ -47,10 +47,10 @@ interface AddCommandArgs extends SchematicsCommandArgs { * when attempting to find a compatible version for a package. * The key is a package name and the value is a SemVer range of versions to exclude. */ -const packageVersionExclusions: Record = { - // @angular/localize@9.x versions do not have peer dependencies setup - '@angular/localize': '9.x', - // @angular/material@7.x versions have unbounded peer dependency ranges (>=7.0.0) +const packageVersionExclusions: Record = { + // @angular/localize@9.x and earlier versions as well as @angular/localize@10.0 prereleases do not have peer dependencies setup. + '@angular/localize': '<10.0.0', + // @angular/material@7.x versions have unbounded peer dependency ranges (>=7.0.0). '@angular/material': '7.x', }; @@ -189,7 +189,10 @@ export class AddCommandModule return false; } // Excluded package versions should not be considered - if (versionExclusions && satisfies(value.version, versionExclusions)) { + if ( + versionExclusions && + satisfies(value.version, versionExclusions, { includePrerelease: true }) + ) { return false; } From 9dcea09c098596b7d72ea1fe90de45165b86b0b4 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Thu, 17 Nov 2022 10:46:51 +0000 Subject: [PATCH 12/17] test(@angular/cli): fix version specifier test Remove `ng add @angular/localize@latest` test. This is currently failing as `@angular/localize@latest` does not support Node.js version 14.15 --- tests/legacy-cli/e2e/tests/commands/add/version-specifier.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/legacy-cli/e2e/tests/commands/add/version-specifier.ts b/tests/legacy-cli/e2e/tests/commands/add/version-specifier.ts index 426f8d5b61e5..5b598ccc9cfb 100644 --- a/tests/legacy-cli/e2e/tests/commands/add/version-specifier.ts +++ b/tests/legacy-cli/e2e/tests/commands/add/version-specifier.ts @@ -25,11 +25,6 @@ export default async function () { throw new Error('Installation was not skipped'); } - const output2 = await ng('add', '@angular/localize@latest', '--skip-confirmation'); - if (output2.stdout.includes('Skipping installation: Package already installed')) { - throw new Error('Installation should not have been skipped'); - } - // v12.2.0 has a package.json engine field that supports Node.js v16+ const output3 = await ng('add', '@angular/localize@12.2.0', '--skip-confirmation'); if (output3.stdout.includes('Skipping installation: Package already installed')) { From e9d30d43a0338957e083f5d08a613d669d527899 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Thu, 17 Nov 2022 11:17:28 -0800 Subject: [PATCH 13/17] release: cut the v14.2.10 release --- CHANGELOG.md | 24 ++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2cbc2dff61e..ce54af5a8afd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ + + +# 14.2.10 (2022-11-17) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------------------------------------------------------- | +| [9ce386caf](https://github.com/angular/angular-cli/commit/9ce386caf6037f21f422a785fec977634406d208) | fix | exclude `@angular/localize@<10.0.0` from ng add pa… ([#24152](https://github.com/angular/angular-cli/pull/24152)) | +| [6446091a3](https://github.com/angular/angular-cli/commit/6446091a310f327ceeb68ae85f3673f6e3e83286) | fix | exclude `@angular/material@7.x` from ng add package discovery | +| [7541e04f3](https://github.com/angular/angular-cli/commit/7541e04f36ff32118e93588be38dcbb5cc2c92a9) | fix | respect registry in RC when running update through yarn | + +### @angular-devkit/build-angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------- | +| [21cea0b42](https://github.com/angular/angular-cli/commit/21cea0b42f08bf56990bdade82e2daa7c33011ed) | fix | update `loader-utils` to `3.2.1` | + +## Special Thanks + +Alan Agius and Charles Lyding + + + # 14.2.9 (2022-11-09) diff --git a/package.json b/package.json index 786fb683cf27..58c41089bc70 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@angular/devkit-repo", - "version": "14.2.9", + "version": "14.2.10", "private": true, "description": "Software Development Kit for Angular", "bin": { From 31e8a58dc12196293cdddcf61376f4e902d559d5 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Thu, 17 Nov 2022 09:02:12 +0000 Subject: [PATCH 14/17] ci: create daily_run_workflow for 14.2.x branch This workflow is used by circle ci scheduled pipelines which is required to create a cron job when using dynamic configurations. See: https://circleci.com/docs/scheduled-pipelines/?utm_source=google&utm_medium=sem&utm_campaign=sem-google-dg--emea-en-dsa-maxConv-auth-nb&utm_term=g_-_c__dsa_&utm_content=&gclid=Cj0KCQiA1NebBhDDARIsAANiDD2Ja2WCBYtxifWx9d8uD2bEZzDjtO4mB2aq7fEtvoUKZZ8GeQbeNtgaAoW5EALw_wcB and https://app.circleci.com/settings/project/github/angular/angular-cli/triggers?return-to=https%3A%2F%2Fapp.circleci.com%2Fpipelines%2Fgithub%2Fangular%2Fangular-cli&triggerSource=&scheduledTriggerId=8e3e6898-fd55-41b1-a3e8-85c52981d941&success=true --- .circleci/dynamic_config.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.circleci/dynamic_config.yml b/.circleci/dynamic_config.yml index 0ecc28f51b54..4d885997d74d 100644 --- a/.circleci/dynamic_config.yml +++ b/.circleci/dynamic_config.yml @@ -385,6 +385,9 @@ jobs: workflows: version: 2 default_workflow: + when: + not: + equal: [scheduled_pipeline, << pipeline.trigger_source >>] jobs: # Linux jobs - setup @@ -485,3 +488,21 @@ workflows: <<: *only_pull_requests requires: - build + + daily_run_workflow: + when: + and: + - equal: [scheduled_pipeline, << pipeline.trigger_source >>] + - equal: ['14.2.x nightly run', << pipeline.schedule.name >>] + jobs: + - setup + - build: + requires: + - setup + - e2e-tests: + name: e2e-cli-nightly + requires: + - build + - test-browsers: + requires: + - build From 6df825df2f7c73365b452207b720852ea321446a Mon Sep 17 00:00:00 2001 From: Joey Perrott Date: Wed, 15 Mar 2023 15:48:12 +0000 Subject: [PATCH 15/17] ci: update to latest version of dev-infra orb --- .circleci/dynamic_config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/dynamic_config.yml b/.circleci/dynamic_config.yml index 4d885997d74d..5ea0540093ad 100644 --- a/.circleci/dynamic_config.yml +++ b/.circleci/dynamic_config.yml @@ -11,7 +11,7 @@ version: 2.1 orbs: browser-tools: circleci/browser-tools@1.1.3 - devinfra: angular/dev-infra@1.0.7 + devinfra: angular/dev-infra@1.0.8 parameters: snapshot_changed: From ddd33bf38d7d76e816ebc0459559917da514477d Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Wed, 15 Mar 2023 15:16:58 +0000 Subject: [PATCH 16/17] fix(@angular-devkit/build-angular): update webpack dependency to `5.76.1` Closes #24861 --- package.json | 2 +- .../angular_devkit/build_angular/package.json | 2 +- .../angular_devkit/build_webpack/package.json | 2 +- packages/ngtools/webpack/package.json | 2 +- yarn.lock | 30 +++++++++++++++++++ 5 files changed, 34 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 58c41089bc70..a3f463975d5a 100644 --- a/package.json +++ b/package.json @@ -218,7 +218,7 @@ "typescript": "4.8.1-rc", "verdaccio": "5.14.0", "verdaccio-auth-memory": "^10.0.0", - "webpack": "5.74.0", + "webpack": "5.76.1", "webpack-dev-middleware": "5.3.3", "webpack-dev-server": "4.11.0", "webpack-merge": "5.8.0", diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index ff68b5ad8fc4..8faa3369da54 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -63,7 +63,7 @@ "text-table": "0.2.0", "tree-kill": "1.2.2", "tslib": "2.4.0", - "webpack": "5.74.0", + "webpack": "5.76.1", "webpack-dev-middleware": "5.3.3", "webpack-dev-server": "4.11.0", "webpack-merge": "5.8.0", diff --git a/packages/angular_devkit/build_webpack/package.json b/packages/angular_devkit/build_webpack/package.json index cf5d07bee2dd..3e7ae03cbc49 100644 --- a/packages/angular_devkit/build_webpack/package.json +++ b/packages/angular_devkit/build_webpack/package.json @@ -13,7 +13,7 @@ "devDependencies": { "@angular-devkit/core": "0.0.0-PLACEHOLDER", "node-fetch": "2.6.7", - "webpack": "5.74.0" + "webpack": "5.76.1" }, "peerDependencies": { "webpack": "^5.30.0", diff --git a/packages/ngtools/webpack/package.json b/packages/ngtools/webpack/package.json index cca17e02995a..d6e21e5be3ad 100644 --- a/packages/ngtools/webpack/package.json +++ b/packages/ngtools/webpack/package.json @@ -31,6 +31,6 @@ "@angular/compiler": "14.1.2", "@angular/compiler-cli": "14.1.2", "typescript": "4.8.1-rc", - "webpack": "5.74.0" + "webpack": "5.76.1" } } diff --git a/yarn.lock b/yarn.lock index 12879154c1af..122ef4f4af5b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11420,6 +11420,36 @@ webpack@5.74.0: watchpack "^2.4.0" webpack-sources "^3.2.3" +webpack@5.76.1: + version "5.76.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.1.tgz#7773de017e988bccb0f13c7d75ec245f377d295c" + integrity sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^0.0.51" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.7.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.10.0" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.4.0" + webpack-sources "^3.2.3" + websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4" resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" From d17791888c965e9732a7c9538f0322081eb6fa87 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Thu, 16 Mar 2023 08:54:23 +0000 Subject: [PATCH 17/17] release: cut the v14.2.11 release --- CHANGELOG.md | 16 ++++++++++++++++ package.json | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce54af5a8afd..fb5950fcca23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ + + +# 14.2.11 (2023-03-16) + +### @angular-devkit/build-angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------- | +| [ddd33bf38](https://github.com/angular/angular-cli/commit/ddd33bf38d7d76e816ebc0459559917da514477d) | fix | update webpack dependency to `5.76.1` | + +## Special Thanks + +Alan Agius and Joey Perrott + + + # 14.2.10 (2022-11-17) diff --git a/package.json b/package.json index a3f463975d5a..a0bad3b2e992 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@angular/devkit-repo", - "version": "14.2.10", + "version": "14.2.11", "private": true, "description": "Software Development Kit for Angular", "bin": {