mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
Compare commits
131 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| caecd1889b | |||
| d8f637ab43 | |||
| 46bd8f2495 | |||
| d84a4eb90f | |||
| 692e8ab21e | |||
| 5d64d17a52 | |||
| 9c6399926a | |||
| 75fc846745 | |||
| debe517d4f | |||
| e29f1d9cf8 | |||
| 553eb2cc9f | |||
| 30d959a48a | |||
| fdcb420bd7 | |||
| 524b4d5a1f | |||
| fb64f711f8 | |||
| e7e78e6709 | |||
| 8233906be2 | |||
| b8183614f5 | |||
| b46ce7d42f | |||
| 36bf0ae985 | |||
| 3b317dcf87 | |||
| 3ad527d86e | |||
| b6ff762e36 | |||
| e196311e5c | |||
| 3cf8f66f3a | |||
| d7b6416fcf | |||
| fc7f92159d | |||
| cb8e51f8cf | |||
| e6b2bedd70 | |||
| 58a19a3021 | |||
| f70d2a2981 | |||
| 3bbf00fdd4 | |||
| 19fa033f79 | |||
| 513b17043e | |||
| c501e86fd2 | |||
| e849e57059 | |||
| e31ed3d0dc | |||
| 545972e5e9 | |||
| 38d51e4926 | |||
| 535837e617 | |||
| bb6555979d | |||
| 738b23347e | |||
| cd8b1a5087 | |||
| c9def401f8 | |||
| dfd6337bc9 | |||
| fe6a5acd17 | |||
| 768a6698a0 | |||
| cd10a4cc13 | |||
| 1e811df79f | |||
| a701c10b77 | |||
| 510931a7ab | |||
| 92fa1a6cc0 | |||
| 616133c704 | |||
| c792dd739a | |||
| 83fa3ee581 | |||
| 304c85edd0 | |||
| 1e39e11ba0 | |||
| e0a8ca7eee | |||
| 6449590ec8 | |||
| 1939613f71 | |||
| 6d6638c1e9 | |||
| cda9d16838 | |||
| 19fd2f4125 | |||
| 7a67597d01 | |||
| ec0a3007c6 | |||
| 67ae442edc | |||
| 9136dbd65c | |||
| 4a1d9a78fa | |||
| 0f8ae8bf7f | |||
| c42b50cfbe | |||
| a3bc29bbb2 | |||
| 387dcc6621 | |||
| 029060f2d6 | |||
| a53d26847c | |||
| 21e2b93046 | |||
| 92012ec4fd | |||
| 6ca81a706c | |||
| 0baabcb7da | |||
| dc6cb5a3d4 | |||
| 7da3570be8 | |||
| ec192b2b71 | |||
| 55fe2c667d | |||
| 8a3d2aad30 | |||
| dd3abdb9d9 | |||
| d93427b806 | |||
| 032e65c895 | |||
| ee05a285f9 | |||
| 4371ff9092 | |||
| a26b0dcc72 | |||
| 30c5b9c144 | |||
| 673f7a7954 | |||
| cdc8c7cad0 | |||
| bd7f0d8b70 | |||
| 3a9ce61ea4 | |||
| ae98b24eb7 | |||
| 4997a3f692 | |||
| 6a59e6b009 | |||
| 6f80c55dbd | |||
| 07846e550c | |||
| f18131f372 | |||
| f24b94f5d9 | |||
| 6caafc2062 | |||
| f883aaeb89 | |||
| 2215af252c | |||
| db4147b4d2 | |||
| 2dc6efed4e | |||
| 1d307bc5bf | |||
| aace1e71d8 | |||
| fbfec946a7 | |||
| 0e47334db8 | |||
| e4f62c12f5 | |||
| ea3a14805e | |||
| a96f9c91a2 | |||
| a8c0f4f1ba | |||
| 11ef03b36f | |||
| 8e798effe4 | |||
| 54f73530a8 | |||
| 61080ea4bc | |||
| 4116d5d18f | |||
| 5572278826 | |||
| b442c4991d | |||
| 014763e42c | |||
| 86cfbf8c8a | |||
| 3b92b4abd3 | |||
| dd6e80aac5 | |||
| da50b9b5e7 | |||
| 86e4b3cdf9 | |||
| 3fddcb5364 | |||
| d5cc87dc88 | |||
| b075721a49 | |||
| 3346cb6e4e |
@@ -114,11 +114,11 @@ build:remote --cpu=k8
|
||||
build:remote --host_cpu=k8
|
||||
|
||||
# Toolchain and platform related flags
|
||||
build:remote --crosstool_top=//dev-infra/bazel/remote-execution/cpp:cc_toolchain_suite
|
||||
build:remote --extra_toolchains=//dev-infra/bazel/remote-execution/cpp:cc_toolchain
|
||||
build:remote --extra_execution_platforms=//dev-infra/bazel/remote-execution:platform
|
||||
build:remote --host_platform=//dev-infra/bazel/remote-execution:platform
|
||||
build:remote --platforms=//dev-infra/bazel/remote-execution:platform
|
||||
build:remote --crosstool_top=@npm//@angular/dev-infra-private/bazel/remote-execution/cpp:cc_toolchain_suite
|
||||
build:remote --extra_toolchains=@npm//@angular/dev-infra-private/bazel/remote-execution/cpp:cc_toolchain
|
||||
build:remote --extra_execution_platforms=@npm//@angular/dev-infra-private/bazel/remote-execution:platform
|
||||
build:remote --host_platform=@npm//@angular/dev-infra-private/bazel/remote-execution:platform
|
||||
build:remote --platforms=@npm//@angular/dev-infra-private/bazel/remote-execution:platform
|
||||
|
||||
# Remote instance and caching
|
||||
build:remote --remote_instance_name=projects/internal-200822/instances/primary_instance
|
||||
|
||||
@@ -24,15 +24,15 @@ version: 2.1
|
||||
# **NOTE 2 **: If you change the cache key prefix, also sync the cache_key_fallback to match.
|
||||
# **NOTE 3 **: Keep the static part of the cache key as prefix to enable correct fallbacks.
|
||||
# See https://circleci.com/docs/2.0/caching/#restoring-cache for how prefixes work in CircleCI.
|
||||
var_3: &cache_key v4-angular-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "aio/yarn.lock" }}
|
||||
var_3: &cache_key v1-angular-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "aio/yarn.lock" }}
|
||||
# We invalidate the cache if the Bazel version changes because otherwise the `bazelisk` cache
|
||||
# folder will contain all previously used versions and ultimately cause the cache restoring to
|
||||
# be slower due to its growing size.
|
||||
var_4: &cache_key_fallback v4-angular-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
|
||||
var_4: &cache_key_fallback v1-angular-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
|
||||
|
||||
# Windows needs its own cache key because binaries in node_modules are different.
|
||||
var_3_win: &cache_key_win v4-angular-win-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "aio/yarn.lock" }}
|
||||
var_4_win: &cache_key_win_fallback v4-angular-win-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
|
||||
var_3_win: &cache_key_win v1-angular-win-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "aio/yarn.lock" }}
|
||||
var_4_win: &cache_key_win_fallback v1-angular-win-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
|
||||
|
||||
# Cache key for the `components-repo-unit-tests` job. **Note** when updating the SHA in the
|
||||
# cache keys also update the SHA for the "COMPONENTS_REPO_COMMIT" environment variable.
|
||||
|
||||
@@ -12,6 +12,7 @@ body:
|
||||
- common
|
||||
- compiler-cli
|
||||
- compiler
|
||||
- core
|
||||
- elements
|
||||
- forms
|
||||
- language-service
|
||||
|
||||
@@ -38,7 +38,6 @@ merge:
|
||||
- 'modules/benchmarks/**'
|
||||
- 'modules/system.d.ts'
|
||||
- 'packages/**'
|
||||
- 'dev-infra/benchmark/driver-utilities/**'
|
||||
# list of patterns to ignore for the files changed by the PR
|
||||
exclude:
|
||||
- 'packages/*'
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
name: DevInfra
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
jobs:
|
||||
breaking-changes-label:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: angular/dev-infra/github-actions/breaking-changes-label@861dc90572784e714aeaa9dfb20ceebeb57cdb07
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
+1
-2
@@ -106,8 +106,7 @@ Fixes #<issue number>
|
||||
# │ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
|
||||
# │ elements|forms|http|language-service|localize|platform-browser|
|
||||
# │ platform-browser-dynamic|platform-server|router|service-worker|
|
||||
# │ upgrade|zone.js|packaging|changelog|dev-infra|docs-infra|migrations|
|
||||
# │ ngcc|ve
|
||||
# │ upgrade|zone.js|packaging|changelog|docs-infra|migrations|ngcc|ve
|
||||
# │ https://github.com/angular/angular/blob/master/CONTRIBUTING.md#scope
|
||||
# │
|
||||
# └─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|style|test
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {CaretakerConfig} from '../dev-infra/caretaker/config';
|
||||
import {CaretakerConfig} from '@angular/dev-infra-private/ng-dev/caretaker/config';
|
||||
|
||||
/** The configuration for `ng-dev caretaker` commands. */
|
||||
export const caretaker: CaretakerConfig = {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {CommitMessageConfig} from '../dev-infra/commit-message/config';
|
||||
import {CommitMessageConfig} from '@angular/dev-infra-private/ng-dev/commit-message/config';
|
||||
|
||||
/**
|
||||
* The configuration for `ng-dev commit-message` commands.
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import {FormatConfig} from '../dev-infra/format/config';
|
||||
import {FormatConfig} from '@angular/dev-infra-private/ng-dev/format/config';
|
||||
|
||||
/**
|
||||
* Configuration for the `ng-dev format` command.
|
||||
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
import {GithubConfig} from '../dev-infra/utils/config';
|
||||
import {GithubConfig} from '@angular/dev-infra-private/ng-dev/utils/config';
|
||||
|
||||
/**
|
||||
* Github configuration for the `ng-dev` command. This repository is used as
|
||||
* remote for the merge script and other utilities like `ng-dev pr rebase`.
|
||||
*/
|
||||
|
||||
export const github: GithubConfig = {
|
||||
owner: 'angular',
|
||||
name: 'angular'
|
||||
name: 'angular',
|
||||
mainBranchName: 'master',
|
||||
};
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
import {DevInfraMergeConfig} from '../dev-infra/pr/merge/config';
|
||||
import {getDefaultTargetLabelConfiguration} from '../dev-infra/pr/merge/defaults';
|
||||
import {DevInfraMergeConfig} from '@angular/dev-infra-private/ng-dev/pr/merge/config';
|
||||
import {getDefaultTargetLabelConfiguration} from '@angular/dev-infra-private/ng-dev/pr/merge/defaults';
|
||||
import {github} from './github';
|
||||
import {release} from './release';
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import {ReleaseConfig} from '@angular/dev-infra-private/ng-dev/release/config';
|
||||
import {join} from 'path';
|
||||
import {ReleaseConfig} from '../dev-infra/release/config';
|
||||
|
||||
/** Configuration for the `ng-dev release` command. */
|
||||
export const release: ReleaseConfig = {
|
||||
|
||||
+1
-6
@@ -190,7 +190,6 @@ groups:
|
||||
- JiaLiPassion # Jia Li
|
||||
- JoostK # Joost Koehoorn
|
||||
- josephperrott # Joey Perrott
|
||||
- kyliau # Keen Yee Liau
|
||||
- manughub # Manu Murthy
|
||||
- mgechev # Minko Gechev
|
||||
- mmalerba # Miles Malerba
|
||||
@@ -570,7 +569,6 @@ groups:
|
||||
users:
|
||||
- alan-agius4
|
||||
- alxhub
|
||||
- kyliau
|
||||
|
||||
# =========================================================
|
||||
# Framework: Router
|
||||
@@ -763,7 +761,6 @@ groups:
|
||||
users:
|
||||
- IgorMinar
|
||||
- josephperrott
|
||||
- kyliau
|
||||
|
||||
# =========================================================
|
||||
# Language Service
|
||||
@@ -781,7 +778,6 @@ groups:
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- kyliau
|
||||
- atscott
|
||||
- zarend
|
||||
|
||||
@@ -1021,7 +1017,7 @@ groups:
|
||||
users:
|
||||
- alan-agius4
|
||||
- clydin
|
||||
- kyliau
|
||||
- dgp1130
|
||||
- IgorMinar
|
||||
reviews:
|
||||
request: -1 # request reviews from everyone
|
||||
@@ -1155,7 +1151,6 @@ groups:
|
||||
'.ng-dev/**',
|
||||
'.vscode/**',
|
||||
'.yarn/**',
|
||||
'dev-infra/**',
|
||||
'docs/*.md',
|
||||
'docs/images/**',
|
||||
'goldens/*',
|
||||
|
||||
@@ -1,3 +1,98 @@
|
||||
<a name="12.2.4"></a>
|
||||
# 12.2.4 (2021-09-01)
|
||||
### compiler-cli
|
||||
| Commit | Description |
|
||||
| -- | -- |
|
||||
| [8233906be2](https://github.com/angular/angular/commit/8233906be25e19da6d8115094616d3e4b5e36fea) | fix: Emit type annotations for synthesized decorator fields ([#43021](https://github.com/angular/angular/pull/43021)) |
|
||||
## Special Thanks:
|
||||
Andrew Scott, Daniel Trevino, George Kalpakas, Joey Perrott, Kristiyan Kostadinov, nickreid and segunb
|
||||
|
||||
|
||||
<a name="12.2.3"></a>
|
||||
# 12.2.3 (2021-08-25)
|
||||
### service-worker
|
||||
| Commit | Description |
|
||||
| -- | -- |
|
||||
| [fc7f92159d](https://github.com/angular/angular/commit/fc7f92159df16e894d9909cfc8969ed4b7d9924a) | fix: NPE if onActionClick is undefined ([#43210](https://github.com/angular/angular/pull/43210)) |
|
||||
## Special Thanks:
|
||||
Daniel Trevino, Erik Slack, George Kalpakas, dario-piotrowicz and shlasouski
|
||||
|
||||
|
||||
<a name="12.2.2"></a>
|
||||
# 12.2.2 (2021-08-18)
|
||||
### animations
|
||||
| Commit | Description |
|
||||
| -- | -- |
|
||||
| [bb6555979d](https://github.com/angular/angular/commit/bb6555979dd02e706f7e98022b9c37a4f54db1ba) | fix: add pure annotations to static property initializers ([#43064](https://github.com/angular/angular/pull/43064)) |
|
||||
### core
|
||||
| Commit | Description |
|
||||
| -- | -- |
|
||||
| [738b23347e](https://github.com/angular/angular/commit/738b23347e5eeadfa0321d1429537837dba5e4c1) | fix: add pure annotations to static property initializers ([#43064](https://github.com/angular/angular/pull/43064)) |
|
||||
### platform-browser
|
||||
| Commit | Description |
|
||||
| -- | -- |
|
||||
| [535837e617](https://github.com/angular/angular/commit/535837e617a0434f8e7bd9071cc4d8c27fd9f373) | perf: avoid intermediate arrays in server transition ([#43145](https://github.com/angular/angular/pull/43145)) |
|
||||
### router
|
||||
| Commit | Description |
|
||||
| -- | -- |
|
||||
| [6449590ec8](https://github.com/angular/angular/commit/6449590ec81eff0873af911fb65679b5a77db27b) | fix: eagerly update internal state on browser-triggered navigations ([#43102](https://github.com/angular/angular/pull/43102)) |
|
||||
## Special Thanks:
|
||||
Andrew Scott, Aristeidis Bampakos, Charles Lyding, Edoardo Dusi, George Kalpakas, Joe Martin (Crowdstaffing), Joey Perrott, Kirk Larkin, Kristiyan Kostadinov, Pete Bacon Darwin, TIffany Davis, Theoklitos Bampouris, ali, dario-piotrowicz and pichuser
|
||||
|
||||
|
||||
<a name="12.2.1"></a>
|
||||
# 12.2.1 (2021-08-11)
|
||||
### router
|
||||
| Commit | Description |
|
||||
| -- | -- |
|
||||
| [dd3abdb9d9](https://github.com/angular/angular/commit/dd3abdb9d9b2c4363fb1f468a05bf449b55f55a5) | fix(router): ensure check for match options is compatible with property renaming ([#43086](https://github.com/angular/angular/pull/43086)) |
|
||||
## Special Thanks:
|
||||
Amadou Sall, Andrew Kushnir, Andrew Scott, Daniel Trevino, Erik Slack, Fabien BERNARD, George Kalpakas, Jeroen van Warmerdam, Joey Perrott, Tim Gates and Vugar_Abdullayev
|
||||
|
||||
|
||||
<a name="12.2.0"></a>
|
||||
# 12.2.0 (2021-08-04)
|
||||
### core
|
||||
| Commit | Description |
|
||||
| -- | -- |
|
||||
| [bd7f0d8b70](https://github.com/angular/angular/commit/bd7f0d8b70150a7e4e7550f4380a2e731cf2b942) | fix(core): incorrect error reported when trying to re-create view which had an error during creation ([#43005](https://github.com/angular/angular/pull/43005)) |
|
||||
### language-service
|
||||
| Commit | Description |
|
||||
| -- | -- |
|
||||
| [aace1e71d8](https://github.com/angular/angular/commit/aace1e71d8fb5e1e52fcd86e2a26892d1016c43e) | fix(language-service): global autocomplete doesn't work when the user tries to modify the symbol ([#42923](https://github.com/angular/angular/pull/42923)) |
|
||||
## Special Thanks:
|
||||
Alex Rickabaugh, Joe Martin, Joey Perrott, Kristiyan Kostadinov, Nichola Alkhouri, Paul Gschwendtner, Pete Bacon Darwin, atscott, dario-piotrowicz and ivanwonder
|
||||
|
||||
|
||||
<a name="12.2.0-rc.0"></a>
|
||||
# 12.2.0-rc.0 (2021-07-28)
|
||||
### compiler-cli
|
||||
| Commit | Description |
|
||||
| -- | -- |
|
||||
| [ed9cfb674f](https://github.com/angular/angular/commit/ed9cfb674f8e52b416ccdaf9aa9c46955b8448f5) | fix(compiler-cli): use correct module resolution context for absolute imports in .d.ts files ([#42879](https://github.com/angular/angular/pull/42879)) |
|
||||
| [5fb23eccea](https://github.com/angular/angular/commit/5fb23ecceaccf0629308dd50210b65f67d51f024) | perf(compiler-cli): skip analysis in incremental builds for files without Angular behavior ([#42562](https://github.com/angular/angular/pull/42562)) |
|
||||
### core
|
||||
| Commit | Description |
|
||||
| -- | -- |
|
||||
| [eefe1682e8](https://github.com/angular/angular/commit/eefe1682e8099b73b6e50bb227b5a7f63105c63d) | fix(core): correctly handle `null` or `undefined` in `ErrorHandler#handleError()` ([#42881](https://github.com/angular/angular/pull/42881)) |
|
||||
### forms
|
||||
| Commit | Description |
|
||||
| -- | -- |
|
||||
| [1d9d02696e](https://github.com/angular/angular/commit/1d9d02696eadbee2c2f719e432efca22f1e494e9) | feat(forms): add hasValidators, addValidators, and removeValidators methods (for both sync and async) ([#42838](https://github.com/angular/angular/pull/42838)) |
|
||||
| [a502279592](https://github.com/angular/angular/commit/a50227959222f39884aac284544d1626aee5ca64) | feat(forms): allow minLength/maxLength validator to be bound to `null` ([#42565](https://github.com/angular/angular/pull/42565)) |
|
||||
### language-service
|
||||
| Commit | Description |
|
||||
| -- | -- |
|
||||
| [7c35ca0e00](https://github.com/angular/angular/commit/7c35ca0e0030f2ded12ddca9092e31f510cebeb1) | feat(language-service): support autocomplete string literal union types in templates ([#42729](https://github.com/angular/angular/pull/42729)) |
|
||||
### router
|
||||
| Commit | Description |
|
||||
| -- | -- |
|
||||
| [0d81b007e4](https://github.com/angular/angular/commit/0d81b007e48a0ac801d2614601fb8180a3517865) | fix(router): add missing outlet events to RouterOutletContract ([#42431](https://github.com/angular/angular/pull/42431)) |
|
||||
| [dbae00195e](https://github.com/angular/angular/commit/dbae00195e114ac8b967201283962a7e2c0581b4) | feat(router): ability to provide custom route reuse strategy via DI for `RouterTestingModule` ([#42434](https://github.com/angular/angular/pull/42434)) |
|
||||
## Special Thanks:
|
||||
Andrew Scott, Daniel Trevino, Dmitrij Kuba, Dylan Hunn, George Kalpakas, Joey Perrott, JoostK, Paul Gschwendtner, Pete Bacon Darwin, Steven Masala, Teri Glover, Vladyslav, Yuvaraj, codebriefcase, iRealNirmal and ivanwonder
|
||||
|
||||
|
||||
<a name="12.1.4"></a>
|
||||
# 12.1.4 (2021-07-28)
|
||||
### compiler-cli
|
||||
|
||||
+2
-3
@@ -248,8 +248,7 @@ Any line of the commit message cannot be longer than 100 characters.
|
||||
│ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
|
||||
│ elements|forms|http|language-service|localize|platform-browser|
|
||||
│ platform-browser-dynamic|platform-server|router|service-worker|
|
||||
│ upgrade|zone.js|packaging|changelog|dev-infra|docs-infra|migrations|
|
||||
│ ngcc|ve
|
||||
│ upgrade|zone.js|packaging|changelog|docs-infra|migrations|ngcc|ve
|
||||
│
|
||||
└─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|test
|
||||
```
|
||||
@@ -302,7 +301,7 @@ There are currently a few exceptions to the "use package name" rule:
|
||||
|
||||
* `changelog`: used for updating the release notes in CHANGELOG.md
|
||||
|
||||
* `dev-infra`: used for dev-infra related changes within the directories /scripts, /tools and /dev-infra
|
||||
* `dev-infra`: used for dev-infra related changes within the directories /scripts and /tools
|
||||
|
||||
* `docs-infra`: used for docs-app (angular.io) related changes within the /aio directory of the repo
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ load("@io_bazel_rules_webtesting//web:repositories.bzl", "web_test_repositories"
|
||||
|
||||
web_test_repositories()
|
||||
|
||||
load("//dev-infra/bazel/browsers:browser_repositories.bzl", "browser_repositories")
|
||||
load("@npm//@angular/dev-infra-private/bazel/browsers:browser_repositories.bzl", "browser_repositories")
|
||||
|
||||
browser_repositories()
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ describe('AppComponent', () => {
|
||||
it('should render title', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.nativeElement;
|
||||
expect(compiled.querySelector('.content span').textContent).toContain('component-overview app is running!');
|
||||
const compiled = fixture.nativeElement as HTMLElement;
|
||||
expect(compiled.querySelector('.content span')?.textContent).toContain('component-overview app is running!');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -21,7 +21,7 @@ export class AdBannerComponent implements OnInit, OnDestroy {
|
||||
@Input() ads: AdItem[] = [];
|
||||
currentAdIndex = -1;
|
||||
@ViewChild(AdDirective, {static: true}) adHost!: AdDirective;
|
||||
interval: any;
|
||||
interval: number | undefined;
|
||||
|
||||
constructor(private componentFactoryResolver: ComponentFactoryResolver) { }
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"tests": [
|
||||
{"cmd": "yarn", "args": ["test", "--browsers=ChromeHeadless", "--no-watch"]},
|
||||
{"cmd": "yarn", "args": ["e2e", "--prod", "--protractor-config=e2e/protractor-puppeteer.conf.js", "--no-webdriver-update", "--port={PORT}"]}
|
||||
{"cmd": "yarn", "args": ["e2e", "--configuration=production", "--protractor-config=e2e/protractor-puppeteer.conf.js", "--no-webdriver-update", "--port={PORT}"]}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ describe('AppComponent', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
expect(compiled.querySelector('h1').textContent).toContain('Forms Overview');
|
||||
const compiled = fixture.nativeElement as HTMLElement;
|
||||
expect(compiled.querySelector('h1')?.textContent).toContain('Forms Overview');
|
||||
}));
|
||||
});
|
||||
|
||||
@@ -10,14 +10,17 @@ import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { AppComponent } from './app.component';
|
||||
import { TopBarComponent } from './top-bar/top-bar.component';
|
||||
import { ProductListComponent } from './product-list/product-list.component';
|
||||
// #docregion declare-product-alerts
|
||||
import { ProductAlertsComponent } from './product-alerts/product-alerts.component';
|
||||
// #enddocregion declare-product-alerts
|
||||
import { ProductDetailsComponent } from './product-details/product-details.component';
|
||||
import { CartComponent } from './cart/cart.component';
|
||||
import { ShippingComponent } from './shipping/shipping.component';
|
||||
|
||||
// #docregion product-details-route, http-client-module, shipping-route, cart-route
|
||||
// #docregion product-details-route, http-client-module, shipping-route, cart-route, declare-product-alerts
|
||||
|
||||
@NgModule({
|
||||
// #enddocregion declare-product-alerts
|
||||
imports: [
|
||||
BrowserModule,
|
||||
// #enddocregion product-details-route, cart-route
|
||||
@@ -36,17 +39,20 @@ import { ShippingComponent } from './shipping/shipping.component';
|
||||
])
|
||||
],
|
||||
// #enddocregion product-details-route, cart-route
|
||||
// #docregion declare-product-alerts
|
||||
declarations: [
|
||||
AppComponent,
|
||||
TopBarComponent,
|
||||
ProductListComponent,
|
||||
ProductAlertsComponent,
|
||||
// #enddocregion declare-product-alerts
|
||||
ProductDetailsComponent,
|
||||
CartComponent,
|
||||
// #enddocregion http-client-module
|
||||
ShippingComponent
|
||||
// #docregion http-client-module
|
||||
// #docregion declare-product-alerts, http-client-module
|
||||
],
|
||||
// #enddocregion declare-product-alerts
|
||||
bootstrap: [
|
||||
AppComponent
|
||||
]
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
"projectType": "testing",
|
||||
"tests": [
|
||||
{"cmd": "yarn", "args": ["test", "--browsers=ChromeHeadless", "--no-watch"]},
|
||||
{"cmd": "yarn", "args": ["e2e", "--prod", "--protractor-config=e2e/protractor-puppeteer.conf.js", "--no-webdriver-update", "--port={PORT}"]}
|
||||
{"cmd": "yarn", "args": ["e2e", "--configuration=production", "--protractor-config=e2e/protractor-puppeteer.conf.js", "--no-webdriver-update", "--port={PORT}"]}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -21,12 +21,12 @@ export class AliasingComponent {
|
||||
|
||||
|
||||
saveIt() {
|
||||
console.warn('Child says: emiting outputEvent1 with', this.input1);
|
||||
console.warn('Child says: emitting outputEvent1 with', this.input1);
|
||||
this.outputEvent1.emit(this.input1);
|
||||
}
|
||||
|
||||
wishForIt() {
|
||||
console.warn('Child says: emiting outputEvent2', this.input2);
|
||||
console.warn('Child says: emitting outputEvent2', this.input2);
|
||||
this.outputEvent2.emit(this.input2);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ export class InTheMetadataComponent {
|
||||
clearanceItem = '';
|
||||
|
||||
buyIt() {
|
||||
console.warn('Child says: emiting buyEvent with', this.clearanceItem);
|
||||
console.warn('Child says: emitting buyEvent with', this.clearanceItem);
|
||||
this.buyEvent.emit(this.clearanceItem);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ export class InputOutputComponent {
|
||||
lineThrough = '';
|
||||
|
||||
delete() {
|
||||
console.warn('Child says: emiting item deleteRequest with', this.item);
|
||||
console.warn('Child says: emitting item deleteRequest with', this.item);
|
||||
this.deleteRequest.emit(this.item);
|
||||
this.lineThrough = this.lineThrough ? '' : 'line-through';
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"projectType": "service-worker",
|
||||
"tests": [
|
||||
{"cmd": "yarn", "args": ["e2e", "--protractor-config=e2e/protractor-puppeteer.conf.js", "--no-webdriver-update", "--port={PORT}"]},
|
||||
{"cmd": "yarn", "args": ["build", "--prod"]},
|
||||
{"cmd": "yarn", "args": ["build"]},
|
||||
{"cmd": "node", "args": ["--eval", "assert(fs.existsSync('./dist/ngsw.json'), 'ngsw.json is missing')"]},
|
||||
{"cmd": "node", "args": ["--eval", "assert(fs.existsSync('./dist/ngsw-worker.js'), 'ngsw-worker.js is missing')"]},
|
||||
{"cmd": "node", "args": ["--eval", "assert(require('./package.json').dependencies['@angular/service-worker'], '@angular/service-worker is missing')"]}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"tests": [
|
||||
{"cmd": "yarn", "args": ["test", "--browsers=ChromeHeadless", "--no-watch"]},
|
||||
{"cmd": "yarn", "args": ["e2e", "--prod", "--protractor-config=e2e/protractor-puppeteer.conf.js", "--no-webdriver-update", "--port={PORT}"]}
|
||||
{"cmd": "yarn", "args": ["e2e", "--configuration=production", "--protractor-config=e2e/protractor-puppeteer.conf.js", "--no-webdriver-update", "--port={PORT}"]}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
"projectType": "testing",
|
||||
"tests": [
|
||||
{"cmd": "yarn", "args": ["test", "--browsers=ChromeHeadless", "--no-watch"]},
|
||||
{"cmd": "yarn", "args": ["e2e", "--prod", "--protractor-config=e2e/protractor-puppeteer.conf.js", "--no-webdriver-update", "--port={PORT}"]}
|
||||
{"cmd": "yarn", "args": ["e2e", "--configuration=production", "--protractor-config=e2e/protractor-puppeteer.conf.js", "--no-webdriver-update", "--port={PORT}"]}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@ describe('AppComponent (initial CLI version)', () => {
|
||||
it('should render title', waitForAsync(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.nativeElement;
|
||||
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
|
||||
const compiled = fixture.nativeElement as HTMLElement;
|
||||
expect(compiled.querySelector('h1')?.textContent).toContain('Welcome to app!');
|
||||
}));
|
||||
});
|
||||
// #enddocregion
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"tests": [
|
||||
{"cmd": "yarn", "args": ["test", "--browsers=ChromeHeadless", "--no-watch"]},
|
||||
{"cmd": "yarn", "args": ["e2e", "--prod", "--protractor-config=e2e/protractor-puppeteer.conf.js", "--no-webdriver-update", "--port={PORT}"]}
|
||||
{"cmd": "yarn", "args": ["e2e", "--configuration=production", "--protractor-config=e2e/protractor-puppeteer.conf.js", "--no-webdriver-update", "--port={PORT}"]}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"projectType": "universal",
|
||||
"e2e": [
|
||||
{"cmd": "yarn", "args": ["e2e", "--prod", "--protractor-config=e2e/protractor-puppeteer.conf.js", "--no-webdriver-update", "--port={PORT}"]},
|
||||
{"cmd": "yarn", "args": ["e2e", "--configuration=production", "--protractor-config=e2e/protractor-puppeteer.conf.js", "--no-webdriver-update", "--port={PORT}"]},
|
||||
{"cmd": "yarn", "args": ["run", "build:ssr"]}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ The template options object, `angularCompilerOptions`, is a sibling to the `comp
|
||||
{@a tsconfig-extends}
|
||||
## Configuration inheritance with extends
|
||||
|
||||
Like the TypeScript compiler, The Angular AOT compiler also supports `extends` in the `angularCompilerOptions` section of the TypeScript configuration file.
|
||||
Like the TypeScript compiler, the Angular AOT compiler also supports `extends` in the `angularCompilerOptions` section of the TypeScript configuration file.
|
||||
The `extends` property is at the top level, parallel to `compilerOptions` and `angularCompilerOptions`.
|
||||
|
||||
A TypeScript configuration can inherit settings from another file using the `extends` property.
|
||||
|
||||
@@ -249,7 +249,7 @@ See the [Styles configuration guide](guide/workspace-config#styles-and-scripts-c
|
||||
### Non-CSS style files
|
||||
|
||||
If you're building with the CLI,
|
||||
you can write style files in [sass](https://sass-lang.com/), [less](http://lesscss.org/), or [stylus](https://stylus-lang.com/) and specify those files in the `@Component.styleUrls` metadata with the appropriate extensions (`.scss`, `.less`, `.styl`) as in the following example:
|
||||
you can write style files in [sass](https://sass-lang.com/), or [less](http://lesscss.org/), and specify those files in the `@Component.styleUrls` metadata with the appropriate extensions (`.scss`, `.less`) as in the following example:
|
||||
|
||||
<code-example>
|
||||
@Component({
|
||||
|
||||
@@ -23,43 +23,43 @@ The most basic form of content projection is *single-slot content projection*. S
|
||||
|
||||
To create a component that uses single-slot content projection:
|
||||
|
||||
1. [Create](guide/component-overview) a component.
|
||||
1. [Create a component](guide/component-overview#creating-a-component).
|
||||
|
||||
1. In the template for your component, add an `ng-content` element where you want the projected content to appear.
|
||||
1. In the template for your component, add an `<ng-content>` element where you want the projected content to appear.
|
||||
|
||||
For example, the following component uses an `ng-content` element to display a message.
|
||||
For example, the following component uses an `<ng-content>` element to display a message.
|
||||
|
||||
<code-example path="content-projection/src/app/zippy-basic/zippy-basic.component.ts" header="content-projection/src/app/zippy-basic/zippy-basic.component.ts"></code-example>
|
||||
|
||||
With the `ng-content` element in place, users of this component can now project their own message into the component. For example:
|
||||
With the `<ng-content>` element in place, users of this component can now project their own message into the component. For example:
|
||||
|
||||
<code-example path="content-projection/src/app/app.component.html" header="content-projection/src/app/app.component.html"
|
||||
region="single-slot"></code-example>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
The `ng-content` element is a placeholder that does not create a real DOM element. Custom attributes applied to `ng-content` are ignored.
|
||||
The `<ng-content>` element is a placeholder that does not create a real DOM element. Custom attributes applied to `<ng-content>` are ignored.
|
||||
|
||||
</div>
|
||||
|
||||
{@a multi-slot}
|
||||
## Multi-slot content projection
|
||||
|
||||
A component can have multiple slots. Each slot can specify a CSS selector that determines which content goes into that slot. This pattern is referred to as *multi-slot content projection*. With this pattern, you must specify where you want the projected content to appear. You accomplish this task by using the `select` attribute of `ng-content`.
|
||||
A component can have multiple slots. Each slot can specify a CSS selector that determines which content goes into that slot. This pattern is referred to as *multi-slot content projection*. With this pattern, you must specify where you want the projected content to appear. You accomplish this task by using the `select` attribute of `<ng-content>`.
|
||||
|
||||
To create a component that uses multi-slot content projection:
|
||||
|
||||
1. [Create](guide/component-overview) a component.
|
||||
1. [Create a component](guide/component-overview#creating-a-component).
|
||||
|
||||
1. In the template for your component, add an `ng-content` element where you want the projected content to appear.
|
||||
1. In the template for your component, add an `<ng-content>` element where you want the projected content to appear.
|
||||
|
||||
1. Add a `select` attribute to the `ng-content` elements. Angular supports [selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors) for any combination of tag name, attribute, CSS class, and the `:not` pseudo-class.
|
||||
1. Add a `select` attribute to the `<ng-content>` elements. Angular supports [selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors) for any combination of tag name, attribute, CSS class, and the `:not` pseudo-class.
|
||||
|
||||
For example, the following component uses two `ng-content` elements.
|
||||
For example, the following component uses two `<ng-content>` elements.
|
||||
|
||||
<code-example path="content-projection/src/app/zippy-multislot/zippy-multislot.component.ts" header="content-projection/src/app/zippy-multislot/zippy-multislot.component.ts"></code-example>
|
||||
|
||||
Content that uses the `question` attribute is projected into the `ng-content` element with the `select=[question]` attribute.
|
||||
Content that uses the `question` attribute is projected into the `<ng-content>` element with the `select=[question]` attribute.
|
||||
|
||||
<code-example path="content-projection/src/app/app.component.html" header="content-projection/src/app/app.component.html"
|
||||
region="multi-slot"></code-example>
|
||||
@@ -68,9 +68,9 @@ region="multi-slot"></code-example>
|
||||
|
||||
<header>ng-content without a select attribute</header>
|
||||
|
||||
If your component includes an `ng-content` element without a `select` attribute, that instance receives all projected components that do not match any of the other `ng-content` elements.
|
||||
If your component includes an `<ng-content>` element without a `select` attribute, that instance receives all projected components that do not match any of the other `<ng-content>` elements.
|
||||
|
||||
In the preceding example, only the second `ng-content` element defines a `select` attribute. As a result, the first `ng-content` element receives any other content projected into the component.
|
||||
In the preceding example, only the second `<ng-content>` element defines a `select` attribute. As a result, the first `<ng-content>` element receives any other content projected into the component.
|
||||
|
||||
</div>
|
||||
|
||||
@@ -78,41 +78,41 @@ In the preceding example, only the second `ng-content` element defines a `select
|
||||
|
||||
## Conditional content projection
|
||||
|
||||
If your component needs to _conditionally_ render content, or render content multiple times, you should configure that component to accept an `ng-template` element that contains the content you want to conditionally render.
|
||||
If your component needs to _conditionally_ render content, or render content multiple times, you should configure that component to accept an `<ng-template>` element that contains the content you want to conditionally render.
|
||||
|
||||
Using an `ng-content` element in these cases is not recommended, because when the consumer of a component supplies the content, that content is _always_ initialized, even if the component does not define an `ng-content` element or if that `ng-content` element is inside of an `ngIf` statement.
|
||||
Using an `<ng-content>` element in these cases is not recommended, because when the consumer of a component supplies the content, that content is _always_ initialized, even if the component does not define an `<ng-content>` element or if that `<ng-content>` element is inside of an `ngIf` statement.
|
||||
|
||||
With an `ng-template` element, you can have your component explicitly render content based on any condition you want, as many times as you want. Angular will not initialize the content of an `ng-template` element until that element is explicitly rendered.
|
||||
With an `<ng-template>` element, you can have your component explicitly render content based on any condition you want, as many times as you want. Angular will not initialize the content of an `<ng-template>` element until that element is explicitly rendered.
|
||||
|
||||
The following steps demonstrate a typical implementation of conditional content projection using `ng-template`.
|
||||
The following steps demonstrate a typical implementation of conditional content projection using `<ng-template>`.
|
||||
|
||||
1. [Create](guide/component-overview) a component.
|
||||
1. [Create a component](guide/component-overview#creating-a-component).
|
||||
|
||||
1. In the component that accepts an `ng-template` element, use an `ng-container` element to render that template, such as:
|
||||
1. In the component that accepts an `<ng-template>` element, use an `<ng-container>` element to render that template, such as:
|
||||
|
||||
<code-example path="content-projection/src/app/example-zippy.template.html" header="content-projection/src/app/example-zippy.template.html" region="ng-container">
|
||||
</code-example>
|
||||
|
||||
This example uses the `ngTemplateOutlet` directive to render a given `ng-template` element, which you will define in a later step. You can apply an `ngTemplateOutlet` directive to any type of element. This example assigns the directive to an `ng-container` element because the component does not need to render a real DOM element.
|
||||
This example uses the `ngTemplateOutlet` directive to render a given `<ng-template>` element, which you will define in a later step. You can apply an `ngTemplateOutlet` directive to any type of element. This example assigns the directive to an `<ng-container>` element because the component does not need to render a real DOM element.
|
||||
|
||||
1. Wrap the `ng-container` element in another element, such as a `div` element, and apply your conditional logic.
|
||||
1. Wrap the `<ng-container>` element in another element, such as a `div` element, and apply your conditional logic.
|
||||
|
||||
<code-example path="content-projection/src/app/example-zippy.template.html" header="content-projection/src/app/example-zippy.template.html" region="ngif">
|
||||
</code-example>
|
||||
|
||||
1. In the template where you want to project content, wrap the projected content in an `ng-template` element, such as:
|
||||
1. In the template where you want to project content, wrap the projected content in an `<ng-template>` element, such as:
|
||||
|
||||
<code-example path="content-projection/src/app/app.component.html" region="ng-template">
|
||||
</code-example>
|
||||
|
||||
The `ng-template` element defines a block of content that a component can render based on its own logic. A component can get a reference to this template content, or [`TemplateRef`](/api/core/TemplateRef), by using either the [`@ContentChild`](/api/core/ContentChild) or [`@ContentChildren`](/api/core/ContentChildren) decorators. The preceding example creates a custom directive, `appExampleZippyContent`, as an API to mark the `ng-template` for the component's content. With the `TemplateRef`, the component can render the referenced content by using either the [`ngTemplateOutlet`](/api/common/NgTemplateOutlet) directive, or with [`ViewContainerRef.createEmbeddedView`](/api/core/ViewContainerRef#createembeddedview).
|
||||
The `<ng-template>` element defines a block of content that a component can render based on its own logic. A component can get a reference to this template content, or `TemplateRef`, by using either the `@ContentChild` or `@ContentChildren` decorators. The preceding example creates a custom directive, `appExampleZippyContent`, as an API to mark the `<ng-template>` for the component's content. With the `TemplateRef`, the component can render the referenced content by using either the `ngTemplateOutlet` directive, or with the `ViewContainerRef` method `createEmbeddedView()`.
|
||||
|
||||
1. Create a directive with a selector that matches the custom attribute for your template. In this directive, inject a TemplateRef instance.
|
||||
1. [Create an attribute directive](guide/attribute-directives#building-an-attribute-directive) with a selector that matches the custom attribute for your template. In this directive, inject a TemplateRef instance.
|
||||
|
||||
<code-example path="content-projection/src/app/app.component.ts" header="content-projection/src/app/app.component.ts" region="zippycontentdirective">
|
||||
</code-example>
|
||||
|
||||
In the previous step, you added an `ng-template` element with a custom attribute, `appExampleZippyDirective`. This code provides the logic that Angular will use when it encounters that custom attribute. In this case, that logic instructs Angular to instantiate a template reference.
|
||||
In the previous step, you added an `<ng-template>` element with a custom attribute, `appExampleZippyDirective`. This code provides the logic that Angular will use when it encounters that custom attribute. In this case, that logic instructs Angular to instantiate a template reference.
|
||||
|
||||
1. In the component you want to project content into, use `@ContentChild` to get the template of the projected content.
|
||||
|
||||
@@ -144,14 +144,14 @@ For instance, consider the following HTML snippet:
|
||||
<code-example path="content-projection/src/app/app.component.html" header="content-projection/src/app/app.component.html" region="ngprojectas">
|
||||
</code-example>
|
||||
|
||||
This example uses an `ng-container` attribute to simulate projecting a component into a more complex structure.
|
||||
This example uses an `<ng-container>` attribute to simulate projecting a component into a more complex structure.
|
||||
|
||||
<div class="callout is-helpful">
|
||||
|
||||
<header>Reminder!</header>
|
||||
|
||||
The `ng-container` element is a logical construct that you can use to group other DOM elements; however, the `ng-container` itself is not rendered in the DOM tree.
|
||||
The `<ng-container>` element is a logical construct that you can use to group other DOM elements; however, the `<ng-container>` itself is not rendered in the DOM tree.
|
||||
|
||||
</div>
|
||||
|
||||
In this example, the content we want to project resides inside another element. To project this content as intended, the template uses the `ngProjectAs` attribute. With `ngProjectAs`, the entire `ng-container` element is projected into a component using the `[question]` selector.
|
||||
In this example, the content we want to project resides inside another element. To project this content as intended, the template uses the `ngProjectAs` attribute. With `ngProjectAs`, the entire `<ng-container>` element is projected into a component using the `[question]` selector.
|
||||
|
||||
@@ -1092,7 +1092,7 @@ See [custom element](#custom-element).
|
||||
|
||||
## workspace
|
||||
|
||||
A collection of Angular [projects](#project) (that is, applications and libraries) powered by the [Angular CLI] (#cli) that are typically co-located in a single source-control repository (such as [git](https://git-scm.com/)).
|
||||
A collection of Angular [projects](#project) (that is, applications and libraries) powered by the [Angular CLI](#cli) that are typically co-located in a single source-control repository (such as [git](https://git-scm.com/)).
|
||||
|
||||
The [CLI](#cli) [`ng new` command](cli/new) creates a file system directory (the "workspace root").
|
||||
In the workspace root, it also creates the workspace [configuration file](#configuration) (`angular.json`) and, by default, an initial application project with the same name.
|
||||
|
||||
@@ -380,7 +380,7 @@ The following is an example of how the `<app-root>` and `<app-child>` view trees
|
||||
...content goes here...
|
||||
</#VIEW>
|
||||
</app-child>
|
||||
<#VIEW>
|
||||
</#VIEW>
|
||||
</app-root>
|
||||
```
|
||||
|
||||
@@ -1021,8 +1021,8 @@ The logical tree representation shows why this is:
|
||||
@Inject(AnimalService, @Optional)=>"🦔">
|
||||
<!-- ^^@SkipSelf() starts here, @Host() stops here^^ -->
|
||||
<app-child>
|
||||
<#VIEW @Provide(AnimalService="🦔")
|
||||
@Inject(AnimalService, @SkipSelf, @Host, @Optional)=>"🐶">
|
||||
<#VIEW @Provide(AnimalService="🐶")
|
||||
@Inject(AnimalService, @SkipSelf, @Host, @Optional)=>"🦔">
|
||||
<!-- Add @SkipSelf ^^-->
|
||||
</#VIEW>
|
||||
</app-child>
|
||||
|
||||
+565
-363
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ As users perform application tasks, they need to move between the different [vie
|
||||
To handle the navigation from one [view](guide/glossary#view) to the next, you use the Angular **`Router`**.
|
||||
The **`Router`** enables navigation by interpreting a browser URL as an instruction to change the view.
|
||||
|
||||
To explore a sample app featuring the router's primary features, see the <live-example stackblitz="router"></live-example>.
|
||||
To explore a sample app featuring the router's primary features, see the <live-example name="router"></live-example>.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
|
||||
@@ -197,8 +197,7 @@ By using the long form, the schematic can provide more explicit formatting of th
|
||||
"css",
|
||||
"scss",
|
||||
"sass",
|
||||
"less",
|
||||
"styl"
|
||||
"less"
|
||||
],
|
||||
"x-prompt": {
|
||||
"message": "Which stylesheet format would you like to use?",
|
||||
@@ -207,8 +206,7 @@ By using the long form, the schematic can provide more explicit formatting of th
|
||||
{ "value": "css", "label": "CSS" },
|
||||
{ "value": "scss", "label": "SCSS [ https://sass-lang.com/documentation/syntax#scss ]" },
|
||||
{ "value": "sass", "label": "Sass [ https://sass-lang.com/documentation/syntax#the-indented-syntax ]" },
|
||||
{ "value": "less", "label": "Less [ http://lesscss.org/ ]" },
|
||||
{ "value": "styl", "label": "Stylus [ https://stylus-lang.com/ ]" }
|
||||
{ "value": "less", "label": "Less [ http://lesscss.org/ ]" }
|
||||
]
|
||||
},
|
||||
},
|
||||
|
||||
@@ -162,6 +162,12 @@ You declare a template input variable using the `let` keyword as in `let hero`.
|
||||
|
||||
There are several such variables in this example: `hero`, `i`, and `odd`.
|
||||
|
||||
```html
|
||||
<ng-template #hero let-hero let-i="index" let-odd="isOdd">
|
||||
<div [class]="{'odd-row': odd}">{{i}}:{{hero.name}}</div>
|
||||
</ng-template>
|
||||
```
|
||||
|
||||
The variable's scope is limited to a single instance of the repeated template.
|
||||
Use the same variable name again in the definition of other structural directives.
|
||||
|
||||
|
||||
@@ -1558,7 +1558,7 @@ You can consolidate the two `beforeEach()` functions into a single, async `befor
|
||||
|
||||
The `compileComponents()` method returns a promise so you can perform the
|
||||
synchronous setup tasks _after_ compilation by moving the synchronous code
|
||||
into a `then(...)` callback.
|
||||
after the `await` keyword, where the promise has been resolved.
|
||||
|
||||
<code-example
|
||||
path="testing/src/app/banner/banner-external.component.spec.ts"
|
||||
|
||||
@@ -203,7 +203,7 @@ The important bit in the `server.ts` file is the `ngExpressEngine()` function.
|
||||
The `ngExpressEngine()` function is a wrapper around Universal's `renderModule()` function which turns a client's
|
||||
requests into server-rendered HTML pages. It accepts an object with the following properties:
|
||||
|
||||
* `bootstrap`: The root `NgModule` or `NgModule` factory to use for bootstraping the application when rendering on the server. For the example app, it is `AppServerModule`. It's the bridge between the Universal server-side renderer and the Angular application.
|
||||
* `bootstrap`: The root `NgModule` or `NgModule` factory to use for bootstrapping the application when rendering on the server. For the example app, it is `AppServerModule`. It's the bridge between the Universal server-side renderer and the Angular application.
|
||||
* `extraProviders`: This is optional and lets you specify dependency providers that apply only when rendering the application on the server. You can do this when your application needs information that can only be determined by the currently running server instance.
|
||||
|
||||
The `ngExpressEngine()` function returns a `Promise` callback that resolves to the rendered page.
|
||||
|
||||
@@ -590,7 +590,7 @@ The safest bet for ensuring compatibility is using the
|
||||
[component API](https://docs.angularjs.org/api/ng/type/angular.Module)
|
||||
introduced in AngularJS 1.5.
|
||||
|
||||
An example of an upgradable component is one that just has a template
|
||||
An example of an upgradeable component is one that just has a template
|
||||
and a controller:
|
||||
|
||||
<code-example path="upgrade-module/src/app/upgrade-static/hero-detail.component.ts" region="hero-detail" header="hero-detail.component.ts">
|
||||
|
||||
@@ -191,10 +191,10 @@ Some additional options can only be set through the configuration file, either b
|
||||
| OPTIONS PROPERTIES | DESCRIPTION |
|
||||
| :------------------------- | :---------------------------- |
|
||||
| `assets` | An object containing paths to static assets to add to the global context of the project. The default paths point to the project's icon file and its `assets` folder. See more in [Assets configuration](#asset-config) below. |
|
||||
| `styles` | An array of style files to add to the global context of the project. Angular CLI supports CSS imports and all major CSS preprocessors: [sass/scss](https://sass-lang.com/), [less](http://lesscss.org/), and [stylus](https://stylus-lang.com/). See more in [Styles and scripts configuration](#style-script-config) below. |
|
||||
| `styles` | An array of style files to add to the global context of the project. Angular CLI supports CSS imports and all major CSS preprocessors: [sass/scss](https://sass-lang.com/) and [less](http://lesscss.org/). See more in [Styles and scripts configuration](#style-script-config) below. |
|
||||
| `stylePreprocessorOptions` | An object containing option-value pairs to pass to style preprocessors. See more in [Styles and scripts configuration](#style-script-config) below. |
|
||||
| `scripts` | An object containing JavaScript script files to add to the global context of the project. The scripts are loaded exactly as if you had added them in a `<script>` tag inside `index.html`. See more in [Styles and scripts configuration](#style-script-config) below. |
|
||||
| `budgets` | Default size-budget type and threshholds for all or parts of your application. You can configure the builder to report a warning or an error when the output reaches or exceeds a threshold size. See [Configure size budgets](guide/build#configure-size-budgets). (Not available in `test` section.) |
|
||||
| `budgets` | Default size-budget type and thresholds for all or parts of your application. You can configure the builder to report a warning or an error when the output reaches or exceeds a threshold size. See [Configure size budgets](guide/build#configure-size-budgets). (Not available in `test` section.) |
|
||||
| `fileReplacements` | An object containing files and their compile-time replacements. See more in [Configure target-specific file replacements](guide/build#configure-target-specific-file-replacements).|
|
||||
|
||||
{@a complex-config}
|
||||
@@ -330,7 +330,7 @@ You can mix simple and complex file references for styles and scripts.
|
||||
|
||||
#### Style preprocessor options
|
||||
|
||||
In Sass and Stylus you can make use of the `includePaths` functionality for both component and global styles, which allows you to add extra base paths that will be checked for imports.
|
||||
In Sass you can make use of the `includePaths` functionality for both component and global styles, which allows you to add extra base paths that will be checked for imports.
|
||||
|
||||
To add paths, use the `stylePreprocessorOptions` option:
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 7.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 6.0 KiB |
@@ -40,7 +40,7 @@
|
||||
"alan-agius4": {
|
||||
"name": "Alan Agius",
|
||||
"groups": ["Angular"],
|
||||
"lead": "kyliau",
|
||||
"lead": "dgp1130",
|
||||
"picture": "alan-agius4.jpg",
|
||||
"bio": "Angular CLI Member, Loves TypeScript, Build Tools, Food, Beer & Coffee :)"
|
||||
},
|
||||
@@ -111,7 +111,7 @@
|
||||
"picture": "aristeidis.jpg",
|
||||
"twitter": "abampakos",
|
||||
"website": "https://medium.com/@abampakos",
|
||||
"bio": "Aristeidis is a front end web developer at Plex-Earth working with Angular. He is a co-organizer of the Angular Athens meetup and the author of Learning Angular - 3rd Edition. He is also a senior Angular instructor at Code.Hub where he teaches the Angular framework to other developers.",
|
||||
"bio": "Aristeidis is a web development team lead at Plex-Earth working with Angular. He is a co-organizer of the Angular Athens meetup and the author of Learning Angular - 3rd Edition and Angular Projects - 2nd Edition books. He is also a senior Angular instructor at Code.Hub where he teaches the Angular framework to other developers.",
|
||||
"groups": ["GDE"]
|
||||
},
|
||||
"bbrennan": {
|
||||
@@ -181,13 +181,6 @@
|
||||
"bio": "Co-founder and CTO of Thinktecture AG, as well as Google GDE and Microsoft MVP. Since two decades active as an engaged and passionate speaker on several software conferences and events all over the world. Some people call him 'Mr. Cross-Platform'.",
|
||||
"groups": ["GDE"]
|
||||
},
|
||||
"cindygk": {
|
||||
"name": "Cindy Greene-Kaplan",
|
||||
"picture": "cindygreenekaplan.jpg",
|
||||
"twitter": "cindykaygk",
|
||||
"bio": "Cindy is a Program Manager on the Angular team at Google. She is passionate about improving team processes and overall execution. She enjoys dance fitness, movies and travel.",
|
||||
"groups": ["Angular"]
|
||||
},
|
||||
"cironunes": {
|
||||
"name": "Ciro Nunes",
|
||||
"picture": "cironunes.jpg",
|
||||
@@ -198,7 +191,7 @@
|
||||
"clydin": {
|
||||
"name": "Charles Lyding",
|
||||
"groups": ["Angular"],
|
||||
"lead": "kyliau",
|
||||
"lead": "dgp1130",
|
||||
"picture": "clydin.jpg"
|
||||
},
|
||||
"coryrylan": {
|
||||
@@ -262,8 +255,7 @@
|
||||
"twitter": "develwoutacause",
|
||||
"website": "https://github.com/dgp1130",
|
||||
"bio": "Doug is an overly-opinionated software developer with a passion for making awesome developer tools. He is motivated primarily by his selfish desire to make his own life easier, but loves to share his tools and workflows with others to make everyone's lives easier.",
|
||||
"groups": ["Angular"],
|
||||
"lead": "kyliau"
|
||||
"groups": ["Angular"]
|
||||
},
|
||||
"doguhan": {
|
||||
"name": "Doguhan Uluca",
|
||||
@@ -325,7 +317,7 @@
|
||||
"website": "https://github.com/filipesilva",
|
||||
"bio": "Filipe is a passion-driven developer that always strives for the most elegant solution for each problem. He is currently an author for Angular.io, a core contributor for Angular-CLI and senior front end engineer at KonnectAgain. When not busy going through PRs, you can find him scouring reddit for new dinner recipes to cook or enjoying a craft beer in Dublin.",
|
||||
"groups": ["Angular"],
|
||||
"lead": "kyliau"
|
||||
"lead": "dgp1130"
|
||||
},
|
||||
"fmalcher": {
|
||||
"name": "Ferdinand Malcher",
|
||||
@@ -354,7 +346,7 @@
|
||||
"gregmagolan": {
|
||||
"name": "Greg Magolan",
|
||||
"groups": ["Angular"],
|
||||
"lead": "kyliau",
|
||||
"lead": "dgp1130",
|
||||
"picture": "gregmagolan.jpg",
|
||||
"bio": "Building great software with Angular and Node.js."
|
||||
},
|
||||
@@ -368,7 +360,7 @@
|
||||
"jbedard": {
|
||||
"name": "Jason Bedard",
|
||||
"groups": ["Collaborators"],
|
||||
"mentor": "kyliau",
|
||||
"mentor": "dgp1130",
|
||||
"picture": "jbedard.jpg"
|
||||
},
|
||||
"jecelynyeen": {
|
||||
@@ -459,6 +451,13 @@
|
||||
"groups": ["Angular"],
|
||||
"lead": "igorminar"
|
||||
},
|
||||
"josmar-crwdstffng": {
|
||||
"name": "Joe Martin",
|
||||
"picture": "josephmmartin.jpg",
|
||||
"bio": "Joe is a technical writer working on the Angular docs.",
|
||||
"groups": ["Angular"],
|
||||
"lead": "aikidave"
|
||||
},
|
||||
"jschwarty": {
|
||||
"name": "Justin Schwartzenberger",
|
||||
"picture": "justinschwartzenberger.jpg",
|
||||
@@ -530,15 +529,6 @@
|
||||
"bio": "Kwinten is a GDE for Angular with a passion for reactive coding. He works as a software engineer for Stackblitz. He shares his passion for Angular and coding through blogposts and training sessions with the company he co-founded called Strongbrew.",
|
||||
"groups": ["GDE"]
|
||||
},
|
||||
"kyliau": {
|
||||
"name": "Keen Yee Liau",
|
||||
"twitter": "liauky",
|
||||
"website": "https://github.com/kyliau",
|
||||
"bio": "Keen works on language service and CLI. He also maintains Karma and Protractor.",
|
||||
"groups": ["Angular"],
|
||||
"lead": "igorminar",
|
||||
"picture": "kyliau.jpg"
|
||||
},
|
||||
"lacolaco": {
|
||||
"name": "Suguru Inatomi",
|
||||
"picture": "lacolaco.jpg",
|
||||
@@ -854,6 +844,12 @@
|
||||
"bio": "Andrew is a software engineer using Angular and .NET. He spends most of his spare time staying up-to-date, helping other people, and experimenting with web tech.",
|
||||
"groups": ["GDE"]
|
||||
},
|
||||
"tmdavisgoogle": {
|
||||
"name": "Tiffany Davis",
|
||||
"bio": "Tiffany is an editor working on Angular documentation.",
|
||||
"groups": ["Angular"],
|
||||
"lead": "aikidave"
|
||||
},
|
||||
"toddmotto": {
|
||||
"name": "Todd Motto",
|
||||
"picture": "toddmotto.jpg",
|
||||
|
||||
@@ -49,6 +49,11 @@
|
||||
"desc": "Add API Based CMS to your Angular app",
|
||||
"url": "https://github.com/ButterCMS/buttercms-angular-tutorial",
|
||||
"title": "API Based CMS with Butter"
|
||||
},
|
||||
"angular-community-meetup": {
|
||||
"desc": "Come learn technical skills and network at this monthly, multi-series, multi-event, multi-timezone online meetup.",
|
||||
"url": "https://angularcommunity.net",
|
||||
"title": "Angular Community Meetup"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -90,6 +95,12 @@
|
||||
"logo": "",
|
||||
"title": "NgRuAir",
|
||||
"url": "https://github.com/ngRuAir/ngruair"
|
||||
},
|
||||
"ngxp": {
|
||||
"desc": "Weekly technical-adjacent podcast by Brooke Avery & Erik Slack. Don't just code in Angular, come enjoy the Angular Experience!",
|
||||
"logo": "",
|
||||
"title": "Angular Experience (NgXP)",
|
||||
"url": "https://ngxp.show"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +199,11 @@ This section walks you through creating a child component, `ProductAlertsCompone
|
||||
|
||||
<code-example header="src/app/product-alerts/product-alerts.component.html" path="getting-started/src/app/product-alerts/product-alerts.component.1.html"></code-example>
|
||||
|
||||
1. To display `ProductAlertsComponent` as a child of `ProductListComponent`, add the selector, `<app-product-alerts>` to `product-list.component.html`.
|
||||
1. To make `ProductAlertsComponent` available to other components in the application, add it to `AppModule`'s declarations in `app.module.ts`.
|
||||
|
||||
<code-example header="src/app/app.module.ts" path="getting-started/src/app/app.module.ts" region="declare-product-alerts"></code-example>
|
||||
|
||||
1. Finally, to display `ProductAlertsComponent` as a child of `ProductListComponent`, add the selector, `<app-product-alerts>` to `product-list.component.html`.
|
||||
Pass the current product as input to the component using property binding.
|
||||
|
||||
<code-example header="src/app/product-list/product-list.component.html" path="getting-started/src/app/product-list/product-list.component.5.html" region="app-product-alerts"></code-example>
|
||||
|
||||
+3
-3
@@ -18,7 +18,7 @@
|
||||
"build-local": "yarn ~~build",
|
||||
"prebuild-local-ci": "yarn setup-local-ci",
|
||||
"build-local-ci": "yarn ~~build --progress=false",
|
||||
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js a57976b98",
|
||||
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js 56c5962df",
|
||||
"lint": "yarn check-env && yarn docs-lint && ng lint && yarn example-lint && yarn tools-lint",
|
||||
"test": "yarn check-env && ng test",
|
||||
"pree2e": "yarn check-env && yarn update-webdriver",
|
||||
@@ -56,7 +56,7 @@
|
||||
"docs-test": "node tools/transforms/test.js",
|
||||
"redirects-test": "node tests/deployment/unit/test",
|
||||
"firebase-utils-test": "node tools/firebase-test-utils/test",
|
||||
"tools-lint": "tslint --config \"tools/tslint.json\" --project \"tools/firebase-test-utils\" && eslint tools/ng-packages-installer",
|
||||
"tools-lint": "eslint tools/firebase-test-utils && eslint tools/ng-packages-installer",
|
||||
"tools-test": "yarn docs-test && yarn boilerplate:test && jasmine tools/ng-packages-installer/index.spec.js && jasmine scripts/deploy-to-firebase.spec.js && yarn firebase-utils-test",
|
||||
"preserve-and-sync": "yarn docs",
|
||||
"serve-and-sync": "run-p \"docs-watch --watch-only\" \"start {@}\" --",
|
||||
@@ -131,7 +131,7 @@
|
||||
"css-selector-parser": "^1.4.1",
|
||||
"dgeni": "^0.4.14",
|
||||
"dgeni-packages": "^0.29.1",
|
||||
"entities": "^2.2.0",
|
||||
"entities": "^3.0.0",
|
||||
"esbuild": "^0.12.0",
|
||||
"eslint": "^7.26.0",
|
||||
"eslint-plugin-import": "^2.23.4",
|
||||
|
||||
@@ -149,7 +149,7 @@ export class DocViewerComponent implements OnDestroy {
|
||||
this.setNoIndex(true);
|
||||
|
||||
// TODO(gkalpak): Remove this once gathering debug info is no longer needed.
|
||||
if (/loading chunk \d+ failed/i.test(errorMessage)) {
|
||||
if (/loading chunk \S+ failed/i.test(errorMessage)) {
|
||||
// Print some info to help with debugging.
|
||||
// (There is no reason to wait for this async call to complete before continuing.)
|
||||
printSwDebugInfo();
|
||||
|
||||
@@ -97,7 +97,6 @@
|
||||
|
||||
.github-links {
|
||||
a {
|
||||
|
||||
.material-icons:hover {
|
||||
background: none;
|
||||
}
|
||||
@@ -167,6 +166,10 @@
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.final-message {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.api-heading {
|
||||
@include mixins.font-size(14);
|
||||
margin: 16px;
|
||||
|
||||
@@ -8,9 +8,17 @@
|
||||
&.api-status-label {
|
||||
background-color: constants.$mediumgray;
|
||||
|
||||
&.deprecated, &.security, &.impure-pipe {
|
||||
&.deprecated,
|
||||
&.security,
|
||||
&.impure-pipe {
|
||||
background-color: constants.$brightred;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
line-height: inherit;
|
||||
font-size: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
&.api-type-label {
|
||||
|
||||
@@ -86,7 +86,7 @@ The file is expected to contain a JSON object with zero or more of the following
|
||||
"cmd": "yarn",
|
||||
"args": [
|
||||
"e2e",
|
||||
"--prod",
|
||||
"--configuration=production",
|
||||
"--protractor-config=e2e/protractor-puppeteer.conf.js",
|
||||
"--no-webdriver-update",
|
||||
"--port={PORT}"
|
||||
|
||||
@@ -266,7 +266,7 @@ function runE2eTestsCLI(appDir, outputFile, bufferOutput, port) {
|
||||
cmd: 'yarn',
|
||||
args: [
|
||||
'e2e',
|
||||
'--prod',
|
||||
'--configuration=production',
|
||||
'--protractor-config=e2e/protractor-puppeteer.conf.js',
|
||||
'--no-webdriver-update',
|
||||
'--port={PORT}',
|
||||
|
||||
@@ -7,47 +7,48 @@
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~12.0.0",
|
||||
"@angular/common": "~12.0.0",
|
||||
"@angular/compiler": "~12.0.0",
|
||||
"@angular/core": "~12.0.0",
|
||||
"@angular/forms": "~12.0.0",
|
||||
"@angular/platform-browser": "~12.0.0",
|
||||
"@angular/platform-browser-dynamic": "~12.0.0",
|
||||
"@angular/router": "~12.0.0",
|
||||
"@angular/animations": "~12.1.0-",
|
||||
"@angular/common": "~12.1.0-",
|
||||
"@angular/compiler": "~12.1.0-",
|
||||
"@angular/core": "~12.1.0-",
|
||||
"@angular/forms": "~12.1.0-",
|
||||
"@angular/platform-browser": "~12.1.0-",
|
||||
"@angular/platform-browser-dynamic": "~12.1.0-",
|
||||
"@angular/router": "~12.1.0-",
|
||||
"angular": "1.8.0",
|
||||
"angular-in-memory-web-api": "~0.11.0",
|
||||
"angular-route": "1.8.0",
|
||||
"rxjs": "~6.6.0",
|
||||
"tslib": "^2.0.0",
|
||||
"tslib": "^2.2.0",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~12.0.0",
|
||||
"@angular/cli": "~12.0.0",
|
||||
"@angular/compiler-cli": "~12.0.0",
|
||||
"@angular-devkit/build-angular": "~12.1.3",
|
||||
"@angular/cli": "~12.1.3",
|
||||
"@angular/compiler-cli": "~12.1.0-",
|
||||
"@types/angular": "1.7.3",
|
||||
"@types/angular-route": "1.7.1",
|
||||
"@types/jasmine": "~3.6.0",
|
||||
"@types/jasmine": "~3.8.0",
|
||||
"@types/node": "^12.11.1",
|
||||
"codelyzer": "^6.0.0",
|
||||
"jasmine-core": "~3.7.0",
|
||||
"jasmine-marbles": "~0.6.0",
|
||||
"jasmine-spec-reporter": "~5.0.0",
|
||||
"jasmine-core": "~3.8.0",
|
||||
"jasmine-marbles": "~0.8.3",
|
||||
"jasmine-spec-reporter": "~7.0.0",
|
||||
"karma": "~6.3.0",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage": "~2.0.3",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "^1.5.0",
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~8.3.0",
|
||||
"ts-node": "~10.1.0",
|
||||
"tslint": "~6.1.0",
|
||||
"typescript": "~4.2.3"
|
||||
"typescript": "~4.3.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,29 +29,10 @@
|
||||
"styles": [
|
||||
"src/styles.css"
|
||||
],
|
||||
"scripts": [],
|
||||
"vendorChunk": true,
|
||||
"extractLicenses": false,
|
||||
"buildOptimizer": false,
|
||||
"sourceMap": true,
|
||||
"optimization": false,
|
||||
"namedChunks": true
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"namedChunks": false,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
@@ -63,20 +44,37 @@
|
||||
"maximumWarning": "2kb",
|
||||
"maximumError": "4kb"
|
||||
}
|
||||
]
|
||||
],
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"buildOptimizer": false,
|
||||
"optimization": false,
|
||||
"vendorChunk": true,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true,
|
||||
"namedChunks": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "angular.io-example:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "angular.io-example:build:production"
|
||||
},
|
||||
"development": {
|
||||
"browserTarget": "angular.io-example:build:development"
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
|
||||
@@ -7,43 +7,44 @@
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~12.0.0",
|
||||
"@angular/common": "~12.0.0",
|
||||
"@angular/compiler": "~12.0.0",
|
||||
"@angular/core": "~12.0.0",
|
||||
"@angular/forms": "~12.0.0",
|
||||
"@angular/platform-browser": "~12.0.0",
|
||||
"@angular/platform-browser-dynamic": "~12.0.0",
|
||||
"@angular/router": "~12.0.0",
|
||||
"@angular/animations": "~12.1.0-",
|
||||
"@angular/common": "~12.1.0-",
|
||||
"@angular/compiler": "~12.1.0-",
|
||||
"@angular/core": "~12.1.0-",
|
||||
"@angular/forms": "~12.1.0-",
|
||||
"@angular/platform-browser": "~12.1.0-",
|
||||
"@angular/platform-browser-dynamic": "~12.1.0-",
|
||||
"@angular/router": "~12.1.0-",
|
||||
"angular-in-memory-web-api": "~0.11.0",
|
||||
"rxjs": "~6.6.0",
|
||||
"tslib": "^2.0.0",
|
||||
"tslib": "^2.2.0",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~12.0.0",
|
||||
"@angular/cli": "~12.0.0",
|
||||
"@angular/compiler-cli": "~12.0.0",
|
||||
"@types/jasmine": "~3.6.0",
|
||||
"@angular-devkit/build-angular": "~12.1.3",
|
||||
"@angular/cli": "~12.1.3",
|
||||
"@angular/compiler-cli": "~12.1.0-",
|
||||
"@types/jasmine": "~3.8.0",
|
||||
"@types/node": "^12.11.1",
|
||||
"codelyzer": "^6.0.0",
|
||||
"jasmine-core": "~3.7.0",
|
||||
"jasmine-marbles": "~0.6.0",
|
||||
"jasmine-spec-reporter": "~5.0.0",
|
||||
"jasmine-core": "~3.8.0",
|
||||
"jasmine-marbles": "~0.8.3",
|
||||
"jasmine-spec-reporter": "~7.0.0",
|
||||
"karma": "~6.3.0",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage": "~2.0.3",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "^1.5.0",
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~8.3.0",
|
||||
"ts-node": "~10.1.0",
|
||||
"tslint": "~6.1.0",
|
||||
"typescript": "~4.2.3"
|
||||
"typescript": "~4.3.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// This file can be replaced during build by using the `fileReplacements` array.
|
||||
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
|
||||
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
|
||||
// The list of file replacements can be found in `angular.json`.
|
||||
|
||||
export const environment = {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"experimentalDecorators": true,
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"target": "es2015",
|
||||
"target": "es2017",
|
||||
"module": "es2020",
|
||||
"lib": [
|
||||
"es2018",
|
||||
|
||||
@@ -7,45 +7,46 @@
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~12.0.0",
|
||||
"@angular/common": "~12.0.0",
|
||||
"@angular/compiler": "~12.0.0",
|
||||
"@angular/core": "~12.0.0",
|
||||
"@angular/elements": "~12.0.0",
|
||||
"@angular/forms": "~12.0.0",
|
||||
"@angular/platform-browser": "~12.0.0",
|
||||
"@angular/platform-browser-dynamic": "~12.0.0",
|
||||
"@angular/router": "~12.0.0",
|
||||
"@angular/animations": "~12.1.0-",
|
||||
"@angular/common": "~12.1.0-",
|
||||
"@angular/compiler": "~12.1.0-",
|
||||
"@angular/core": "~12.1.0-",
|
||||
"@angular/elements": "~12.1.0-",
|
||||
"@angular/forms": "~12.1.0-",
|
||||
"@angular/platform-browser": "~12.1.0-",
|
||||
"@angular/platform-browser-dynamic": "~12.1.0-",
|
||||
"@angular/router": "~12.1.0-",
|
||||
"@webcomponents/custom-elements": "^1.4.2",
|
||||
"angular-in-memory-web-api": "~0.11.0",
|
||||
"rxjs": "~6.6.0",
|
||||
"tslib": "^2.0.0",
|
||||
"tslib": "^2.2.0",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~12.0.0",
|
||||
"@angular/cli": "~12.0.0",
|
||||
"@angular/compiler-cli": "~12.0.0",
|
||||
"@types/jasmine": "~3.6.0",
|
||||
"@angular-devkit/build-angular": "~12.1.3",
|
||||
"@angular/cli": "~12.1.3",
|
||||
"@angular/compiler-cli": "~12.1.0-",
|
||||
"@types/jasmine": "~3.8.0",
|
||||
"@types/node": "^12.11.1",
|
||||
"codelyzer": "^6.0.0",
|
||||
"jasmine-core": "~3.7.0",
|
||||
"jasmine-marbles": "~0.6.0",
|
||||
"jasmine-spec-reporter": "~5.0.0",
|
||||
"jasmine-core": "~3.8.0",
|
||||
"jasmine-marbles": "~0.8.3",
|
||||
"jasmine-spec-reporter": "~7.0.0",
|
||||
"karma": "~6.3.0",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage": "~2.0.3",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "^1.5.0",
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~8.3.0",
|
||||
"ts-node": "~10.1.0",
|
||||
"tslint": "~6.1.0",
|
||||
"typescript": "~4.2.3"
|
||||
"typescript": "~4.3.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
"main": "src/main.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"aot": true,
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
@@ -41,19 +40,6 @@
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"namedChunks": false,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
@@ -65,28 +51,45 @@
|
||||
"maximumWarning": "2kb",
|
||||
"maximumError": "4kb"
|
||||
}
|
||||
]
|
||||
],
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"buildOptimizer": false,
|
||||
"optimization": false,
|
||||
"vendorChunk": true,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true,
|
||||
"namedChunks": true
|
||||
},
|
||||
"fr": {
|
||||
"localize": [
|
||||
"fr"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "angular.io-example:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "angular.io-example:build:production"
|
||||
},
|
||||
"development": {
|
||||
"browserTarget": "angular.io-example:build:development"
|
||||
},
|
||||
"fr": {
|
||||
"browserTarget": "angular.io-example:build:fr"
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"start:fr": "ng serve --configuration=fr",
|
||||
"build": "ng build",
|
||||
"build:fr": "ng build --configuration=production-fr",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e",
|
||||
@@ -16,38 +17,38 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~12.0.0",
|
||||
"@angular/common": "~12.0.0",
|
||||
"@angular/compiler": "~12.0.0",
|
||||
"@angular/core": "~12.0.0",
|
||||
"@angular/forms": "~12.0.0",
|
||||
"@angular/localize": "~12.0.0",
|
||||
"@angular/platform-browser": "~12.0.0",
|
||||
"@angular/platform-browser-dynamic": "~12.0.0",
|
||||
"@angular/router": "~12.0.0",
|
||||
"@angular/animations": "~12.1.0-",
|
||||
"@angular/common": "~12.1.0-",
|
||||
"@angular/compiler": "~12.1.0-",
|
||||
"@angular/core": "~12.1.0-",
|
||||
"@angular/forms": "~12.1.0-",
|
||||
"@angular/localize": "~12.1.0-",
|
||||
"@angular/platform-browser": "~12.1.0-",
|
||||
"@angular/platform-browser-dynamic": "~12.1.0-",
|
||||
"@angular/router": "~12.1.0-",
|
||||
"angular-in-memory-web-api": "~0.11.0",
|
||||
"rxjs": "~6.6.0",
|
||||
"tslib": "^2.0.0",
|
||||
"tslib": "^2.2.0",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~12.0.0",
|
||||
"@angular/cli": "~12.0.0",
|
||||
"@angular/compiler-cli": "~12.0.0",
|
||||
"@types/jasmine": "~3.6.0",
|
||||
"@angular-devkit/build-angular": "~12.1.3",
|
||||
"@angular/cli": "~12.1.3",
|
||||
"@angular/compiler-cli": "~12.1.0-",
|
||||
"@types/jasmine": "~3.8.0",
|
||||
"@types/node": "^12.11.1",
|
||||
"codelyzer": "^6.0.0",
|
||||
"jasmine-core": "~3.7.0",
|
||||
"jasmine-marbles": "~0.6.0",
|
||||
"jasmine-spec-reporter": "~5.0.0",
|
||||
"jasmine-core": "~3.8.0",
|
||||
"jasmine-marbles": "~0.8.3",
|
||||
"jasmine-spec-reporter": "~7.0.0",
|
||||
"karma": "~6.3.0",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage": "~2.0.3",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "^1.5.0",
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~8.3.0",
|
||||
"ts-node": "~10.1.0",
|
||||
"tslint": "~6.1.0",
|
||||
"typescript": "~4.2.3"
|
||||
"typescript": "~4.3.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
"main": "src/main.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"aot": true,
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
@@ -34,19 +33,6 @@
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"namedChunks": false,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
@@ -58,20 +44,37 @@
|
||||
"maximumWarning": "2kb",
|
||||
"maximumError": "4kb"
|
||||
}
|
||||
]
|
||||
],
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"buildOptimizer": false,
|
||||
"optimization": false,
|
||||
"vendorChunk": true,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true,
|
||||
"namedChunks": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "angular.io-example:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "angular.io-example:build:production"
|
||||
},
|
||||
"development": {
|
||||
"browserTarget": "angular.io-example:build:development"
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
"main": "src/main.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"aot": true,
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
@@ -30,24 +29,12 @@
|
||||
"styles": [
|
||||
"src/styles.css"
|
||||
],
|
||||
"scripts": []
|
||||
"scripts": [],
|
||||
"serviceWorker": true,
|
||||
"ngswConfigPath": "ngsw-config.json"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"namedChunks": false,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
"serviceWorker": true,
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
@@ -59,20 +46,37 @@
|
||||
"maximumWarning": "2kb",
|
||||
"maximumError": "4kb"
|
||||
}
|
||||
]
|
||||
],
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"buildOptimizer": false,
|
||||
"optimization": false,
|
||||
"vendorChunk": true,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true,
|
||||
"namedChunks": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "angular.io-example:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "angular.io-example:build:production"
|
||||
},
|
||||
"development": {
|
||||
"browserTarget": "angular.io-example:build:development"
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
|
||||
@@ -7,44 +7,45 @@
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~12.0.0",
|
||||
"@angular/common": "~12.0.0",
|
||||
"@angular/compiler": "~12.0.0",
|
||||
"@angular/core": "~12.0.0",
|
||||
"@angular/forms": "~12.0.0",
|
||||
"@angular/platform-browser": "~12.0.0",
|
||||
"@angular/platform-browser-dynamic": "~12.0.0",
|
||||
"@angular/router": "~12.0.0",
|
||||
"@angular/service-worker": "~12.0.0",
|
||||
"@angular/animations": "~12.1.0-",
|
||||
"@angular/common": "~12.1.0-",
|
||||
"@angular/compiler": "~12.1.0-",
|
||||
"@angular/core": "~12.1.0-",
|
||||
"@angular/forms": "~12.1.0-",
|
||||
"@angular/platform-browser": "~12.1.0-",
|
||||
"@angular/platform-browser-dynamic": "~12.1.0-",
|
||||
"@angular/router": "~12.1.0-",
|
||||
"@angular/service-worker": "~12.1.0-",
|
||||
"angular-in-memory-web-api": "~0.11.0",
|
||||
"rxjs": "~6.6.0",
|
||||
"tslib": "^2.0.0",
|
||||
"tslib": "^2.2.0",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~12.0.0",
|
||||
"@angular/cli": "~12.0.0",
|
||||
"@angular/compiler-cli": "~12.0.0",
|
||||
"@types/jasmine": "~3.6.0",
|
||||
"@angular-devkit/build-angular": "~12.1.3",
|
||||
"@angular/cli": "~12.1.3",
|
||||
"@angular/compiler-cli": "~12.1.0-",
|
||||
"@types/jasmine": "~3.8.0",
|
||||
"@types/node": "^12.11.1",
|
||||
"codelyzer": "^6.0.0",
|
||||
"jasmine-core": "~3.7.0",
|
||||
"jasmine-marbles": "~0.6.0",
|
||||
"jasmine-spec-reporter": "~5.0.0",
|
||||
"jasmine-core": "~3.8.0",
|
||||
"jasmine-marbles": "~0.8.3",
|
||||
"jasmine-spec-reporter": "~7.0.0",
|
||||
"karma": "~6.3.0",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage": "~2.0.3",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "^1.5.0",
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~8.3.0",
|
||||
"ts-node": "~10.1.0",
|
||||
"tslint": "~6.1.0",
|
||||
"typescript": "~4.2.3"
|
||||
"typescript": "~4.3.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,36 +26,36 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~12.0.0",
|
||||
"@angular/common": "~12.0.0",
|
||||
"@angular/compiler": "~12.0.0",
|
||||
"@angular/core": "~12.0.0",
|
||||
"@angular/forms": "~12.0.0",
|
||||
"@angular/platform-browser": "~12.0.0",
|
||||
"@angular/platform-browser-dynamic": "~12.0.0",
|
||||
"@angular/router": "~12.0.0",
|
||||
"@angular/upgrade": "~12.0.0",
|
||||
"@angular/animations": "~12.1.0-",
|
||||
"@angular/common": "~12.1.0-",
|
||||
"@angular/compiler": "~12.1.0-",
|
||||
"@angular/core": "~12.1.0-",
|
||||
"@angular/forms": "~12.1.0-",
|
||||
"@angular/platform-browser": "~12.1.0-",
|
||||
"@angular/platform-browser-dynamic": "~12.1.0-",
|
||||
"@angular/router": "~12.1.0-",
|
||||
"@angular/upgrade": "~12.1.0-",
|
||||
"core-js": "^2.5.4",
|
||||
"rxjs": "~6.6.0",
|
||||
"tslib": "^2.0.0",
|
||||
"tslib": "^2.2.0",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/compiler-cli": "~12.0.0",
|
||||
"@angular/compiler-cli": "~12.1.0-",
|
||||
"@types/angular": "1.7.3",
|
||||
"@types/angular-animate": "1.5.10",
|
||||
"@types/angular-mocks": "1.7.0",
|
||||
"@types/angular-resource": "1.5.16",
|
||||
"@types/angular-route": "1.7.1",
|
||||
"@types/jasmine": "~3.6.0",
|
||||
"@types/jasmine": "~3.8.0",
|
||||
"@types/node": "^12.11.1",
|
||||
"concurrently": "^5.0.1",
|
||||
"http-server": "^0.12.0",
|
||||
"jasmine-core": "~3.7.0",
|
||||
"jasmine-core": "~3.8.0",
|
||||
"karma": "~6.3.0",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "^1.5.0",
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"lite-server": "^2.6.1",
|
||||
"protractor": "~7.0.0",
|
||||
"rollup": "^1.1.0",
|
||||
@@ -63,6 +63,6 @@
|
||||
"rollup-plugin-node-resolve": "^4.0.0",
|
||||
"rollup-plugin-terser": "^5.3.0",
|
||||
"tslint": "~6.1.0",
|
||||
"typescript": "~4.2.3"
|
||||
"typescript": "~4.3.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
"main": "src/main.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"aot": true,
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
@@ -35,19 +34,6 @@
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"namedChunks": false,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
@@ -59,20 +45,37 @@
|
||||
"maximumWarning": "2kb",
|
||||
"maximumError": "4kb"
|
||||
}
|
||||
]
|
||||
],
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"buildOptimizer": false,
|
||||
"optimization": false,
|
||||
"vendorChunk": true,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true,
|
||||
"namedChunks": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "angular.io-example:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "angular.io-example:build:production"
|
||||
},
|
||||
"development": {
|
||||
"browserTarget": "angular.io-example:build:development"
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
"main": "src/main.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"aot": true,
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
@@ -34,19 +33,6 @@
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"namedChunks": false,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
@@ -58,20 +44,37 @@
|
||||
"maximumWarning": "2kb",
|
||||
"maximumError": "4kb"
|
||||
}
|
||||
]
|
||||
],
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"buildOptimizer": false,
|
||||
"optimization": false,
|
||||
"vendorChunk": true,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true,
|
||||
"namedChunks": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "angular.io-example:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "angular.io-example:build:production"
|
||||
},
|
||||
"development": {
|
||||
"browserTarget": "angular.io-example:build:development"
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
@@ -136,37 +139,48 @@
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"sourceMap": false,
|
||||
"optimization": true
|
||||
]
|
||||
},
|
||||
"development": {
|
||||
"optimization": false,
|
||||
"sourceMap": true,
|
||||
"extractLicenses": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve-ssr": {
|
||||
"builder": "@nguniversal/builders:ssr-dev-server",
|
||||
"options": {
|
||||
"browserTarget": "angular.io-example:build",
|
||||
"serverTarget": "angular.io-example:server"
|
||||
},
|
||||
"configurations": {
|
||||
"development": {
|
||||
"browserTarget": "angular.io-example:build:development",
|
||||
"serverTarget": "angular.io-example:server:development"
|
||||
},
|
||||
"production": {
|
||||
"browserTarget": "angular.io-example:build:production",
|
||||
"serverTarget": "angular.io-example:server:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"prerender": {
|
||||
"builder": "@nguniversal/builders:prerender",
|
||||
"options": {
|
||||
"browserTarget": "angular.io-example:build:production",
|
||||
"serverTarget": "angular.io-example:server:production",
|
||||
"routes": [
|
||||
"/"
|
||||
]
|
||||
},
|
||||
"configurations": {
|
||||
"production": {}
|
||||
}
|
||||
"production": {
|
||||
"browserTarget": "angular.io-example:build:production",
|
||||
"serverTarget": "angular.io-example:server:production"
|
||||
},
|
||||
"development": {
|
||||
"browserTarget": "angular.io-example:build:development",
|
||||
"serverTarget": "angular.io-example:server:development"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,52 +7,53 @@
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e",
|
||||
"dev:ssr": "ng run angular.io-example:serve-ssr",
|
||||
"serve:ssr": "node dist/server/main.js",
|
||||
"build:ssr": "ng build --prod && ng run angular.io-example:server:production",
|
||||
"build:ssr": "ng build && ng run angular.io-example:server",
|
||||
"prerender": "ng run angular.io-example:prerender"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~12.0.0",
|
||||
"@angular/common": "~12.0.0",
|
||||
"@angular/compiler": "~12.0.0",
|
||||
"@angular/core": "~12.0.0",
|
||||
"@angular/forms": "~12.0.0",
|
||||
"@angular/platform-browser": "~12.0.0",
|
||||
"@angular/platform-browser-dynamic": "~12.0.0",
|
||||
"@angular/platform-server": "~12.0.0",
|
||||
"@angular/router": "~12.0.0",
|
||||
"@nguniversal/express-engine": "^12.0.0",
|
||||
"@angular/animations": "~12.1.0-",
|
||||
"@angular/common": "~12.1.0-",
|
||||
"@angular/compiler": "~12.1.0-",
|
||||
"@angular/core": "~12.1.0-",
|
||||
"@angular/forms": "~12.1.0-",
|
||||
"@angular/platform-browser": "~12.1.0-",
|
||||
"@angular/platform-browser-dynamic": "~12.1.0-",
|
||||
"@angular/platform-server": "~12.1.0-",
|
||||
"@angular/router": "~12.1.0-",
|
||||
"@nguniversal/express-engine": "~12.1.0",
|
||||
"angular-in-memory-web-api": "~0.11.0",
|
||||
"express": "^4.15.2",
|
||||
"rxjs": "~6.6.0",
|
||||
"tslib": "^2.0.0",
|
||||
"tslib": "^2.2.0",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~12.0.0",
|
||||
"@angular/cli": "~12.0.0",
|
||||
"@angular/compiler-cli": "~12.0.0",
|
||||
"@nguniversal/builders": "^12.0.0",
|
||||
"@angular-devkit/build-angular": "~12.1.3",
|
||||
"@angular/cli": "~12.1.3",
|
||||
"@angular/compiler-cli": "~12.1.0-",
|
||||
"@nguniversal/builders": "~12.1.0",
|
||||
"@types/express": "^4.17.8",
|
||||
"@types/jasmine": "~3.6.0",
|
||||
"@types/jasmine": "~3.8.0",
|
||||
"@types/node": "^12.11.1",
|
||||
"codelyzer": "^6.0.0",
|
||||
"jasmine-core": "~3.7.0",
|
||||
"jasmine-marbles": "~0.6.0",
|
||||
"jasmine-spec-reporter": "~5.0.0",
|
||||
"jasmine-core": "~3.8.0",
|
||||
"jasmine-marbles": "~0.8.3",
|
||||
"jasmine-spec-reporter": "~7.0.0",
|
||||
"karma": "~6.3.0",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage": "~2.0.3",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "^1.5.0",
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~8.3.0",
|
||||
"ts-node": "~10.1.0",
|
||||
"tslint": "~6.1.0",
|
||||
"typescript": "~4.2.3"
|
||||
"typescript": "~4.3.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,20 +21,20 @@
|
||||
"license": "MIT",
|
||||
"repository": {},
|
||||
"dependencies": {
|
||||
"@angular/animations": "~12.0.0",
|
||||
"@angular/common": "~12.0.0",
|
||||
"@angular/compiler": "~12.0.0",
|
||||
"@angular/core": "~12.0.0",
|
||||
"@angular/elements": "~12.0.0",
|
||||
"@angular/forms": "~12.0.0",
|
||||
"@angular/localize": "~12.0.0",
|
||||
"@angular/platform-browser": "~12.0.0",
|
||||
"@angular/platform-browser-dynamic": "~12.0.0",
|
||||
"@angular/platform-server": "~12.0.0",
|
||||
"@angular/router": "~12.0.0",
|
||||
"@angular/service-worker": "~12.0.0",
|
||||
"@angular/upgrade": "~12.0.0",
|
||||
"@nguniversal/express-engine": "^12.0.0",
|
||||
"@angular/animations": "~12.1.0-",
|
||||
"@angular/common": "~12.1.0-",
|
||||
"@angular/compiler": "~12.1.0-",
|
||||
"@angular/core": "~12.1.0-",
|
||||
"@angular/elements": "~12.1.0-",
|
||||
"@angular/forms": "~12.1.0-",
|
||||
"@angular/localize": "~12.1.0-",
|
||||
"@angular/platform-browser": "~12.1.0-",
|
||||
"@angular/platform-browser-dynamic": "~12.1.0-",
|
||||
"@angular/platform-server": "~12.1.0-",
|
||||
"@angular/router": "~12.1.0-",
|
||||
"@angular/service-worker": "~12.1.0-",
|
||||
"@angular/upgrade": "~12.1.0-",
|
||||
"@nguniversal/express-engine": "~12.1.0",
|
||||
"@webcomponents/custom-elements": "^1.4.2",
|
||||
"angular": "1.8.0",
|
||||
"angular-in-memory-web-api": "~0.11.0",
|
||||
@@ -43,35 +43,35 @@
|
||||
"express": "^4.15.2",
|
||||
"rxjs": "~6.6.0",
|
||||
"systemjs": "0.19.39",
|
||||
"tslib": "^2.0.0",
|
||||
"tslib": "^2.2.0",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~12.0.0",
|
||||
"@angular/cli": "~12.0.0",
|
||||
"@angular/compiler-cli": "~12.0.0",
|
||||
"@nguniversal/builders": "^12.0.0",
|
||||
"@angular-devkit/build-angular": "~12.1.3",
|
||||
"@angular/cli": "~12.1.3",
|
||||
"@angular/compiler-cli": "~12.1.0-",
|
||||
"@nguniversal/builders": "~12.1.0",
|
||||
"@types/angular": "1.7.3",
|
||||
"@types/angular-animate": "1.5.10",
|
||||
"@types/angular-mocks": "1.7.0",
|
||||
"@types/angular-resource": "1.5.16",
|
||||
"@types/angular-route": "1.7.1",
|
||||
"@types/express": "^4.17.8",
|
||||
"@types/jasmine": "~3.6.0",
|
||||
"@types/jasmine": "~3.8.0",
|
||||
"@types/jquery": "3.5.1",
|
||||
"@types/node": "^12.11.1",
|
||||
"canonical-path": "1.0.0",
|
||||
"codelyzer": "^6.0.0",
|
||||
"concurrently": "^5.0.1",
|
||||
"http-server": "^0.12.0",
|
||||
"jasmine-core": "~3.7.0",
|
||||
"jasmine-marbles": "~0.6.0",
|
||||
"jasmine-spec-reporter": "~5.0.0",
|
||||
"jasmine-core": "~3.8.0",
|
||||
"jasmine-marbles": "~0.8.3",
|
||||
"jasmine-spec-reporter": "~7.0.0",
|
||||
"karma": "~6.3.0",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage": "~2.0.3",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "^1.5.0",
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"lite-server": "^2.6.1",
|
||||
"lodash": "^4.16.2",
|
||||
"protractor": "~7.0.0",
|
||||
@@ -82,8 +82,8 @@
|
||||
"rollup-plugin-node-resolve": "^4.0.0",
|
||||
"rollup-plugin-terser": "^5.3.0",
|
||||
"source-map-explorer": "^1.3.2",
|
||||
"ts-node": "~8.3.0",
|
||||
"ts-node": "~10.1.0",
|
||||
"tslint": "~6.1.0",
|
||||
"typescript": "~4.2.3"
|
||||
"typescript": "~4.3.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
// see boilerplate/tsconfig.json for the tsconfig used in examples
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"target": "es2017",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"experimentalDecorators": true,
|
||||
"lib": ["es2015", "dom"],
|
||||
"lib": ["es2018", "dom"],
|
||||
"noImplicitAny": true,
|
||||
"suppressImplicitAnyIndexErrors": true,
|
||||
"typeRoots": [
|
||||
|
||||
+1494
-1358
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"extends": "../../.eslintrc.json",
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.js"],
|
||||
"env": {
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020
|
||||
},
|
||||
"rules": {
|
||||
"quotes": ["error", "single"],
|
||||
"semi": ["error", "always"],
|
||||
"no-var": ["error"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -7,11 +7,10 @@ export class FirebaseRedirect {
|
||||
destination: string;
|
||||
|
||||
constructor(readonly rawConfig: FirebaseRedirectConfig) {
|
||||
const {source, regex, destination} = rawConfig;
|
||||
this.source = (typeof source === 'string') ?
|
||||
FirebaseRedirectSource.fromGlobPattern(source) :
|
||||
FirebaseRedirectSource.fromRegexPattern(regex!);
|
||||
this.destination = destination;
|
||||
this.source = (rawConfig.regex === undefined) ?
|
||||
FirebaseRedirectSource.fromGlobPattern(rawConfig.source) :
|
||||
FirebaseRedirectSource.fromRegexPattern(rawConfig.regex);
|
||||
this.destination = rawConfig.destination;
|
||||
}
|
||||
|
||||
replace(url: string): string | undefined {
|
||||
|
||||
@@ -344,21 +344,21 @@ function testSource(source: FirebaseRedirectSource, matches: string[], nonMatche
|
||||
function testGlobMatch(
|
||||
pattern: string,
|
||||
captures: { named?: string[], rest?: string[] },
|
||||
matches: { [url: string]: object|undefined }) {
|
||||
matches: { [url: string]: unknown|undefined }) {
|
||||
return testSourceMatch(FirebaseRedirectSource.fromGlobPattern(pattern), captures, matches);
|
||||
}
|
||||
|
||||
function testRegexMatch(
|
||||
pattern: string,
|
||||
captures: { named?: string[], rest?: string[] },
|
||||
matches: { [url: string]: object|undefined }) {
|
||||
matches: { [url: string]: unknown|undefined }) {
|
||||
return testSourceMatch(FirebaseRedirectSource.fromRegexPattern(pattern), captures, matches);
|
||||
}
|
||||
|
||||
function testSourceMatch(
|
||||
source: FirebaseRedirectSource,
|
||||
captures: { named?: string[], rest?: string[] },
|
||||
matches: { [url: string]: object|undefined }) {
|
||||
matches: { [url: string]: unknown|undefined }) {
|
||||
expect(source.namedGroups).toEqual(captures.named || []);
|
||||
expect(source.restNamedGroups).toEqual(captures.rest || []);
|
||||
Object.keys(matches).forEach(url => expect(source.match(url)).toEqual(matches[url]));
|
||||
|
||||
@@ -40,7 +40,7 @@ export class FirebaseRedirectSource {
|
||||
restNamedGroups.push(groupName);
|
||||
return `(?:${leadingSlash}(?<${groupName}>.🐷))?`;
|
||||
})
|
||||
.replace(namedParam, `$1(?<$2>[^/]+)`)
|
||||
.replace(namedParam, '$1(?<$2>[^/]+)')
|
||||
.replace(doubleStar, '$1.🐷$2') // use the pig to avoid replacing ** in next rule
|
||||
.replace(star, '[^/]*') // match a single segment
|
||||
.replace(possiblyEmptyInitialSegments, '(?:.*)')// deal with **/ special cases
|
||||
@@ -89,6 +89,7 @@ export class FirebaseRedirectSource {
|
||||
|
||||
const result: { [key: string]: string } = {};
|
||||
const names = this.regex.xregexp.captureNames || [];
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
names.forEach(name => result[name] = match.groups![name]);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Use this tag to indicate that this class can be extended.
|
||||
*
|
||||
* This is the opposite of the Java `sealed` keyword.
|
||||
*/
|
||||
module.exports = function() {
|
||||
return {
|
||||
name: 'extensible',
|
||||
transforms: function() { return true; }
|
||||
};
|
||||
};
|
||||
@@ -26,6 +26,9 @@
|
||||
{% if doc.deprecated !== undefined %}<label class="api-status-label deprecated">deprecated</label>{% endif %}
|
||||
{% if doc.security !== undefined %}<label class="api-status-label security">security</label>{% endif %}
|
||||
{% if doc.pipeOptions.pure === 'false' %}<label class="api-status-label impure-pipe">impure</label>{% endif %}
|
||||
{% if doc.docType === 'class' and doc.extensible !== true and not doc.isAbstract %}<label class="github-links api-status-label final" title="This class should not be extended.">
|
||||
<a href="{$ github.githubVersionedUrl(versionInfo) $}/docs/PUBLIC_API.md#final-classes">final</a>
|
||||
</label>{% endif %}
|
||||
</header>
|
||||
{% endblock %}
|
||||
<aio-toc class="embedded"></aio-toc>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{% import "lib/ngmodule.html" as ngModuleHelpers -%}
|
||||
{% extends 'export-base.template.html' -%}
|
||||
|
||||
{% block overview %}
|
||||
{% include "includes/class-overview.html" %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -95,6 +95,14 @@
|
||||
{% if method.shortDescription %}<tr>
|
||||
<td class="short-description">
|
||||
{$ method.shortDescription | marked $}
|
||||
|
||||
{% if method.containerDoc.docType === 'class' and method.name === 'constructor' and not method.containerDoc.isAbstract and method.containerDoc.extensible !== true %}
|
||||
<p class="final-message">
|
||||
This class is "final" and should not be extended.
|
||||
See the <a href="{$ github.githubVersionedUrl(versionInfo) $}/docs/PUBLIC_API.md#final-classes">public API notes</a>.
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
{%- if method.see.length %}
|
||||
<p>See also:</p>
|
||||
<ul>
|
||||
|
||||
@@ -2,17 +2,23 @@
|
||||
{$ fileInfo.realProjectRelativePath if fileInfo.realProjectRelativePath else fileInfo.projectRelativePath $}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro githubViewHref(doc, versionInfo) -%}
|
||||
{% set githubUrl = 'https://github.com/' + versionInfo.gitRepoInfo.owner + '/' + versionInfo.gitRepoInfo.repo -%}
|
||||
{% macro githubBaseUrl(versionInfo) -%}
|
||||
https://github.com/{$ versionInfo.gitRepoInfo.owner $}/{$ versionInfo.gitRepoInfo.repo $}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro githubVersionedUrl(versionInfo) -%}
|
||||
{% set version = versionInfo.currentVersion.isSnapshot and versionInfo.currentVersion.SHA or versionInfo.currentVersion.raw -%}
|
||||
{$ githubBaseUrl(versionInfo) $}/tree/{$ version $}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro githubViewHref(doc, versionInfo) -%}
|
||||
{% set lineInfo = doc.startingLine and ('#L' + (doc.startingLine + 1) + '-L' + (doc.endingLine + 1)) or '' -%}
|
||||
{$ githubUrl $}/tree/{$ version $}/{$ projectRelativePath(doc.fileInfo) $}{$ lineInfo $}
|
||||
{$ githubVersionedUrl(versionInfo) $}/{$ projectRelativePath(doc.fileInfo) $}{$ lineInfo $}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro githubEditHref(doc, versionInfo, pathPrefix) -%}
|
||||
{% set githubUrl = 'https://github.com/' + versionInfo.gitRepoInfo.owner + '/' + versionInfo.gitRepoInfo.repo -%}
|
||||
{% set lineInfo = doc.startingLine and ('#L' + (doc.startingLine + 1) + '-L' + (doc.endingLine + 1)) or '' -%}
|
||||
{$ githubUrl $}/edit/master/{$ projectRelativePath(doc.fileInfo) $}?message=docs
|
||||
{$ githubBaseUrl(versionInfo) $}/edit/master/{$ projectRelativePath(doc.fileInfo) $}?message=docs
|
||||
{%- if doc.moduleDoc %}({$ doc.moduleDoc.id.split('/')[0] $})
|
||||
{%- elseif doc.docType === 'module' %}({$ doc.id.split('/')[0] $})
|
||||
{%- elseif doc.docType === 'content' %}
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
{
|
||||
"rulesDirectory": [
|
||||
"../node_modules/codelyzer"
|
||||
],
|
||||
"rules": {
|
||||
"class-name": true,
|
||||
"comment-format": [
|
||||
true,
|
||||
"check-space"
|
||||
],
|
||||
"curly": true,
|
||||
"eofline": true,
|
||||
"forin": true,
|
||||
"indent": [
|
||||
true,
|
||||
"spaces"
|
||||
],
|
||||
"label-position": true,
|
||||
"max-line-length": [
|
||||
true,
|
||||
140
|
||||
],
|
||||
"member-access": false,
|
||||
"no-arg": true,
|
||||
"no-bitwise": true,
|
||||
"no-console": [
|
||||
true,
|
||||
"debug",
|
||||
"info",
|
||||
"time",
|
||||
"timeEnd",
|
||||
"trace"
|
||||
],
|
||||
"no-construct": true,
|
||||
"no-debugger": true,
|
||||
"no-duplicate-variable": true,
|
||||
"no-empty": false,
|
||||
"no-eval": true,
|
||||
"no-inferrable-types": true,
|
||||
"no-string-literal": false,
|
||||
"no-switch-case-fall-through": true,
|
||||
"no-trailing-whitespace": true,
|
||||
"no-unused-expression": true,
|
||||
"no-var-keyword": true,
|
||||
"object-literal-sort-keys": false,
|
||||
"one-line": [
|
||||
true,
|
||||
"check-open-brace",
|
||||
"check-catch",
|
||||
"check-else",
|
||||
"check-whitespace"
|
||||
],
|
||||
"quotemark": [
|
||||
true,
|
||||
"single"
|
||||
],
|
||||
"radix": true,
|
||||
"semicolon": [
|
||||
true
|
||||
],
|
||||
"triple-equals": [
|
||||
true,
|
||||
"allow-null-check"
|
||||
],
|
||||
"typedef-whitespace": [
|
||||
true,
|
||||
{
|
||||
"call-signature": "nospace",
|
||||
"index-signature": "nospace",
|
||||
"parameter": "nospace",
|
||||
"property-declaration": "nospace",
|
||||
"variable-declaration": "nospace"
|
||||
}
|
||||
],
|
||||
"variable-name": false,
|
||||
"whitespace": [
|
||||
true,
|
||||
"check-branch",
|
||||
"check-decl",
|
||||
"check-operator",
|
||||
"check-separator",
|
||||
"check-type"
|
||||
],
|
||||
|
||||
"import-destructuring-spacing": true
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -4743,11 +4743,16 @@ entities@^1.1.1:
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
|
||||
integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
|
||||
|
||||
entities@^2.0.0, entities@^2.2.0:
|
||||
entities@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
|
||||
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
|
||||
|
||||
entities@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4"
|
||||
integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==
|
||||
|
||||
env-paths@^2.2.0:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
# BEGIN-INTERNAL
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "pkg_npm")
|
||||
load("//dev-infra:defaults.bzl", "ng_dev_rolled_up_generated_file", "ts_library")
|
||||
# END-INTERNAL
|
||||
|
||||
exports_files(["tsconfig.json"])
|
||||
|
||||
# BEGIN-INTERNAL
|
||||
ts_library(
|
||||
name = "cli",
|
||||
srcs = [
|
||||
"cli.ts",
|
||||
],
|
||||
deps = [
|
||||
"//dev-infra/caretaker",
|
||||
"//dev-infra/commit-message",
|
||||
"//dev-infra/format",
|
||||
"//dev-infra/misc",
|
||||
"//dev-infra/ngbot",
|
||||
"//dev-infra/pr",
|
||||
"//dev-infra/pullapprove",
|
||||
"//dev-infra/release",
|
||||
"//dev-infra/ts-circular-dependencies",
|
||||
"//dev-infra/utils",
|
||||
"@npm//@types/node",
|
||||
"@npm//@types/yargs",
|
||||
"@npm//yargs",
|
||||
],
|
||||
)
|
||||
|
||||
genrule(
|
||||
name = "package-json",
|
||||
srcs = [
|
||||
"tmpl-package.json",
|
||||
"//:package.json",
|
||||
],
|
||||
outs = ["package.json"],
|
||||
cmd = """
|
||||
$(execpath //tools:inline-package-json-deps) $(execpath tmpl-package.json) \
|
||||
$(execpath //:package.json) $@
|
||||
""",
|
||||
tools = ["//tools:inline-package-json-deps"],
|
||||
)
|
||||
|
||||
pkg_npm(
|
||||
name = "npm_package",
|
||||
srcs = [
|
||||
# Main bazel entry-point for the shared `dev-infra` package.
|
||||
"index.bzl",
|
||||
"BUILD.bazel",
|
||||
# Some tools within `dev-infra` which are shipped as Bazel rules might
|
||||
# rely on a tsconfig file. We bring the config into the NPM package.
|
||||
"tsconfig.json",
|
||||
"//dev-infra/bazel:files",
|
||||
"//dev-infra/benchmark:files",
|
||||
],
|
||||
substitutions = {
|
||||
# angular/angular should not consume it's own packages, so we use
|
||||
# substitutions to replace these in the published version of dev-infra.
|
||||
"@angular//dev-infra/": "@npm//@angular/dev-infra-private/",
|
||||
"//dev-infra/": "@npm//@angular/dev-infra-private/",
|
||||
"//dev-infra:": "@npm//@angular/dev-infra-private:",
|
||||
|
||||
# Substitutions needed for `//dev-infra/benchmark`:
|
||||
"//packages/benchpress": "@npm//@angular/benchpress",
|
||||
"//packages/bazel": "@npm//@angular/bazel",
|
||||
"//packages/zone.js/bundles:zone.umd.js": "@npm//zone.js",
|
||||
"//packages/core": "@npm//@angular/core",
|
||||
"//packages/platform-browser": "@npm//@angular/platform-browser",
|
||||
# This substitution is particularly verbose because we need to make sure
|
||||
# that only things available via Angular Bazel are imported from
|
||||
# tools/defaults.bzl.
|
||||
"load\\(\"//tools:defaults.bzl\", \"ng_module\"\\)": "load(\"@npm//@angular/bazel:index.bzl\", \"ng_module\")",
|
||||
},
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":cli",
|
||||
":package-json",
|
||||
"//dev-infra/benchmark/driver-utilities",
|
||||
"//dev-infra/commit-message",
|
||||
"//dev-infra/ts-circular-dependencies",
|
||||
"//dev-infra/tslint-rules",
|
||||
],
|
||||
)
|
||||
|
||||
# Because the angular/angular repository relies on the local repository for running ng-dev commands,
|
||||
# the rollup generated javascript files are committed into the repository to be used as node
|
||||
# scripts. To ensure they stay up to date, they are created using a generated file test.
|
||||
#
|
||||
# Currently there are two generated files which are needed
|
||||
# ng-dev.js - The main script representing ng-dev
|
||||
# build-worker.js - The worker script for the `ng-dev release build` command, allowing it to run
|
||||
# in a forked process.
|
||||
ng_dev_rolled_up_generated_file(
|
||||
name = "ng-dev",
|
||||
entry_point = ":cli.ts",
|
||||
rollup_args = [
|
||||
"--plugin",
|
||||
"rollup-plugin-hashbang",
|
||||
],
|
||||
deps = [
|
||||
":cli",
|
||||
# TODO(josephperrott): Determine if this plugin is the best method for ensuring the hashbang
|
||||
# in both local and published use case.
|
||||
"@npm//rollup-plugin-hashbang",
|
||||
],
|
||||
)
|
||||
|
||||
ng_dev_rolled_up_generated_file(
|
||||
name = "build-worker",
|
||||
entry_point = "//dev-infra/release/build:build-worker.ts",
|
||||
deps = [
|
||||
"//dev-infra/release/build",
|
||||
],
|
||||
)
|
||||
# END-INTERNAL
|
||||
@@ -1,13 +0,0 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
filegroup(
|
||||
name = "files",
|
||||
srcs = [
|
||||
"BUILD.bazel",
|
||||
"expand_template.bzl",
|
||||
"extract_js_module_output.bzl",
|
||||
"//dev-infra/bazel/api-golden:files",
|
||||
"//dev-infra/bazel/browsers:files",
|
||||
"//dev-infra/bazel/remote-execution:files",
|
||||
],
|
||||
)
|
||||
@@ -1,35 +0,0 @@
|
||||
load("@npm//@bazel/typescript:index.bzl", "ts_library")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
exports_files([
|
||||
"index.ts",
|
||||
"index_npm_packages.ts",
|
||||
])
|
||||
|
||||
ts_library(
|
||||
name = "api-golden",
|
||||
srcs = [
|
||||
"find_entry_points.ts",
|
||||
"index.ts",
|
||||
"index_npm_packages.ts",
|
||||
"test_api_report.ts",
|
||||
],
|
||||
# A tsconfig needs to be specified as otherwise `ts_library` will look for the config
|
||||
# in `//:package.json` and this breaks when the BUILD file is copied to `@npm//`.
|
||||
tsconfig = "//dev-infra:tsconfig.json",
|
||||
deps = [
|
||||
"@npm//@bazel/runfiles",
|
||||
"@npm//@microsoft/api-extractor",
|
||||
"@npm//@types/node",
|
||||
"@npm//chalk",
|
||||
"@npm//tslib",
|
||||
"@npm//typescript",
|
||||
],
|
||||
)
|
||||
|
||||
# Expose the sources in the dev-infra NPM package.
|
||||
filegroup(
|
||||
name = "files",
|
||||
srcs = glob(["*"]),
|
||||
)
|
||||
@@ -1,62 +0,0 @@
|
||||
/**
|
||||
* @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 {lstatSync, readdirSync, readFileSync} from 'fs';
|
||||
import {dirname, join} from 'path';
|
||||
|
||||
/** Interface describing a resolved NPM package entry point. */
|
||||
export interface PackageEntryPoint {
|
||||
typesEntryPointPath: string;
|
||||
packageJsonPath: string;
|
||||
}
|
||||
|
||||
/** Interface describing contents of a `package.json`. */
|
||||
interface PackageJson {
|
||||
types?: string;
|
||||
typings?: string;
|
||||
}
|
||||
|
||||
/** Finds all entry points within a given NPM package directory. */
|
||||
export function findEntryPointsWithinNpmPackage(dirPath: string): PackageEntryPoint[] {
|
||||
const entryPoints: PackageEntryPoint[] = [];
|
||||
|
||||
for (const packageJsonFilePath of findPackageJsonFilesInDirectory(dirPath)) {
|
||||
const packageJson = JSON.parse(readFileSync(packageJsonFilePath, 'utf8')) as PackageJson;
|
||||
const typesFile = packageJson.types || packageJson.typings;
|
||||
|
||||
if (typesFile) {
|
||||
entryPoints.push({
|
||||
packageJsonPath: packageJsonFilePath,
|
||||
typesEntryPointPath: join(dirname(packageJsonFilePath), typesFile),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return entryPoints;
|
||||
}
|
||||
|
||||
/** Determine if the provided path is a directory. */
|
||||
function isDirectory(dirPath: string) {
|
||||
try {
|
||||
return lstatSync(dirPath).isDirectory();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Finds all `package.json` files within a directory. */
|
||||
function* findPackageJsonFilesInDirectory(directoryPath: string): IterableIterator<string> {
|
||||
for (const fileName of readdirSync(directoryPath)) {
|
||||
const fullPath = join(directoryPath, fileName);
|
||||
if (isDirectory(fullPath)) {
|
||||
yield* findPackageJsonFilesInDirectory(fullPath);
|
||||
} else if (fileName === 'package.json') {
|
||||
yield fullPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
load("//dev-infra/bazel:extract_js_module_output.bzl", "extract_js_module_output")
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary", "nodejs_test")
|
||||
|
||||
nodejs_test_args = [
|
||||
# Needed so that node doesn't walk back to the source directory.
|
||||
# From there, the relative imports would point to .ts files.
|
||||
"--node_options=--preserve-symlinks",
|
||||
# TODO(josephperrott): update dependency usages to no longer need bazel patch module resolver
|
||||
# See: https://github.com/bazelbuild/rules_nodejs/wiki#--bazel_patch_module_resolver-now-defaults-to-false-2324
|
||||
"--bazel_patch_module_resolver",
|
||||
]
|
||||
|
||||
default_strip_export_pattern = "^ɵ(?!ɵdefineInjectable|ɵinject|ɵInjectableDef)"
|
||||
|
||||
"""Escapes a Regular expression so that it can be passed as process argument."""
|
||||
|
||||
def _escape_regex_for_arg(value):
|
||||
return "\"%s\"" % value
|
||||
|
||||
"""
|
||||
Extracts type names from a list of NPM type targets.
|
||||
|
||||
For example: Consider the `@npm//@types/node` target. This function extracts `node`
|
||||
from the label. This is needed so that the Node types can be wired up within a
|
||||
TypeScript program using the `types` tsconfig option.
|
||||
"""
|
||||
|
||||
def extract_type_names_from_labels(type_targets):
|
||||
type_names = []
|
||||
for type_target in type_targets:
|
||||
type_package = Label(type_target).package
|
||||
|
||||
if (type_package.startswith("@types/")):
|
||||
type_names.append(type_package[len("@types/"):])
|
||||
else:
|
||||
fail("Expected type target to match the following format: " +
|
||||
"`@<npm_workspace>//@types/<name>`, but got: %s" % type_target)
|
||||
|
||||
return type_names
|
||||
|
||||
"""
|
||||
Builds an API report for the specified entry-point and compares it against the
|
||||
specified golden
|
||||
"""
|
||||
|
||||
def api_golden_test(
|
||||
name,
|
||||
golden,
|
||||
entry_point,
|
||||
data = [],
|
||||
strip_export_pattern = default_strip_export_pattern,
|
||||
types = [],
|
||||
**kwargs):
|
||||
quoted_export_pattern = _escape_regex_for_arg(strip_export_pattern)
|
||||
|
||||
kwargs["tags"] = kwargs.get("tags", []) + ["api_guard"]
|
||||
|
||||
# For API golden tests not running against a NPM package, we extract all transitive
|
||||
# declarations of the specified `data` targets. This is necessary because API extractor
|
||||
# needs to resolve other targets that have been linked by the Bazel NodeJS rules. The
|
||||
# linker by default only provides access to JavaScript sources, but the API extractor is
|
||||
# specifically concerned with type definitions that we can extract manually here.
|
||||
extract_js_module_output(
|
||||
name = "%s_data_typings" % name,
|
||||
deps = data,
|
||||
provider = "JSModuleInfo",
|
||||
include_declarations = True,
|
||||
include_default_files = False,
|
||||
)
|
||||
|
||||
test_data = ["//dev-infra/bazel/api-golden", "//:package.json", ":%s_data_typings" % name] + \
|
||||
data + types
|
||||
|
||||
nodejs_test(
|
||||
name = name,
|
||||
data = test_data,
|
||||
entry_point = "//dev-infra/bazel/api-golden:index.ts",
|
||||
templated_args = nodejs_test_args + [golden, entry_point, "false", quoted_export_pattern] +
|
||||
extract_type_names_from_labels(types),
|
||||
**kwargs
|
||||
)
|
||||
|
||||
nodejs_binary(
|
||||
name = name + ".accept",
|
||||
testonly = True,
|
||||
data = test_data,
|
||||
entry_point = "//dev-infra/bazel/api-golden:index.ts",
|
||||
templated_args = nodejs_test_args + [golden, entry_point, "true", quoted_export_pattern] +
|
||||
extract_type_names_from_labels(types),
|
||||
**kwargs
|
||||
)
|
||||
|
||||
"""
|
||||
Builds an API report for all entrypoints within the given NPM package and compares it
|
||||
against goldens within the specified directory.
|
||||
"""
|
||||
|
||||
def api_golden_test_npm_package(
|
||||
name,
|
||||
golden_dir,
|
||||
npm_package,
|
||||
data = [],
|
||||
strip_export_pattern = default_strip_export_pattern,
|
||||
types = [],
|
||||
**kwargs):
|
||||
quoted_export_pattern = _escape_regex_for_arg(strip_export_pattern)
|
||||
|
||||
kwargs["tags"] = kwargs.get("tags", []) + ["api_guard"]
|
||||
|
||||
nodejs_test(
|
||||
name = name,
|
||||
data = ["//dev-infra/bazel/api-golden"] + data + types,
|
||||
entry_point = "//dev-infra/bazel/api-golden:index_npm_packages.ts",
|
||||
templated_args = nodejs_test_args + [golden_dir, npm_package, "false", quoted_export_pattern] +
|
||||
extract_type_names_from_labels(types),
|
||||
**kwargs
|
||||
)
|
||||
|
||||
nodejs_binary(
|
||||
name = name + ".accept",
|
||||
testonly = True,
|
||||
data = ["//dev-infra/bazel/api-golden"] + data + types,
|
||||
entry_point = "//dev-infra/bazel/api-golden:index_npm_packages.ts",
|
||||
templated_args = nodejs_test_args + [golden_dir, npm_package, "true", quoted_export_pattern] +
|
||||
extract_type_names_from_labels(types),
|
||||
**kwargs
|
||||
)
|
||||
@@ -1,47 +0,0 @@
|
||||
/**
|
||||
* @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 {runfiles} from '@bazel/runfiles';
|
||||
import * as chalk from 'chalk';
|
||||
|
||||
import {testApiGolden} from './test_api_report';
|
||||
|
||||
/**
|
||||
* Entry point for the `api_golden_test` Bazel rule. This function builds an API report for
|
||||
* the specified entry point file and compares it against the specified golden file.
|
||||
*/
|
||||
async function main(
|
||||
goldenFilePath: string, entryPointFilePath: string, approveGolden: boolean,
|
||||
stripExportPattern: RegExp, typeNames: string[]) {
|
||||
const {succeeded, apiReportChanged} = await testApiGolden(
|
||||
goldenFilePath, entryPointFilePath, approveGolden, stripExportPattern, typeNames);
|
||||
|
||||
if (!succeeded && apiReportChanged) {
|
||||
console.error(chalk.red(`The API signature has changed and the golden file is outdated.`));
|
||||
console.info(chalk.yellow(
|
||||
`Golden can be updated by running: yarn bazel run ${process.env.TEST_TARGET}.accept`));
|
||||
}
|
||||
|
||||
// Bazel expects `3` as exit code for failing tests.
|
||||
process.exitCode = succeeded ? 0 : 3;
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
const args = process.argv.slice(2);
|
||||
const goldenFilePath = runfiles.resolve(args[0]);
|
||||
const entryPointFilePath = runfiles.resolve(args[1]);
|
||||
const approveGolden = args[2] === 'true';
|
||||
const stripExportPattern = new RegExp(args[3]);
|
||||
const typeNames = args.slice(4);
|
||||
|
||||
main(goldenFilePath, entryPointFilePath, approveGolden, stripExportPattern, typeNames)
|
||||
.catch(e => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/**
|
||||
* @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 {runfiles} from '@bazel/runfiles';
|
||||
import * as chalk from 'chalk';
|
||||
import {join, relative} from 'path';
|
||||
|
||||
import {findEntryPointsWithinNpmPackage} from './find_entry_points';
|
||||
import {testApiGolden} from './test_api_report';
|
||||
|
||||
/**
|
||||
* Entry point for the `api_golden_test_npm_package` Bazel rule. This function determines
|
||||
* all types within the specified NPM package and builds API reports that will be compared
|
||||
* against golden files within the given golden directory.
|
||||
*/
|
||||
async function main(
|
||||
goldenDir: string, npmPackageDir: string, approveGolden: boolean, stripExportPattern: RegExp,
|
||||
typeNames: string[]) {
|
||||
const entryPoints = findEntryPointsWithinNpmPackage(npmPackageDir);
|
||||
const outdatedGoldens: string[] = [];
|
||||
let allTestsSucceeding = true;
|
||||
|
||||
for (const {packageJsonPath, typesEntryPointPath} of entryPoints) {
|
||||
const pkgRelativeName = relative(npmPackageDir, typesEntryPointPath);
|
||||
// API extractor generates API reports as markdown files. For each types
|
||||
// entry-point we maintain a separate golden file. These golden files are
|
||||
// based on the name of the entry-point `.d.ts` file in the NPM package,
|
||||
// but with the proper `.md` file extension.
|
||||
// See: https://api-extractor.com/pages/overview/demo_api_report/.
|
||||
const goldenName = pkgRelativeName.replace(/\.d\.ts$/, '.md');
|
||||
const goldenFilePath = join(goldenDir, goldenName);
|
||||
|
||||
const {succeeded, apiReportChanged} = await testApiGolden(
|
||||
goldenFilePath, typesEntryPointPath, approveGolden, stripExportPattern, typeNames,
|
||||
packageJsonPath);
|
||||
|
||||
// Keep track of outdated goldens.
|
||||
if (!succeeded && apiReportChanged) {
|
||||
outdatedGoldens.push(goldenName);
|
||||
}
|
||||
|
||||
allTestsSucceeding = allTestsSucceeding && succeeded;
|
||||
}
|
||||
|
||||
if (outdatedGoldens.length) {
|
||||
console.error(chalk.red(`The following goldens are outdated:`));
|
||||
outdatedGoldens.forEach(name => console.info(`- ${name}`));
|
||||
console.info();
|
||||
console.info(chalk.yellow(
|
||||
`The goldens can be updated by running: yarn bazel run ${process.env.TEST_TARGET}.accept`));
|
||||
}
|
||||
|
||||
// Bazel expects `3` as exit code for failing tests.
|
||||
process.exitCode = allTestsSucceeding ? 0 : 3;
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
const args = process.argv.slice(2);
|
||||
const goldenDir = runfiles.resolve(args[0]);
|
||||
const npmPackageDir = runfiles.resolve(args[1]);
|
||||
const approveGolden = args[2] === 'true';
|
||||
const stripExportPattern = new RegExp(args[3]);
|
||||
const typeNames = args.slice(4);
|
||||
|
||||
main(goldenDir, npmPackageDir, approveGolden, stripExportPattern, typeNames).catch(e => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
/**
|
||||
* @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 {runfiles} from '@bazel/runfiles';
|
||||
import {ConsoleMessageId, Extractor, ExtractorConfig, ExtractorLogLevel, ExtractorMessage, ExtractorMessageId, ExtractorResult, IConfigFile} from '@microsoft/api-extractor';
|
||||
import {AstModule} from '@microsoft/api-extractor/lib/analyzer/AstModule';
|
||||
import {ExportAnalyzer} from '@microsoft/api-extractor/lib/analyzer/ExportAnalyzer';
|
||||
import {basename, dirname} from 'path';
|
||||
|
||||
/**
|
||||
* Original definition of the `ExportAnalyzer#fetchAstModuleExportInfo` method.
|
||||
* We store the original function since we monkey-patch it later to account for
|
||||
* specified strip export patterns.
|
||||
* */
|
||||
const _origFetchAstModuleExportInfo = ExportAnalyzer.prototype.fetchAstModuleExportInfo;
|
||||
|
||||
/**
|
||||
* Builds an API report for the given entry-point file and compares
|
||||
* it against a golden file.
|
||||
*
|
||||
* @param goldenFilePath Path to an API report file that is used as golden
|
||||
* @param indexFilePath Entry point file that is analyzed to build the API report.
|
||||
* @param approveGolden Whether the golden file should be updated.
|
||||
* @param stripExportPattern Regular Expression that can be used to filter out exports
|
||||
* from the API report.
|
||||
* @param typeNames Name of types which should be included for analysis of the entry-point.
|
||||
* Types are expected to exist within the default `node_modules/@types/` folder.
|
||||
* @param packageJsonPath Optional path to a `package.json` file that contains the entry
|
||||
* point. Note that the `package.json` is currently only used by `api-extractor` to determine
|
||||
* the package name displayed within the API golden.
|
||||
*/
|
||||
export async function testApiGolden(
|
||||
goldenFilePath: string, indexFilePath: string, approveGolden: boolean,
|
||||
stripExportPattern: RegExp, typeNames: string[] = [],
|
||||
packageJsonPath = resolveWorkspacePackageJsonPath()): Promise<ExtractorResult> {
|
||||
// If no `TEST_TMPDIR` is defined, then this script runs using `bazel run`. We use
|
||||
// the runfile directory as temporary directory for API extractor.
|
||||
const tempDir = process.env.TEST_TMPDIR ?? process.cwd();
|
||||
|
||||
const configObject: IConfigFile = {
|
||||
compiler: {
|
||||
overrideTsconfig:
|
||||
// We disable automatic `@types` resolution as this throws-off API reports
|
||||
// when the API test is run outside sandbox. Instead we expect a list of
|
||||
// hard-coded types that should be included. This works in non-sandbox too.
|
||||
{files: [indexFilePath], compilerOptions: {types: typeNames, lib: ['esnext', 'dom']}}
|
||||
},
|
||||
projectFolder: dirname(packageJsonPath),
|
||||
mainEntryPointFilePath: indexFilePath,
|
||||
dtsRollup: {enabled: false},
|
||||
docModel: {enabled: false},
|
||||
apiReport: {
|
||||
enabled: true,
|
||||
reportFolder: dirname(goldenFilePath),
|
||||
reportTempFolder: tempDir,
|
||||
reportFileName: basename(goldenFilePath),
|
||||
},
|
||||
tsdocMetadata: {enabled: false},
|
||||
newlineKind: 'lf',
|
||||
messages: {
|
||||
extractorMessageReporting: {
|
||||
// If an export does not have a release tag (like `@public`), API extractor maps
|
||||
// considers it still as `Public`. We hide the message for now given the Angular
|
||||
// repositories do not follow the TSDoc standard. https://tsdoc.org/.
|
||||
// TODO: Make this an error once TSDoc standard is followed in all projects.
|
||||
[ExtractorMessageId.MissingReleaseTag]: {logLevel: ExtractorLogLevel.None},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// We read the specified `package.json` manually and build a package name that is
|
||||
// compatible with the API extractor. This is a workaround for a bug in api-extractor.
|
||||
// TODO remove once https://github.com/microsoft/rushstack/issues/2774 is resolved.
|
||||
const packageJson = require(packageJsonPath);
|
||||
const packageNameSegments = packageJson.name.split('/');
|
||||
const packageName = packageNameSegments.length === 1 ?
|
||||
packageNameSegments[0] :
|
||||
`${packageNameSegments[0]}/${packageNameSegments.slice(1).join('_')}`;
|
||||
|
||||
const extractorConfig = ExtractorConfig.prepare({
|
||||
configObject,
|
||||
// TODO: Remove workaround once https://github.com/microsoft/rushstack/issues/2774 is fixed.
|
||||
packageJson: {name: packageName},
|
||||
packageJsonFullPath: packageJsonPath,
|
||||
configObjectFullPath: undefined,
|
||||
});
|
||||
|
||||
// This patches the `ExportAnalyzer` of `api-extractor` so that we can filter out
|
||||
// exports that match a specified pattern. Ideally this would not be needed as the
|
||||
// TSDoc JSDoc annotations could be used to filter out exports from the API report,
|
||||
// but there are cases in Angular where exports cannot be `@internal` but at the same
|
||||
// time are denoted as unstable. Such exports are allowed to change frequently and should
|
||||
// not be captured in the API report (as this would be unnecessarily inconvenient).
|
||||
ExportAnalyzer.prototype.fetchAstModuleExportInfo = function(module: AstModule) {
|
||||
const info = _origFetchAstModuleExportInfo.apply(this, [module]);
|
||||
|
||||
info.exportedLocalEntities.forEach((entity, exportName) => {
|
||||
if (stripExportPattern.test(exportName)) {
|
||||
info.exportedLocalEntities.delete(exportName);
|
||||
}
|
||||
});
|
||||
|
||||
return info;
|
||||
};
|
||||
|
||||
return Extractor.invoke(extractorConfig, {
|
||||
// If the golden should be approved, then `localBuild: true` instructs
|
||||
// API extractor to update the file.
|
||||
localBuild: approveGolden,
|
||||
// Process messages from the API extractor (and modify log levels if needed).
|
||||
messageCallback: msg => processExtractorMessage(msg, approveGolden),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an API extractor message. Microsoft's API extractor allows developers to
|
||||
* handle messages before API extractor prints them. This allows us to adjust log level
|
||||
* for certain messages, or to fully prevent messages from being printed out.
|
||||
* */
|
||||
async function processExtractorMessage(message: ExtractorMessage, isApprove: boolean) {
|
||||
// If the golden does not match, we hide the error as API extractor prints
|
||||
// a warning asking the user to manually copy the new API report. We print
|
||||
// a custom warning below asking the developer to run the `.accept` Bazel target.
|
||||
// TODO: Simplify once https://github.com/microsoft/rushstack/issues/2773 is resolved.
|
||||
if (message.messageId === ConsoleMessageId.ApiReportNotCopied) {
|
||||
// Mark the message as handled so that API-extractor does not print it. We print
|
||||
// a message manually after extraction.
|
||||
message.handled = true;
|
||||
message.logLevel = isApprove ? ExtractorLogLevel.None : ExtractorLogLevel.Error;
|
||||
}
|
||||
}
|
||||
|
||||
/** Resolves the `package.json` of the workspace executing this action. */
|
||||
function resolveWorkspacePackageJsonPath(): string {
|
||||
const workspaceName = process.env.BAZEL_WORKSPACE!;
|
||||
return runfiles.resolve(`${workspaceName}/package.json`);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
# Make source files available for distribution via pkg_npm
|
||||
filegroup(
|
||||
name = "files",
|
||||
srcs = glob(["*"]) + [
|
||||
"//dev-infra/bazel/browsers/chromium:files",
|
||||
"//dev-infra/bazel/browsers/firefox:files",
|
||||
],
|
||||
)
|
||||
@@ -1,110 +0,0 @@
|
||||
# Browser configuration and versioning for testing of Angular
|
||||
|
||||
Within the Angular organization, we use Chrome and Firefox to perform most of the local testing, and rely on Sauce Labs and BrowserStack to do cross-browser testing on our CI.
|
||||
|
||||
The version of Chrome used in tests within this monorepo is configured and controlled via Bazel and `puppeteer`.
|
||||
We manually keep the configuration of these two tools in sync to create a consistent testing environment across unit, e2e, and integration tests.
|
||||
|
||||
## Bazel
|
||||
|
||||
Bazel `karma_web_test_suite` and `protractor_web_test_suite` targets will use Chromium or Firefox provisioned by `//dev-infra/bazel/browsers`.
|
||||
The version of Chrome and Firefox are specified in the `chromium.bzl` and `firefox.bzl` files in `/dev-infra/bazel/browsers`.
|
||||
|
||||
The process of updating the Chrome or Firefox version is not straightforward, but below are dedicated sections for each browser.
|
||||
|
||||
## Updating Chromium
|
||||
|
||||
1. Visit https://chromium.woolyss.com/ and note the version (commit position) of the latest stable version.
|
||||
|
||||
For example, "Google Chrome 83.0.4103.97 (756066) • Wednesday, 3 Jun 2020".
|
||||
Alternatively, you can look in https://omahaproxy.appspot.com/.
|
||||
|
||||
2. Find the closest commit position number available for each platform in chromium-browser-snapshots: https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html
|
||||
|
||||
For example:
|
||||
* https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Linux_x64/756066/
|
||||
* https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Mac/756053/
|
||||
* https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Win/756065/
|
||||
|
||||
You can download Chromium for your local platform and double check that the `--version` matches up with what you expect.
|
||||
|
||||
For example:
|
||||
``` bash
|
||||
$ ~/Downloads/chrome-mac/Chromium.app/Contents/MacOS/Chromium --version
|
||||
Chromium 83.0.4103.0
|
||||
```
|
||||
|
||||
3. Update the chrome & chrome driver build numbers in `dev-infra/bazel/browsers/chromium/chromium.bzl` and either run `bazel query @org_chromium_chromium_amd64//...` to prompt Bazel to calculate the new `sha256` for each platform binary or determine the new `sha256` values manually.
|
||||
|
||||
Here is an example with `curl` & `shasum`:
|
||||
``` bash
|
||||
curl -L https://commondatastorage.googleapis.com/chromium-browser-snapshots/Linux_x64/756066/chrome-linux.zip | shasum -a 256
|
||||
```
|
||||
|
||||
## Puppeteer
|
||||
|
||||
1. Visit https://github.com/puppeteer/puppeteer/blob/master/docs/api.md to determine which version of puppeteer corresponds to the version of Chrome desired.
|
||||
|
||||
2. Visit https://chromedriver.chromium.org/downloads to determine which version of ChromeDriver should be used for the version of Chrome desired.
|
||||
|
||||
> NOTE:
|
||||
> The version of Chrome does not necessarily correspond exactly with the version of ChromeDriver.
|
||||
> For example, you might have to use ChromeDriver v87.0.4280.x to drive Chrome v87.0.4272.x.
|
||||
|
||||
3. Update `scripts/puppeteer-chromedriver-versions.js` to include an entry with the new version of puppeteer as key and the new version of ChromeDriver as value (as determined in the two previous steps).
|
||||
|
||||
4. Update all of the puppeteer versions throughout the repo:
|
||||
|
||||
* `package.json`
|
||||
* `aio/package.json`
|
||||
* `aio/tools/examples/shared/package.json`
|
||||
|
||||
...and their corresponding `yarn.lock` files.
|
||||
|
||||
## Firefox
|
||||
|
||||
In order to update Firefox, open the `dev-infra/bazel/browsers/firefox/firefox.bzl` file and update the repository URLs to the desired version.
|
||||
For example:
|
||||
|
||||
```bzl
|
||||
platform_http_file(
|
||||
name = "org_mozilla_firefox_amd64",
|
||||
licenses = ["reciprocal"], # MPL 2.0
|
||||
sha256 = "bde6e020556a21561e4b8d7aaecf8db7077951f179b98ca5d0305435bc6802c9",
|
||||
# Firefox v78.0
|
||||
urls = ["https://ftp.mozilla.org/pub/firefox/releases/78.0/linux-x86_64/en-US/firefox-78.0.tar.bz2"],
|
||||
)
|
||||
```
|
||||
|
||||
1. Go to the `urls` property and update the URL by replacing all `78.0` occurrences with the version you intend to use.
|
||||
Once done, do the same change for other platforms (such as `macos`).
|
||||
|
||||
2. Update the `sha256` checksum of the browser archives.
|
||||
You can do this by downloading the artifacts from the URLs you just updated, and then running `shasum` on those files:
|
||||
```sh
|
||||
curl -L <BROWSER_URL> | shasum -a 256
|
||||
```
|
||||
|
||||
In the same file, you can also update the version of gecko driver (the WebDriver implementation for Firefox browsers).
|
||||
|
||||
1. Go to https://firefox-source-docs.mozilla.org/testing/geckodriver/Support.html and find a version that is compatible with the used version of Firefox.
|
||||
|
||||
2. Update the `geckodriver` repository URLs to the desired version:
|
||||
|
||||
```bzl
|
||||
platform_http_file(
|
||||
name = "org_mozilla_geckodriver_amd64",
|
||||
licenses = ["reciprocal"], # MPL 2.0
|
||||
sha256 = "d59ca434d8e41ec1e30dd7707b0c95171dd6d16056fb6db9c978449ad8b93cc0",
|
||||
# Geckodriver v0.26.0
|
||||
urls = ["https://github.com/mozilla/geckodriver/releases/download/v0.26.0/geckodriver-v0.26.0-linux64.tar.gz"],
|
||||
)
|
||||
```
|
||||
|
||||
For example, replace all occurrences of `0.26.0` with the newer version.
|
||||
|
||||
3. Update the `sha256` checksum of the driver archives.
|
||||
You can do this by downloading the artifacts from the URLs you just updated, and then running `shasum` on those files:
|
||||
```sh
|
||||
curl -L <DRIVER_URL> | shasum -a 256
|
||||
```
|
||||
@@ -1,80 +0,0 @@
|
||||
"""Implementation of the `browser_archive` rule."""
|
||||
|
||||
def _browser_archive_impl(ctx):
|
||||
ctx.report_progress("Downloading browser archive from: %s" % ctx.attr.url)
|
||||
ctx.download_and_extract(
|
||||
url = ctx.attr.url,
|
||||
sha256 = ctx.attr.sha256,
|
||||
)
|
||||
|
||||
# The browser archive has been downloaded and extracted. We now generate a repository
|
||||
# `BUILD.bazel` file that exposes the archive files, together with the specified
|
||||
# named files using the `browser_configure` rule.
|
||||
ctx.file("BUILD.bazel", content = """
|
||||
load("@angular//dev-infra/bazel/browsers:browser_configure.bzl", "browser_configure")
|
||||
|
||||
licenses(%s)
|
||||
|
||||
browser_configure(
|
||||
name = "metadata",
|
||||
files = glob(["**/*"]),
|
||||
named_files = %s,
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""" % (str(ctx.attr.licenses), str(ctx.attr.named_files)))
|
||||
|
||||
"""
|
||||
Rule that can be used to download and unpack a browser archive in a dedicated Bazel
|
||||
repository. Additionally, files within the archive can be denoted with an unique name
|
||||
so that web tests can access browser files in a platform-agnostic way, regardless of
|
||||
which `browser_archive` repository is added as dependency.
|
||||
|
||||
As an example for the concept of denoting archive files with an unique name, consider a case
|
||||
where a a web test decides conditionally based on the current exec platform which
|
||||
`browser_archive` repository is used (e.g. mac, windows or linux). The archives are different
|
||||
for each platform. The test usually would need to determine the current platform, and know how
|
||||
each archive is structured in order to access the browser binary within the repository. By
|
||||
defining named files though, the web test could just pull a named file called `BINARY` that
|
||||
always resolves to the browser binary in a platform-agnostic way.
|
||||
|
||||
Note #1: This rule exists as an alternative to the `platform_http_file` concept
|
||||
from `rules_webtesting` because the `platform_http_file` rule does not extract the archive
|
||||
directly, but relies on later build actions to perform the unpacking. This results in less
|
||||
efficient caching because build actions are invalidated more frequently (e.g. `bazel clean).
|
||||
We also noticed that the extraction within RBE containers is rather unstable, and extracting
|
||||
the archives as part of a Bazel repository mitigates this (as extractions happens on the host).
|
||||
|
||||
Note #2: Additionally `rules_webtesting` defines a single repository for all platforms,
|
||||
where only an archive for the current host platform is pulled. This breaks cross-compilation
|
||||
because the wrong platform archive would be used for web tests that run in the exec platform.
|
||||
"""
|
||||
browser_archive = repository_rule(
|
||||
implementation = _browser_archive_impl,
|
||||
attrs = {
|
||||
"url": attr.string(
|
||||
doc = "Browser archive to download and extract.",
|
||||
mandatory = True,
|
||||
),
|
||||
"sha256": attr.string(
|
||||
doc = "SHA256 checksum for the archive.",
|
||||
mandatory = True,
|
||||
),
|
||||
"licenses": attr.string_list(
|
||||
mandatory = True,
|
||||
allow_empty = False,
|
||||
doc = """
|
||||
Licenses that apply to the archive. Will be passed to a `licenses` invocation
|
||||
within the repository. https://docs.bazel.build/versions/0.24.0/be/functions.html#licenses.
|
||||
""",
|
||||
),
|
||||
"named_files": attr.string_dict(
|
||||
doc = """
|
||||
Dictionary that maps files to unique identifiers. This is useful
|
||||
if browser archives are different on different platforms and the web
|
||||
tests would not want to care about archive-specific paths. e.g. targets
|
||||
expect a `CHROMIUM` key to point to the Chromium browser binary.
|
||||
""",
|
||||
mandatory = True,
|
||||
),
|
||||
},
|
||||
)
|
||||
@@ -1,69 +0,0 @@
|
||||
load("@io_bazel_rules_webtesting//web/internal:metadata.bzl", "metadata")
|
||||
load("@io_bazel_rules_webtesting//web/internal:provider.bzl", "WebTestInfo")
|
||||
|
||||
"""Converts the specified label to a manifest path"""
|
||||
|
||||
def _label_to_manifest_path(label):
|
||||
if label.package != "":
|
||||
return "%s/%s" % (label.workspace_name, label.package)
|
||||
return label.workspace_name
|
||||
|
||||
"""Implementation of the `browser_configure` rule."""
|
||||
|
||||
def _browser_configure_impl(ctx):
|
||||
named_files = {}
|
||||
base_dir = _label_to_manifest_path(ctx.label)
|
||||
|
||||
# Update the named files to manifest paths that can be resolved
|
||||
# with Bazel runfile resolution in web tests.
|
||||
for n, p in ctx.attr.named_files.items():
|
||||
named_files[n] = base_dir + "/" + p
|
||||
|
||||
# Create a web test metadata file that will be provided as part of
|
||||
# the `WebTestInfo` provider.
|
||||
metadata.create_file(
|
||||
ctx = ctx,
|
||||
output = ctx.outputs.web_test_metadata,
|
||||
web_test_files = [
|
||||
metadata.web_test_files(ctx = ctx, named_files = named_files),
|
||||
],
|
||||
)
|
||||
|
||||
return [
|
||||
DefaultInfo(runfiles = ctx.runfiles(files = ctx.files.files)),
|
||||
WebTestInfo(metadata = ctx.outputs.web_test_metadata),
|
||||
]
|
||||
|
||||
"""
|
||||
Rule that is used in combination with the `browser_archive` rule. It captures a set
|
||||
of files which are needed for dealing with a browser. Additionally, specific files
|
||||
for the browser can be denoted with an unique name so that web tests can access browser
|
||||
files in a platform-agnostic way, regardless of which browser repository is selected.
|
||||
|
||||
The specified browser files are exposed as runfiles of the target defined through this
|
||||
rule. The unique names with their associated files are captured within a metadata file
|
||||
that is exposed through a `WebTestInfo` provider. Web tests will be able to deal with
|
||||
this metadata file to resolve browser files in a platform-agnostic way.
|
||||
|
||||
More details on this can be found in the `browser_archive` rule.
|
||||
"""
|
||||
browser_configure = rule(
|
||||
attrs = {
|
||||
"files": attr.label_list(
|
||||
mandatory = True,
|
||||
allow_files = True,
|
||||
doc = "List of files which are needed for the browser.",
|
||||
),
|
||||
"named_files": attr.string_dict(
|
||||
doc = """
|
||||
Dictionary that maps files to unique identifiers. This is useful
|
||||
if browser archives are different on different platforms and the web
|
||||
tests would not want to care about archive-specific paths. e.g. targets
|
||||
expect a `CHROMIUM` key to point to the Chromium browser binary.
|
||||
""",
|
||||
mandatory = True,
|
||||
),
|
||||
},
|
||||
outputs = {"web_test_metadata": "%{name}.gen.json"},
|
||||
implementation = _browser_configure_impl,
|
||||
)
|
||||
@@ -1,15 +0,0 @@
|
||||
"""Pinned browser versions.
|
||||
|
||||
This function is here to make browser repositories work with cross-platform RBE.
|
||||
Unlike the `rules_webtesting` `browser_repositories`, this function defines
|
||||
separate repositories for each platform.
|
||||
"""
|
||||
|
||||
load("//dev-infra/bazel/browsers/chromium:chromium.bzl", "define_chromium_repositories")
|
||||
load("//dev-infra/bazel/browsers/firefox:firefox.bzl", "define_firefox_repositories")
|
||||
|
||||
def browser_repositories():
|
||||
"""Load pinned rules_webtesting browser versions."""
|
||||
|
||||
define_chromium_repositories()
|
||||
define_firefox_repositories()
|
||||
@@ -1,30 +0,0 @@
|
||||
load("@io_bazel_rules_webtesting//web:web.bzl", "browser")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
browser(
|
||||
name = "chromium",
|
||||
metadata = "chromium.json",
|
||||
deps = [
|
||||
"@io_bazel_rules_webtesting//go/wsl",
|
||||
] + select({
|
||||
"@io_bazel_rules_webtesting//common/conditions:linux": [
|
||||
"@org_chromium_chromedriver_amd64//:metadata",
|
||||
"@org_chromium_chromium_amd64//:metadata",
|
||||
],
|
||||
"@io_bazel_rules_webtesting//common/conditions:mac": [
|
||||
"@org_chromium_chromedriver_macos//:metadata",
|
||||
"@org_chromium_chromium_macos//:metadata",
|
||||
],
|
||||
"@io_bazel_rules_webtesting//common/conditions:windows": [
|
||||
"@org_chromium_chromedriver_windows//:metadata",
|
||||
"@org_chromium_chromium_windows//:metadata",
|
||||
],
|
||||
}),
|
||||
)
|
||||
|
||||
# Make source files available for distribution via pkg_npm
|
||||
filegroup(
|
||||
name = "files",
|
||||
srcs = glob(["*"]),
|
||||
)
|
||||
@@ -1,76 +0,0 @@
|
||||
load("//dev-infra/bazel/browsers:browser_archive_repo.bzl", "browser_archive")
|
||||
|
||||
"""
|
||||
Defines repositories for Chromium that can be used inside Karma unit tests
|
||||
and Protractor e2e tests with Bazel.
|
||||
"""
|
||||
|
||||
def define_chromium_repositories():
|
||||
# To update to a newer version of Chromium see instructions in
|
||||
# https://github.com/angular/angular/blob/master/dev-infra/bazel/browsers/README.md.
|
||||
|
||||
browser_archive(
|
||||
name = "org_chromium_chromium_amd64",
|
||||
licenses = ["notice"], # BSD 3-clause (maybe more?)
|
||||
sha256 = "36759ed6d151645d00a3a015200334edc70188b422eec51bcaa5790c8e906e27",
|
||||
# 87.0.4280
|
||||
url = "https://commondatastorage.googleapis.com/chromium-browser-snapshots/Linux_x64/812847/chrome-linux.zip",
|
||||
named_files = {
|
||||
"CHROMIUM": "chrome-linux/chrome",
|
||||
},
|
||||
)
|
||||
|
||||
browser_archive(
|
||||
name = "org_chromium_chromium_macos",
|
||||
licenses = ["notice"], # BSD 3-clause (maybe more?)
|
||||
sha256 = "e10533c84ef57232975d6bde9cd28fd0354371e9556dda85e01178e6dcd56b93",
|
||||
# 87.0.4280
|
||||
url = "https://commondatastorage.googleapis.com/chromium-browser-snapshots/Mac/812851/chrome-mac.zip",
|
||||
named_files = {
|
||||
"CHROMIUM": "chrome-mac/Chromium.app/Contents/MacOS/chromium",
|
||||
},
|
||||
)
|
||||
|
||||
browser_archive(
|
||||
name = "org_chromium_chromium_windows",
|
||||
licenses = ["notice"], # BSD 3-clause (maybe more?)
|
||||
sha256 = "40d0dec1892d729db2f7d8f27feff762b070a02f04d4e14f4e37b97d6b7c3c8f",
|
||||
# 87.0.4280
|
||||
url = "https://commondatastorage.googleapis.com/chromium-browser-snapshots/Win/812822/chrome-win.zip",
|
||||
named_files = {
|
||||
"CHROMIUM": "chrome-win/chrome.exe",
|
||||
},
|
||||
)
|
||||
|
||||
browser_archive(
|
||||
name = "org_chromium_chromedriver_amd64",
|
||||
licenses = ["reciprocal"], # BSD 3-clause, ICU, MPL 1.1, libpng (BSD/MIT-like), Academic Free License v. 2.0, BSD 2-clause, MIT
|
||||
sha256 = "d859f8ecb21e26d3ddaf3f229da695bc86512f4e6c9fe32533af7a8b36783ec5",
|
||||
# 87.0.4280
|
||||
url = "https://commondatastorage.googleapis.com/chromium-browser-snapshots/Linux_x64/812847/chromedriver_linux64.zip",
|
||||
named_files = {
|
||||
"CHROMEDRIVER": "chromedriver_linux64/chromedriver",
|
||||
},
|
||||
)
|
||||
|
||||
browser_archive(
|
||||
name = "org_chromium_chromedriver_macos",
|
||||
licenses = ["reciprocal"], # BSD 3-clause, ICU, MPL 1.1, libpng (BSD/MIT-like), Academic Free License v. 2.0, BSD 2-clause, MIT
|
||||
sha256 = "aa7a99fa23287725d7108cc07baa94e6f0ef4171ff7b134018387a939a67d93d",
|
||||
# 87.0.4280
|
||||
url = "https://commondatastorage.googleapis.com/chromium-browser-snapshots/Mac/812851/chromedriver_mac64.zip",
|
||||
named_files = {
|
||||
"CHROMEDRIVER": "chromedriver_mac64/chromedriver",
|
||||
},
|
||||
)
|
||||
|
||||
browser_archive(
|
||||
name = "org_chromium_chromedriver_windows",
|
||||
licenses = ["reciprocal"], # BSD 3-clause, ICU, MPL 1.1, libpng (BSD/MIT-like), Academic Free License v. 2.0, BSD 2-clause, MIT
|
||||
sha256 = "826f2bd0c50b823e7642860ed08cacf69d3756002a71ac30cdd77c68f31d2d24",
|
||||
# 87.0.4280
|
||||
url = "https://commondatastorage.googleapis.com/chromium-browser-snapshots/Win/812822/chromedriver_win32.zip",
|
||||
named_files = {
|
||||
"CHROMEDRIVER": "chromedriver_win32/chromedriver.exe",
|
||||
},
|
||||
)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user