Compare commits
151 Commits
zone.js-0.
...
zone.js-0.
Author | SHA1 | Date | |
---|---|---|---|
cda205deb4 | |||
466f5c67d6 | |||
b9dfe66028 | |||
4d96cf5197 | |||
024c31da25 | |||
5064dc75ac | |||
bef27f2a28 | |||
628b0c1154 | |||
e4d5102b17 | |||
b25f925311 | |||
7d4c9e4b67 | |||
a5f39aeda6 | |||
a91ab15525 | |||
a95f860a96 | |||
6215636bc6 | |||
3cd8a2b907 | |||
ebcf79d7f3 | |||
a91a55a6d2 | |||
48487cb70e | |||
c68371ed14 | |||
9406104c0a | |||
c0194e0115 | |||
914900a561 | |||
4ea3e7e000 | |||
6eb9c2fab0 | |||
7b9414565e | |||
37de490e23 | |||
753080133b | |||
9a37e827e2 | |||
3df54be9e4 | |||
c0d5684078 | |||
2b289250d8 | |||
ddd02044ea | |||
c198a27a3c | |||
4f37487b1c | |||
0ddf0c4895 | |||
fd6ed1713d | |||
eb5412d76f | |||
7533338362 | |||
9896d438c0 | |||
684579b338 | |||
695f322dc1 | |||
f90c7a9df0 | |||
f2466cf4ee | |||
bed680cff8 | |||
a647298412 | |||
2abbe98e33 | |||
7613f13e54 | |||
4b8cdd4b57 | |||
17e289c39f | |||
2913340af7 | |||
f8c27d42ed | |||
17bb633031 | |||
9106271f2c | |||
48a3741d5a | |||
9d1f43f3ba | |||
6f98107d5e | |||
a8e2ee1343 | |||
e906a4f0d8 | |||
b5b33d12d6 | |||
22d3cabc10 | |||
a06043b703 | |||
4689ea2727 | |||
939529ce5d | |||
46304a4f83 | |||
f7eebd0227 | |||
8af2cc1efe | |||
e5a89e047c | |||
29d3b68554 | |||
93d27eefd5 | |||
ed70f73794 | |||
ef12e10e59 | |||
2954d1b5ca | |||
3077c9a1f8 | |||
9537b2ff84 | |||
961d663fbe | |||
57e15fc08b | |||
b70746a113 | |||
0709ed4c2b | |||
fa699f65d7 | |||
18bc4eda9f | |||
f542649b2b | |||
a574e462c9 | |||
65cafa0eec | |||
18aa173d39 | |||
bc8eb8508b | |||
7db269ba6a | |||
8e5567d964 | |||
541ce98432 | |||
e7e3f5d952 | |||
382d3ed1d2 | |||
a07de82f79 | |||
2e84f4e0cd | |||
a5b12db7d6 | |||
8b94d6a402 | |||
96cbcd6da4 | |||
2a6e6c02ed | |||
fa4e17082c | |||
ebb27727e4 | |||
046532b661 | |||
7b9891d7cd | |||
a2183ddb7a | |||
3122f3415a | |||
aaf29c8099 | |||
32e2f4daef | |||
a7c71d1a57 | |||
f2d47c96c4 | |||
184d270725 | |||
a610d12266 | |||
d0d875a3fe | |||
e8b8f6d09b | |||
9e9179e915 | |||
c1ae6124c8 | |||
b3b5c66414 | |||
82b97280f3 | |||
ecffbda664 | |||
adc39752f3 | |||
584b42343f | |||
8e7a0d4ff9 | |||
4db959260b | |||
76503e65c8 | |||
eac993dfce | |||
975917bafd | |||
185b3dd08e | |||
78659ec0b0 | |||
a9ec3db91a | |||
561ec6a5be | |||
c0317d40c9 | |||
a4bc0db474 | |||
430124a051 | |||
e08391b333 | |||
a77d0e22bf | |||
4f42eb4e77 | |||
f216724c2c | |||
5c9a8961da | |||
3479fddf68 | |||
5bebac42f9 | |||
cbcbe23fd1 | |||
fc6f48185c | |||
80f290e301 | |||
5e5be43acd | |||
0386c964b5 | |||
f5c605b608 | |||
14dba72aee | |||
5f0d5e9ccf | |||
5296c04f61 | |||
40a0666651 | |||
4da805243a | |||
14ae50b4c3 | |||
397d0ba9a3 | |||
859ebdd836 |
@ -37,5 +37,5 @@ build --verbose_failures=true
|
||||
# > Example job: https://circleci.com/gh/angular/angular/385517
|
||||
# We expect that TypeScript compilations will parallelize wider than the number of local cores anyway
|
||||
# so we should saturate remote workers with TS compilations
|
||||
build --strategy=TypeScriptCompile=standalone
|
||||
build --strategy=AngularTemplateCompile=standalone
|
||||
build --strategy=AngularTemplateCompile=local
|
||||
build --strategy=TypeScriptCompile=local
|
||||
|
@ -143,7 +143,7 @@ var_14: ¬ify_dev_infra_on_fail
|
||||
|
||||
# Cache key for the Material unit tests job. **Note** when updating the SHA in the cache keys,
|
||||
# also update the SHA for the "MATERIAL_REPO_COMMIT" environment variable.
|
||||
var_15: &material_unit_tests_cache_key v4-angular-material-701302dc482d7e4b77990b24e3b5ab330bbf1aa5
|
||||
var_15: &material_unit_tests_cache_key v4-angular-material-097f4335a4e0b6e6b579829ae3a9cffce6292d2b
|
||||
var_16: &material_unit_tests_cache_key_short v4-angular-material
|
||||
|
||||
version: 2
|
||||
@ -321,7 +321,7 @@ jobs:
|
||||
- *attach_workspace
|
||||
- *init_environment
|
||||
# Build aio (with local Angular packages)
|
||||
- run: yarn --cwd aio build-local --progress=false
|
||||
- run: yarn --cwd aio build-local-ci
|
||||
# Run unit tests
|
||||
- run: yarn --cwd aio test --progress=false --watch=false
|
||||
# Run e2e tests
|
||||
@ -340,7 +340,7 @@ jobs:
|
||||
- *attach_workspace
|
||||
- *init_environment
|
||||
# Build aio with Ivy (using local Angular packages)
|
||||
- run: yarn --cwd aio build-with-ivy --progress=false
|
||||
- run: yarn --cwd aio build-with-ivy-ci
|
||||
# Run unit tests
|
||||
- run: yarn --cwd aio test --progress=false --watch=false
|
||||
# Run e2e tests
|
||||
|
@ -79,7 +79,7 @@ setPublicVar MATERIAL_REPO_TMP_DIR "/tmp/material2"
|
||||
setPublicVar MATERIAL_REPO_URL "https://github.com/angular/material2.git"
|
||||
setPublicVar MATERIAL_REPO_BRANCH "master"
|
||||
# **NOTE**: When updating the commit SHA, also update the cache key in the CircleCI "config.yml".
|
||||
setPublicVar MATERIAL_REPO_COMMIT "701302dc482d7e4b77990b24e3b5ab330bbf1aa5"
|
||||
setPublicVar MATERIAL_REPO_COMMIT "097f4335a4e0b6e6b579829ae3a9cffce6292d2b"
|
||||
|
||||
# Source `$BASH_ENV` to make the variables available immediately.
|
||||
source $BASH_ENV;
|
||||
|
@ -1,126 +0,0 @@
|
||||
# escape=`
|
||||
|
||||
ARG core=mcr.microsoft.com/windows/servercore:1809
|
||||
ARG target=mcr.microsoft.com/powershell:windowsservercore-1809
|
||||
|
||||
FROM $core as download
|
||||
|
||||
ARG node_version=10.13.0
|
||||
ARG yarn_version=1.13.0
|
||||
|
||||
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
|
||||
|
||||
ENV GPG_VERSION 2.3.4
|
||||
|
||||
RUN Invoke-WebRequest $('https://files.gpg4win.org/gpg4win-vanilla-{0}.exe' -f $env:GPG_VERSION) -OutFile 'gpg4win.exe' -UseBasicParsing ; `
|
||||
Start-Process .\gpg4win.exe -ArgumentList '/S' -NoNewWindow -Wait
|
||||
|
||||
RUN @( `
|
||||
'94AE36675C464D64BAFA68DD7434390BDBE9B9C5', `
|
||||
'FD3A5288F042B6850C66B31F09FE44734EB7990E', `
|
||||
'71DCFD284A79C3B38668286BC97EC7A07EDE3FC1', `
|
||||
'DD8F2338BAE7501E3DD5AC78C273792F7D83545D', `
|
||||
'C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8', `
|
||||
'B9AE9905FFD7803F25714661B63B535A4C206CA9', `
|
||||
'77984A986EBC2AA786BC0F66B01FBB92821C587A', `
|
||||
'8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600', `
|
||||
'4ED778F539E3634C779C87C6D7062848A1AB005C', `
|
||||
'A48C2BEE680E841632CD4E44F07496B3EB3C1762', `
|
||||
'B9E2F5981AA6E0CD28160D9FF13993A75599653C' `
|
||||
) | foreach { `
|
||||
gpg --keyserver ha.pool.sks-keyservers.net --recv-keys $_ ; `
|
||||
}
|
||||
|
||||
ENV NODE_VERSION=$node_version
|
||||
|
||||
RUN Invoke-WebRequest $('https://nodejs.org/dist/v{0}/SHASUMS256.txt.asc' -f $env:NODE_VERSION) -OutFile 'SHASUMS256.txt.asc' -UseBasicParsing ; `
|
||||
gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc
|
||||
|
||||
RUN Invoke-WebRequest $('https://nodejs.org/dist/v{0}/node-v{0}-win-x64.zip' -f $env:NODE_VERSION) -OutFile 'node.zip' -UseBasicParsing ; `
|
||||
$sum = $(cat SHASUMS256.txt.asc | sls $(' node-v{0}-win-x64.zip' -f $env:NODE_VERSION)) -Split ' ' ; `
|
||||
if ((Get-FileHash node.zip -Algorithm sha256).Hash -ne $sum[0]) { Write-Error 'SHA256 mismatch' } ; `
|
||||
Expand-Archive node.zip -DestinationPath C:\ ; `
|
||||
Rename-Item -Path $('C:\node-v{0}-win-x64' -f $env:NODE_VERSION) -NewName 'C:\nodejs'
|
||||
|
||||
ENV YARN_VERSION=$yarn_version
|
||||
|
||||
RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; `
|
||||
Invoke-WebRequest $('https://yarnpkg.com/downloads/{0}/yarn-{0}.msi' -f $env:YARN_VERSION) -OutFile yarn.msi -UseBasicParsing ; `
|
||||
$sig = Get-AuthenticodeSignature yarn.msi ; `
|
||||
if ($sig.Status -ne 'Valid') { Write-Error 'Authenticode signature is not valid' } ; `
|
||||
Write-Output $sig.SignerCertificate.Thumbprint ; `
|
||||
if (@( `
|
||||
'7E253367F8A102A91D04829E37F3410F14B68A5F', `
|
||||
'AF764E1EA56C762617BDC757C8B0F3780A0CF5F9' `
|
||||
) -notcontains $sig.SignerCertificate.Thumbprint) { Write-Error 'Unknown signer certificate' } ; `
|
||||
Start-Process msiexec.exe -ArgumentList '/i', 'yarn.msi', '/quiet', '/norestart' -NoNewWindow -Wait
|
||||
|
||||
ENV GIT_VERSION 2.20.1
|
||||
ENV GIT_DOWNLOAD_URL https://github.com/git-for-windows/git/releases/download/v${GIT_VERSION}.windows.1/MinGit-${GIT_VERSION}-busybox-64-bit.zip
|
||||
ENV GIT_SHA256 9817ab455d9cbd0b09d8664b4afbe4bbf78d18b556b3541d09238501a749486c
|
||||
|
||||
RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; `
|
||||
Invoke-WebRequest -UseBasicParsing $env:GIT_DOWNLOAD_URL -OutFile git.zip; `
|
||||
if ((Get-FileHash git.zip -Algorithm sha256).Hash -ne $env:GIT_SHA256) {exit 1} ; `
|
||||
Expand-Archive git.zip -DestinationPath C:\git; `
|
||||
Remove-Item git.zip
|
||||
|
||||
FROM $target as baseimage
|
||||
|
||||
ENV NPM_CONFIG_LOGLEVEL info
|
||||
|
||||
COPY --from=download /nodejs /nodejs
|
||||
COPY --from=download [ "/Program Files (x86)/yarn", "/yarn" ]
|
||||
COPY --from=download /git /git
|
||||
|
||||
ARG SETX=/M
|
||||
RUN setx %SETX% PATH "%PATH%;C:\nodejs;C:\yarn\bin;C:\git\cmd;C:\git\mingw64\bin;C:\git\usr\bin"
|
||||
|
||||
CMD [ "node.exe" ]
|
||||
|
||||
FROM baseimage
|
||||
|
||||
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
|
||||
|
||||
# Install Bazel prereqs on Windows (https://docs.bazel.build/versions/master/install-windows.html)
|
||||
|
||||
# Install MSYS2
|
||||
RUN Invoke-WebRequest -UseBasicParsing 'https://www.7-zip.org/a/7z1805-x64.exe' -OutFile 7z.exe; `
|
||||
Start-Process -FilePath 'C:\\7z.exe' -ArgumentList '/S', '/D=C:\\7zip0' -NoNewWindow -Wait; `
|
||||
Invoke-WebRequest -UseBasicParsing 'http://repo.msys2.org/distrib/x86_64/msys2-base-x86_64-20180531.tar.xz' -OutFile msys2.tar.xz; `
|
||||
Start-Process -FilePath 'C:\\7zip\\7z' -ArgumentList 'e', 'msys2.tar.xz' -Wait; `
|
||||
Start-Process -FilePath 'C:\\7zip\\7z' -ArgumentList 'x', 'msys2.tar', '-oC:\\' -Wait; `
|
||||
Remove-Item msys2.tar.xz; `
|
||||
Remove-Item msys2.tar; `
|
||||
Remove-Item 7z.exe; `
|
||||
Remove-Item -Recurse 7zip; `
|
||||
[Environment]::SetEnvironmentVariable('Path', $env:Path + ';C:\msys64\usr\bin', [System.EnvironmentVariableTarget]::Machine); `
|
||||
[Environment]::SetEnvironmentVariable('BAZEL_SH', 'C:\msys64\usr\bin\bash.exe', [System.EnvironmentVariableTarget]::Machine)
|
||||
|
||||
# Install MSYS2 packages
|
||||
RUN C:\msys64\usr\bin\bash.exe -l -c \"pacman --needed --noconfirm -S zip unzip patch diffutils git\"
|
||||
|
||||
# Install VS Build Tools (required to build C++ targets)
|
||||
RUN Invoke-WebRequest -UseBasicParsing https://download.visualstudio.microsoft.com/download/pr/df649173-11e9-4af2-8eb7-0eb02ba8958a/cadb5bdac41e55bb8f6a6b7c45273370/vs_buildtools.exe -OutFile vs_BuildTools.exe; `
|
||||
# Installer won't detect DOTNET_SKIP_FIRST_TIME_EXPERIENCE if ENV is used, must use setx /M
|
||||
setx /M DOTNET_SKIP_FIRST_TIME_EXPERIENCE 1; `
|
||||
Start-Process vs_BuildTools.exe `
|
||||
-ArgumentList `
|
||||
'--add', 'Microsoft.VisualStudio.Workload.VCTools', `
|
||||
'--add', 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64', `
|
||||
'--add', 'Microsoft.Component.VC.Runtime.UCRTSDK', `
|
||||
'--add', 'Microsoft.VisualStudio.Component.Windows10SDK.17763', `
|
||||
'--quiet', '--norestart', '--nocache' `
|
||||
-NoNewWindow -Wait; `
|
||||
Remove-Item -Force vs_buildtools.exe; `
|
||||
Remove-Item -Force -Recurse \"${Env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\"; `
|
||||
Remove-Item -Force -Recurse ${Env:TEMP}\*; `
|
||||
Remove-Item -Force -Recurse \"${Env:ProgramData}\Package Cache\"; `
|
||||
[Environment]::SetEnvironmentVariable('BAZEL_VC', \"${Env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\BuildTools\VC\", [System.EnvironmentVariableTarget]::Machine)
|
||||
|
||||
# Install Python (required to build Python targets)
|
||||
RUN Invoke-WebRequest -UseBasicParsing https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe -OutFile python-3.5.1.exe; `
|
||||
Start-Process python-3.5.1.exe -ArgumentList '/quiet InstallAllUsers=1 PrependPath=1' -Wait; `
|
||||
Remove-Item -Force python-3.5.1.exe
|
||||
|
||||
CMD ["cmd.exe"]
|
@ -1,33 +0,0 @@
|
||||
# CodeFresh configuration
|
||||
|
||||
[](https://g.codefresh.io/public/accounts/angular/pipelines/angular/angular/angular)
|
||||
|
||||
This folder contains configuration for the [CodeFresh](<https://codefresh.io/>) based CI checks for this repository.
|
||||
|
||||
## The build pipeline
|
||||
|
||||
CodeFresh uses a several pipeline for each repository. The `codefresh.yml` file defines pipeline [build steps](https://codefresh.io/docs/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) for this repository.
|
||||
|
||||
Run results can be seen in the GitHub checks interface and in the [public pipeline](https://g.codefresh.io/public/accounts/angular/pipelines/angular/angular/angular)
|
||||
|
||||
Although most configuration is done via `pipeline.yml`, some options are only available in the online [pipeline settings](https://g.codefresh.io/pipelines/angular/services?repoOwner=angular&repoName=angular&project=angular%2Fangular&context=github&serviceName=angular%2Fangular), which needs a login to access.
|
||||
|
||||
|
||||
## Caretaker
|
||||
|
||||
CodeFresh status can be found at <http://status.codefresh.io/>.
|
||||
|
||||
Issues related to the CodeFresh setup should be escalated to the Tools Team via the current caretaker, followed by Alex Eagle and Filipe Silva.
|
||||
|
||||
## Rollout strategy
|
||||
|
||||
Currently it is only used for tests on Windows platforms, on the master branch, and without pushing user-facing reports. It's only possible to see current builds in the [public pipeline dashboard](https://g.codefresh.io/public/accounts/angular/pipelines/angular/angular/angular).
|
||||
|
||||
After a week or two of running like this, we should reassess how stable and reliable it is.
|
||||
|
||||
Next steps include:
|
||||
- building PRs
|
||||
- showing build status publicly
|
||||
- blocking PRs that break the build
|
||||
- expanding the test suite
|
||||
|
@ -1,38 +0,0 @@
|
||||
# These options are enabled when running on CI
|
||||
# We do this by copying this file to /etc/bazel.bazelrc at the start of the build.
|
||||
# See documentation in /docs/BAZEL.md
|
||||
|
||||
# Save built files and downloaded repositories in a location that can be cached by CodeFresh and
|
||||
# shared between builds. This helps speed up the analysis time significantly with Bazel managed node
|
||||
# dependencies on the CI.
|
||||
# https://codefresh.io/docs/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#caching-the-artifacts-of-your-build-system
|
||||
build --repository_cache=C:/codefresh/volume/bazel_repository_cache
|
||||
# Setting the output_base to a Docker volume is currently broken because of a Docker bug on Windows:
|
||||
# https://github.com/moby/moby/issues/37024
|
||||
# This affects Bazel because bazel_output_base\external\bazel_tools is an absolute path junction.
|
||||
# When its fixed we can uncomment this line, and use a different output_base for Ivy tests (they
|
||||
# use a separate compiler and destructively replace the cache).
|
||||
# startup --output_base=C:/codefresh/volume/bazel_output_base
|
||||
|
||||
# Don't be spammy in the logs
|
||||
# TODO(gmagolan): Hide progress again once build performance improves
|
||||
# Presently, CircleCI can timeout during bazel test ... with the following
|
||||
# error: Too long with no output (exceeded 10m0s)
|
||||
build --noshow_progress
|
||||
|
||||
# Print all the options that apply to the build.
|
||||
# This helps us diagnose which options override others
|
||||
# (e.g. /etc/bazel.bazelrc vs. tools/bazel.rc)
|
||||
build --announce_rc
|
||||
|
||||
# Workaround https://github.com/bazelbuild/bazel/issues/3645
|
||||
# Bazel doesn't calculate the memory ceiling correctly when running under Docker.
|
||||
# Limit Bazel to consuming resources that fit in CodeFresh VMs
|
||||
# TODO(filipesilva): determine the correct memory limit
|
||||
build --local_resources=10240,8.0,1.0
|
||||
|
||||
# Retry in the event of flakes, eg. https://circleci.com/gh/angular/angular/31309
|
||||
test --flaky_test_attempts=2
|
||||
|
||||
# More details on failures
|
||||
build --verbose_failures=true
|
@ -1,28 +0,0 @@
|
||||
version: '1.0'
|
||||
|
||||
steps:
|
||||
BuildImage:
|
||||
title: Build Docker image
|
||||
type: build
|
||||
image_name: node-bazel-windows
|
||||
working_directory: ./.codefresh
|
||||
no_cf_cache: true
|
||||
build_arguments:
|
||||
- node_version=10.13.0
|
||||
- yarn_version=1.13.0
|
||||
dockerfile: ./Dockerfile.win-1809
|
||||
|
||||
RunTests:
|
||||
title: Run Bazel tests
|
||||
image: ${{BuildImage}}
|
||||
commands:
|
||||
# Install dependencies
|
||||
- yarn install --frozen-lockfile --non-interactive --network-timeout 100000 --no-progress
|
||||
# Add Bazel CI config
|
||||
- copy .codefresh\bazel.rc %ProgramData%\bazel.bazelrc
|
||||
# Run tests
|
||||
# At the moment 'browser:chromium-local' are broken in CI while locally they work
|
||||
# VE
|
||||
- yarn bazel test --build_tag_filters=-ivy-only --test_tag_filters=-ivy-only,-browser:chromium-local //...
|
||||
# Ivy
|
||||
- yarn bazel test --define=compile=aot --build_tag_filters=-no-ivy-aot,-fixme-ivy-aot --test_tag_filters=-no-ivy-aot,-fixme-ivy-aot,-browser:chromium-local //...
|
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
@ -884,7 +884,6 @@ testing/** @angular/fw-test
|
||||
/* @angular/fw-dev-infra
|
||||
/.buildkite/** @angular/fw-dev-infra
|
||||
/.circleci/** @angular/fw-dev-infra
|
||||
/.codefresh/** @angular/fw-dev-infra
|
||||
/.devcontainer/** @angular/fw-dev-infra
|
||||
/.github/** @angular/fw-dev-infra
|
||||
/.vscode/** @angular/fw-dev-infra
|
||||
|
140
CHANGELOG.md
140
CHANGELOG.md
@ -1,25 +1,94 @@
|
||||
<a name="8.2.0-rc.0"></a>
|
||||
# [8.2.0-rc.0](https://github.com/angular/angular/compare/8.2.0-next.2...8.2.0-rc.0) (2019-07-26)
|
||||
<a name="9.0.0-next.2"></a>
|
||||
# [9.0.0-next.2](https://github.com/angular/angular/compare/9.0.0-next.1...9.0.0-next.2) (2019-08-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
### Bug Fixes
|
||||
|
||||
* **bazel:** disable treeshaking when generating FESM and UMD bundles ([#32069](https://github.com/angular/angular/issues/32069)) ([4f37487](https://github.com/angular/angular/commit/4f37487))
|
||||
* **compiler:** do not remove whitespace wrapping i18n expansions ([#31962](https://github.com/angular/angular/issues/31962)) ([0ddf0c4](https://github.com/angular/angular/commit/0ddf0c4))
|
||||
* **ivy:** reuse compilation scope for incremental template changes. ([#31932](https://github.com/angular/angular/issues/31932)) ([eb5412d](https://github.com/angular/angular/commit/eb5412d)), closes [#31654](https://github.com/angular/angular/issues/31654)
|
||||
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **ivy:** don't read global state when interpolated values don't change ([#32093](https://github.com/angular/angular/issues/32093)) ([6eb9c2f](https://github.com/angular/angular/commit/6eb9c2f))
|
||||
|
||||
|
||||
|
||||
<a name="8.2.2"></a>
|
||||
## [8.2.2](https://github.com/angular/angular/compare/8.2.1...8.2.2) (2019-08-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bazel:** disable treeshaking when generating FESM and UMD bundles ([#32069](https://github.com/angular/angular/issues/32069)) ([3420d29](https://github.com/angular/angular/commit/3420d29))
|
||||
|
||||
|
||||
<a name="9.0.0-next.1"></a>
|
||||
# [9.0.0-next.1](https://github.com/angular/angular/compare/9.0.0-next.0...9.0.0-next.1) (2019-08-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **language-service:** getSourceFile() should only be called on TS files ([#31920](https://github.com/angular/angular/issues/31920)) ([e8b8f6d](https://github.com/angular/angular/commit/e8b8f6d))
|
||||
* **language-service:** Make Definition and QuickInfo compatible with TS LS ([#31972](https://github.com/angular/angular/issues/31972)) ([a8e2ee1](https://github.com/angular/angular/commit/a8e2ee1))
|
||||
* **upgrade:** compile downgraded components synchronously (if possible) ([#31840](https://github.com/angular/angular/issues/31840)) ([c1ae612](https://github.com/angular/angular/commit/c1ae612)), closes [#27217](https://github.com/angular/angular/issues/27217) [#30330](https://github.com/angular/angular/issues/30330)
|
||||
|
||||
|
||||
|
||||
<a name="8.2.1"></a>
|
||||
## [8.2.1](https://github.com/angular/angular/compare/8.2.0...8.2.1) (2019-08-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **upgrade:** compile downgraded components synchronously (if possible) ([#31840](https://github.com/angular/angular/issues/31840)) ([04ebd59](https://github.com/angular/angular/commit/04ebd59)), closes [#27217](https://github.com/angular/angular/issues/27217) [#30330](https://github.com/angular/angular/issues/30330)
|
||||
|
||||
|
||||
|
||||
<a name="9.0.0-next.0"></a>
|
||||
# [9.0.0-next.0](https://github.com/angular/angular/compare/8.2.0-next.2...9.0.0-next.0) (2019-07-31)
|
||||
|
||||
* Ivy related improvements and fixes
|
||||
|
||||
|
||||
<a name="8.2.0"></a>
|
||||
# [8.2.0](https://github.com/angular/angular/compare/8.2.0-rc.0...8.2.0) (2019-07-31)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **core:** TypeScript 3.5 support ([#31615](https://github.com/angular/angular/issues/31615)) ([6ece7db](https://github.com/angular/angular/commit/6ece7db))
|
||||
* **core:** add automatic migration from Renderer to Renderer2 ([#30936](https://github.com/angular/angular/issues/30936)) ([c095597](https://github.com/angular/angular/commit/c095597))
|
||||
* **bazel:** compile targets used for indexing by Kythe with Ivy ([#31786](https://github.com/angular/angular/issues/31786)) ([82055b2](https://github.com/angular/angular/commit/82055b2))
|
||||
* **upgrade:** support $element in upgraded component template/templateUrl functions ([#31637](https://github.com/angular/angular/issues/31637)) ([29e1c53](https://github.com/angular/angular/commit/29e1c53))
|
||||
* **bazel:** allow passing a custom bazel compiler host to ngc compile ([#31341](https://github.com/angular/angular/issues/31341)) ([a29dc96](https://github.com/angular/angular/commit/a29dc96))
|
||||
* **bazel:** allow passing and rewriting an old bazel host ([#31381](https://github.com/angular/angular/issues/31381)) ([11a208f](https://github.com/angular/angular/commit/11a208f)), closes [#31341](https://github.com/angular/angular/issues/31341)
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **compiler:** avoid copying from prototype while cloning an object ([#31638](https://github.com/angular/angular/issues/31638)) ([24ca582](https://github.com/angular/angular/commit/24ca582)), closes [#31627](https://github.com/angular/angular/issues/31627)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **core:** DebugElement.listeners not cleared on destroy ([#31820](https://github.com/angular/angular/issues/31820)) ([46b160e](https://github.com/angular/angular/commit/46b160e))
|
||||
* **bazel:** increase memory limit of ngc under bazel from 2 to 4 GB ([#31784](https://github.com/angular/angular/issues/31784)) ([5a8eb92](https://github.com/angular/angular/commit/5a8eb92))
|
||||
* **core:** allow Z variations of CSS transforms in sanitizer ([#29264](https://github.com/angular/angular/issues/29264)) ([78e7fdd](https://github.com/angular/angular/commit/78e7fdd))
|
||||
* **elements:** handle falsy initial value ([#31604](https://github.com/angular/angular/issues/31604)) ([7151eae](https://github.com/angular/angular/commit/7151eae)), closes [angular/angular#30834](https://github.com/angular/angular/issues/30834)
|
||||
* **platform-browser:** debug element query predicates not compatible with strictFunctionTypes ([#30993](https://github.com/angular/angular/issues/30993)) ([10a1e19](https://github.com/angular/angular/commit/10a1e19))
|
||||
* use the correct WTF array to iterate over ([#31208](https://github.com/angular/angular/issues/31208)) ([9204de9](https://github.com/angular/angular/commit/9204de9))
|
||||
* **bazel:** pass custom bazel compiler host rather than rewriting one ([#31496](https://github.com/angular/angular/issues/31496)) ([0c61a35](https://github.com/angular/angular/commit/0c61a35))
|
||||
* **compiler-cli:** Return original sourceFile instead of redirected sourceFile from getSourceFile ([#26036](https://github.com/angular/angular/issues/26036)) ([3166cff](https://github.com/angular/angular/commit/3166cff)), closes [#22524](https://github.com/angular/angular/issues/22524)
|
||||
* **language-service:** Eagarly initialize data members ([#31577](https://github.com/angular/angular/issues/31577)) ([0110de2](https://github.com/angular/angular/commit/0110de2))
|
||||
* **bazel:** revert location of xi18n outputs to bazel-genfiles ([#31410](https://github.com/angular/angular/issues/31410)) ([1d3e227](https://github.com/angular/angular/commit/1d3e227))
|
||||
* **compiler:** give ASTWithSource its own visit method ([#31347](https://github.com/angular/angular/issues/31347)) ([6aaca21](https://github.com/angular/angular/commit/6aaca21))
|
||||
* **core:** handle `undefined` meta in `injectArgs` ([#31333](https://github.com/angular/angular/issues/31333)) ([80ccd6c](https://github.com/angular/angular/commit/80ccd6c)), closes [CLI #14888](https://github.com/angular/angular-cli/issues/14888)
|
||||
* **service-worker:** cache opaque responses in data groups with `freshness` strategy ([#30977](https://github.com/angular/angular/issues/30977)) ([d7be38f](https://github.com/angular/angular/commit/d7be38f)), closes [#30968](https://github.com/angular/angular/issues/30968)
|
||||
* **service-worker:** cache opaque responses when requests exceeds timeout threshold ([#30977](https://github.com/angular/angular/issues/30977)) ([93abc35](https://github.com/angular/angular/commit/93abc35))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **bazel:** compile targets used for indexing by Kythe with Ivy ([#31786](https://github.com/angular/angular/issues/31786)) ([82055b2](https://github.com/angular/angular/commit/82055b2))
|
||||
* **upgrade:** support $element in upgraded component template/templateUrl functions ([#31637](https://github.com/angular/angular/issues/31637)) ([29e1c53](https://github.com/angular/angular/commit/29e1c53))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **compiler:** avoid copying from prototype while cloning an object ([#31638](https://github.com/angular/angular/issues/31638)) ([24ca582](https://github.com/angular/angular/commit/24ca582)), closes [#31627](https://github.com/angular/angular/issues/31627)
|
||||
|
||||
|
||||
<a name="8.1.3"></a>
|
||||
## [8.1.3](https://github.com/angular/angular/compare/8.1.2...8.1.3) (2019-07-26)
|
||||
@ -35,17 +104,6 @@
|
||||
* **compiler:** avoid copying from prototype while cloning an object ([#31638](https://github.com/angular/angular/issues/31638)) ([1f3daa0](https://github.com/angular/angular/commit/1f3daa0)), closes [#31627](https://github.com/angular/angular/issues/31627)
|
||||
|
||||
|
||||
<a name="8.2.0-next.2"></a>
|
||||
# [8.2.0-next.2](https://github.com/angular/angular/compare/8.2.0-next.1...8.2.0-next.2) (2019-07-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* use the correct WTF array to iterate over ([#31208](https://github.com/angular/angular/issues/31208)) ([9204de9](https://github.com/angular/angular/commit/9204de9))
|
||||
* **bazel:** pass custom bazel compiler host rather than rewriting one ([#31496](https://github.com/angular/angular/issues/31496)) ([0c61a35](https://github.com/angular/angular/commit/0c61a35))
|
||||
* **compiler-cli:** Return original sourceFile instead of redirected sourceFile from getSourceFile ([#26036](https://github.com/angular/angular/issues/26036)) ([3166cff](https://github.com/angular/angular/commit/3166cff)), closes [#22524](https://github.com/angular/angular/issues/22524)
|
||||
* **language-service:** Eagarly initialize data members ([#31577](https://github.com/angular/angular/issues/31577)) ([0110de2](https://github.com/angular/angular/commit/0110de2))
|
||||
|
||||
|
||||
|
||||
<a name="8.1.2"></a>
|
||||
@ -59,23 +117,6 @@
|
||||
* **core:** export provider interfaces that are part of the public API types ([#31377](https://github.com/angular/angular/issues/31377)) ([bebf089](https://github.com/angular/angular/commit/bebf089)), closes [/github.com/angular/angular/pull/31377#discussion_r299254408](https://github.com//github.com/angular/angular/pull/31377/issues/discussion_r299254408) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts#L365-L366](https://github.com//github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts/issues/L365-L366) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts#L283-L284](https://github.com//github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts/issues/L283-L284) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/index.ts#L23](https://github.com//github.com/angular/angular/blob/9e34670b2/packages/core/src/di/index.ts/issues/L23)
|
||||
|
||||
|
||||
|
||||
<a name="8.2.0-next.1"></a>
|
||||
# [8.2.0-next.1](https://github.com/angular/angular/compare/8.2.0-next.0...8.2.0-next.1) (2019-07-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bazel:** revert location of xi18n outputs to bazel-genfiles ([#31410](https://github.com/angular/angular/issues/31410)) ([1d3e227](https://github.com/angular/angular/commit/1d3e227))
|
||||
* **compiler:** give ASTWithSource its own visit method ([#31347](https://github.com/angular/angular/issues/31347)) ([6aaca21](https://github.com/angular/angular/commit/6aaca21))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **core:** add automatic migration from Renderer to Renderer2 ([#30936](https://github.com/angular/angular/issues/30936)) ([c095597](https://github.com/angular/angular/commit/c095597))
|
||||
|
||||
|
||||
|
||||
<a name="8.1.1"></a>
|
||||
## [8.1.1](https://github.com/angular/angular/compare/8.1.0...8.1.1) (2019-07-10)
|
||||
|
||||
@ -85,23 +126,6 @@
|
||||
* **core:** export provider interfaces that are part of the public API types ([#31377](https://github.com/angular/angular/issues/31377)) ([bebf089](https://github.com/angular/angular/commit/bebf089)), closes [/github.com/angular/angular/pull/31377#discussion_r299254408](https://github.com//github.com/angular/angular/pull/31377/issues/discussion_r299254408) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts#L365-L366](https://github.com//github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts/issues/L365-L366) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts#L283-L284](https://github.com//github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts/issues/L283-L284) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/index.ts#L23](https://github.com//github.com/angular/angular/blob/9e34670b2/packages/core/src/di/index.ts/issues/L23)
|
||||
|
||||
|
||||
<a name="8.2.0-next.0"></a>
|
||||
# [8.2.0-next.0](https://github.com/angular/angular/compare/8.1.0-rc.0...8.2.0-next.0) (2019-07-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **core:** handle `undefined` meta in `injectArgs` ([#31333](https://github.com/angular/angular/issues/31333)) ([80ccd6c](https://github.com/angular/angular/commit/80ccd6c)), closes [CLI #14888](https://github.com/angular/angular-cli/issues/14888)
|
||||
* **service-worker:** cache opaque responses in data groups with `freshness` strategy ([#30977](https://github.com/angular/angular/issues/30977)) ([d7be38f](https://github.com/angular/angular/commit/d7be38f)), closes [#30968](https://github.com/angular/angular/issues/30968)
|
||||
* **service-worker:** cache opaque responses when requests exceeds timeout threshold ([#30977](https://github.com/angular/angular/issues/30977)) ([93abc35](https://github.com/angular/angular/commit/93abc35))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **bazel:** allow passing a custom bazel compiler host to ngc compile ([#31341](https://github.com/angular/angular/issues/31341)) ([a29dc96](https://github.com/angular/angular/commit/a29dc96))
|
||||
* **bazel:** allow passing and rewriting an old bazel host ([#31381](https://github.com/angular/angular/issues/31381)) ([11a208f](https://github.com/angular/angular/commit/11a208f)), closes [#31341](https://github.com/angular/angular/issues/31341)
|
||||
|
||||
|
||||
|
||||
<a name="8.1.0"></a>
|
||||
# [8.1.0](https://github.com/angular/angular/compare/8.1.0-rc.0...8.1.0) (2019-07-02)
|
||||
|
12
WORKSPACE
12
WORKSPACE
@ -21,8 +21,8 @@ http_archive(
|
||||
patch_args = ["-p1"],
|
||||
# Patch https://github.com/bazelbuild/rules_nodejs/pull/903
|
||||
patches = ["//tools:rollup_bundle_commonjs_ignoreGlobal.patch"],
|
||||
sha256 = "6d4edbf28ff6720aedf5f97f9b9a7679401bf7fca9d14a0fff80f644a99992b4",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.32.2/rules_nodejs-0.32.2.tar.gz"],
|
||||
sha256 = "7c4a690268be97c96f04d505224ec4cb1ae53c2c2b68be495c9bd2634296a5cd",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.34.0/rules_nodejs-0.34.0.tar.gz"],
|
||||
)
|
||||
|
||||
# Check the bazel version and download npm dependencies
|
||||
@ -53,7 +53,8 @@ Try running `yarn bazel` instead.
|
||||
# - 0.32.0 yarn_install and npm_install no longer puts build files under symlinked node_modules
|
||||
# - 0.32.1 remove override of @bazel/tsetse & exclude typescript lib declarations in node_module_library transitive_declarations
|
||||
# - 0.32.2 resolves bug in @bazel/hide-bazel-files postinstall step
|
||||
check_rules_nodejs_version(minimum_version_string = "0.32.2")
|
||||
# - 0.34.0 introduces protractor rule
|
||||
check_rules_nodejs_version(minimum_version_string = "0.34.0")
|
||||
|
||||
# Setup the Node.js toolchain
|
||||
node_repositories(
|
||||
@ -91,6 +92,11 @@ load("//packages/bazel:package.bzl", "rules_angular_dev_dependencies")
|
||||
|
||||
rules_angular_dev_dependencies()
|
||||
|
||||
# Load protractor dependencies
|
||||
load("@npm_bazel_protractor//:package.bzl", "npm_bazel_protractor_dependencies")
|
||||
|
||||
npm_bazel_protractor_dependencies()
|
||||
|
||||
# Load karma dependencies
|
||||
load("@npm_bazel_karma//:package.bzl", "rules_karma_dependencies")
|
||||
|
||||
|
@ -14,10 +14,12 @@ Here are the most important tasks you might need to use:
|
||||
|
||||
* `yarn` - install all the dependencies.
|
||||
* `yarn setup` - install all the dependencies, boilerplate, stackblitz, zips and run dgeni on the docs.
|
||||
* `yarn setup-local` - same as `setup`, but use the locally built Angular packages for aio and docs examples boilerplate.
|
||||
* `yarn setup-local` - same as `setup`, but build the Angular packages from the source code and use these locally built versions (instead of the ones fetched from npm) for aio and docs examples boilerplate.
|
||||
|
||||
* `yarn build` - create a production build of the application (after installing dependencies, boilerplate, etc).
|
||||
* `yarn build-local` - same as `build`, but use `setup-local` instead of `setup`.
|
||||
* `yarn build-with-ivy` - same as `build-local`, but in addition also turns on `ivy` mode in aio.
|
||||
(Note: To turn on `ivy` mode in examples, see `yarn boilerplate:add` below.)
|
||||
|
||||
* `yarn start` - run a development web server that watches the files; then builds the doc-viewer and reloads the page, as necessary.
|
||||
* `yarn serve-and-sync` - run both the `docs-watch` and `start` in the same console.
|
||||
@ -31,7 +33,10 @@ Here are the most important tasks you might need to use:
|
||||
* `yarn docs-lint` - check that the doc gen code follows our style rules.
|
||||
* `yarn docs-test` - run the unit tests for the doc generation code.
|
||||
|
||||
* `yarn boilerplate:add` - generate all the boilerplate code for the examples, so that they can be run locally. Add the option `--local` to use your local version of Angular contained in the "dist" folder.
|
||||
* `yarn boilerplate:add` - generate all the boilerplate code for the examples, so that they can be run locally.
|
||||
- Add the option `--local` to use your local version of Angular contained in the "dist" folder.
|
||||
- Add the option `--ivy` to turn on `ivy` mode.
|
||||
|
||||
* `yarn boilerplate:remove` - remove all the boilerplate code that was added via `yarn boilerplate:add`.
|
||||
* `yarn generate-stackblitz` - generate the stackblitz files that are used by the `live-example` tags in the docs.
|
||||
* `yarn generate-zips` - generate the zip files from the examples. Zip available via the `live-example` tags in the docs.
|
||||
|
@ -1,12 +0,0 @@
|
||||
{
|
||||
"description": "Quickstart AppComponent Testing",
|
||||
"files":[
|
||||
"src/browser-test-shim.js",
|
||||
"src/app/app.component.ts",
|
||||
"src/app/app.component.spec.ts",
|
||||
"src/quickstart-specs.html"
|
||||
],
|
||||
"main": "src/quickstart-specs.html",
|
||||
"file": "src/app/app.component.spec.ts",
|
||||
"tags": ["quickstart", "setup", "testing"]
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
<!-- Run application specs in a browser -->
|
||||
<!-- #docregion -->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<base href="/">
|
||||
<title>1st Specs</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
<link rel="stylesheet" href="node_modules/jasmine-core/lib/jasmine-core/jasmine.css">
|
||||
</head>
|
||||
<body>
|
||||
<!-- Polyfills -->
|
||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||
|
||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||
|
||||
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
|
||||
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
|
||||
<script src="node_modules/jasmine-core/lib/jasmine-core/boot.js"></script>
|
||||
|
||||
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||
<script src="node_modules/zone.js/dist/zone-testing.js"></script>
|
||||
|
||||
<!-- #docregion files -->
|
||||
<script>
|
||||
var __spec_files__ = [
|
||||
'app/app.component.spec'
|
||||
];
|
||||
</script>
|
||||
<!-- #enddocregion files-->
|
||||
<script src="browser-test-shim.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,12 +0,0 @@
|
||||
{
|
||||
"description": "QuickStart Setup",
|
||||
"files": [
|
||||
"src/app/app.component.ts",
|
||||
"src/app/app.module.ts",
|
||||
"src/index.html",
|
||||
"src/main.ts",
|
||||
"src/styles.css"
|
||||
],
|
||||
"file": "src/app/app.component.ts",
|
||||
"tags": ["quickstart", "setup", "seed"]
|
||||
}
|
@ -1,24 +1,22 @@
|
||||
{
|
||||
"description": "Testing - specs",
|
||||
"files":[
|
||||
"src/expected.ts",
|
||||
"src/index-specs.html",
|
||||
"src/main-specs.ts",
|
||||
"src/styles.css",
|
||||
"src/test.css",
|
||||
"src/tests.sb.ts",
|
||||
|
||||
"e2e/src/**/*.ts",
|
||||
|
||||
"src/app/**/*.css",
|
||||
"src/app/**/*.html",
|
||||
"src/app/**/*.ts",
|
||||
"src/app/**/*.spec.ts",
|
||||
|
||||
"src/testing/*.ts",
|
||||
"src/testing/**/*",
|
||||
|
||||
"!src/main.ts",
|
||||
"!src/app/bag/*.*",
|
||||
"!src/app/1st.spec.ts",
|
||||
|
||||
"src/expected.ts",
|
||||
"src/test.css",
|
||||
"src/tests.sb.ts",
|
||||
"src/main-specs.ts",
|
||||
"src/index-specs.html"
|
||||
"src/**/*.spec.ts"
|
||||
],
|
||||
"main": "src/index-specs.html",
|
||||
"tags": ["testing"]
|
||||
|
@ -1,3 +1,3 @@
|
||||
const jasmineRequire = require('jasmine-core/lib/jasmine-core/jasmine.js');
|
||||
import jasmineRequire from 'jasmine-core/lib/jasmine-core/jasmine.js';
|
||||
|
||||
window['jasmineRequire'] = jasmineRequire;
|
||||
|
@ -1,19 +1,18 @@
|
||||
{
|
||||
"description": "Heroes Test App",
|
||||
"files":[
|
||||
"src/index.html",
|
||||
"src/main.ts",
|
||||
"src/styles.css",
|
||||
"src/test.css",
|
||||
|
||||
"e2e/src/**/*.ts",
|
||||
|
||||
"src/app/**/*.css",
|
||||
"src/app/**/*.html",
|
||||
"src/app/**/*.ts",
|
||||
|
||||
"!src/app/bag/*.*",
|
||||
|
||||
"!src/test.ts",
|
||||
|
||||
"src/test.css",
|
||||
"src/main.ts",
|
||||
"src/index.html"
|
||||
"!src/**/*.spec.ts"
|
||||
],
|
||||
"tags": ["testing"]
|
||||
}
|
||||
|
@ -179,3 +179,8 @@ Books
|
||||
* "A Web for Everyone: Designing Accessible User Experiences", Sarah Horton and Whitney Quesenbery
|
||||
|
||||
* "Inclusive Design Patterns", Heydon Pickering
|
||||
|
||||
## More on accessibility
|
||||
|
||||
You may also be interested in the following:
|
||||
* [Audit your Angular app's accessibility with codelyzer](https://web.dev/accessible-angular-with-codelyzer/).
|
||||
|
148
aio/content/guide/angular-compiler-options.md
Normal file
148
aio/content/guide/angular-compiler-options.md
Normal file
@ -0,0 +1,148 @@
|
||||
# Angular compiler options
|
||||
|
||||
When you use [AOT compilation](guide/aot-compiler), you can control how your application is compiled by specifying *template* compiler options in the `tsconfig.json` [TypeScript configuration file](guide/typescript-configuration).
|
||||
|
||||
The template options object, `angularCompilerOptions`, is a sibling to the `compilerOptions` object that supplies standard options to the TypeScript compiler.
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
...
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"fullTemplateTypeCheck": true,
|
||||
"preserveWhitespaces": true,
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
This page describes the available Angular template compiler options.
|
||||
|
||||
### `allowEmptyCodegenFiles`
|
||||
|
||||
When true, generate all possible files even if they are empty. Default is false. Used by the Bazel build rules to simplify how Bazel rules track file dependencies. Do not use this option outside of the Bazel rules.
|
||||
|
||||
### `annotationsAs`
|
||||
|
||||
Modifies how Angular-specific annotations are emitted to improve tree-shaking. Non-Angular annotations are not affected. One of `static fields` (the default) or `decorators`.
|
||||
|
||||
* By default, the compiler replaces decorators with a static field in the class, which allows advanced tree-shakers like [Closure compiler](https://github.com/google/closure-compiler) to remove unused classes.
|
||||
|
||||
* The `decorators` value leaves the decorators in place, which makes compilation faster. TypeScript emits calls to the` __decorate` helper. Use `--emitDecoratorMetadata` for runtime reflection (but note taht the resulting code will not properly tree-shake.
|
||||
|
||||
### `annotateForClosureCompiler`
|
||||
|
||||
When true, use [Tsickle](https://github.com/angular/tsickle) to annotate the emitted JavaScript with [JSDoc](http://usejsdoc.org/) comments needed by the
|
||||
[Closure Compiler](https://github.com/google/closure-compiler). Default is false.
|
||||
|
||||
### `disableExpressionLowering`
|
||||
|
||||
When true (the default), transforms code that is or could be used in an annotation, to allow it to be imported from template factory modules. See [metadata rewriting](guide/aot-compiler#metadata-rewriting) for more information.
|
||||
|
||||
When `false`, disables this rewriting, requiring the rewriting to be done manually.
|
||||
|
||||
### `disableTypeScriptVersionCheck`
|
||||
|
||||
When `true`, the compiler does not check the TypeScript version and does not report an error when an unsupported version of TypeScript is used. Not recommended, as unsupported versions of TypeScript might have undefined behavior. Default is false.
|
||||
|
||||
### `enableResourceInlining`
|
||||
|
||||
When true, replaces the `templateUrl` and `styleUrls` property in all `@Component` decorators with inlined contents in `template` and `styles` properties.
|
||||
|
||||
When enabled, the `.js` output of `ngc` does not include any lazy-loaded template or style URLs.
|
||||
|
||||
|
||||
{@a enablelegacytemplate}
|
||||
|
||||
### `enableLegacyTemplate`
|
||||
|
||||
When true, enables use of the `<template>` element, which was deprecated in Angular 4.0, in favor of `<ng-template>` (to avoid colliding with the DOM's element of the same name). Default is false. Might be required by some third-party Angular libraries. |
|
||||
|
||||
### `flatModuleId`
|
||||
|
||||
The module ID to use for importing a flat module (when `flatModuleOutFile` is true). References generated by the template compiler use this module name when importing symbols
|
||||
from the flat module. Ignored if `flatModuleOutFile` is false.
|
||||
|
||||
### `flatModuleOutFile`
|
||||
|
||||
When true, generates a flat module index of the given file name and the corresponding flat module metadata. Use to create flat modules that are packaged similarly to `@angular/core` and `@angular/common`. When this option is used, the `package.json` for the library should refer
|
||||
to the generated flat module index instead of the library index file.
|
||||
|
||||
Produces only one `.metadata.json` file, which contains all the metadata necessary
|
||||
for symbols exported from the library index. In the generated `.ngfactory.js` files, the flat
|
||||
module index is used to import symbols that includes both the public API from the library index
|
||||
as well as shrowded internal symbols.
|
||||
|
||||
By default the `.ts` file supplied in the `files` field is assumed to be the library index.
|
||||
If more than one `.ts` file is specified, `libraryIndex` is used to select the file to use.
|
||||
If more than one `.ts` file is supplied without a `libraryIndex`, an error is produced.
|
||||
|
||||
A flat module index `.d.ts` and `.js` is created with the given `flatModuleOutFile` name in the same location as the library index `.d.ts` file.
|
||||
|
||||
For example, if a library uses the `public_api.ts` file as the library index of the module, the `tsconfig.json` `files` field would be `["public_api.ts"]`.
|
||||
The `flatModuleOutFile` options could then be set to (for example) `"index.js"`, which produces `index.d.ts` and `index.metadata.json` files.
|
||||
The `module` field of the library's `package.json` would be `"index.js"` and the `typings` field
|
||||
would be `"index.d.ts"`.
|
||||
|
||||
### `fullTemplateTypeCheck`
|
||||
|
||||
When true (recommended), enables the [binding expression validation](guide/aot-compiler#binding-expression-validation) phase of the template compiler, which uses TypeScript to validate binding expressions.
|
||||
|
||||
Default is currently false.
|
||||
|
||||
### `generateCodeForLibraries`
|
||||
|
||||
When true (the default), generates factory files (`.ngfactory.js` and `.ngstyle.js`)
|
||||
for `.d.ts` files with a corresponding `.metadata.json` file.
|
||||
|
||||
When false, factory files are generated only for `.ts` files. Do this when using factory summaries.
|
||||
|
||||
|
||||
### `preserveWhitespaces`
|
||||
|
||||
When false (the default), removes blank text nodes from compiled templates, which results in smaller emitted template factory modules. Set to true to preserve blank text nodes.
|
||||
|
||||
### `skipMetadataEmit`
|
||||
|
||||
When true, does not to produce `.metadata.json` files. Default is `false`.
|
||||
|
||||
The `.metadata.json` files contain information needed by the template compiler from a `.ts`
|
||||
file that is not included in the `.d.ts` file produced by the TypeScript compiler.
|
||||
This information includes, for example, the content of annotations (such as a component's template), which TypeScript emits to the `.js` file but not to the `.d.ts` file.
|
||||
|
||||
You can set to `true` when using factory summaries, because the factory summaries
|
||||
include a copy of the information that is in the `.metadata.json` file.
|
||||
|
||||
Set to `true` if you are using TypeScript's `--outFile` option, because the metadata files
|
||||
are not valid for this style of TypeScript output. However, we do not recommend using `--outFile` with Angular. Use a bundler, such as [webpack](https://webpack.js.org/), instead.
|
||||
|
||||
### `skipTemplateCodegen`
|
||||
|
||||
When true, does not emit `.ngfactory.js` and `.ngstyle.js` files. This turns off most of the template compiler and disables the reporting of template diagnostics.
|
||||
|
||||
Can be used to instruct the template compiler to produce `.metadata.json` files for distribution with an `npm` package while avoiding the production of `.ngfactory.js` and `.ngstyle.js` files that cannot be distributed to `npm`.
|
||||
|
||||
### `strictMetadataEmit`
|
||||
|
||||
When true, reports an error to the `.metadata.json` file if `"skipMetadataEmit"` is `false`.
|
||||
Default is false. Use only when `"skipMetadataEmit"` is false and `"skipTemplateCodeGen"` is true.
|
||||
|
||||
This option is intended to validate the `.metadata.json` files emitted for bundling with an `npm` package. The validation is strict and can emit errors for metadata that would never produce an error when used by the template compiler. You can choose to suppress the error emitted by this option for an exported symbol by including `@dynamic` in the comment documenting the symbol.
|
||||
|
||||
It is valid for `.metadata.json` files to contain errors.
|
||||
The template compiler reports these errors if the metadata is used to determine the contents of an annotation.
|
||||
The metadata collector cannot predict the symbols that are designed for use in an annotation, so it preemptively includes error nodes in the metadata for the exported symbols.
|
||||
The template compiler can then use the error nodes to report an error if these symbols are used.
|
||||
|
||||
If the client of a library intends to use a symbol in an annotation, the template compiler does not normally report this until the client uses the symbol.
|
||||
This option allows detection of these errors during the build phase of
|
||||
the library and is used, for example, in producing Angular libraries themselves.
|
||||
|
||||
### `strictInjectionParameters`
|
||||
|
||||
When true (recommended), reports an error for a supplied parameter whose injection type cannot be determined. When false (currently the default), constructor parameters of classes marked with `@Injectable` whose type cannot be resolved produce a warning.
|
||||
|
||||
### `trace`
|
||||
|
||||
When true, prints extra information while compiling templates. Default is false.
|
@ -128,7 +128,7 @@ The third argument, `easing`, controls how the animation [accelerates and decele
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
**Note:** See the Angular Material Design website's topic on [Natural easing curves](https://material.io/design/motion/speed.html#easing) for general information on easing curves.
|
||||
**Note:** See the Material Design website's topic on [Natural easing curves](https://material.io/design/motion/speed.html#easing) for general information on easing curves.
|
||||
</div>
|
||||
|
||||
This example provides a state transition from `open` to `closed` with a one second transition between states.
|
||||
|
@ -79,11 +79,9 @@ there are fewer opportunities for injection attacks.
|
||||
|
||||
When you use the Angular AOT compiler, you can control your app compilation in two ways:
|
||||
|
||||
* By providing template compiler options in the `tsconfig.json` file.
|
||||
* By [specifying Angular metadata](#metadata-aot), as described below.
|
||||
|
||||
For more information, see [Angular template compiler options](#compiler-options).
|
||||
|
||||
* By [specifying Angular metadata](#metadata-aot).
|
||||
* By providing options in the `tsconfig.json` [TypeScript configuration file](guide/typescript-configuration). See [Angular compiler options](guide/angular-compiler-options).
|
||||
|
||||
|
||||
{@a metadata-aot}
|
||||
@ -1165,7 +1163,7 @@ Chuck: After reviewing your PR comment I'm still at a loss. See [comment there](
|
||||
In the validation phase, the Angular template compiler uses the TypeScript compiler to validate the
|
||||
binding expressions in templates. Enable this phase explicitly by adding the compiler
|
||||
option `"fullTemplateTypeCheck"` in the `"angularCompilerOptions"` of the project's `tsconfig.json` (see
|
||||
[Angular Compiler Options](#compiler-options)).
|
||||
[Angular Compiler Options](guide/angular-compiler-options)).
|
||||
|
||||
Template validation produces error messages when a type error is detected in a template binding
|
||||
expression, similar to how type errors are reported by the TypeScript compiler against code in a `.ts`
|
||||
@ -1329,198 +1327,3 @@ Similar to TypeScript Compiler, Angular Compiler also supports `extends` in the
|
||||
}
|
||||
```
|
||||
More information about tsconfig extends can be found in the [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html).
|
||||
|
||||
{@a compiler-options}
|
||||
## Angular template compiler options
|
||||
|
||||
The template compiler options are specified as members of the `"angularCompilerOptions"` object in the `tsconfig.json` file. Specify template compiler options along with the options supplied to the TypeScript compiler as shown here:
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
...
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"fullTemplateTypeCheck": true,
|
||||
"preserveWhitespaces": true,
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The following section describes the Angular's template compiler options.
|
||||
|
||||
### *enableResourceInlining*
|
||||
This option instructs the compiler to replace the `templateUrl` and `styleUrls` property in all `@Component` decorators with inlined contents in `template` and `styles` properties.
|
||||
When enabled, the `.js` output of `ngc` will have no lazy-loaded `templateUrl` or `styleUrls`.
|
||||
|
||||
### *skipMetadataEmit*
|
||||
|
||||
This option tells the compiler not to produce `.metadata.json` files.
|
||||
The option is `false` by default.
|
||||
|
||||
`.metadata.json` files contain information needed by the template compiler from a `.ts`
|
||||
file that is not included in the `.d.ts` file produced by the TypeScript compiler. This information contains,
|
||||
for example, the content of annotations (such as a component's template), which TypeScript
|
||||
emits to the `.js` file but not to the `.d.ts` file.
|
||||
|
||||
This option should be set to `true` if you are using TypeScript's `--outFile` option, because the metadata files
|
||||
are not valid for this style of TypeScript output. It is not recommended to use `--outFile` with
|
||||
Angular. Use a bundler, such as [webpack](https://webpack.js.org/), instead.
|
||||
|
||||
This option can also be set to `true` when using factory summaries because the factory summaries
|
||||
include a copy of the information that is in the `.metadata.json` file.
|
||||
|
||||
### *strictMetadataEmit*
|
||||
|
||||
This option tells the template compiler to report an error to the `.metadata.json`
|
||||
file if `"skipMetadataEmit"` is `false`. This option is `false` by default. This should only be used when `"skipMetadataEmit"` is `false` and `"skipTemplateCodeGen"` is `true`.
|
||||
|
||||
This option is intended to validate the `.metadata.json` files emitted for bundling with an `npm` package. The validation is strict and can emit errors for metadata that would never produce an error when used by the template compiler. You can choose to suppress the error emitted by this option for an exported symbol by including `@dynamic` in the comment documenting the symbol.
|
||||
|
||||
It is valid for `.metadata.json` files to contain errors. The template compiler reports these errors
|
||||
if the metadata is used to determine the contents of an annotation. The metadata
|
||||
collector cannot predict the symbols that are designed for use in an annotation, so it will preemptively
|
||||
include error nodes in the metadata for the exported symbols. The template compiler can then use the error
|
||||
nodes to report an error if these symbols are used. If the client of a library intends to use a symbol in an annotation, the template compiler will not normally report
|
||||
this until the client uses the symbol. This option allows detecting these errors during the build phase of
|
||||
the library and is used, for example, in producing Angular libraries themselves.
|
||||
|
||||
### *skipTemplateCodegen*
|
||||
|
||||
This option tells the compiler to suppress emitting `.ngfactory.js` and `.ngstyle.js` files. When set,
|
||||
this turns off most of the template compiler and disables reporting template diagnostics.
|
||||
This option can be used to instruct the
|
||||
template compiler to produce `.metadata.json` files for distribution with an `npm` package while
|
||||
avoiding the production of `.ngfactory.js` and `.ngstyle.js` files that cannot be distributed to
|
||||
`npm`.
|
||||
|
||||
### *strictInjectionParameters*
|
||||
|
||||
When set to `true`, this options tells the compiler to report an error for a parameter supplied
|
||||
whose injection type cannot be determined. When this option is not provided or is `false`, constructor parameters of classes marked with `@Injectable` whose type cannot be resolved will
|
||||
produce a warning.
|
||||
|
||||
*Note*: It is recommended to change this option explicitly to `true` as this option will default to `true` in the future.
|
||||
|
||||
### *flatModuleOutFile*
|
||||
|
||||
When set to `true`, this option tells the template compiler to generate a flat module
|
||||
index of the given file name and the corresponding flat module metadata. Use this option when creating
|
||||
flat modules that are packaged similarly to `@angular/core` and `@angular/common`. When this option
|
||||
is used, the `package.json` for the library should refer
|
||||
to the generated flat module index instead of the library index file. With this
|
||||
option only one `.metadata.json` file is produced, which contains all the metadata necessary
|
||||
for symbols exported from the library index. In the generated `.ngfactory.js` files, the flat
|
||||
module index is used to import symbols that includes both the public API from the library index
|
||||
as well as shrowded internal symbols.
|
||||
|
||||
By default the `.ts` file supplied in the `files` field is assumed to be the library index.
|
||||
If more than one `.ts` file is specified, `libraryIndex` is used to select the file to use.
|
||||
If more than one `.ts` file is supplied without a `libraryIndex`, an error is produced. A flat module
|
||||
index `.d.ts` and `.js` will be created with the given `flatModuleOutFile` name in the same
|
||||
location as the library index `.d.ts` file. For example, if a library uses the
|
||||
`public_api.ts` file as the library index of the module, the `tsconfig.json` `files` field
|
||||
would be `["public_api.ts"]`. The `flatModuleOutFile` options could then be set to, for
|
||||
example `"index.js"`, which produces `index.d.ts` and `index.metadata.json` files. The
|
||||
library's `package.json`'s `module` field would be `"index.js"` and the `typings` field
|
||||
would be `"index.d.ts"`.
|
||||
|
||||
### *flatModuleId*
|
||||
|
||||
This option specifies the preferred module id to use for importing a flat module.
|
||||
References generated by the template compiler will use this module name when importing symbols
|
||||
from the flat module.
|
||||
This is only meaningful when `flatModuleOutFile` is also supplied. Otherwise the compiler ignores
|
||||
this option.
|
||||
|
||||
### *generateCodeForLibraries*
|
||||
|
||||
This option tells the template compiler to generate factory files (`.ngfactory.js` and `.ngstyle.js`)
|
||||
for `.d.ts` files with a corresponding `.metadata.json` file. This option defaults to
|
||||
`true`. When this option is `false`, factory files are generated only for `.ts` files.
|
||||
|
||||
This option should be set to `false` when using factory summaries.
|
||||
|
||||
### *fullTemplateTypeCheck*
|
||||
|
||||
This option tells the compiler to enable the [binding expression validation](#binding-expression-validation)
|
||||
phase of the template compiler which uses TypeScript to validate binding expressions.
|
||||
|
||||
This option is `false` by default.
|
||||
|
||||
*Note*: It is recommended to set this to `true` because this option will default to `true` in the future.
|
||||
|
||||
### *annotateForClosureCompiler*
|
||||
|
||||
This option tells the compiler to use [Tsickle](https://github.com/angular/tsickle) to annotate the emitted
|
||||
JavaScript with [JSDoc](http://usejsdoc.org/) comments needed by the
|
||||
[Closure Compiler](https://github.com/google/closure-compiler). This option defaults to `false`.
|
||||
|
||||
### *annotationsAs*
|
||||
|
||||
Use this option to modify how the Angular specific annotations are emitted to improve tree-shaking. Non-Angular
|
||||
annotations and decorators are unaffected. Default is `static fields`.
|
||||
|
||||
<style>
|
||||
td, th {vertical-align: top}
|
||||
</style>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Value</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>decorators</code></td>
|
||||
<td>Leave the decorators in place. This makes compilation faster. TypeScript will emit calls to the __decorate helper. Use <code>--emitDecoratorMetadata</code> for runtime reflection. However, the resulting code will not properly tree-shake.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>static fields</code></td>
|
||||
<td>Replace decorators with a static field in the class. Allows advanced tree-shakers like
|
||||
<a href="https://github.com/google/closure-compiler">Closure compiler</a> to remove unused classes.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
### *trace*
|
||||
|
||||
This tells the compiler to print extra information while compiling templates.
|
||||
|
||||
### *enableLegacyTemplate*
|
||||
|
||||
Use of the `<template>` element was deprecated starting in Angular 4.0 in favor of using
|
||||
`<ng-template>` to avoid colliding with the DOM's element of the same name. Setting this option to
|
||||
`true` enables the use of the deprecated `<template>` element. This option
|
||||
is `false` by default. This option might be required by some third-party Angular libraries.
|
||||
|
||||
### *disableExpressionLowering*
|
||||
|
||||
The Angular template compiler transforms code that is used, or could be used, in an annotation
|
||||
to allow it to be imported from template factory modules. See
|
||||
[metadata rewriting](#metadata-rewriting) for more information.
|
||||
|
||||
Setting this option to `false` disables this rewriting, requiring the rewriting to be
|
||||
done manually.
|
||||
|
||||
### *disableTypeScriptVersionCheck*
|
||||
|
||||
When `true`, this option tells the compiler not to check the TypeScript version.
|
||||
The compiler will skip checking and will not error out when an unsupported version of TypeScript is used.
|
||||
Setting this option to `true` is not recommended because unsupported versions of TypeScript might have undefined behavior.
|
||||
|
||||
This option is `false` by default.
|
||||
|
||||
### *preserveWhitespaces*
|
||||
|
||||
This option tells the compiler whether to remove blank text nodes from compiled templates.
|
||||
As of v6, this option is `false` by default, which results in smaller emitted template factory modules.
|
||||
|
||||
### *allowEmptyCodegenFiles*
|
||||
|
||||
Tells the compiler to generate all the possible generated files even if they are empty. This option is
|
||||
`false` by default. This is an option used by the Bazel build rules and is needed to simplify
|
||||
how Bazel rules track file dependencies. It is not recommended to use this option outside of the Bazel
|
||||
rules.
|
||||
|
||||
|
@ -53,7 +53,7 @@ Angular supports most recent browsers. This includes the following specific vers
|
||||
IE
|
||||
</td>
|
||||
<td>
|
||||
11, 10, 9
|
||||
11, 10, 9 ("compatibility view" mode not supported)
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -183,7 +183,7 @@ These are the polyfills required to run an Angular application on each supported
|
||||
|
||||
<td>
|
||||
Chrome, Firefox, Edge, <br>
|
||||
Safari, Android, IE10+
|
||||
Safari, Android, IE 10+
|
||||
</td>
|
||||
|
||||
<td>
|
||||
@ -197,7 +197,7 @@ These are the polyfills required to run an Angular application on each supported
|
||||
<tr style="vertical-align: top">
|
||||
|
||||
<td>
|
||||
IE9
|
||||
IE 9
|
||||
</td>
|
||||
|
||||
<td>
|
||||
@ -275,7 +275,7 @@ Some features of Angular may require additional polyfills.
|
||||
</td>
|
||||
|
||||
<td>
|
||||
All but Chrome, Firefox, Edge, IE11 and Safari 10
|
||||
All but Chrome, Firefox, Edge, IE 11 and Safari 10
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
@ -294,7 +294,7 @@ Some features of Angular may require additional polyfills.
|
||||
</td>
|
||||
|
||||
<td>
|
||||
IE10, IE11
|
||||
IE 10, IE 11
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
@ -214,14 +214,17 @@ Each budget entry is a JSON object with the following properties:
|
||||
|
||||
<tr>
|
||||
<td>type</td>
|
||||
<td>The type of budget. One of:
|
||||
<td>
|
||||
|
||||
* bundle - The size of a specific bundle.
|
||||
* initial - The initial size of the app.
|
||||
* allScript - The size of all scripts.
|
||||
* all - The size of the entire app.
|
||||
* anyScript - The size of any one script.
|
||||
* any - The size of any file.
|
||||
The type of budget. One of:
|
||||
|
||||
* `bundle` - The size of a specific bundle.
|
||||
* `initial` - The initial size of the app.
|
||||
* `allScript` - The size of all scripts.
|
||||
* `all` - The size of the entire app.
|
||||
* `anyComponentStyle` - This size of any one component stylesheet.
|
||||
* `anyScript` - The size of any one script.
|
||||
* `any` - The size of any file.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -253,7 +253,7 @@ In the `package.json` file, add a `builders` key that tells the Architect tool w
|
||||
</code-example>
|
||||
|
||||
The official name of our builder is now ` @example/command-runner:command`.
|
||||
The first part of this is the package name (resolved using node resolution), and the second part is the builder name (resolved using the `builder.json` file).
|
||||
The first part of this is the package name (resolved using node resolution), and the second part is the builder name (resolved using the `builders.json` file).
|
||||
|
||||
Using one of our `options` is very straightforward, we did this in the previous section when we accessed `options.command`.
|
||||
|
||||
@ -279,28 +279,28 @@ By default, for example, the `build` command runs the builder `@angular-devkit/
|
||||
"myApp": {
|
||||
...
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist/myApp",
|
||||
"index": "src/index.html",
|
||||
...
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
...
|
||||
}
|
||||
}
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist/myApp",
|
||||
"index": "src/index.html",
|
||||
...
|
||||
},
|
||||
...
|
||||
"configurations": {
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
...
|
||||
}
|
||||
}
|
||||
},
|
||||
...
|
||||
|
||||
</code-example>
|
||||
|
||||
@ -419,15 +419,13 @@ We need to update the `angular.json` file to add a target for this builder to th
|
||||
"projects": {
|
||||
"builder-test": {
|
||||
"architect": {
|
||||
"builder-test": {
|
||||
"touch": {
|
||||
"builder": "@example/command-runner:command",
|
||||
"options": {
|
||||
"command": "touch",
|
||||
"args": [
|
||||
"src/main.ts"
|
||||
]
|
||||
}
|
||||
"touch": {
|
||||
"builder": "@example/command-runner:command",
|
||||
"options": {
|
||||
"command": "touch",
|
||||
"args": [
|
||||
"src/main.ts"
|
||||
]
|
||||
}
|
||||
},
|
||||
"build": {
|
||||
@ -497,14 +495,14 @@ The test uses the builder to run the `ls` command, then validates that it ran su
|
||||
|
||||
<code-example language="typescript">
|
||||
|
||||
import { Architect, ArchitectHost } from '@angular-devkit/architect';
|
||||
import { Architect } from '@angular-devkit/architect';
|
||||
import { TestingArchitectHost } from '@angular-devkit/architect/testing';
|
||||
// Our builder forwards the STDOUT of the command to the logger.
|
||||
import { logging, schema } from '@angular-devkit/core';
|
||||
|
||||
describe('Command Runner Builder', () => {
|
||||
let architect: Architect;
|
||||
let architectHost: ArchitectHost;
|
||||
let architectHost: TestingArchitectHost;
|
||||
|
||||
beforeEach(async () => {
|
||||
const registry = new schema.CoreSchemaRegistry();
|
||||
|
@ -30,7 +30,7 @@ The Filter/Stagger tab in the live example shows a list of heroes with an introd
|
||||
|
||||
The following example demonstrates how to use `query()` and `stagger()` functions on the entry of an animated element.
|
||||
|
||||
* Use `query()` to look for any element entering or leaving the page. The query specifies elements meeting certain CSS class criteria.
|
||||
* Use `query()` to look for an element entering the page that meets certain criteria.
|
||||
|
||||
* For each of these elements, use `style()` to set the same initial style for the element. Make it invisible and use `transform` to move it out of position so that it can slide into place.
|
||||
|
||||
|
@ -178,7 +178,7 @@ For more information, see [/deep/, >>>, and ::ng-deep](guide/component-styles#de
|
||||
{@a template-tag}
|
||||
### <template> tag
|
||||
|
||||
The `<template>` tag was deprecated in v4 to avoid colliding with the DOM's element of the same name (such as when using web components). Use `<ng-template>` instead. For more information, see the [Ahead-of-Time Compilation](guide/aot-compiler#enablelegacytemplate) guide.
|
||||
The `<template>` tag was deprecated in v4 to avoid colliding with the DOM's element of the same name (such as when using web components). Use `<ng-template>` instead. For more information, see the [Ahead-of-Time Compilation](guide/angular-compiler-options#enablelegacytemplate) guide.
|
||||
|
||||
|
||||
|
||||
|
@ -207,3 +207,6 @@ You may also be interested in the following:
|
||||
* [Routing and Navigation](guide/router).
|
||||
* [Providers](guide/providers).
|
||||
* [Types of Feature Modules](guide/module-types).
|
||||
* [Route-level code-splitting in Angular](https://web.dev/route-level-code-splitting-in-angular/)
|
||||
* [Route preloading strategies in Angular](https://web.dev/route-preloading-in-angular/)
|
||||
|
||||
|
@ -2,15 +2,17 @@
|
||||
|
||||
Angular makes use of observables as an interface to handle a variety of common asynchronous operations. For example:
|
||||
|
||||
* The `EventEmitter` class extends `Observable`.
|
||||
* You can define [custom events](guide/template-syntax#custom-events-with-eventemitter) that send observable output data from a child to a parent component.
|
||||
* The HTTP module uses observables to handle AJAX requests and responses.
|
||||
* The Router and Forms modules use observables to listen for and respond to user-input events.
|
||||
|
||||
## Event emitter
|
||||
## Transmitting data between components
|
||||
|
||||
Angular provides an `EventEmitter` class that is used when publishing values from a component through the `@Output()` decorator. `EventEmitter` extends `Observable`, adding an `emit()` method so it can send arbitrary values. When you call `emit()`, it passes the emitted value to the `next()` method of any subscribed observer.
|
||||
Angular provides an `EventEmitter` class that is used when publishing values from a component through the [`@Output()` decorator](guide/template-syntax#how-to-use-output).
|
||||
`EventEmitter` extends [RxJS `Subject`](https://rxjs.dev/api/index/class/Subject), adding an `emit()` method so it can send arbitrary values.
|
||||
When you call `emit()`, it passes the emitted value to the `next()` method of any subscribed observer.
|
||||
|
||||
A good example of usage can be found on the [EventEmitter](https://angular.io/api/core/EventEmitter) documentation. Here is the example component that listens for open and close events:
|
||||
A good example of usage can be found in the [EventEmitter](https://angular.io/api/core/EventEmitter) documentation. Here is the example component that listens for open and close events:
|
||||
|
||||
`<zippy (open)="onOpen($event)" (close)="onClose($event)"></zippy>`
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# The RxJS library
|
||||
|
||||
Reactive programming is an asynchronous programming paradigm concerned with data streams and the propagation of change ([Wikipedia](https://en.wikipedia.org/wiki/Reactive_programming)). RxJS (Reactive Extensions for JavaScript) is a library for reactive programming using observables that makes it easier to compose asynchronous or callback-based code ([RxJS Docs](http://reactivex.io/rxjs/)).
|
||||
Reactive programming is an asynchronous programming paradigm concerned with data streams and the propagation of change ([Wikipedia](https://en.wikipedia.org/wiki/Reactive_programming)). RxJS (Reactive Extensions for JavaScript) is a library for reactive programming using observables that makes it easier to compose asynchronous or callback-based code. See ([RxJS Docs](https://rxjs.dev/guide/overview)).
|
||||
|
||||
RxJS provides an implementation of the `Observable` type, which is needed until the type becomes part of the language and until browsers support it. The library also provides utility functions for creating and working with observables. These utility functions can be used for:
|
||||
|
||||
@ -45,7 +45,7 @@ The `pipe()` function is also a method on the RxJS `Observable`, so you use this
|
||||
|
||||
### Common operators
|
||||
|
||||
RxJS provides many operators, but only a handful are used frequently. For a list of operators and usage samples, visit the [RxJS API Documentation](https://rxjs-dev.firebaseapp.com/api).
|
||||
RxJS provides many operators, but only a handful are used frequently. For a list of operators and usage samples, visit the [RxJS API Documentation](https://rxjs.dev/api).
|
||||
|
||||
<div class="alert is-helpful">
|
||||
Note that, for Angular apps, we prefer combining operators with pipes, rather than chaining. Chaining is used in many RxJS examples.
|
||||
|
@ -927,7 +927,7 @@ As always, strive for consistency.
|
||||
<div class="s-rule do">
|
||||
|
||||
**Do** use a custom prefix for a component selector.
|
||||
For example, the prefix `toh` represents from **T**our **o**f **H**eroes and the prefix `admin` represents an admin feature area.
|
||||
For example, the prefix `toh` represents **T**our **o**f **H**eroes and the prefix `admin` represents an admin feature area.
|
||||
|
||||
</div>
|
||||
|
||||
@ -1080,6 +1080,10 @@ For example, the prefix `toh` represents from **T**our **o**f **H**eroes and the
|
||||
|
||||
|
||||
**Do** use consistent names for all pipes, named after their feature.
|
||||
The pipe class name should use [UpperCamelCase](guide/glossary#case-types)
|
||||
(the general convention for class names),
|
||||
and the corresponding `name` string should use *lowerCamelCase*.
|
||||
The `name` string cannot use hyphens ("dash-case" or "kebab-case").
|
||||
|
||||
|
||||
</div>
|
||||
@ -1670,7 +1674,7 @@ keep the **F**lattest structure you can, and
|
||||
|
||||
|
||||
|
||||
**Why?** LIFT Provides a consistent structure that scales well, is modular, and makes it easier to increase developer efficiency by finding code quickly.
|
||||
**Why?** LIFT provides a consistent structure that scales well, is modular, and makes it easier to increase developer efficiency by finding code quickly.
|
||||
To confirm your intuition about a particular structure, ask:
|
||||
_can I quickly open and start work in all of the related files for this feature_?
|
||||
|
||||
@ -1690,7 +1694,7 @@ _can I quickly open and start work in all of the related files for this feature_
|
||||
|
||||
|
||||
|
||||
**Do** make locating code intuitive, simple and fast.
|
||||
**Do** make locating code intuitive, simple, and fast.
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -6,14 +6,14 @@ This guide offers tips and techniques for unit and integration testing Angular a
|
||||
The guide presents tests of a sample application created with the [Angular CLI](cli). This sample application is much like the one created in the [_Tour of Heroes_ tutorial](tutorial).
|
||||
The sample application and all tests in this guide are available for inspection and experimentation:
|
||||
|
||||
- <live-example embedded-style>Sample app</live-example>
|
||||
- <live-example stackblitz="specs">Tests</live-example>
|
||||
- <live-example embedded-style noDownload>Sample app</live-example>
|
||||
- <live-example stackblitz="specs" noDownload>Tests</live-example>
|
||||
|
||||
<hr>
|
||||
|
||||
## Setup
|
||||
|
||||
The Angular CLI downloads and install everything you need to test an Angular application with the [Jasmine test framework](https://jasmine.github.io/).
|
||||
The Angular CLI downloads and installs everything you need to test an Angular application with the [Jasmine test framework](https://jasmine.github.io/).
|
||||
|
||||
The project you create with the CLI is immediately ready to test.
|
||||
Just run the [`ng test`](cli/test) CLI command:
|
||||
@ -116,7 +116,7 @@ jobs:
|
||||
build:
|
||||
working_directory: ~/my-project
|
||||
docker:
|
||||
- image: circleci/node:8-browsers
|
||||
- image: circleci/node:10-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
You learned the basics of Angular animations in the [introduction](guide/animations) page.
|
||||
|
||||
In this guide, we go into greater depth on special transition states such as `*` (wildcard) and `void`, and show how these special states are used for elements entering and leaving a view. The chapter also explores on multiple animation triggers, animation callbacks and sequence-based animation using keyframes.
|
||||
In this guide, we go into greater depth on special transition states such as `*` (wildcard) and `void`, and show how these special states are used for elements entering and leaving a view. The chapter also explores multiple animation triggers, animation callbacks and sequence-based animation using keyframes.
|
||||
|
||||
## Predefined states and wildcard matching
|
||||
|
||||
|
@ -348,7 +348,7 @@ For example:
|
||||
|
||||
<code-example language="json">
|
||||
|
||||
"sourceMaps": { "scripts": true, "styles": false, "hidden": true, "vendor": true }
|
||||
"sourceMap": { "scripts": true, "styles": false, "hidden": true, "vendor": true }
|
||||
|
||||
</code-example>
|
||||
|
||||
|
@ -13,35 +13,23 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- ng-conf 2019-->
|
||||
<!-- NG-DE 2019-->
|
||||
<tr>
|
||||
<th><a href="https://ng-conf.org/" title="ng-conf">ng-conf</a></th>
|
||||
<td>Salt Lake City, Utah</td>
|
||||
<td>May 1-3, 2019</td>
|
||||
<th><a href="https://ng-de.org/" title="NG-DE">NG-DE</a></th>
|
||||
<td>Berlin, Germany</td>
|
||||
<td>August 29th workshops, 30-31 conference, 2019</td>
|
||||
</tr>
|
||||
<!-- ngVikings 2019-->
|
||||
<tr>
|
||||
<th><a href="https://ngvikings.org/" title="ngVikings">ngVikings</a></th>
|
||||
<td>Copenhagen, Denmark</td>
|
||||
<td>May 26 (workshops), 27-28 (conference), 2019</td>
|
||||
</tr>
|
||||
<!-- ngJapan-->
|
||||
<tr>
|
||||
<th><a href="https://ngjapan.org" title="ng-japan">ng-japan</a></th>
|
||||
<td>Tokyo, Japan</td>
|
||||
<td>July 13, 2019</td>
|
||||
</tr>
|
||||
<!-- AngularConnect 2019-->
|
||||
<tr>
|
||||
<th><a href="https://www.angularconnect.com/?utm_source=angular.io&utm_medium=referral" title="AngularConnect">AngularConnect</a></th>
|
||||
<td>London, UK</td>
|
||||
<td>September 19-20, 2019</td>
|
||||
</tr>
|
||||
<!-- NG-DE 2019-->
|
||||
<!-- ReactiveConf 2019 -->
|
||||
<tr>
|
||||
<th><a href="https://ng-de.org/" title="NG-DE">NG-DE</a></th>
|
||||
<td>Berlin, Germany</td>
|
||||
<td>August 29th workshops, 30-31 conference, 2019</td>
|
||||
<th><a href="https://reactiveconf.com/" title="ReactiveConf">ReactiveConf</a></th>
|
||||
<td>Prague, Czech Republic</td>
|
||||
<td>October 30 - November 1, 2019</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@ -56,6 +44,24 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- ngJapan-->
|
||||
<tr>
|
||||
<th><a href="https://ngjapan.org" title="ng-japan">ng-japan</a></th>
|
||||
<td>Tokyo, Japan</td>
|
||||
<td>July 13, 2019</td>
|
||||
</tr>
|
||||
<!-- ngVikings 2019-->
|
||||
<tr>
|
||||
<th><a href="https://ngvikings.org/" title="ngVikings">ngVikings</a></th>
|
||||
<td>Copenhagen, Denmark</td>
|
||||
<td>May 26 (workshops), 27-28 (conference), 2019</td>
|
||||
</tr>
|
||||
<!-- ng-conf 2019-->
|
||||
<tr>
|
||||
<th><a href="https://ng-conf.org/" title="ng-conf">ng-conf</a></th>
|
||||
<td>Salt Lake City, Utah</td>
|
||||
<td>May 1-3, 2019</td>
|
||||
</tr>
|
||||
<!-- ng-India 2019-->
|
||||
<tr>
|
||||
<th><a href="https://www.ng-ind.com/" title="ng-India">ng-India</a></th>
|
||||
|
@ -259,6 +259,12 @@
|
||||
"UI Components": {
|
||||
"order": 4,
|
||||
"resources": {
|
||||
"AngularUIToolkit": {
|
||||
"desc": "Angular UI Toolkit: 115 professionally maintained UI components ranging from a robust grid to charts and more. Try for free & build Angular apps faster.",
|
||||
"rev": true,
|
||||
"title": "Angular UI Toolkit",
|
||||
"url": "https://www.angular-ui-tools.com"
|
||||
},
|
||||
"IgniteUIforAngular": {
|
||||
"desc": "Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps.",
|
||||
"rev": true,
|
||||
@ -637,6 +643,12 @@
|
||||
"rev": true,
|
||||
"title": "Loiane Training (Português)",
|
||||
"url": "https://loiane.training/course/angular/"
|
||||
},
|
||||
"web-dev-angular": {
|
||||
"desc": "Build performant and progressive Angular applications.",
|
||||
"rev": true,
|
||||
"title": "web.dev/angular",
|
||||
"url": "https://web.dev/angular"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -728,7 +740,7 @@
|
||||
"desc": "Angular trainings delivered by Zenika (FRANCE)",
|
||||
"rev": true,
|
||||
"title": "Angular Trainings (French)",
|
||||
"url": "https://training.zenika.com/fr/training/angular2/description"
|
||||
"url": "https://training.zenika.com/fr/training/angular/description"
|
||||
},
|
||||
"formationjs": {
|
||||
"desc": "Angular onsite training in Paris (France). Monthly Angular workshops and custom onsite classes. We are focused on Angular, so we are always up to date.",
|
||||
|
@ -597,6 +597,11 @@
|
||||
"title": "Ahead-of-Time Compilation",
|
||||
"tooltip": "Learn why and how to use the Ahead-of-Time (AOT) compiler."
|
||||
},
|
||||
{
|
||||
"url": "guide/angular-compiler-options",
|
||||
"title": "Compiler Options",
|
||||
"tooltip": "Configuration options for the AOT compiler."
|
||||
},
|
||||
{
|
||||
"url": "guide/build",
|
||||
"title": "Building & Serving",
|
||||
|
@ -91,8 +91,6 @@ configures it with the `routes` in one step by calling
|
||||
|
||||
Next, `AppRoutingModule` exports `RouterModule` so it will be available throughout the app.
|
||||
|
||||
Open the `AppComponent` template and replace the `<app-heroes>` element with a `<router-outlet>` element.
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts (exports array)" region="export-routermodule">
|
||||
</code-example>
|
||||
|
||||
|
@ -317,7 +317,7 @@ Each hero in the heroes list should have a delete button.
|
||||
Add the following button element to the `HeroesComponent` template, after the hero
|
||||
name in the repeated `<li>` element.
|
||||
|
||||
<code-example path="toh-pt6/src/app/heroes/heroes.component.html" header="src/app/hero.service.ts" region="delete"></code-example>
|
||||
<code-example path="toh-pt6/src/app/heroes/heroes.component.html" header="src/app/heroes/heroes.component.html" region="delete"></code-example>
|
||||
|
||||
The HTML for the list of heroes should look like this:
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
"scripts": {
|
||||
"preinstall": "node ../tools/yarn/check-yarn.js",
|
||||
"postinstall": "node tools/cli-patches/patch.js",
|
||||
"aio-use-local": "node tools/ng-packages-installer overwrite . --debug",
|
||||
"aio-use-local": "node tools/ng-packages-installer overwrite . --debug --force --build-packages",
|
||||
"aio-use-npm": "node tools/ng-packages-installer restore .",
|
||||
"aio-check-local": "node tools/ng-packages-installer check .",
|
||||
"ng": "yarn check-env && ng",
|
||||
@ -17,18 +17,22 @@
|
||||
"build": "yarn ~~build",
|
||||
"prebuild-local": "yarn setup-local",
|
||||
"build-local": "yarn ~~build",
|
||||
"prebuild-local-ci": "yarn setup-local --no-build-packages",
|
||||
"build-local-ci": "yarn ~~build --progress=false",
|
||||
"prebuild-with-ivy": "yarn setup-local && node scripts/switch-to-ivy",
|
||||
"build-with-ivy": "yarn ~~build",
|
||||
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js a8fe15cb6",
|
||||
"prebuild-with-ivy-ci": "yarn setup-local --no-build-packages && node scripts/switch-to-ivy",
|
||||
"build-with-ivy-ci": "yarn ~~build --progress=false",
|
||||
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js bb4be27da",
|
||||
"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",
|
||||
"e2e": "ng e2e --no-webdriver-update",
|
||||
"presetup": "yarn --cwd .. install && yarn install --frozen-lockfile && yarn ~~check-env && yarn ~~clean-generated && yarn boilerplate:remove",
|
||||
"setup": "yarn aio-use-npm && yarn example-use-npm",
|
||||
"setup": "yarn example-use-npm && yarn aio-use-npm",
|
||||
"postsetup": "yarn boilerplate:add && yarn extract-cli-command-docs && yarn docs",
|
||||
"presetup-local": "yarn presetup",
|
||||
"setup-local": "yarn aio-use-local && yarn example-use-local",
|
||||
"setup-local": "yarn example-use-local && yarn aio-use-local",
|
||||
"postsetup-local": "yarn postsetup",
|
||||
"set-opensearch-url": "node --eval \"const sh = require('shelljs'); sh.set('-e'); sh.sed('-i', /PLACEHOLDER_URL/g, process.argv[1], 'dist/assets/opensearch.xml');\"",
|
||||
"presmoke-tests": "yarn update-webdriver",
|
||||
@ -39,7 +43,7 @@
|
||||
"test-pwa-score-localhost": "run-p --race \"~~light-server -s dist -p 4200 --quiet\" \"test-pwa-score http://localhost:4200 {1} {2}\" --",
|
||||
"example-e2e": "yarn example-check-local && node ./tools/examples/run-example-e2e",
|
||||
"example-lint": "tslint --config \"content/examples/tslint.json\" \"content/examples/**/*.ts\" --exclude \"content/examples/styleguide/**/*.avoid.ts\"",
|
||||
"example-use-local": "node tools/ng-packages-installer overwrite ./tools/examples/shared --debug",
|
||||
"example-use-local": "node tools/ng-packages-installer overwrite ./tools/examples/shared --debug --force",
|
||||
"example-use-npm": "node tools/ng-packages-installer restore ./tools/examples/shared",
|
||||
"example-check-local": "node tools/ng-packages-installer check ./tools/examples/shared",
|
||||
"deploy-production": "scripts/deploy-to-firebase.sh",
|
||||
|
@ -28,11 +28,11 @@
|
||||
"uncompressed": {
|
||||
"runtime-es5": 2932,
|
||||
"runtime-es2015": 2938,
|
||||
"main-es5": 555102,
|
||||
"main-es2015": 572938,
|
||||
"main-es5": 560811,
|
||||
"main-es2015": 499846,
|
||||
"polyfills-es5": 129161,
|
||||
"polyfills-es2015": 53295
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -9,5 +9,4 @@
|
||||
@import 'marketing-layout';
|
||||
@import 'not-found';
|
||||
@import 'sidenav';
|
||||
@import 'table-of-contents';
|
||||
@import 'top-menu';
|
||||
|
@ -1,10 +0,0 @@
|
||||
nav#main-table-of-contents {
|
||||
width: 200px;
|
||||
height: 900px;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 50px;
|
||||
bottom: 100px;
|
||||
margin-left: 32px;
|
||||
background-color: $blue;
|
||||
}
|
@ -2,112 +2,96 @@
|
||||
max-width: 1200px;
|
||||
|
||||
table {
|
||||
margin: 12px 0 24px;
|
||||
margin: 12px 0 24px;
|
||||
|
||||
th {
|
||||
text-transform: none;
|
||||
@include font-size(16);
|
||||
font-weight: bold;
|
||||
th {
|
||||
text-transform: none;
|
||||
@include font-size(16);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
tr {
|
||||
border-bottom: 1px solid $lightgray;
|
||||
}
|
||||
|
||||
td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
// This is overriding a style here:
|
||||
// https://github.com/angular/angular/blob/95993e1/aio/src/styles/2-modules/_table.scss#L58-L62
|
||||
tbody > tr > td tr td:first-child {
|
||||
@media screen and (max-width: 480px) {
|
||||
background-color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
tr:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&.item-table {
|
||||
td {
|
||||
padding: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
&.list-table {
|
||||
td {
|
||||
padding: 16px 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.short-description {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&.parameters-table {
|
||||
margin-top: 0;
|
||||
@include font-size(14);
|
||||
box-shadow: none;
|
||||
|
||||
tr {
|
||||
border-bottom: 1px solid $lightgray;
|
||||
@media screen and (max-width: 480px) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
td:first-child {
|
||||
font-weight: 600;
|
||||
padding-left: 16px;
|
||||
width: 20%;
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
vertical-align: middle;
|
||||
padding: 8px 8px 8px 0;
|
||||
border: 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
// This is overriding a style here:
|
||||
// https://github.com/angular/angular/blob/95993e1/aio/src/styles/2-modules/_table.scss#L58-L62
|
||||
tbody > tr > td tr td:first-child {
|
||||
@media screen and (max-width: 480px) {
|
||||
background-color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
tr:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&.item-table {
|
||||
td {
|
||||
padding: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
&.list-table {
|
||||
td {
|
||||
padding: 16px 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.short-description {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&.parameters-table {
|
||||
margin-top: 0;
|
||||
@include font-size(14);
|
||||
box-shadow: none;
|
||||
|
||||
tr {
|
||||
@media screen and (max-width: 480px) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
td:first-child {
|
||||
font-weight: 600;
|
||||
padding-left: 16px;
|
||||
width: 20%;
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 8px 8px 8px 0;
|
||||
border: 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
&.property-table {
|
||||
td {
|
||||
vertical-align: top;
|
||||
}
|
||||
&.property-table {
|
||||
td {
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.class-overview {
|
||||
position: relative;
|
||||
|
||||
code-example {
|
||||
clear: left;
|
||||
clear: left;
|
||||
}
|
||||
}
|
||||
|
||||
.short-description {
|
||||
margin: 6px 0 0 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.breadcrumb-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.api-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
@ -117,10 +101,12 @@
|
||||
|
||||
.github-links {
|
||||
float: right;
|
||||
|
||||
.material-icons {
|
||||
border-radius: 4px;
|
||||
padding: 4px;
|
||||
@include font-size(20);
|
||||
|
||||
&:hover {
|
||||
background-color: $mist;
|
||||
}
|
||||
@ -128,19 +114,20 @@
|
||||
}
|
||||
|
||||
.api-body {
|
||||
|
||||
.class-overview {
|
||||
position: relative;
|
||||
|
||||
code-example {
|
||||
clear: left;
|
||||
clear: left;
|
||||
}
|
||||
}
|
||||
|
||||
.method-table, .option-table, .list-table {
|
||||
.method-table,
|
||||
.option-table,
|
||||
.list-table {
|
||||
td > code {
|
||||
background-color: inherit;
|
||||
white-space: pre;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.with-github-links {
|
||||
@ -161,7 +148,7 @@
|
||||
|
||||
h3 {
|
||||
margin: 6px 0;
|
||||
font-weight: bold;
|
||||
font-weight: 500;
|
||||
clear: left;
|
||||
}
|
||||
|
||||
@ -172,10 +159,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.api-heading {
|
||||
padding: 5px 0;
|
||||
@include font-size(14);
|
||||
margin: 16px;
|
||||
}
|
||||
|
||||
.parameters-table {
|
||||
@ -244,7 +230,9 @@
|
||||
}
|
||||
|
||||
|
||||
.from-constructor, .read-only-property, .write-only-property {
|
||||
.from-constructor,
|
||||
.read-only-property,
|
||||
.write-only-property {
|
||||
@include font-size(12);
|
||||
font-weight: 600;
|
||||
@include letter-spacing(0.5);
|
||||
@ -259,7 +247,8 @@
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.selector-list, .inherited-members-list {
|
||||
.selector-list,
|
||||
.inherited-members-list {
|
||||
ul {
|
||||
padding: 0;
|
||||
li {
|
||||
@ -270,7 +259,8 @@
|
||||
}
|
||||
|
||||
.selector-list {
|
||||
li, a {
|
||||
li,
|
||||
a {
|
||||
font-weight: bold;
|
||||
i {
|
||||
font-weight: normal;
|
||||
@ -279,6 +269,39 @@
|
||||
}
|
||||
}
|
||||
|
||||
.breadcrumb-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.api-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: -4px;
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.github-links {
|
||||
float: right;
|
||||
.material-icons {
|
||||
border-radius: 4px;
|
||||
padding: 4px;
|
||||
font-size: 20px;
|
||||
&:hover {
|
||||
background-color: $mist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.deprecated-api-item {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
@ -1,6 +1,11 @@
|
||||
code-example, code-tabs {
|
||||
code-example,
|
||||
code-tabs {
|
||||
clear: both;
|
||||
display: block;
|
||||
|
||||
ol {
|
||||
list-style: decimal;
|
||||
}
|
||||
}
|
||||
|
||||
code-example {
|
||||
|
@ -30,159 +30,160 @@
|
||||
&:hover {
|
||||
color: $accentblue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
button.toc-heading,
|
||||
button.toc-more-items {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
background: 0;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
text-align: start;
|
||||
button {
|
||||
&.toc-heading,
|
||||
&.toc-more-items {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
background: 0;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
text-align: start;
|
||||
|
||||
&.embedded:focus {
|
||||
outline: none;
|
||||
background: $lightgray;
|
||||
}
|
||||
}
|
||||
|
||||
button.toc-heading {
|
||||
mat-icon.rotating-icon {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
position: relative;
|
||||
left: -4px;
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
&:hover:not(.embedded) {
|
||||
color: $accentblue;
|
||||
}
|
||||
}
|
||||
|
||||
button.toc-more-items {
|
||||
color: $mediumgray;
|
||||
top: 10px;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
color: $accentblue;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: 'expand_less';
|
||||
}
|
||||
|
||||
&.collapsed::after {
|
||||
content: 'more_horiz';
|
||||
}
|
||||
}
|
||||
|
||||
.mat-icon {
|
||||
&.collapsed {
|
||||
@include rotate(0deg);
|
||||
}
|
||||
|
||||
&:not(.collapsed) {
|
||||
@include rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
ul.toc-list {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0 8px 0 0;
|
||||
|
||||
@media (max-width: 800px) {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
li {
|
||||
box-sizing: border-box;
|
||||
@include font-size(12);
|
||||
@include line-height(16);
|
||||
padding: 3px 0 3px 12px;
|
||||
position: relative;
|
||||
transition: all 0.3s ease-in-out;
|
||||
|
||||
&.h1:after {
|
||||
content: '';
|
||||
display: block;
|
||||
height: 1px;
|
||||
width: 40%;
|
||||
margin: 7px 0 4px 0;
|
||||
&.embedded:focus {
|
||||
outline: none;
|
||||
background: $lightgray;
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
&.toc-heading {
|
||||
mat-icon.rotating-icon {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
position: relative;
|
||||
left: -4px;
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
&.h3 {
|
||||
padding-left: 24px;
|
||||
&:hover:not(.embedded) {
|
||||
color: $accentblue;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: lighten($darkgray, 10);
|
||||
overflow: visible;
|
||||
@include font-size(12);
|
||||
display: table-cell;
|
||||
}
|
||||
&.toc-more-items {
|
||||
color: $mediumgray;
|
||||
top: 10px;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
* {
|
||||
color: $accentblue;
|
||||
}
|
||||
color: $accentblue;
|
||||
}
|
||||
|
||||
&.active {
|
||||
* {
|
||||
color: $blue;
|
||||
font-weight: 500;
|
||||
&::after {
|
||||
content: 'expand_less';
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
border-radius: 50%;
|
||||
left: -3px;
|
||||
top: 12px;
|
||||
background: $blue;
|
||||
position: absolute;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
&.collapsed::after {
|
||||
content: 'more_horiz';
|
||||
}
|
||||
}
|
||||
|
||||
.mat-icon {
|
||||
&.collapsed {
|
||||
@include rotate(0deg);
|
||||
}
|
||||
|
||||
&:not(.collapsed) {
|
||||
@include rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
ul.toc-list {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0 8px 0 0;
|
||||
|
||||
@media (max-width: 800px) {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
li {
|
||||
box-sizing: border-box;
|
||||
@include font-size(12);
|
||||
@include line-height(16);
|
||||
padding: 3px 0 3px 12px;
|
||||
position: relative;
|
||||
transition: all 0.3s ease-in-out;
|
||||
|
||||
&.h1:after {
|
||||
content: '';
|
||||
display: block;
|
||||
height: 1px;
|
||||
width: 40%;
|
||||
margin: 7px 0 4px 0;
|
||||
background: $lightgray;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
&.h3 {
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: lighten($darkgray, 10);
|
||||
overflow: visible;
|
||||
@include font-size(12);
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
* {
|
||||
color: $accentblue;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
* {
|
||||
color: $blue;
|
||||
font-weight: 500;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
border-radius: 50%;
|
||||
left: -3px;
|
||||
top: 12px;
|
||||
background: $blue;
|
||||
position: absolute;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.embedded) li {
|
||||
&:before {
|
||||
border-left: 1px solid $lightgray;
|
||||
bottom: 0;
|
||||
content: '';
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
&:not(.embedded) li {
|
||||
&:before {
|
||||
border-left: 1px solid $lightgray;
|
||||
bottom: 0;
|
||||
content: '';
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&:first-child:before {
|
||||
top: 13px;
|
||||
}
|
||||
&:first-child:before {
|
||||
top: 13px;
|
||||
}
|
||||
|
||||
&:last-child:before {
|
||||
bottom: calc(100% - 14px);
|
||||
}
|
||||
&:last-child:before {
|
||||
bottom: calc(100% - 14px);
|
||||
}
|
||||
|
||||
&:not(.active):hover a:before {
|
||||
content: '';
|
||||
border-radius: 50%;
|
||||
left: -3px;
|
||||
top: 12px;
|
||||
background: $lightgray;
|
||||
position: absolute;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
&:not(.active):hover a:before {
|
||||
content: '';
|
||||
border-radius: 50%;
|
||||
left: -3px;
|
||||
top: 12px;
|
||||
background: $lightgray;
|
||||
position: absolute;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,25 +84,23 @@ class ExampleZipper {
|
||||
const outputFileName = path.join(outputDirName, relativeDirName, exampleZipName + '.zip');
|
||||
let defaultIncludes = ['**/*.ts', '**/*.js', '**/*.es6', '**/*.css', '**/*.html', '**/*.md', '**/*.json', '**/*.png', '**/*.svg'];
|
||||
let alwaysIncludes = [
|
||||
'bs-config.json',
|
||||
'e2e/protractor.conf.js',
|
||||
'angular.json',
|
||||
'.editorconfig',
|
||||
'.gitignore',
|
||||
'tslint.json',
|
||||
'angular.json',
|
||||
'browserslist',
|
||||
'bs-config.json',
|
||||
'karma.conf.js',
|
||||
'karma-test-shim.js',
|
||||
'tsconfig.json',
|
||||
'src/testing/**/*',
|
||||
'src/.babelrc',
|
||||
'src/browserslist',
|
||||
'tsconfig.*',
|
||||
'tslint.*',
|
||||
'e2e/protractor.conf.js',
|
||||
'e2e/tsconfig.json',
|
||||
'src/favicon.ico',
|
||||
'src/karma.conf.js',
|
||||
'src/polyfills.ts',
|
||||
'src/test.ts',
|
||||
'src/typings.d.ts',
|
||||
'src/environments/**/*',
|
||||
'src/tsconfig.*',
|
||||
'src/tslint.*',
|
||||
'src/testing/**/*',
|
||||
// Only ignore root package.json
|
||||
'!package.json'
|
||||
];
|
||||
|
@ -46,6 +46,8 @@ if (argv.ivy) {
|
||||
* Must be used in conjunction with --setup as this is when the packages are copied.
|
||||
* e.g. --setup --local
|
||||
*
|
||||
* --ivy to turn on `ivy` mode
|
||||
*
|
||||
* --shard to shard the specs into groups to allow you to run them in parallel
|
||||
* e.g. --shard=0/2 // the even specs: 0, 2, 4, etc
|
||||
* e.g. --shard=1/2 // the odd specs: 1, 3, 5, etc
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/app",
|
||||
"types": []
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/spec",
|
||||
"types": [
|
||||
@ -8,8 +8,8 @@
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"test.ts",
|
||||
"polyfills.ts"
|
||||
"src/test.ts",
|
||||
"src/polyfills.ts"
|
||||
],
|
||||
"include": [
|
||||
"src/**/*.spec.ts",
|
||||
|
@ -471,7 +471,7 @@
|
||||
|
||||
"@types/node@~8.9.4":
|
||||
version "8.9.5"
|
||||
resolved "http://registry.npmjs.org/@types/node/-/node-8.9.5.tgz#162b864bc70be077e6db212b322754917929e976"
|
||||
resolved "https://registry.npmjs.org/@types/node/-/node-8.9.5.tgz#162b864bc70be077e6db212b322754917929e976"
|
||||
|
||||
"@types/q@^0.0.32":
|
||||
version "0.0.32"
|
||||
@ -2820,7 +2820,7 @@ express@2.5.x:
|
||||
|
||||
express@^4.14.1:
|
||||
version "4.16.3"
|
||||
resolved "http://registry.npmjs.org/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53"
|
||||
resolved "https://registry.npmjs.org/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53"
|
||||
dependencies:
|
||||
accepts "~1.3.5"
|
||||
array-flatten "1.1.1"
|
||||
@ -3039,7 +3039,7 @@ finalhandler@1.0.6:
|
||||
|
||||
finalhandler@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105"
|
||||
resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105"
|
||||
dependencies:
|
||||
debug "2.6.9"
|
||||
encodeurl "~1.0.2"
|
||||
@ -5592,7 +5592,7 @@ p-finally@^1.0.0:
|
||||
|
||||
p-is-promise@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "http://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e"
|
||||
resolved "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e"
|
||||
|
||||
p-limit@^2.0.0:
|
||||
version "2.0.0"
|
||||
|
@ -14,7 +14,8 @@ const LOCAL_MARKER_PATH = 'node_modules/_local_.json';
|
||||
const PACKAGE_JSON_REGEX = /^[^/]+\/package\.json$/;
|
||||
|
||||
const ANGULAR_ROOT_DIR = path.resolve(__dirname, '../../..');
|
||||
const ANGULAR_DIST_PACKAGES = path.resolve(ANGULAR_ROOT_DIR, 'dist/packages-dist');
|
||||
const ANGULAR_DIST_PACKAGES = path.join(ANGULAR_ROOT_DIR, 'dist/packages-dist');
|
||||
const ANGULAR_DIST_PACKAGES_BUILD_CMD = path.join(ANGULAR_ROOT_DIR, 'scripts/build-packages-dist.sh');
|
||||
|
||||
/**
|
||||
* A tool that can install Angular dependencies for a project from NPM or from the
|
||||
@ -29,16 +30,17 @@ class NgPackagesInstaller {
|
||||
* Create a new installer for a project in the specified directory.
|
||||
*
|
||||
* @param {string} projectDir - the path to the directory containing the project.
|
||||
* @param {object} options - a hash of options for the install
|
||||
* * `debug` (`boolean`) - whether to display debug messages.
|
||||
* * `force` (`boolean`) - whether to force a local installation
|
||||
* even if there is a local marker file.
|
||||
* * `ignorePackages` (`string[]`) - a collection of names of packages
|
||||
* that should not be copied over.
|
||||
* @param {object} options - a hash of options for the install:
|
||||
* * `debug` (`boolean`) - whether to display debug messages.
|
||||
* * `force` (`boolean`) - whether to force a local installation even if there is a local marker file.
|
||||
* * `buildPackages` (`boolean`) - whether to build the local Angular packages before using them.
|
||||
* (NOTE: Building the packages is currently not supported on Windows, so a message is printed instead.)
|
||||
* * `ignorePackages` (`string[]`) - a collection of names of packages that should not be copied over.
|
||||
*/
|
||||
constructor(projectDir, options = {}) {
|
||||
this.debug = options.debug;
|
||||
this.force = options.force;
|
||||
this.debug = this._parseBooleanArg(options.debug);
|
||||
this.force = this._parseBooleanArg(options.force);
|
||||
this.buildPackages = this._parseBooleanArg(options.buildPackages);
|
||||
this.ignorePackages = options.ignorePackages || [];
|
||||
this.projectDir = path.resolve(projectDir);
|
||||
this.localMarkerPath = path.resolve(this.projectDir, LOCAL_MARKER_PATH);
|
||||
@ -160,6 +162,31 @@ class NgPackagesInstaller {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the local Angular packages.
|
||||
*
|
||||
* NOTE:
|
||||
* Building the packages is currently not supported on Windows, so a message is printed instead, prompting the user to
|
||||
* do it themselves (e.g. using Windows Subsystem for Linux or a docker container).
|
||||
*/
|
||||
_buildDistPackages() {
|
||||
const canBuild = process.platform !== 'win32';
|
||||
|
||||
if (canBuild) {
|
||||
this._log(`Building the Angular packages with: ${ANGULAR_DIST_PACKAGES_BUILD_CMD}`);
|
||||
shelljs.exec(ANGULAR_DIST_PACKAGES_BUILD_CMD);
|
||||
} else {
|
||||
this._warn([
|
||||
'Automatically building the local Angular packages is currently not supported on Windows.',
|
||||
`Please, ensure '${ANGULAR_DIST_PACKAGES}' exists and is up-to-date (e.g. by running ` +
|
||||
`'${ANGULAR_DIST_PACKAGES_BUILD_CMD}' in Git Bash for Windows, Windows Subsystem for Linux or a Linux ` +
|
||||
'docker container or VM).',
|
||||
'',
|
||||
'Proceeding anyway...',
|
||||
].join('\n'));
|
||||
}
|
||||
}
|
||||
|
||||
_collectDependencies(dependencies, packages) {
|
||||
const peerDependencies = Object.create(null);
|
||||
const mergedDependencies = Object.assign(Object.create(null), dependencies);
|
||||
@ -184,32 +211,35 @@ class NgPackagesInstaller {
|
||||
|
||||
/**
|
||||
* A hash of Angular package configs.
|
||||
* (Detected as directories in '/packages/' that contain a top-level 'package.json' file.)
|
||||
* (Detected as directories in '/dist/packages-dist/' that contain a top-level 'package.json' file.)
|
||||
*/
|
||||
_getDistPackages() {
|
||||
const packageConfigs = Object.create(null);
|
||||
const distDir = ANGULAR_DIST_PACKAGES;
|
||||
|
||||
[ANGULAR_DIST_PACKAGES].forEach(distDir => {
|
||||
this._log(`Angular distributable directory: ${distDir}.`);
|
||||
shelljs
|
||||
.find(distDir)
|
||||
.map(filePath => filePath.slice(distDir.length + 1))
|
||||
.filter(filePath => PACKAGE_JSON_REGEX.test(filePath))
|
||||
.forEach(packagePath => {
|
||||
const packageName = `@angular/${packagePath.slice(0, -PACKAGE_JSON.length -1)}`;
|
||||
if (this.ignorePackages.indexOf(packageName) === -1) {
|
||||
const packageConfig = require(path.resolve(distDir, packagePath));
|
||||
packageConfigs[packageName] = {
|
||||
parentDir: distDir,
|
||||
packageJsonPath: path.resolve(distDir, packagePath),
|
||||
config: packageConfig
|
||||
};
|
||||
} else {
|
||||
this._log('Ignoring package', packageName);
|
||||
}
|
||||
});
|
||||
this._log(`Angular distributable directory: ${distDir}.`);
|
||||
|
||||
});
|
||||
if (this.buildPackages) {
|
||||
this._buildDistPackages();
|
||||
}
|
||||
|
||||
shelljs
|
||||
.find(distDir)
|
||||
.map(filePath => filePath.slice(distDir.length + 1))
|
||||
.filter(filePath => PACKAGE_JSON_REGEX.test(filePath))
|
||||
.forEach(packagePath => {
|
||||
const packageName = `@angular/${packagePath.slice(0, -PACKAGE_JSON.length -1)}`;
|
||||
if (this.ignorePackages.indexOf(packageName) === -1) {
|
||||
const packageConfig = require(path.resolve(distDir, packagePath));
|
||||
packageConfigs[packageName] = {
|
||||
parentDir: distDir,
|
||||
packageJsonPath: path.resolve(distDir, packagePath),
|
||||
config: packageConfig
|
||||
};
|
||||
} else {
|
||||
this._log('Ignoring package', packageName);
|
||||
}
|
||||
});
|
||||
|
||||
this._log('Found the following Angular distributables:', Object.keys(packageConfigs).map(key => `\n - ${key}`));
|
||||
return packageConfigs;
|
||||
@ -234,6 +264,21 @@ class NgPackagesInstaller {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the value for a boolean cli argument/option. When passing an option multiple times, `yargs` parses it as an
|
||||
* array of boolean values. In that case, we only care about the last occurrence.
|
||||
*
|
||||
* This can be useful, for example, when one has a base command with the option turned on and another command
|
||||
* (building on top of the first one) turning the option off:
|
||||
* ```
|
||||
* "base-command": "my-script --foo --bar",
|
||||
* "no-bar-command": "yarn base-command --no-bar",
|
||||
* ```
|
||||
*/
|
||||
_parseBooleanArg(value) {
|
||||
return Array.isArray(value) ? value.pop() : value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse and return a `yarn.lock` file.
|
||||
*/
|
||||
@ -254,17 +299,28 @@ class NgPackagesInstaller {
|
||||
const restoreCmd = `node ${relativeScriptPath} restore ${absoluteProjectDir}`;
|
||||
|
||||
// Log a warning.
|
||||
this._warn([
|
||||
`The project at "${absoluteProjectDir}" is running against the local Angular build.`,
|
||||
'',
|
||||
'To restore the npm packages run:',
|
||||
'',
|
||||
` "${restoreCmd}"`,
|
||||
].join('\n'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a warning message do draw user's attention.
|
||||
* @param {...string[]} messages - The messages to be logged.
|
||||
*/
|
||||
_warn(...messages) {
|
||||
const lines = messages.join(' ').split('\n');
|
||||
console.warn(chalk.yellow([
|
||||
'',
|
||||
'!'.repeat(110),
|
||||
'!!!',
|
||||
'!!! WARNING',
|
||||
'!!!',
|
||||
`!!! The project at "${absoluteProjectDir}" is running against the local Angular build.`,
|
||||
'!!!',
|
||||
'!!! To restore the npm packages run:',
|
||||
'!!!',
|
||||
`!!! "${restoreCmd}"`,
|
||||
...lines.map(line => `!!! ${line}`),
|
||||
'!!!',
|
||||
'!'.repeat(110),
|
||||
'',
|
||||
@ -287,24 +343,27 @@ class NgPackagesInstaller {
|
||||
function main() {
|
||||
shelljs.set('-e');
|
||||
|
||||
const createInstaller = argv => {
|
||||
const {projectDir, ...options} = argv;
|
||||
return new NgPackagesInstaller(projectDir, options);
|
||||
};
|
||||
|
||||
yargs
|
||||
.usage('$0 <cmd> [args]')
|
||||
|
||||
.option('debug', { describe: 'Print additional debug information.', default: false })
|
||||
.option('force', { describe: 'Force the command to execute even if not needed.', default: false })
|
||||
.option('build-packages', { describe: 'Build the local Angular packages, before using them.', default: false })
|
||||
.option('ignore-packages', { describe: 'List of Angular packages that should not be used in local mode.', default: [], array: true })
|
||||
|
||||
.command('overwrite <projectDir> [--force] [--debug] [--ignore-packages package1 package2]', 'Install dependencies from the locally built Angular distributables.', () => {}, argv => {
|
||||
const installer = new NgPackagesInstaller(argv.projectDir, argv);
|
||||
installer.installLocalDependencies();
|
||||
createInstaller(argv).installLocalDependencies();
|
||||
})
|
||||
.command('restore <projectDir> [--debug]', 'Install dependencies from the npm registry.', () => {}, argv => {
|
||||
const installer = new NgPackagesInstaller(argv.projectDir, argv);
|
||||
installer.restoreNpmDependencies();
|
||||
createInstaller(argv).restoreNpmDependencies();
|
||||
})
|
||||
.command('check <projectDir> [--debug]', 'Check that dependencies came from npm. Otherwise display a warning message.', () => {}, argv => {
|
||||
const installer = new NgPackagesInstaller(argv.projectDir, argv);
|
||||
installer.checkDependencies();
|
||||
createInstaller(argv).checkDependencies();
|
||||
})
|
||||
.demandCommand(1, 'Please supply a command from the list above.')
|
||||
.strict()
|
||||
|
@ -8,13 +8,14 @@ const shelljs = require('shelljs');
|
||||
const NgPackagesInstaller = require('./index');
|
||||
|
||||
describe('NgPackagesInstaller', () => {
|
||||
const rootDir = 'root/dir';
|
||||
const absoluteRootDir = path.resolve(rootDir);
|
||||
const nodeModulesDir = path.resolve(absoluteRootDir, 'node_modules');
|
||||
const packageJsonPath = path.resolve(absoluteRootDir, 'package.json');
|
||||
const yarnLockPath = path.resolve(absoluteRootDir, 'yarn.lock');
|
||||
const packagesDir = path.resolve(path.resolve(__dirname, '../../../dist/packages-dist'));
|
||||
const toolsDir = path.resolve(path.resolve(__dirname, '../../../dist/tools/@angular'));
|
||||
const projectDir = 'root/dir';
|
||||
const absoluteProjectDir = path.resolve(projectDir);
|
||||
const nodeModulesDir = path.resolve(absoluteProjectDir, 'node_modules');
|
||||
const packageJsonPath = path.resolve(absoluteProjectDir, 'package.json');
|
||||
const yarnLockPath = path.resolve(absoluteProjectDir, 'yarn.lock');
|
||||
const ngRootDir = path.resolve(__dirname, '../../..');
|
||||
const packagesDir = path.join(ngRootDir, 'dist/packages-dist');
|
||||
const toolsDir = path.join(ngRootDir, 'dist/tools/@angular');
|
||||
let installer;
|
||||
|
||||
beforeEach(() => {
|
||||
@ -25,7 +26,7 @@ describe('NgPackagesInstaller', () => {
|
||||
spyOn(shelljs, 'rm');
|
||||
spyOn(console, 'log');
|
||||
spyOn(console, 'warn');
|
||||
installer = new NgPackagesInstaller(rootDir);
|
||||
installer = new NgPackagesInstaller(projectDir);
|
||||
});
|
||||
|
||||
describe('checkDependencies()', () => {
|
||||
@ -36,14 +37,14 @@ describe('NgPackagesInstaller', () => {
|
||||
it('should not print a warning if there is no _local_.json file', () => {
|
||||
fs.existsSync.and.returnValue(false);
|
||||
installer.checkDependencies();
|
||||
expect(fs.existsSync).toHaveBeenCalledWith(path.resolve(rootDir, 'node_modules/_local_.json'));
|
||||
expect(fs.existsSync).toHaveBeenCalledWith(path.resolve(projectDir, 'node_modules/_local_.json'));
|
||||
expect(installer._printWarning).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should print a warning if there is a _local_.json file', () => {
|
||||
fs.existsSync.and.returnValue(true);
|
||||
installer.checkDependencies();
|
||||
expect(fs.existsSync).toHaveBeenCalledWith(path.resolve(rootDir, 'node_modules/_local_.json'));
|
||||
expect(fs.existsSync).toHaveBeenCalledWith(path.resolve(projectDir, 'node_modules/_local_.json'));
|
||||
expect(installer._printWarning).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@ -242,7 +243,68 @@ describe('NgPackagesInstaller', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('_buildDistPackages()', () => {
|
||||
// Call `_buildDistPackages()` with a mock `process.platform` value.
|
||||
const buildDistPackagesOnPlatform = platform => {
|
||||
const originalDescriptor = Object.getOwnPropertyDescriptor(process, 'platform');
|
||||
Object.defineProperty(process, 'platform', {...originalDescriptor, value: platform});
|
||||
installer._buildDistPackages();
|
||||
Object.defineProperty(process, 'platform', originalDescriptor);
|
||||
};
|
||||
|
||||
it('should build the local packages, when not on Windows', () => {
|
||||
const buildScript = path.join(ngRootDir, 'scripts/build-packages-dist.sh');
|
||||
|
||||
buildDistPackagesOnPlatform('linux');
|
||||
expect(shelljs.exec).toHaveBeenCalledWith(buildScript);
|
||||
|
||||
shelljs.exec.calls.reset();
|
||||
|
||||
buildDistPackagesOnPlatform('darwin');
|
||||
expect(shelljs.exec).toHaveBeenCalledWith(buildScript);
|
||||
|
||||
shelljs.exec.calls.reset();
|
||||
|
||||
buildDistPackagesOnPlatform('anythingButWindows :(');
|
||||
expect(shelljs.exec).toHaveBeenCalledWith(buildScript);
|
||||
|
||||
// Ensure that the script does actually exist (e.g. it was not renamed/moved).
|
||||
fs.existsSync.and.callThrough();
|
||||
expect(fs.existsSync(buildScript)).toBe(true);
|
||||
});
|
||||
|
||||
it('should print a warning, when on Windows', () => {
|
||||
buildDistPackagesOnPlatform('win32');
|
||||
const warning = console.warn.calls.argsFor(0)[0];
|
||||
|
||||
expect(shelljs.exec).not.toHaveBeenCalled();
|
||||
expect(warning).toContain(
|
||||
'Automatically building the local Angular packages is currently not supported on Windows.');
|
||||
expect(warning).toContain('Git Bash for Windows');
|
||||
expect(warning).toContain('Windows Subsystem for Linux');
|
||||
expect(warning).toContain('Linux docker container or VM');
|
||||
});
|
||||
});
|
||||
|
||||
describe('_getDistPackages()', () => {
|
||||
beforeEach(() => spyOn(NgPackagesInstaller.prototype, '_buildDistPackages'));
|
||||
|
||||
it('should not build the local packages by default', () => {
|
||||
installer._getDistPackages();
|
||||
expect(installer._buildDistPackages).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should build the local packages, if `buildPackages` is true', () => {
|
||||
installer = new NgPackagesInstaller(projectDir, {buildPackages: true});
|
||||
installer._getDistPackages();
|
||||
expect(installer._buildDistPackages).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should not build the local packages by default', () => {
|
||||
installer._getDistPackages();
|
||||
expect(installer._buildDistPackages).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should include top level Angular packages', () => {
|
||||
const ngPackages = installer._getDistPackages();
|
||||
const expectedValue = jasmine.objectContaining({
|
||||
@ -269,7 +331,7 @@ describe('NgPackagesInstaller', () => {
|
||||
});
|
||||
|
||||
it('should not include packages that have been ignored', () => {
|
||||
installer = new NgPackagesInstaller(rootDir, { ignorePackages: ['@angular/router'] });
|
||||
installer = new NgPackagesInstaller(projectDir, { ignorePackages: ['@angular/router'] });
|
||||
const ngPackages = installer._getDistPackages();
|
||||
|
||||
expect(ngPackages['@angular/common']).toBeDefined();
|
||||
@ -283,9 +345,9 @@ describe('NgPackagesInstaller', () => {
|
||||
});
|
||||
|
||||
it('should assign the debug property from the options', () => {
|
||||
installer = new NgPackagesInstaller(rootDir, { debug: true });
|
||||
installer = new NgPackagesInstaller(projectDir, { debug: true });
|
||||
expect(installer.debug).toBe(true);
|
||||
installer = new NgPackagesInstaller(rootDir, { });
|
||||
installer = new NgPackagesInstaller(projectDir, { });
|
||||
expect(installer.debug).toBe(undefined);
|
||||
});
|
||||
|
||||
@ -350,7 +412,7 @@ describe('NgPackagesInstaller', () => {
|
||||
expect(console.warn.calls.argsFor(0)[0]).toMatch(restoreCmdRe1);
|
||||
|
||||
// When run for a different directory...
|
||||
const dir2 = rootDir;
|
||||
const dir2 = projectDir;
|
||||
const restoreCmdRe2 = RegExp(`\\bnode .*?ng-packages-installer/index restore .*?${path.resolve(dir1)}\\b`);
|
||||
installer = new NgPackagesInstaller(dir2);
|
||||
installer._printWarning('');
|
||||
@ -361,14 +423,14 @@ describe('NgPackagesInstaller', () => {
|
||||
describe('_installDeps()', () => {
|
||||
it('should run yarn install with the given options', () => {
|
||||
installer._installDeps('option-1', 'option-2');
|
||||
expect(shelljs.exec).toHaveBeenCalledWith('yarn install option-1 option-2', { cwd: absoluteRootDir });
|
||||
expect(shelljs.exec).toHaveBeenCalledWith('yarn install option-1 option-2', { cwd: absoluteProjectDir });
|
||||
});
|
||||
});
|
||||
|
||||
describe('local marker helpers', () => {
|
||||
let installer;
|
||||
beforeEach(() => {
|
||||
installer = new NgPackagesInstaller(rootDir);
|
||||
installer = new NgPackagesInstaller(projectDir);
|
||||
});
|
||||
|
||||
describe('_checkLocalMarker', () => {
|
||||
|
@ -208,9 +208,9 @@
|
||||
<code>{$ renderMemberSyntax(property) $}</code>
|
||||
</td>
|
||||
<td>
|
||||
{%- if (property.isGetAccessor or property.isReadonly) and not property.isSetAccessor %}<span class='read-only-property'>Read-only.</span>{% endif %}
|
||||
{%- if property.isSetAccessor and not property.isGetAccessor %}<span class='write-only-property'>Write-only.</span>{% endif %}
|
||||
{% if property.constructorParamDoc %} <span class='from-constructor'>Declared in constructor.</span>{% endif %}
|
||||
{%- if (property.isGetAccessor or property.isReadonly) and not property.isSetAccessor %}<span class='read-only-property'>Read-Only</span>{% endif %}
|
||||
{%- if property.isSetAccessor and not property.isGetAccessor %}<span class='write-only-property'>Write-Only</span>{% endif %}
|
||||
{% if property.constructorParamDoc %} <span class='from-constructor'>Declared in Constructor</span>{% endif %}
|
||||
{% if property.shortDescription %}{$ property.shortDescription | marked $}{% endif %}
|
||||
{$ (property.description or property.constructorParamDoc.description) | marked $}
|
||||
{%- if property.see.length %}
|
||||
|
@ -12,7 +12,7 @@
|
||||
"master": {
|
||||
"uncompressed": {
|
||||
"runtime": 1440,
|
||||
"main": 14021,
|
||||
"main": 13517,
|
||||
"polyfills": 43567
|
||||
}
|
||||
}
|
||||
@ -34,4 +34,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -8,8 +8,8 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
# Fetch rules_nodejs so we can install our npm dependencies
|
||||
http_archive(
|
||||
name = "build_bazel_rules_nodejs",
|
||||
sha256 = "6d4edbf28ff6720aedf5f97f9b9a7679401bf7fca9d14a0fff80f644a99992b4",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.32.2/rules_nodejs-0.32.2.tar.gz"],
|
||||
sha256 = "7c4a690268be97c96f04d505224ec4cb1ae53c2c2b68be495c9bd2634296a5cd",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.34.0/rules_nodejs-0.34.0.tar.gz"],
|
||||
)
|
||||
|
||||
# Fetch sass rules for compiling sass files
|
||||
@ -62,6 +62,11 @@ load("@npm//:install_bazel_dependencies.bzl", "install_bazel_dependencies")
|
||||
|
||||
install_bazel_dependencies()
|
||||
|
||||
# Load protractor dependencies
|
||||
load("@npm_bazel_protractor//:package.bzl", "npm_bazel_protractor_dependencies")
|
||||
|
||||
npm_bazel_protractor_dependencies()
|
||||
|
||||
# Load karma dependencies
|
||||
load("@npm_bazel_karma//:package.bzl", "rules_karma_dependencies")
|
||||
|
||||
|
@ -23,11 +23,10 @@
|
||||
"@angular/compiler": "file:../../dist/packages-dist/compiler",
|
||||
"@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli",
|
||||
"@bazel/bazel": "file:../../node_modules/@bazel/bazel",
|
||||
"@bazel/hide-bazel-files": "0.32.2",
|
||||
"@bazel/karma": "0.32.2",
|
||||
"@bazel/typescript": "0.32.2",
|
||||
"@bazel/karma": "0.34.0",
|
||||
"@bazel/protractor": "0.34.0",
|
||||
"@bazel/typescript": "0.34.0",
|
||||
"@types/jasmine": "2.8.8",
|
||||
"protractor": "5.1.2",
|
||||
"typescript": "3.4.2"
|
||||
},
|
||||
"scripts": {
|
||||
|
@ -1,5 +1,5 @@
|
||||
load("@npm_bazel_protractor//:index.bzl", "protractor_web_test_suite")
|
||||
load("@npm_bazel_typescript//:index.bzl", "ts_library")
|
||||
load("@npm_angular_bazel//:index.bzl", "protractor_web_test_suite")
|
||||
|
||||
ts_library(
|
||||
name = "e2e",
|
||||
@ -7,7 +7,7 @@ ts_library(
|
||||
srcs = ["app.spec.ts"],
|
||||
tsconfig = ":tsconfig.json",
|
||||
deps = [
|
||||
"@npm//@types",
|
||||
"@npm//@types/jasmine",
|
||||
"@npm//protractor",
|
||||
],
|
||||
)
|
||||
@ -18,8 +18,8 @@ ts_library(
|
||||
srcs = ["on-prepare.ts"],
|
||||
tsconfig = ":tsconfig.json",
|
||||
deps = [
|
||||
"@npm//@angular/bazel",
|
||||
"@npm//@types",
|
||||
"@npm//@bazel/protractor",
|
||||
"@npm//@types/node",
|
||||
"@npm//protractor",
|
||||
],
|
||||
)
|
||||
@ -27,10 +27,6 @@ ts_library(
|
||||
protractor_web_test_suite(
|
||||
name = "devserver_test",
|
||||
configuration = "//:protractor.conf.js",
|
||||
data = [
|
||||
"@npm//@angular/bazel",
|
||||
"@npm//protractor",
|
||||
],
|
||||
on_prepare = ":ts_on_prepare",
|
||||
server = "//src:devserver",
|
||||
deps = [":e2e"],
|
||||
@ -39,10 +35,6 @@ protractor_web_test_suite(
|
||||
protractor_web_test_suite(
|
||||
name = "prodserver_test",
|
||||
configuration = "//:protractor.conf.js",
|
||||
data = [
|
||||
"@npm//@angular/bazel",
|
||||
"@npm//protractor",
|
||||
],
|
||||
on_prepare = ":ts_on_prepare",
|
||||
server = "//src:prodserver",
|
||||
deps = [":e2e"],
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { browser } from 'protractor';
|
||||
import {OnPrepareConfig, runServer} from '@angular/bazel/protractor-utils';
|
||||
import {OnPrepareConfig, runServer} from '@bazel/protractor/protractor-utils';
|
||||
|
||||
export = function(config: OnPrepareConfig) {
|
||||
const portFlag = /prodserver(\.exe)?$/.test(config.server) ? '-p' : '-port';
|
||||
|
@ -30,12 +30,12 @@
|
||||
rxjs "6.4.0"
|
||||
|
||||
"@angular/animations@file:../../dist/packages-dist/animations":
|
||||
version "8.1.0-next.3"
|
||||
version "8.2.0-next.2"
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
"@angular/bazel@file:../../dist/packages-dist/bazel":
|
||||
version "8.1.0-next.3"
|
||||
version "8.2.0-next.2"
|
||||
dependencies:
|
||||
"@angular-devkit/architect" "^0.800.0-beta.15"
|
||||
"@angular-devkit/core" "^8.0.0-beta.15"
|
||||
@ -57,12 +57,12 @@
|
||||
parse5 "^5.0.0"
|
||||
|
||||
"@angular/common@file:../../dist/packages-dist/common":
|
||||
version "8.1.0-next.3"
|
||||
version "8.2.0-next.2"
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
"@angular/compiler-cli@file:../../dist/packages-dist/compiler-cli":
|
||||
version "8.1.0-next.3"
|
||||
version "8.2.0-next.2"
|
||||
dependencies:
|
||||
canonical-path "1.0.0"
|
||||
chokidar "^2.1.1"
|
||||
@ -76,17 +76,17 @@
|
||||
yargs "13.1.0"
|
||||
|
||||
"@angular/compiler@file:../../dist/packages-dist/compiler":
|
||||
version "8.1.0-next.3"
|
||||
version "8.2.0-next.2"
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
"@angular/core@file:../../dist/packages-dist/core":
|
||||
version "8.1.0-next.3"
|
||||
version "8.2.0-next.2"
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
"@angular/forms@file:../../dist/packages-dist/forms":
|
||||
version "8.1.0-next.3"
|
||||
version "8.2.0-next.2"
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
@ -98,51 +98,53 @@
|
||||
tslib "^1.7.1"
|
||||
|
||||
"@angular/platform-browser-dynamic@file:../../dist/packages-dist/platform-browser-dynamic":
|
||||
version "8.1.0-next.3"
|
||||
version "8.2.0-next.2"
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
"@angular/platform-browser@file:../../dist/packages-dist/platform-browser":
|
||||
version "8.1.0-next.3"
|
||||
version "8.2.0-next.2"
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
"@angular/router@file:../../dist/packages-dist/router":
|
||||
version "8.1.0-next.3"
|
||||
version "8.2.0-next.2"
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
"@bazel/bazel-darwin_x64@0.27.0":
|
||||
version "0.27.0"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/bazel-darwin_x64/-/bazel-darwin_x64-0.27.0.tgz#83a03c92d52ae60e48e86a1ee697e69e12ddbdf6"
|
||||
integrity sha512-CyavIbRKRa/55aMyfEM9hjbt4TVISfv7HLeymHTGTLWzS8uQokQ8W9tR/pgc7YJn8F0x64dd7nQKxhbYHM1Qfg==
|
||||
"@bazel/bazel-darwin_x64@0.28.1":
|
||||
version "0.28.1"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/bazel-darwin_x64/-/bazel-darwin_x64-0.28.1.tgz#415658785e1dbd6f7ab5c8f2b98c1c99c614e1d5"
|
||||
integrity sha512-VDKWmplAfa4uCAbkIQ5nRn04MFQqtsPNuc2HkluJ8OIum773yC2dPR+OlLBKxrlBuKJYB27TtbOwOa6w/uK7aw==
|
||||
|
||||
"@bazel/bazel-linux_x64@0.27.0":
|
||||
version "0.27.0"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/bazel-linux_x64/-/bazel-linux_x64-0.27.0.tgz#2358292aa4901f526ba9b90874256f63d6d6608c"
|
||||
integrity sha512-hO04v7C6M3Jf+qNlLE+IticZZKkkS7Nv6+pXDnENgFWrqLV2H93un6kNQnk83B0hP2cEqRQ8rw5yrIcqXNNuSQ==
|
||||
"@bazel/bazel-linux_x64@0.28.1":
|
||||
version "0.28.1"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/bazel-linux_x64/-/bazel-linux_x64-0.28.1.tgz#f78006089e17660261088272a0e04fc886572e34"
|
||||
integrity sha512-n4XfNxagYhejQD32V4XSxT/qzuH1l/2jxslbKSak66/uQ+wad8Ew9rjNb4JUin3xtrfFtzmxx2jpQkybZsRVGA==
|
||||
|
||||
"@bazel/bazel-win32_x64@0.27.0":
|
||||
version "0.27.0"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/bazel-win32_x64/-/bazel-win32_x64-0.27.0.tgz#0e5e498de5ccccc9a6cf481cd46904ee938ab6c2"
|
||||
integrity sha512-7hIGNhdgaxRt9ceSOCs3eSTtCNi4GXz3nu6OjfgSp+QiqLbW/iAVWa8M8vD5aemZ1BSHek4/LISdWUTncLJk+w==
|
||||
"@bazel/bazel-win32_x64@0.28.1":
|
||||
version "0.28.1"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/bazel-win32_x64/-/bazel-win32_x64-0.28.1.tgz#60a2819618cf7582cc35ac16c01763a5e807b414"
|
||||
integrity sha512-T4xksGfKikaHS4zxnGT6r5R436mz9j2lz//L1vc5sJnaEF/1e2Gv6MLl86vfZW2Xxo6iIEi6ntSzgYxP2Blohw==
|
||||
|
||||
"@bazel/bazel@file:../../node_modules/@bazel/bazel":
|
||||
version "0.27.0"
|
||||
version "0.28.1"
|
||||
dependencies:
|
||||
"@bazel/hide-bazel-files" latest
|
||||
optionalDependencies:
|
||||
"@bazel/bazel-darwin_x64" "0.27.0"
|
||||
"@bazel/bazel-linux_x64" "0.27.0"
|
||||
"@bazel/bazel-win32_x64" "0.27.0"
|
||||
"@bazel/bazel-darwin_x64" "0.28.1"
|
||||
"@bazel/bazel-linux_x64" "0.28.1"
|
||||
"@bazel/bazel-win32_x64" "0.28.1"
|
||||
|
||||
"@bazel/hide-bazel-files@0.32.2":
|
||||
version "0.32.2"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/hide-bazel-files/-/hide-bazel-files-0.32.2.tgz#a482855eafbccb56b1fce0d92ff922c2c6e0a90c"
|
||||
integrity sha512-585XY53mhMZaCjEQJ+aDqkmydWZbuXsKrZsSpoW9YeAVEH0poQY3YhdyCPmMVBo7/l1mkrqpFuOK5BpECfwdtA==
|
||||
"@bazel/hide-bazel-files@latest":
|
||||
version "0.34.0"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/hide-bazel-files/-/hide-bazel-files-0.34.0.tgz#368ea84db2756ff80ead23bb9eb179e9ed24b462"
|
||||
integrity sha512-suyO6cZf8iV6W2LkM1X1spWBt7CsRRXH7gU1wYNuAuHYkkfI0A6qj84yPiIXiOt/2G44kbioGyC1bUsI3fKv7A==
|
||||
|
||||
"@bazel/karma@0.32.2":
|
||||
version "0.32.2"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/karma/-/karma-0.32.2.tgz#0f6adf0cf1970c50cfdcf9cb2b10a8d3e21731fe"
|
||||
integrity sha512-iWb8aqE+llpZhlreDweM7llwnSAQ9QTYdz4VvIcZBGVD0KtHxHaKiqK4Zo4Qrmr9H0kcOhT7nvRBg3QOUJVrUw==
|
||||
"@bazel/karma@0.34.0":
|
||||
version "0.34.0"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/karma/-/karma-0.34.0.tgz#ee468501a408244a2c1844b48ca5a938874d9444"
|
||||
integrity sha512-9EziieE3Zkf7D5tBuX4rO+hhpI4ypNAWReiO/fykjj5oYpLYhhhGGUyFQ8PCIfduPcGZooCTMsctmwZJUb3rRA==
|
||||
dependencies:
|
||||
jasmine-core "2.8.0"
|
||||
karma "^4.0.0"
|
||||
@ -156,10 +158,17 @@
|
||||
semver "5.6.0"
|
||||
tmp "0.0.33"
|
||||
|
||||
"@bazel/typescript@0.32.2":
|
||||
version "0.32.2"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/typescript/-/typescript-0.32.2.tgz#c296bb44cb6362a0e3a08ca88752852bc9591ecf"
|
||||
integrity sha512-32zDyvHdYjIa63vtImhl6wy5ErOFVWPkjMT2T035D0UPSKI1tvENW/bRZ3QFlFHqfmJZRBpaI3GiUpO3vUvzmw==
|
||||
"@bazel/protractor@0.34.0":
|
||||
version "0.34.0"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/protractor/-/protractor-0.34.0.tgz#af166306518bf1319e8ca255f798712c8714b5e9"
|
||||
integrity sha512-U6O8hRlerkQ/WfnEVct1yipVQr5epdYaLiOW1eLpmiRMM4RuMhIpIyKkpum5xqFlYP5kwqwje8BS8NHvBfvZnQ==
|
||||
dependencies:
|
||||
protractor "^5.4.2"
|
||||
|
||||
"@bazel/typescript@0.34.0":
|
||||
version "0.34.0"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/typescript/-/typescript-0.34.0.tgz#ca0fdf15343a930fc1418dbbf7d6cae49e6bc89b"
|
||||
integrity sha512-GXVSADXdbPyWLskIYAzQsBB1LhZgWF5+M6WCQGOvRWjZfXgRP5QDG5pKJavRGzVd6ofigLPA1xT6Vc7dUEDNtg==
|
||||
dependencies:
|
||||
protobufjs "6.8.8"
|
||||
semver "5.6.0"
|
||||
@ -327,20 +336,15 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.9.tgz#2e8d678039d27943ce53a1913386133227fd9066"
|
||||
integrity sha512-NelG/dSahlXYtSoVPErrp06tYFrvzj8XLWmKA+X8x0W//4MqbUyZu++giUG/v0bjAT6/Qxa8IjodrfdACyb0Fg==
|
||||
|
||||
"@types/node@^6.0.46":
|
||||
version "6.14.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-6.14.6.tgz#31df045b4c7618ff74d84f542fc3d29445dd566b"
|
||||
integrity sha512-rFs9zCFtSHuseiNXxYxFlun8ibu+jtZPgRM+2ILCmeLiGeGLiIGxuOzD+cNyHegI1GD+da3R/cIbs9+xCLp13w==
|
||||
|
||||
"@types/q@^0.0.32":
|
||||
version "0.0.32"
|
||||
resolved "https://registry.yarnpkg.com/@types/q/-/q-0.0.32.tgz#bd284e57c84f1325da702babfc82a5328190c0c5"
|
||||
integrity sha1-vShOV8hPEyXacCur/IKlMoGQwMU=
|
||||
|
||||
"@types/selenium-webdriver@^2.53.35", "@types/selenium-webdriver@~2.53.39":
|
||||
version "2.53.43"
|
||||
resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-2.53.43.tgz#2de3d718819bc20165754c4a59afb7e9833f6707"
|
||||
integrity sha512-UBYHWph6P3tutkbXpW6XYg9ZPbTKjw/YC2hGG1/GEvWwTbvezBUv3h+mmUFw79T3RFPnmedpiXdOBbXX+4l0jg==
|
||||
"@types/selenium-webdriver@^3.0.0":
|
||||
version "3.0.16"
|
||||
resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-3.0.16.tgz#50a4755f8e33edacd9c406729e9b930d2451902a"
|
||||
integrity sha512-lMC2G0ItF2xv4UCiwbJGbnJlIuUixHrioOhNGHSCsYCJ8l4t9hMCUimCytvFv7qy6AfSzRxhRHoGa+UqaqwyeA==
|
||||
|
||||
"@types/z-schema@3.16.31":
|
||||
version "3.16.31"
|
||||
@ -360,12 +364,7 @@ accepts@~1.3.4:
|
||||
mime-types "~2.1.24"
|
||||
negotiator "0.6.2"
|
||||
|
||||
adm-zip@0.4.4:
|
||||
version "0.4.4"
|
||||
resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.4.tgz#a61ed5ae6905c3aea58b3a657d25033091052736"
|
||||
integrity sha1-ph7VrmkFw66lizplfSUDMJEFJzY=
|
||||
|
||||
adm-zip@^0.4.7, adm-zip@^0.4.9, adm-zip@~0.4.3:
|
||||
adm-zip@^0.4.9, adm-zip@~0.4.3:
|
||||
version "0.4.13"
|
||||
resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.13.tgz#597e2f8cc3672151e1307d3e95cddbc75672314a"
|
||||
integrity sha512-fERNJX8sOXfel6qCBCMPvZLzENBEhZTzKqg6vrOW5pvoEaQuJhRU4ndTAh6lHOxn1I6jnz2NHra56ZODM751uw==
|
||||
@ -375,14 +374,6 @@ after@0.8.2:
|
||||
resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
|
||||
integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=
|
||||
|
||||
agent-base@2:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.1.1.tgz#d6de10d5af6132d5bd692427d46fc538539094c7"
|
||||
integrity sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=
|
||||
dependencies:
|
||||
extend "~3.0.0"
|
||||
semver "~5.0.1"
|
||||
|
||||
agent-base@^4.1.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
|
||||
@ -601,10 +592,10 @@ blob@0.0.5:
|
||||
resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683"
|
||||
integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==
|
||||
|
||||
blocking-proxy@0.0.5:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.yarnpkg.com/blocking-proxy/-/blocking-proxy-0.0.5.tgz#462905e0dcfbea970f41aa37223dda9c07b1912b"
|
||||
integrity sha1-RikF4Nz76pcPQao3Ij3anAexkSs=
|
||||
blocking-proxy@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/blocking-proxy/-/blocking-proxy-1.0.1.tgz#81d6fd1fe13a4c0d6957df7f91b75e98dac40cb2"
|
||||
integrity sha512-KE8NFMZr3mN2E0HcvCgRtX7DjhiIQrwle+nSVJVC/yqFb9+xznHl2ZcoBp2L9qzkI4t4cBFJ1efXF8Dwi132RA==
|
||||
dependencies:
|
||||
minimist "^1.2.0"
|
||||
|
||||
@ -653,6 +644,13 @@ braces@^2.3.1, braces@^2.3.2:
|
||||
split-string "^3.0.2"
|
||||
to-regex "^3.0.1"
|
||||
|
||||
browserstack@^1.5.1:
|
||||
version "1.5.2"
|
||||
resolved "https://registry.yarnpkg.com/browserstack/-/browserstack-1.5.2.tgz#17d8bb76127a1cc0ea416424df80d218f803673f"
|
||||
integrity sha512-+6AFt9HzhKykcPF79W6yjEUJcdvZOV0lIXdkORXMJftGrDl0OKWqRF4GHqpDNkxiceDT/uB7Fb/aDwktvXX7dg==
|
||||
dependencies:
|
||||
https-proxy-agent "^2.2.1"
|
||||
|
||||
buffer-alloc-unsafe@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
|
||||
@ -905,7 +903,7 @@ date-format@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/date-format/-/date-format-2.0.0.tgz#7cf7b172f1ec564f0003b39ea302c5498fb98c8f"
|
||||
integrity sha512-M6UqVvZVgFYqZL1SfHsRGIQSz3ZL+qgbsV5Lp1Vj61LZVYuEwcMXYay7DRDtYs2HQQBK5hQtQ0fD9aEJ89V0LA==
|
||||
|
||||
debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
|
||||
debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
|
||||
@ -1171,7 +1169,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2:
|
||||
assign-symbols "^1.0.0"
|
||||
is-extendable "^1.0.1"
|
||||
|
||||
extend@3, extend@^3.0.0, extend@~3.0.0, extend@~3.0.2:
|
||||
extend@^3.0.0, extend@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||
@ -1486,15 +1484,6 @@ http-signature@~1.2.0:
|
||||
jsprim "^1.2.2"
|
||||
sshpk "^1.7.0"
|
||||
|
||||
https-proxy-agent@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz#35f7da6c48ce4ddbfa264891ac593ee5ff8671e6"
|
||||
integrity sha1-NffabEjOTdv6JkiRrFk+5f+GceY=
|
||||
dependencies:
|
||||
agent-base "2"
|
||||
debug "2"
|
||||
extend "3"
|
||||
|
||||
https-proxy-agent@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0"
|
||||
@ -1748,7 +1737,7 @@ isstream@~0.1.2:
|
||||
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
||||
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
|
||||
|
||||
jasmine-core@2.8.0:
|
||||
jasmine-core@2.8.0, jasmine-core@~2.8.0:
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.8.0.tgz#bcc979ae1f9fd05701e45e52e65d3a5d63f1a24e"
|
||||
integrity sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=
|
||||
@ -1758,19 +1747,14 @@ jasmine-core@^3.3:
|
||||
resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.4.0.tgz#2a74618e966026530c3518f03e9f845d26473ce3"
|
||||
integrity sha512-HU/YxV4i6GcmiH4duATwAbJQMlE0MsDIR5XmSVxURxKHn3aGAdbY1/ZJFmVRbKtnLwIxxMJD7gYaPsypcbYimg==
|
||||
|
||||
jasmine-core@~2.99.0:
|
||||
version "2.99.1"
|
||||
resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.99.1.tgz#e6400df1e6b56e130b61c4bcd093daa7f6e8ca15"
|
||||
integrity sha1-5kAN8ea1bhMLYcS80JPap/boyhU=
|
||||
|
||||
jasmine@^2.5.3:
|
||||
version "2.99.0"
|
||||
resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-2.99.0.tgz#8ca72d102e639b867c6489856e0e18a9c7aa42b7"
|
||||
integrity sha1-jKctEC5jm4Z8ZImFbg4YqceqQrc=
|
||||
jasmine@2.8.0:
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-2.8.0.tgz#6b089c0a11576b1f16df11b80146d91d4e8b8a3e"
|
||||
integrity sha1-awicChFXax8W3xG4AUbZHU6Lij4=
|
||||
dependencies:
|
||||
exit "^0.1.2"
|
||||
glob "^7.0.6"
|
||||
jasmine-core "~2.99.0"
|
||||
jasmine-core "~2.8.0"
|
||||
|
||||
jasminewd2@^2.1.0:
|
||||
version "2.2.0"
|
||||
@ -1819,6 +1803,16 @@ jsprim@^1.2.2:
|
||||
json-schema "0.2.3"
|
||||
verror "1.10.0"
|
||||
|
||||
jszip@^3.1.3:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.2.2.tgz#b143816df7e106a9597a94c77493385adca5bd1d"
|
||||
integrity sha512-NmKajvAFQpbg3taXQXr/ccS2wcucR1AZ+NtyWp2Nq7HHVsXhcJFR8p0Baf32C2yVvBylFWVeKf+WI2AnvlPhpA==
|
||||
dependencies:
|
||||
lie "~3.3.0"
|
||||
pako "~1.0.2"
|
||||
readable-stream "~2.3.6"
|
||||
set-immediate-shim "~1.0.1"
|
||||
|
||||
jszip@^3.1.5:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.2.1.tgz#c5d32df7274042282b157efb16e522b43435e01a"
|
||||
@ -2308,11 +2302,6 @@ optimist@^0.6.1, optimist@~0.6.0:
|
||||
minimist "~0.0.1"
|
||||
wordwrap "~0.0.2"
|
||||
|
||||
options@>=0.0.5:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f"
|
||||
integrity sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=
|
||||
|
||||
os-homedir@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
|
||||
@ -2489,25 +2478,25 @@ protobufjs@6.8.8:
|
||||
"@types/node" "^10.1.0"
|
||||
long "^4.0.0"
|
||||
|
||||
protractor@5.1.2:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/protractor/-/protractor-5.1.2.tgz#9b221741709a4c62d5cd53c6aadd54a71137e95f"
|
||||
integrity sha1-myIXQXCaTGLVzVPGqt1UpxE36V8=
|
||||
protractor@^5.4.2:
|
||||
version "5.4.2"
|
||||
resolved "https://registry.yarnpkg.com/protractor/-/protractor-5.4.2.tgz#329efe37f48b2141ab9467799be2d4d12eb48c13"
|
||||
integrity sha512-zlIj64Cr6IOWP7RwxVeD8O4UskLYPoyIcg0HboWJL9T79F1F0VWtKkGTr/9GN6BKL+/Q/GmM7C9kFVCfDbP5sA==
|
||||
dependencies:
|
||||
"@types/node" "^6.0.46"
|
||||
"@types/q" "^0.0.32"
|
||||
"@types/selenium-webdriver" "~2.53.39"
|
||||
blocking-proxy "0.0.5"
|
||||
"@types/selenium-webdriver" "^3.0.0"
|
||||
blocking-proxy "^1.0.0"
|
||||
browserstack "^1.5.1"
|
||||
chalk "^1.1.3"
|
||||
glob "^7.0.3"
|
||||
jasmine "^2.5.3"
|
||||
jasmine "2.8.0"
|
||||
jasminewd2 "^2.1.0"
|
||||
optimist "~0.6.0"
|
||||
q "1.4.1"
|
||||
saucelabs "~1.3.0"
|
||||
selenium-webdriver "3.0.1"
|
||||
saucelabs "^1.5.0"
|
||||
selenium-webdriver "3.6.0"
|
||||
source-map-support "~0.4.0"
|
||||
webdriver-js-extender "^1.0.0"
|
||||
webdriver-js-extender "2.1.0"
|
||||
webdriver-manager "^12.0.6"
|
||||
|
||||
pseudomap@^1.0.2:
|
||||
@ -2774,44 +2763,21 @@ saucelabs@^1.5.0:
|
||||
dependencies:
|
||||
https-proxy-agent "^2.2.1"
|
||||
|
||||
saucelabs@~1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/saucelabs/-/saucelabs-1.3.0.tgz#d240e8009df7fa87306ec4578a69ba3b5c424fee"
|
||||
integrity sha1-0kDoAJ33+ocwbsRXimm6O1xCT+4=
|
||||
dependencies:
|
||||
https-proxy-agent "^1.0.0"
|
||||
|
||||
sax@0.6.x:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-0.6.1.tgz#563b19c7c1de892e09bfc4f2fc30e3c27f0952b9"
|
||||
integrity sha1-VjsZx8HeiS4Jv8Ty/DDjwn8JUrk=
|
||||
|
||||
sax@>=0.6.0, sax@^1.2.4:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
||||
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
|
||||
|
||||
selenium-webdriver@3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-3.0.1.tgz#a2dea5da4a97f6672e89e7ca7276cefa365147a7"
|
||||
integrity sha1-ot6l2kqX9mcuiefKcnbO+jZRR6c=
|
||||
selenium-webdriver@3.6.0, selenium-webdriver@^3.0.1:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz#2ba87a1662c020b8988c981ae62cb2a01298eafc"
|
||||
integrity sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==
|
||||
dependencies:
|
||||
adm-zip "^0.4.7"
|
||||
jszip "^3.1.3"
|
||||
rimraf "^2.5.4"
|
||||
tmp "0.0.30"
|
||||
xml2js "^0.4.17"
|
||||
|
||||
selenium-webdriver@^2.53.2:
|
||||
version "2.53.3"
|
||||
resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-2.53.3.tgz#d29ff5a957dff1a1b49dc457756e4e4bfbdce085"
|
||||
integrity sha1-0p/1qVff8aG0ncRXdW5OS/vc4IU=
|
||||
dependencies:
|
||||
adm-zip "0.4.4"
|
||||
rimraf "^2.2.8"
|
||||
tmp "0.0.24"
|
||||
ws "^1.0.1"
|
||||
xml2js "0.4.4"
|
||||
|
||||
selenium-webdriver@^4.0.0-alpha.1:
|
||||
version "4.0.0-alpha.3"
|
||||
resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.0.0-alpha.3.tgz#fb974f29696a6801ecaf203e38a65c3dbe7e363a"
|
||||
@ -2832,11 +2798,6 @@ semver@^5.3.0, semver@^5.5.0, semver@^5.6.0:
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b"
|
||||
integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==
|
||||
|
||||
semver@~5.0.1:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.0.3.tgz#77466de589cd5d3c95f138aa78bc569a3cb5d27a"
|
||||
integrity sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=
|
||||
|
||||
set-blocking@^2.0.0, set-blocking@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
|
||||
@ -3158,11 +3119,6 @@ tar@^4:
|
||||
safe-buffer "^5.1.2"
|
||||
yallist "^3.0.3"
|
||||
|
||||
tmp@0.0.24:
|
||||
version "0.0.24"
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.24.tgz#d6a5e198d14a9835cc6f2d7c3d9e302428c8cf12"
|
||||
integrity sha1-1qXhmNFKmDXMby18PZ4wJCjIzxI=
|
||||
|
||||
tmp@0.0.30:
|
||||
version "0.0.30"
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.30.tgz#72419d4a8be7d6ce75148fd8b324e593a711c2ed"
|
||||
@ -3276,11 +3232,6 @@ typescript@~3.4.3:
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.4.5.tgz#2d2618d10bb566572b8d7aad5180d84257d70a99"
|
||||
integrity sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==
|
||||
|
||||
ultron@1.0.x:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa"
|
||||
integrity sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=
|
||||
|
||||
ultron@~1.1.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c"
|
||||
@ -3378,13 +3329,13 @@ void-elements@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
|
||||
integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=
|
||||
|
||||
webdriver-js-extender@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/webdriver-js-extender/-/webdriver-js-extender-1.0.0.tgz#81c533a9e33d5bfb597b4e63e2cdb25b54777515"
|
||||
integrity sha1-gcUzqeM9W/tZe05j4s2yW1R3dRU=
|
||||
webdriver-js-extender@2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz#57d7a93c00db4cc8d556e4d3db4b5db0a80c3bb7"
|
||||
integrity sha512-lcUKrjbBfCK6MNsh7xaY2UAUmZwe+/ib03AjVOpFobX4O7+83BUveSrLfU0Qsyb1DaKJdQRbuU+kM9aZ6QUhiQ==
|
||||
dependencies:
|
||||
"@types/selenium-webdriver" "^2.53.35"
|
||||
selenium-webdriver "^2.53.2"
|
||||
"@types/selenium-webdriver" "^3.0.0"
|
||||
selenium-webdriver "^3.0.1"
|
||||
|
||||
webdriver-manager@^12.0.6:
|
||||
version "12.1.5"
|
||||
@ -3440,14 +3391,6 @@ wrappy@1:
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||
|
||||
ws@^1.0.1:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.5.tgz#cbd9e6e75e09fc5d2c90015f21f0c40875e0dd51"
|
||||
integrity sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==
|
||||
dependencies:
|
||||
options ">=0.0.5"
|
||||
ultron "1.0.x"
|
||||
|
||||
ws@~3.3.1:
|
||||
version "3.3.3"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2"
|
||||
@ -3457,14 +3400,6 @@ ws@~3.3.1:
|
||||
safe-buffer "~5.1.0"
|
||||
ultron "~1.1.0"
|
||||
|
||||
xml2js@0.4.4:
|
||||
version "0.4.4"
|
||||
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.4.tgz#3111010003008ae19240eba17497b57c729c555d"
|
||||
integrity sha1-MREBAAMAiuGSQOuhdJe1fHKcVV0=
|
||||
dependencies:
|
||||
sax "0.6.x"
|
||||
xmlbuilder ">=1.0.0"
|
||||
|
||||
xml2js@^0.4.17, xml2js@^0.4.19:
|
||||
version "0.4.19"
|
||||
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7"
|
||||
@ -3473,11 +3408,6 @@ xml2js@^0.4.17, xml2js@^0.4.19:
|
||||
sax ">=0.6.0"
|
||||
xmlbuilder "~9.0.1"
|
||||
|
||||
xmlbuilder@>=1.0.0:
|
||||
version "13.0.2"
|
||||
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-13.0.2.tgz#02ae33614b6a047d1c32b5389c1fdacb2bce47a7"
|
||||
integrity sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ==
|
||||
|
||||
xmlbuilder@~9.0.1:
|
||||
version "9.0.7"
|
||||
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
|
||||
|
@ -45,7 +45,7 @@
|
||||
"karma-jasmine-html-reporter": "^0.2.2",
|
||||
"protractor": "file:../../node_modules/protractor",
|
||||
"ts-node": "~7.0.0",
|
||||
"tslint": "~5.11.0",
|
||||
"tslint": "~5.18.0",
|
||||
"typescript": "file:../../node_modules/typescript"
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@
|
||||
"karma-jasmine-html-reporter": "^0.2.2",
|
||||
"protractor": "file:../../node_modules/protractor",
|
||||
"ts-node": "~7.0.0",
|
||||
"tslint": "~5.11.0",
|
||||
"tslint": "~5.18.0",
|
||||
"typescript": "file:../../node_modules/typescript"
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@
|
||||
"karma-jasmine-html-reporter": "^0.2.2",
|
||||
"protractor": "file:../../node_modules/protractor",
|
||||
"ts-node": "~4.1.0",
|
||||
"tslint": "~5.13.0",
|
||||
"tslint": "~5.18.0",
|
||||
"typescript": "file:../../node_modules/typescript"
|
||||
}
|
||||
}
|
||||
|
@ -8084,7 +8084,7 @@ through2@^2.0.0:
|
||||
|
||||
"through@>=2.2.7 <3", through@X.X.X, through@^2.3.6:
|
||||
version "2.3.8"
|
||||
resolved "http://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
|
||||
|
||||
thunkify@~2.1.1:
|
||||
|
@ -20,12 +20,12 @@
|
||||
],
|
||||
"textSpan": {
|
||||
"start": {
|
||||
"line": 7,
|
||||
"offset": 30
|
||||
"line": 5,
|
||||
"offset": 26
|
||||
},
|
||||
"end": {
|
||||
"line": 7,
|
||||
"offset": 47
|
||||
"line": 5,
|
||||
"offset": 30
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
"request_seq": 2,
|
||||
"success": true,
|
||||
"body": {
|
||||
"kind": "",
|
||||
"kind": "property",
|
||||
"kindModifiers": "",
|
||||
"start": {
|
||||
"line": 5,
|
||||
@ -15,7 +15,7 @@
|
||||
"line": 5,
|
||||
"offset": 30
|
||||
},
|
||||
"displayString": "property name of AppComponent",
|
||||
"displayString": "(property) AppComponent.name",
|
||||
"documentation": "",
|
||||
"tags": []
|
||||
}
|
||||
|
@ -67,8 +67,15 @@ if [[ $? != 0 ]]; then exit 1; fi
|
||||
grep "_MatMenuBase.ngBaseDef = ɵngcc0.ɵɵdefineBase({ inputs: {" node_modules/@angular/material/esm5/menu.es5.js
|
||||
if [[ $? != 0 ]]; then exit 1; fi
|
||||
|
||||
# Did it handle namespace imported decorators in UMD?
|
||||
# Did it handle namespace imported decorators in UMD using `__decorate` syntax?
|
||||
grep "type: core.Injectable" node_modules/@angular/common/bundles/common.umd.js
|
||||
# (and ensure the @angular/common package is indeed using `__decorate` syntax)
|
||||
grep "JsonPipe = __decorate(" node_modules/@angular/common/bundles/common.umd.js.__ivy_ngcc_bak
|
||||
|
||||
# Did it handle namespace imported decorators in UMD using static properties?
|
||||
grep "type: core.Injectable," node_modules/@angular/cdk/bundles/cdk-a11y.umd.js
|
||||
# (and ensure the @angular/cdk/a11y package is indeed using static properties)
|
||||
grep "FocusMonitor.decorators =" node_modules/@angular/cdk/bundles/cdk-a11y.umd.js.__ivy_ngcc_bak
|
||||
|
||||
# Can it be safely run again (as a noop)?
|
||||
# And check that it logged skipping compilation as expected
|
||||
|
@ -4,7 +4,7 @@
|
||||
"experimentalDecorators": true,
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"outDir": "../../dist/typings_test_ts32/",
|
||||
"outDir": "../../dist/typings_test_ts34/",
|
||||
"rootDir": ".",
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
|
@ -4,7 +4,7 @@
|
||||
"experimentalDecorators": true,
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"outDir": "../../dist/typings_test_ts32/",
|
||||
"outDir": "../../dist/typings_test_ts35/",
|
||||
"rootDir": ".",
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
|
@ -1,4 +1,4 @@
|
||||
load("//packages/bazel:index.bzl", "protractor_web_test_suite")
|
||||
load("@npm_bazel_protractor//:index.bzl", "protractor_web_test_suite")
|
||||
|
||||
"""
|
||||
Macro that can be used to define a benchmark test. This differentiates from
|
||||
@ -18,7 +18,6 @@ def benchmark_test(name, server, deps, tags = []):
|
||||
server = server,
|
||||
tags = tags,
|
||||
deps = [
|
||||
"@npm//protractor",
|
||||
"@npm//yargs",
|
||||
] + deps,
|
||||
)
|
||||
|
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
const protractorUtils = require('@angular/bazel/protractor-utils');
|
||||
const protractorUtils = require('@bazel/protractor/protractor-utils');
|
||||
const protractor = require('protractor');
|
||||
|
||||
module.exports = async function(config) {
|
||||
|
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
const protractorUtils = require('@angular/bazel/protractor-utils');
|
||||
const protractorUtils = require('@bazel/protractor/protractor-utils');
|
||||
const protractor = require('protractor');
|
||||
|
||||
module.exports = async function(config) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
load("//packages/bazel:index.bzl", "protractor_web_test_suite")
|
||||
load("@npm_bazel_protractor//:index.bzl", "protractor_web_test_suite")
|
||||
load("//tools:defaults.bzl", "ts_library")
|
||||
|
||||
def example_test(name, srcs, server, data = [], **kwargs):
|
||||
@ -18,12 +18,11 @@ def example_test(name, srcs, server, data = [], **kwargs):
|
||||
|
||||
protractor_web_test_suite(
|
||||
name = "protractor_tests",
|
||||
data = ["//packages/bazel/src/protractor/utils"] + data,
|
||||
data = data,
|
||||
on_prepare = "//modules/playground/e2e_test:start-server.js",
|
||||
server = server,
|
||||
deps = [
|
||||
":%s_lib" % name,
|
||||
"@npm//protractor",
|
||||
"@npm//selenium-webdriver",
|
||||
"@npm//yargs",
|
||||
"@npm//source-map",
|
||||
|
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
const protractorUtils = require('@angular/bazel/protractor-utils');
|
||||
const protractorUtils = require('@bazel/protractor/protractor-utils');
|
||||
const protractor = require('protractor');
|
||||
|
||||
module.exports = async function(config) {
|
||||
|
12
package.json
12
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "angular-srcs",
|
||||
"version": "8.2.0-next.2",
|
||||
"version": "9.0.0-next.2",
|
||||
"private": true,
|
||||
"description": "Angular - a web framework for modern web apps",
|
||||
"homepage": "https://github.com/angular/angular",
|
||||
@ -35,10 +35,10 @@
|
||||
"@angular-devkit/core": "^8.0.0-beta.15",
|
||||
"@angular-devkit/schematics": "^8.0.0-beta.15",
|
||||
"@angular/bazel": "file:./tools/npm/@angular_bazel",
|
||||
"@bazel/jasmine": "0.32.2",
|
||||
"@bazel/hide-bazel-files": "0.32.2",
|
||||
"@bazel/karma": "0.32.2",
|
||||
"@bazel/typescript": "0.32.2",
|
||||
"@bazel/jasmine": "0.34.0",
|
||||
"@bazel/karma": "0.34.0",
|
||||
"@bazel/protractor": "0.34.0",
|
||||
"@bazel/typescript": "0.34.0",
|
||||
"@microsoft/api-extractor": "^7.0.21",
|
||||
"@schematics/angular": "^8.0.0-beta.15",
|
||||
"@types/angular": "^1.6.47",
|
||||
@ -120,7 +120,7 @@
|
||||
"// 3": "when updating @bazel/bazel version you also need to update the RBE settings in .bazelrc (see https://github.com/angular/angular/pull/27935)",
|
||||
"devDependencies": {
|
||||
"@angular/cli": "^8.0.0-beta.15",
|
||||
"@bazel/bazel": "0.27.0",
|
||||
"@bazel/bazel": "0.28.1",
|
||||
"@bazel/buildifier": "^0.26.0",
|
||||
"@bazel/ibazel": "~0.9.0",
|
||||
"@types/minimist": "^1.2.0",
|
||||
|
@ -25,12 +25,13 @@ def rules_angular_dev_dependencies():
|
||||
"""
|
||||
|
||||
# Needed for Remote Execution
|
||||
# https://github.com/bazelbuild/bazel-toolchains/releases
|
||||
_maybe(
|
||||
http_archive,
|
||||
name = "bazel_toolchains",
|
||||
sha256 = "4598bf5a8b4f5ced82c782899438a7ba695165d47b3bf783ce774e89a8c6e617",
|
||||
strip_prefix = "bazel-toolchains-0.27.0",
|
||||
url = "https://github.com/bazelbuild/bazel-toolchains/archive/0.27.0.tar.gz",
|
||||
sha256 = "dcb58e7e5f0b4da54c6c5f8ebc65e63fcfb37414466010cf82ceff912162296e",
|
||||
strip_prefix = "bazel-toolchains-0.28.2",
|
||||
url = "https://github.com/bazelbuild/bazel-toolchains/archive/0.28.2.tar.gz",
|
||||
)
|
||||
|
||||
#############################################
|
||||
|
@ -15,8 +15,8 @@ workspace(
|
||||
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
RULES_NODEJS_VERSION = "0.32.2"
|
||||
RULES_NODEJS_SHA256 = "6d4edbf28ff6720aedf5f97f9b9a7679401bf7fca9d14a0fff80f644a99992b4"
|
||||
RULES_NODEJS_VERSION = "0.34.0"
|
||||
RULES_NODEJS_SHA256 = "7c4a690268be97c96f04d505224ec4cb1ae53c2c2b68be495c9bd2634296a5cd"
|
||||
http_archive(
|
||||
name = "build_bazel_rules_nodejs",
|
||||
sha256 = RULES_NODEJS_SHA256,
|
||||
@ -63,8 +63,6 @@ node_repositories(
|
||||
|
||||
yarn_install(
|
||||
name = "npm",
|
||||
# TODO(gregmagolan): fix rules_nodejs so that if @bazel/hide-bazel-files is detected then this is forced true
|
||||
always_hide_bazel_files = True,
|
||||
package_json = "//:package.json",
|
||||
yarn_lock = "//:yarn.lock",
|
||||
)
|
||||
@ -72,6 +70,9 @@ yarn_install(
|
||||
load("@npm//:install_bazel_dependencies.bzl", "install_bazel_dependencies")
|
||||
install_bazel_dependencies()
|
||||
|
||||
load("@npm_bazel_protractor//:package.bzl", "npm_bazel_protractor_dependencies")
|
||||
npm_bazel_protractor_dependencies()
|
||||
|
||||
load("@npm_bazel_karma//:package.bzl", "rules_karma_dependencies")
|
||||
rules_karma_dependencies()
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
load("@npm_bazel_protractor//:index.bzl", "protractor_web_test_suite")
|
||||
load("@npm_bazel_typescript//:index.bzl", "ts_library")
|
||||
load("@npm_angular_bazel//:index.bzl", "protractor_web_test_suite")
|
||||
|
||||
ts_library(
|
||||
name = "e2e_lib",
|
||||
@ -21,10 +21,6 @@ ts_library(
|
||||
|
||||
protractor_web_test_suite(
|
||||
name = "prodserver_test",
|
||||
data = [
|
||||
"@npm//@angular/bazel",
|
||||
"@npm//protractor",
|
||||
],
|
||||
on_prepare = ":protractor.on-prepare.js",
|
||||
server = "//src:prodserver",
|
||||
deps = [":e2e_lib"],
|
||||
@ -32,10 +28,6 @@ protractor_web_test_suite(
|
||||
|
||||
protractor_web_test_suite(
|
||||
name = "devserver_test",
|
||||
data = [
|
||||
"@npm//@angular/bazel",
|
||||
"@npm//protractor",
|
||||
],
|
||||
on_prepare = ":protractor.on-prepare.js",
|
||||
server = "//src:devserver",
|
||||
deps = [":e2e_lib"],
|
||||
|
@ -112,11 +112,13 @@ def _rollup(ctx, bundle_name, rollup_config, entry_point, inputs, js_output, for
|
||||
args.add("--amd.id", package_name)
|
||||
|
||||
# After updating to build_bazel_rules_nodejs 0.27.0+, rollup has been updated to v1.3.1
|
||||
# which tree shakes @__PURE__ annotations by default. We turn this feature off
|
||||
# for ng_package as Angular bundles contain these annotations and there are
|
||||
# test failures if they are removed. See comments in
|
||||
# https://github.com/angular/angular/pull/29210 for more information.
|
||||
args.add("--no-treeshake.annotations")
|
||||
# which tree shakes @__PURE__ annotations and const variables which are later amended by NGCC.
|
||||
# We turn this feature off for ng_package as Angular bundles contain these and there are
|
||||
# test failures if they are removed.
|
||||
# See comments in:
|
||||
# https://github.com/angular/angular/pull/29210
|
||||
# https://github.com/angular/angular/pull/32069
|
||||
args.add("--no-treeshake")
|
||||
|
||||
# Note: if the input has external source maps then we need to also install and use
|
||||
# `rollup-plugin-sourcemaps`, which will require us to use rollup.config.js file instead
|
||||
|
@ -5,11 +5,11 @@
|
||||
// If the function returns a promise, as it does here, protractor will wait
|
||||
// for the promise to resolve before running tests.
|
||||
|
||||
const protractorUtils = require('@angular/bazel/protractor-utils');
|
||||
const protractorUtils = require('@bazel/protractor/protractor-utils');
|
||||
const protractor = require('protractor');
|
||||
|
||||
module.exports = function(config) {
|
||||
// In this example, `@angular/bazel/protractor-utils` is used to run
|
||||
// In this example, `@bazel/protractor/protractor-utils` is used to run
|
||||
// the server. protractorUtils.runServer() runs the server on a randomly
|
||||
// selected port (given a port flag to pass to the server as an argument).
|
||||
// The port used is returned in serverSpec and the protractor serverUrl
|
||||
|
@ -48,11 +48,11 @@ function addDevDependenciesToPackageJson(options: Schema) {
|
||||
|
||||
const devDependencies: {[k: string]: string} = {
|
||||
'@angular/bazel': angularCoreVersion,
|
||||
'@bazel/bazel': '^0.27.0',
|
||||
'@bazel/hide-bazel-files': '0.32.2',
|
||||
'@bazel/bazel': '^0.28.1',
|
||||
'@bazel/ibazel': '^0.10.2',
|
||||
'@bazel/karma': '0.32.2',
|
||||
'@bazel/typescript': '0.32.2',
|
||||
'@bazel/karma': '0.34.0',
|
||||
'@bazel/protractor': '0.34.0',
|
||||
'@bazel/typescript': '0.34.0',
|
||||
};
|
||||
|
||||
const recorder = host.beginUpdate(packageJson);
|
||||
|
@ -113,9 +113,10 @@ describe('ng-add schematic', () => {
|
||||
const json = JSON.parse(content);
|
||||
const devDeps = Object.keys(json.devDependencies);
|
||||
expect(devDeps).toContain('@bazel/bazel');
|
||||
expect(devDeps).toContain('@bazel/hide-bazel-files');
|
||||
expect(devDeps).toContain('@bazel/ibazel');
|
||||
expect(devDeps).toContain('@bazel/karma');
|
||||
expect(devDeps).toContain('@bazel/protractor');
|
||||
expect(devDeps).toContain('@bazel/typescript');
|
||||
});
|
||||
|
||||
it('should replace an existing dev dependency', async() => {
|
||||
|
@ -133,6 +133,10 @@ describe('@angular/core ng_package', () => {
|
||||
} else {
|
||||
it('should have decorators',
|
||||
() => { expect(shx.cat('fesm5/core.js')).toContain('__decorate'); });
|
||||
|
||||
// See: https://github.com/angular/angular/pull/32069
|
||||
it('should retain access to const',
|
||||
() => { expect(shx.cat('fesm5/core.js')).toContain('!ivyEnabled'); });
|
||||
}
|
||||
|
||||
it('should load tslib from external bundle', () => {
|
||||
|
@ -111,6 +111,41 @@ Hello
|
||||
See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
/* global Reflect, Promise */
|
||||
|
||||
var extendStatics = function(d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
|
||||
function __extends(d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
}
|
||||
|
||||
var __assign = function() {
|
||||
__assign = Object.assign || function __assign(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
|
||||
function __rest(s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
|
||||
t[p[i]] = s[p[i]];
|
||||
return t;
|
||||
}
|
||||
|
||||
function __decorate(decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
@ -119,6 +154,136 @@ Hello
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
}
|
||||
|
||||
function __param(paramIndex, decorator) {
|
||||
return function (target, key) { decorator(target, key, paramIndex); }
|
||||
}
|
||||
|
||||
function __metadata(metadataKey, metadataValue) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
|
||||
}
|
||||
|
||||
function __awaiter(thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
}
|
||||
|
||||
function __generator(thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
}
|
||||
|
||||
function __exportStar(m, exports) {
|
||||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
||||
}
|
||||
|
||||
function __values(o) {
|
||||
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
|
||||
if (m) return m.call(o);
|
||||
return {
|
||||
next: function () {
|
||||
if (o && i >= o.length) o = void 0;
|
||||
return { value: o && o[i++], done: !o };
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function __read(o, n) {
|
||||
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
||||
if (!m) return o;
|
||||
var i = m.call(o), r, ar = [], e;
|
||||
try {
|
||||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
||||
}
|
||||
catch (error) { e = { error: error }; }
|
||||
finally {
|
||||
try {
|
||||
if (r && !r.done && (m = i["return"])) m.call(i);
|
||||
}
|
||||
finally { if (e) throw e.error; }
|
||||
}
|
||||
return ar;
|
||||
}
|
||||
|
||||
function __spread() {
|
||||
for (var ar = [], i = 0; i < arguments.length; i++)
|
||||
ar = ar.concat(__read(arguments[i]));
|
||||
return ar;
|
||||
}
|
||||
|
||||
function __await(v) {
|
||||
return this instanceof __await ? (this.v = v, this) : new __await(v);
|
||||
}
|
||||
|
||||
function __asyncGenerator(thisArg, _arguments, generator) {
|
||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
||||
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
|
||||
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
|
||||
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
||||
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
||||
function fulfill(value) { resume("next", value); }
|
||||
function reject(value) { resume("throw", value); }
|
||||
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
||||
}
|
||||
|
||||
function __asyncDelegator(o) {
|
||||
var i, p;
|
||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
|
||||
}
|
||||
|
||||
function __asyncValues(o) {
|
||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
||||
var m = o[Symbol.asyncIterator], i;
|
||||
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
||||
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
||||
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
||||
}
|
||||
|
||||
function __makeTemplateObject(cooked, raw) {
|
||||
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
|
||||
return cooked;
|
||||
};
|
||||
|
||||
function __importStar(mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result.default = mod;
|
||||
return result;
|
||||
}
|
||||
|
||||
function __importDefault(mod) {
|
||||
return (mod && mod.__esModule) ? mod : { default: mod };
|
||||
}
|
||||
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
@ -210,6 +375,41 @@ e.SecondaryModule=o,e.a=1,Object.defineProperty(e,"__esModule",{value:!0})});
|
||||
See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
/* global Reflect, Promise */
|
||||
|
||||
var extendStatics = function(d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
|
||||
function __extends(d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
}
|
||||
|
||||
var __assign = function() {
|
||||
__assign = Object.assign || function __assign(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
|
||||
function __rest(s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
|
||||
t[p[i]] = s[p[i]];
|
||||
return t;
|
||||
}
|
||||
|
||||
function __decorate(decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
@ -218,6 +418,136 @@ e.SecondaryModule=o,e.a=1,Object.defineProperty(e,"__esModule",{value:!0})});
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
}
|
||||
|
||||
function __param(paramIndex, decorator) {
|
||||
return function (target, key) { decorator(target, key, paramIndex); }
|
||||
}
|
||||
|
||||
function __metadata(metadataKey, metadataValue) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
|
||||
}
|
||||
|
||||
function __awaiter(thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
}
|
||||
|
||||
function __generator(thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
}
|
||||
|
||||
function __exportStar(m, exports) {
|
||||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
||||
}
|
||||
|
||||
function __values(o) {
|
||||
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
|
||||
if (m) return m.call(o);
|
||||
return {
|
||||
next: function () {
|
||||
if (o && i >= o.length) o = void 0;
|
||||
return { value: o && o[i++], done: !o };
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function __read(o, n) {
|
||||
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
||||
if (!m) return o;
|
||||
var i = m.call(o), r, ar = [], e;
|
||||
try {
|
||||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
||||
}
|
||||
catch (error) { e = { error: error }; }
|
||||
finally {
|
||||
try {
|
||||
if (r && !r.done && (m = i["return"])) m.call(i);
|
||||
}
|
||||
finally { if (e) throw e.error; }
|
||||
}
|
||||
return ar;
|
||||
}
|
||||
|
||||
function __spread() {
|
||||
for (var ar = [], i = 0; i < arguments.length; i++)
|
||||
ar = ar.concat(__read(arguments[i]));
|
||||
return ar;
|
||||
}
|
||||
|
||||
function __await(v) {
|
||||
return this instanceof __await ? (this.v = v, this) : new __await(v);
|
||||
}
|
||||
|
||||
function __asyncGenerator(thisArg, _arguments, generator) {
|
||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
||||
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
|
||||
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
|
||||
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
||||
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
||||
function fulfill(value) { resume("next", value); }
|
||||
function reject(value) { resume("throw", value); }
|
||||
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
||||
}
|
||||
|
||||
function __asyncDelegator(o) {
|
||||
var i, p;
|
||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
|
||||
}
|
||||
|
||||
function __asyncValues(o) {
|
||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
||||
var m = o[Symbol.asyncIterator], i;
|
||||
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
||||
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
||||
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
||||
}
|
||||
|
||||
function __makeTemplateObject(cooked, raw) {
|
||||
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
|
||||
return cooked;
|
||||
};
|
||||
|
||||
function __importStar(mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result.default = mod;
|
||||
return result;
|
||||
}
|
||||
|
||||
function __importDefault(mod) {
|
||||
return (mod && mod.__esModule) ? mod : { default: mod };
|
||||
}
|
||||
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
|
@ -134,7 +134,8 @@ function formatNumberToLocaleString(
|
||||
* such as "$" or "Canadian Dollar". Used in output string, but does not affect the operation
|
||||
* of the function.
|
||||
* @param currencyCode The [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217)
|
||||
* currency code to use in the result string, such as `USD` for the US dollar and `EUR` for the euro.
|
||||
* currency code, such as `USD` for the US dollar and `EUR` for the euro.
|
||||
* Used to determine the number of digits in the decimal part.
|
||||
* @param digitInfo Decimal representation options, specified by a string in the following format:
|
||||
* `{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}`. See `DecimalPipe` for more details.
|
||||
*
|
||||
|
@ -25,12 +25,12 @@ export interface PopStateEvent {
|
||||
*
|
||||
* A service that applications can use to interact with a browser's URL.
|
||||
*
|
||||
* Depending on the `LocationStrategy` used, `Location` will either persist
|
||||
* Depending on the `LocationStrategy` used, `Location` persists
|
||||
* to the URL's path or the URL's hash segment.
|
||||
*
|
||||
* @usageNotes
|
||||
*
|
||||
* It's better to use the {@link Router#navigate} service to trigger route changes. Use
|
||||
* It's better to use the `Router#navigate` service to trigger route changes. Use
|
||||
* `Location` only if you need to interact with or create normalized URLs outside of
|
||||
* routing.
|
||||
*
|
||||
@ -77,9 +77,9 @@ export class Location {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the normalized URL path.
|
||||
* Normalizes the URL path for this location.
|
||||
*
|
||||
* @param includeHash Whether path has an anchor fragment.
|
||||
* @param includeHash True to include an anchor fragment in the path.
|
||||
*
|
||||
* @returns The normalized URL path.
|
||||
*/
|
||||
@ -90,17 +90,18 @@ export class Location {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current value of the history.state object.
|
||||
* Reports the current state of the location history.
|
||||
* @returns The current value of the `history.state` object.
|
||||
*/
|
||||
getState(): unknown { return this._platformLocation.getState(); }
|
||||
|
||||
/**
|
||||
* Normalizes the given path and compares to the current normalized path.
|
||||
*
|
||||
* @param path The given URL path
|
||||
* @param query Query parameters
|
||||
* @param path The given URL path.
|
||||
* @param query Query parameters.
|
||||
*
|
||||
* @returns `true` if the given URL path is equal to the current normalized path, `false`
|
||||
* @returns True if the given URL path is equal to the current normalized path, false
|
||||
* otherwise.
|
||||
*/
|
||||
isCurrentPathEqualTo(path: string, query: string = ''): boolean {
|
||||
@ -108,23 +109,21 @@ export class Location {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a string representing a URL, returns the URL path after stripping the
|
||||
* trailing slashes.
|
||||
* Normalizes a URL path by stripping any trailing slashes.
|
||||
*
|
||||
* @param url String representing a URL.
|
||||
*
|
||||
* @returns Normalized URL string.
|
||||
* @returns The normalized URL string.
|
||||
*/
|
||||
normalize(url: string): string {
|
||||
return Location.stripTrailingSlash(_stripBaseHref(this._baseHref, _stripIndexHtml(url)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a string representing a URL, returns the platform-specific external URL path.
|
||||
* If the given URL doesn't begin with a leading slash (`'/'`), this method adds one
|
||||
* before normalizing. This method also adds a hash if `HashLocationStrategy` is
|
||||
* used, or the `APP_BASE_HREF` if the `PathLocationStrategy` is in use.
|
||||
*
|
||||
* Normalizes an external URL path.
|
||||
* If the given URL doesn't begin with a leading slash (`'/'`), adds one
|
||||
* before normalizing. Adds a hash if `HashLocationStrategy` is
|
||||
* in use, or the `APP_BASE_HREF` if the `PathLocationStrategy` is in use.
|
||||
*
|
||||
* @param url String representing a URL.
|
||||
*
|
||||
@ -139,12 +138,12 @@ export class Location {
|
||||
|
||||
// TODO: rename this method to pushState
|
||||
/**
|
||||
* Changes the browsers URL to a normalized version of the given URL, and pushes a
|
||||
* Changes the browser's URL to a normalized version of a given URL, and pushes a
|
||||
* new item onto the platform's history.
|
||||
*
|
||||
* @param path URL path to normalizze
|
||||
* @param query Query parameters
|
||||
* @param state Location history state
|
||||
* @param path URL path to normalize.
|
||||
* @param query Query parameters.
|
||||
* @param state Location history state.
|
||||
*
|
||||
*/
|
||||
go(path: string, query: string = '', state: any = null): void {
|
||||
@ -157,9 +156,9 @@ export class Location {
|
||||
* Changes the browser's URL to a normalized version of the given URL, and replaces
|
||||
* the top item on the platform's history stack.
|
||||
*
|
||||
* @param path URL path to normalizze
|
||||
* @param query Query parameters
|
||||
* @param state Location history state
|
||||
* @param path URL path to normalize.
|
||||
* @param query Query parameters.
|
||||
* @param state Location history state.
|
||||
*/
|
||||
replaceState(path: string, query: string = '', state: any = null): void {
|
||||
this._platformStrategy.replaceState(state, '', path, query);
|
||||
@ -178,8 +177,10 @@ export class Location {
|
||||
back(): void { this._platformStrategy.back(); }
|
||||
|
||||
/**
|
||||
* Register URL change listeners. This API can be used to catch updates performed by the Angular
|
||||
* framework. These are not detectible through "popstate" or "hashchange" events.
|
||||
* Registers a URL change listener. Use to catch updates performed by the Angular
|
||||
* framework that are not detectible through "popstate" or "hashchange" events.
|
||||
*
|
||||
* @param fn The change handler function, which take a URL and a location history state.
|
||||
*/
|
||||
onUrlChange(fn: (url: string, state: unknown) => void) {
|
||||
this._urlChangeListeners.push(fn);
|
||||
@ -192,7 +193,7 @@ export class Location {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to the platform's `popState` events.
|
||||
* Subscribes to the platform's `popState` events.
|
||||
*
|
||||
* @param value Event that is triggered when the state history changes.
|
||||
* @param exception The exception to throw.
|
||||
@ -206,25 +207,24 @@ export class Location {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a string of url parameters, prepend with `?` if needed, otherwise return the
|
||||
* parameters as is.
|
||||
* Normalizes URL parameters by prepending with `?` if needed.
|
||||
*
|
||||
* @param params String of URL parameters
|
||||
* @param params String of URL parameters.
|
||||
*
|
||||
* @returns URL parameters prepended with `?` or the parameters as is.
|
||||
* @returns The normalized URL parameters string.
|
||||
*/
|
||||
public static normalizeQueryParams(params: string): string {
|
||||
return params && params[0] !== '?' ? '?' + params : params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given 2 parts of a URL, join them with a slash if needed.
|
||||
* Joins two parts of a URL with a slash if needed.
|
||||
*
|
||||
* @param start URL string
|
||||
* @param end URL string
|
||||
*
|
||||
*
|
||||
* @returns Given URL strings joined with a slash, if needed.
|
||||
* @returns The joined URL string.
|
||||
*/
|
||||
public static joinWithSlash(start: string, end: string): string {
|
||||
if (start.length == 0) {
|
||||
@ -250,14 +250,13 @@ export class Location {
|
||||
}
|
||||
|
||||
/**
|
||||
* If URL has a trailing slash, remove it, otherwise return the URL as is. The
|
||||
* method looks for the first occurrence of either `#`, `?`, or the end of the
|
||||
* Removes a trailing slash from a URL string if needed.
|
||||
* Looks for the first occurrence of either `#`, `?`, or the end of the
|
||||
* line as `/` characters and removes the trailing slash if one exists.
|
||||
*
|
||||
* @param url URL string
|
||||
* @param url URL string.
|
||||
*
|
||||
* @returns Returns a URL string after removing the trailing slash if one exists, otherwise
|
||||
* returns the string as is.
|
||||
* @returns The URL string, modified if needed.
|
||||
*/
|
||||
public static stripTrailingSlash(url: string): string {
|
||||
const match = url.match(/#|\?|$/);
|
||||
|
@ -161,8 +161,8 @@ export class DatePipe implements PipeTransform {
|
||||
* @param format The date/time components to include, using predefined options or a
|
||||
* custom format string.
|
||||
* @param timezone A timezone offset (such as `'+0430'`), or a standard
|
||||
* UTC/GMT or continental US timezone abbreviation. Default is
|
||||
* the local system timezone of the end-user's machine.
|
||||
* UTC/GMT or continental US timezone abbreviation.
|
||||
* When not supplied, uses the end-user's local system timezone.
|
||||
* @param locale A locale code for the locale format rules to use.
|
||||
* When not supplied, uses the value of `LOCALE_ID`, which is `en-US` by default.
|
||||
* See [Setting your app locale](guide/i18n#setting-up-the-locale-of-your-app).
|
||||
|
@ -15,6 +15,7 @@ import localeHu from '@angular/common/locales/hu';
|
||||
import localeSr from '@angular/common/locales/sr';
|
||||
import localeTh from '@angular/common/locales/th';
|
||||
import {isDate, toDate, formatDate} from '@angular/common/src/i18n/format_date';
|
||||
import {ɵDEFAULT_LOCALE_ID as DEFAULT_LOCALE_ID} from '@angular/core';
|
||||
|
||||
describe('Format date', () => {
|
||||
describe('toDate', () => {
|
||||
@ -46,13 +47,12 @@ describe('Format date', () => {
|
||||
|
||||
describe('formatDate', () => {
|
||||
const isoStringWithoutTime = '2015-01-01';
|
||||
const defaultLocale = 'en-US';
|
||||
const defaultFormat = 'mediumDate';
|
||||
let date: Date;
|
||||
|
||||
// Check the transformation of a date into a pattern
|
||||
function expectDateFormatAs(date: Date | string, pattern: any, output: string): void {
|
||||
expect(formatDate(date, pattern, defaultLocale)).toEqual(output, `pattern: "${pattern}"`);
|
||||
expect(formatDate(date, pattern, DEFAULT_LOCALE_ID)).toEqual(output, `pattern: "${pattern}"`);
|
||||
}
|
||||
|
||||
beforeAll(() => {
|
||||
@ -209,7 +209,8 @@ describe('Format date', () => {
|
||||
};
|
||||
|
||||
Object.keys(dateFixtures).forEach((pattern: string) => {
|
||||
expect(formatDate(date, pattern, defaultLocale, '+0430')).toMatch(dateFixtures[pattern]);
|
||||
expect(formatDate(date, pattern, DEFAULT_LOCALE_ID, '+0430'))
|
||||
.toMatch(dateFixtures[pattern]);
|
||||
});
|
||||
});
|
||||
|
||||
@ -253,22 +254,22 @@ describe('Format date', () => {
|
||||
};
|
||||
|
||||
Object.keys(dateFixtures).forEach((pattern: string) => {
|
||||
expect(formatDate(date, pattern, defaultLocale)).toMatch(dateFixtures[pattern]);
|
||||
expect(formatDate(date, pattern, DEFAULT_LOCALE_ID)).toMatch(dateFixtures[pattern]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should format invalid in IE ISO date',
|
||||
() => expect(formatDate('2017-01-11T12:00:00.014-0500', defaultFormat, defaultLocale))
|
||||
() => expect(formatDate('2017-01-11T12:00:00.014-0500', defaultFormat, DEFAULT_LOCALE_ID))
|
||||
.toEqual('Jan 11, 2017'));
|
||||
|
||||
it('should format invalid in Safari ISO date',
|
||||
() => expect(formatDate('2017-01-20T12:00:00+0000', defaultFormat, defaultLocale))
|
||||
() => expect(formatDate('2017-01-20T12:00:00+0000', defaultFormat, DEFAULT_LOCALE_ID))
|
||||
.toEqual('Jan 20, 2017'));
|
||||
|
||||
// https://github.com/angular/angular/issues/9524
|
||||
// https://github.com/angular/angular/issues/9524
|
||||
it('should format correctly with iso strings that contain time',
|
||||
() => expect(formatDate('2017-05-07T22:14:39', 'dd-MM-yyyy HH:mm', defaultLocale))
|
||||
() => expect(formatDate('2017-05-07T22:14:39', 'dd-MM-yyyy HH:mm', DEFAULT_LOCALE_ID))
|
||||
.toMatch(/07-05-2017 \d{2}:\d{2}/));
|
||||
|
||||
// https://github.com/angular/angular/issues/21491
|
||||
@ -276,22 +277,22 @@ describe('Format date', () => {
|
||||
// this test only works if the timezone is not in UTC
|
||||
// which is the case for BrowserStack when we test Safari
|
||||
if (new Date().getTimezoneOffset() !== 0) {
|
||||
expect(formatDate('2018-01-11T13:00:00', 'HH', defaultLocale))
|
||||
.not.toEqual(formatDate('2018-01-11T13:00:00Z', 'HH', defaultLocale));
|
||||
expect(formatDate('2018-01-11T13:00:00', 'HH', DEFAULT_LOCALE_ID))
|
||||
.not.toEqual(formatDate('2018-01-11T13:00:00Z', 'HH', DEFAULT_LOCALE_ID));
|
||||
}
|
||||
});
|
||||
|
||||
// https://github.com/angular/angular/issues/16624
|
||||
// https://github.com/angular/angular/issues/17478
|
||||
it('should show the correct time when the timezone is fixed', () => {
|
||||
expect(formatDate('2017-06-13T10:14:39+0000', 'shortTime', defaultLocale, '+0000'))
|
||||
expect(formatDate('2017-06-13T10:14:39+0000', 'shortTime', DEFAULT_LOCALE_ID, '+0000'))
|
||||
.toEqual('10:14 AM');
|
||||
expect(formatDate('2017-06-13T10:14:39+0000', 'h:mm a', defaultLocale, '+0000'))
|
||||
expect(formatDate('2017-06-13T10:14:39+0000', 'h:mm a', DEFAULT_LOCALE_ID, '+0000'))
|
||||
.toEqual('10:14 AM');
|
||||
});
|
||||
|
||||
it('should remove bidi control characters',
|
||||
() => expect(formatDate(date, 'MM/dd/yyyy', defaultLocale) !.length).toEqual(10));
|
||||
() => expect(formatDate(date, 'MM/dd/yyyy', DEFAULT_LOCALE_ID) !.length).toEqual(10));
|
||||
|
||||
it(`should format the date correctly in various locales`, () => {
|
||||
expect(formatDate(date, 'short', 'de')).toEqual('15.06.15, 09:03');
|
||||
|
@ -12,10 +12,9 @@ import localeFr from '@angular/common/locales/fr';
|
||||
import localeAr from '@angular/common/locales/ar';
|
||||
import {formatCurrency, formatNumber, formatPercent, registerLocaleData} from '@angular/common';
|
||||
import {describe, expect, it} from '@angular/core/testing/src/testing_internal';
|
||||
import {ɵDEFAULT_LOCALE_ID as DEFAULT_LOCALE_ID} from '@angular/core';
|
||||
|
||||
describe('Format number', () => {
|
||||
const defaultLocale = 'en-US';
|
||||
|
||||
beforeAll(() => {
|
||||
registerLocaleData(localeEn);
|
||||
registerLocaleData(localeEsUS);
|
||||
@ -26,18 +25,18 @@ describe('Format number', () => {
|
||||
describe('Number', () => {
|
||||
describe('transform', () => {
|
||||
it('should return correct value for numbers', () => {
|
||||
expect(formatNumber(12345, defaultLocale)).toEqual('12,345');
|
||||
expect(formatNumber(123, defaultLocale, '.2')).toEqual('123.00');
|
||||
expect(formatNumber(1, defaultLocale, '3.')).toEqual('001');
|
||||
expect(formatNumber(1.1, defaultLocale, '3.4-5')).toEqual('001.1000');
|
||||
expect(formatNumber(1.123456, defaultLocale, '3.4-5')).toEqual('001.12346');
|
||||
expect(formatNumber(1.1234, defaultLocale)).toEqual('1.123');
|
||||
expect(formatNumber(1.123456, defaultLocale, '.2')).toEqual('1.123');
|
||||
expect(formatNumber(1.123456, defaultLocale, '.4')).toEqual('1.1235');
|
||||
expect(formatNumber(12345, DEFAULT_LOCALE_ID)).toEqual('12,345');
|
||||
expect(formatNumber(123, DEFAULT_LOCALE_ID, '.2')).toEqual('123.00');
|
||||
expect(formatNumber(1, DEFAULT_LOCALE_ID, '3.')).toEqual('001');
|
||||
expect(formatNumber(1.1, DEFAULT_LOCALE_ID, '3.4-5')).toEqual('001.1000');
|
||||
expect(formatNumber(1.123456, DEFAULT_LOCALE_ID, '3.4-5')).toEqual('001.12346');
|
||||
expect(formatNumber(1.1234, DEFAULT_LOCALE_ID)).toEqual('1.123');
|
||||
expect(formatNumber(1.123456, DEFAULT_LOCALE_ID, '.2')).toEqual('1.123');
|
||||
expect(formatNumber(1.123456, DEFAULT_LOCALE_ID, '.4')).toEqual('1.1235');
|
||||
});
|
||||
|
||||
it('should throw if minFractionDigits is explicitly higher than maxFractionDigits', () => {
|
||||
expect(() => formatNumber(1.1, defaultLocale, '3.4-2'))
|
||||
expect(() => formatNumber(1.1, DEFAULT_LOCALE_ID, '3.4-2'))
|
||||
.toThrowError(/is higher than the maximum/);
|
||||
});
|
||||
});
|
||||
@ -51,27 +50,27 @@ describe('Format number', () => {
|
||||
describe('Percent', () => {
|
||||
describe('transform', () => {
|
||||
it('should return correct value for numbers', () => {
|
||||
expect(formatPercent(1.23, defaultLocale)).toEqual('123%');
|
||||
expect(formatPercent(1.2, defaultLocale, '.2')).toEqual('120.00%');
|
||||
expect(formatPercent(1.2, defaultLocale, '4.2')).toEqual('0,120.00%');
|
||||
expect(formatPercent(1.23, DEFAULT_LOCALE_ID)).toEqual('123%');
|
||||
expect(formatPercent(1.2, DEFAULT_LOCALE_ID, '.2')).toEqual('120.00%');
|
||||
expect(formatPercent(1.2, DEFAULT_LOCALE_ID, '4.2')).toEqual('0,120.00%');
|
||||
expect(formatPercent(1.2, 'fr', '4.2')).toEqual('0 120,00 %');
|
||||
expect(formatPercent(1.2, 'ar', '4.2')).toEqual('0,120.00%');
|
||||
// see issue #20136
|
||||
expect(formatPercent(0.12345674, defaultLocale, '0.0-10')).toEqual('12.345674%');
|
||||
expect(formatPercent(0, defaultLocale, '0.0-10')).toEqual('0%');
|
||||
expect(formatPercent(0.00, defaultLocale, '0.0-10')).toEqual('0%');
|
||||
expect(formatPercent(1, defaultLocale, '0.0-10')).toEqual('100%');
|
||||
expect(formatPercent(0.1, defaultLocale, '0.0-10')).toEqual('10%');
|
||||
expect(formatPercent(0.12, defaultLocale, '0.0-10')).toEqual('12%');
|
||||
expect(formatPercent(0.123, defaultLocale, '0.0-10')).toEqual('12.3%');
|
||||
expect(formatPercent(12.3456, defaultLocale, '0.0-10')).toEqual('1,234.56%');
|
||||
expect(formatPercent(12.345600, defaultLocale, '0.0-10')).toEqual('1,234.56%');
|
||||
expect(formatPercent(12.345699999, defaultLocale, '0.0-6')).toEqual('1,234.57%');
|
||||
expect(formatPercent(12.345699999, defaultLocale, '0.4-6')).toEqual('1,234.5700%');
|
||||
expect(formatPercent(100, defaultLocale, '0.4-6')).toEqual('10,000.0000%');
|
||||
expect(formatPercent(100, defaultLocale, '0.0-10')).toEqual('10,000%');
|
||||
expect(formatPercent(1.5e2, defaultLocale)).toEqual('15,000%');
|
||||
expect(formatPercent(1e100, defaultLocale)).toEqual('1E+102%');
|
||||
expect(formatPercent(0.12345674, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('12.345674%');
|
||||
expect(formatPercent(0, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('0%');
|
||||
expect(formatPercent(0.00, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('0%');
|
||||
expect(formatPercent(1, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('100%');
|
||||
expect(formatPercent(0.1, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('10%');
|
||||
expect(formatPercent(0.12, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('12%');
|
||||
expect(formatPercent(0.123, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('12.3%');
|
||||
expect(formatPercent(12.3456, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('1,234.56%');
|
||||
expect(formatPercent(12.345600, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('1,234.56%');
|
||||
expect(formatPercent(12.345699999, DEFAULT_LOCALE_ID, '0.0-6')).toEqual('1,234.57%');
|
||||
expect(formatPercent(12.345699999, DEFAULT_LOCALE_ID, '0.4-6')).toEqual('1,234.5700%');
|
||||
expect(formatPercent(100, DEFAULT_LOCALE_ID, '0.4-6')).toEqual('10,000.0000%');
|
||||
expect(formatPercent(100, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('10,000%');
|
||||
expect(formatPercent(1.5e2, DEFAULT_LOCALE_ID)).toEqual('15,000%');
|
||||
expect(formatPercent(1e100, DEFAULT_LOCALE_ID)).toEqual('1E+102%');
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -80,16 +79,16 @@ describe('Format number', () => {
|
||||
const defaultCurrencyCode = 'USD';
|
||||
describe('transform', () => {
|
||||
it('should return correct value for numbers', () => {
|
||||
expect(formatCurrency(123, defaultLocale, '$')).toEqual('$123.00');
|
||||
expect(formatCurrency(12, defaultLocale, 'EUR', 'EUR', '.1')).toEqual('EUR12.0');
|
||||
expect(
|
||||
formatCurrency(5.1234, defaultLocale, defaultCurrencyCode, defaultCurrencyCode, '.0-3'))
|
||||
expect(formatCurrency(123, DEFAULT_LOCALE_ID, '$')).toEqual('$123.00');
|
||||
expect(formatCurrency(12, DEFAULT_LOCALE_ID, 'EUR', 'EUR', '.1')).toEqual('EUR12.0');
|
||||
expect(formatCurrency(
|
||||
5.1234, DEFAULT_LOCALE_ID, defaultCurrencyCode, defaultCurrencyCode, '.0-3'))
|
||||
.toEqual('USD5.123');
|
||||
expect(formatCurrency(5.1234, defaultLocale, defaultCurrencyCode)).toEqual('USD5.12');
|
||||
expect(formatCurrency(5.1234, defaultLocale, '$')).toEqual('$5.12');
|
||||
expect(formatCurrency(5.1234, defaultLocale, 'CA$')).toEqual('CA$5.12');
|
||||
expect(formatCurrency(5.1234, defaultLocale, '$')).toEqual('$5.12');
|
||||
expect(formatCurrency(5.1234, defaultLocale, '$', defaultCurrencyCode, '5.2-2'))
|
||||
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, defaultCurrencyCode)).toEqual('USD5.12');
|
||||
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, '$')).toEqual('$5.12');
|
||||
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, 'CA$')).toEqual('CA$5.12');
|
||||
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, '$')).toEqual('$5.12');
|
||||
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, '$', defaultCurrencyCode, '5.2-2'))
|
||||
.toEqual('$00,005.12');
|
||||
expect(formatCurrency(5.1234, 'fr', '$', defaultCurrencyCode, '5.2-2'))
|
||||
.toEqual('00 005,12 $');
|
||||
@ -98,20 +97,21 @@ describe('Format number', () => {
|
||||
|
||||
it('should support any currency code name', () => {
|
||||
// currency code is unknown, default formatting options will be used
|
||||
expect(formatCurrency(5.1234, defaultLocale, 'unexisting_ISO_code'))
|
||||
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, 'unexisting_ISO_code'))
|
||||
.toEqual('unexisting_ISO_code5.12');
|
||||
// currency code is USD, the pipe will format based on USD but will display "Custom name"
|
||||
expect(formatCurrency(5.1234, defaultLocale, 'Custom name')).toEqual('Custom name5.12');
|
||||
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, 'Custom name')).toEqual('Custom name5.12');
|
||||
});
|
||||
|
||||
it('should round to the default number of digits if no digitsInfo', () => {
|
||||
// IDR has a default number of digits of 0
|
||||
expect(formatCurrency(5.1234, defaultLocale, 'IDR', 'IDR')).toEqual('IDR5');
|
||||
expect(formatCurrency(5.1234, defaultLocale, 'IDR', 'IDR', '.2')).toEqual('IDR5.12');
|
||||
expect(formatCurrency(5.1234, defaultLocale, 'Custom name', 'IDR')).toEqual('Custom name5');
|
||||
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, 'IDR', 'IDR')).toEqual('IDR5');
|
||||
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, 'IDR', 'IDR', '.2')).toEqual('IDR5.12');
|
||||
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, 'Custom name', 'IDR'))
|
||||
.toEqual('Custom name5');
|
||||
// BHD has a default number of digits of 3
|
||||
expect(formatCurrency(5.1234, defaultLocale, 'BHD', 'BHD')).toEqual('BHD5.123');
|
||||
expect(formatCurrency(5.1234, defaultLocale, 'BHD', 'BHD', '.1-2')).toEqual('BHD5.12');
|
||||
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, 'BHD', 'BHD')).toEqual('BHD5.123');
|
||||
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, 'BHD', 'BHD', '.1-2')).toEqual('BHD5.12');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -144,6 +144,7 @@ export class $locationShim {
|
||||
this.$$parse(oldUrl);
|
||||
this.state(oldState);
|
||||
this.setBrowserUrlWithFallback(oldUrl, false, oldState);
|
||||
this.$$notifyChangeListeners(this.url(), this.$$state, oldUrl, oldState);
|
||||
} else {
|
||||
this.initalizing = false;
|
||||
$rootScope.$broadcast('$locationChangeSuccess', newUrl, oldUrl, newState, oldState);
|
||||
@ -199,6 +200,9 @@ export class $locationShim {
|
||||
}
|
||||
$rootScope.$broadcast(
|
||||
'$locationChangeSuccess', newUrl, oldUrl, this.$$state, oldState);
|
||||
if (urlOrStateChanged) {
|
||||
this.$$notifyChangeListeners(this.url(), this.$$state, oldUrl, oldState);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -415,7 +419,6 @@ export class $locationShim {
|
||||
// state object; this makes possible quick checking if the state changed in the digest
|
||||
// loop. Checking deep equality would be too expensive.
|
||||
this.$$state = this.browserState();
|
||||
this.$$notifyChangeListeners(url, state, oldUrl, oldState);
|
||||
} catch (e) {
|
||||
// Restore old values if pushState fails
|
||||
this.url(oldUrl);
|
||||
|
@ -628,6 +628,7 @@ describe('$location.onChange()', () => {
|
||||
|
||||
let $location: $locationShim;
|
||||
let upgradeModule: UpgradeModule;
|
||||
let mock$rootScope: $rootScopeMock;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
@ -640,6 +641,7 @@ describe('$location.onChange()', () => {
|
||||
|
||||
upgradeModule = TestBed.get(UpgradeModule);
|
||||
upgradeModule.$injector = {get: injectorFactory()};
|
||||
mock$rootScope = upgradeModule.$injector.get('$rootScope');
|
||||
});
|
||||
|
||||
beforeEach(inject([$locationShim], (loc: $locationShim) => { $location = loc; }));
|
||||
@ -674,17 +676,44 @@ describe('$location.onChange()', () => {
|
||||
|
||||
$location.onChange(changeListener);
|
||||
|
||||
// Mock out setting browserUrl
|
||||
($location as any).browserUrl = (url: string, replace: boolean, state: unknown) => {};
|
||||
|
||||
const newState = {foo: 'bar'};
|
||||
($location as any).setBrowserUrlWithFallback('/newUrl', false, newState);
|
||||
$location.state(newState);
|
||||
$location.path('/newUrl');
|
||||
mock$rootScope.runWatchers();
|
||||
|
||||
expect(onChangeVals.url).toBe('/newUrl');
|
||||
expect(onChangeVals.state).toBe(newState);
|
||||
expect(onChangeVals.oldUrl).toBe('/');
|
||||
expect(onChangeVals.state).toEqual(newState);
|
||||
expect(onChangeVals.oldUrl).toBe('http://host.com');
|
||||
expect(onChangeVals.oldState).toBe(null);
|
||||
});
|
||||
|
||||
it('should call changeListeners after $locationChangeSuccess', () => {
|
||||
|
||||
let changeListenerCalled = false;
|
||||
let locationChangeSuccessEmitted = false;
|
||||
|
||||
function changeListener(url: string, state: unknown, oldUrl: string, oldState: unknown) {
|
||||
changeListenerCalled = true;
|
||||
}
|
||||
|
||||
$location.onChange(changeListener);
|
||||
|
||||
mock$rootScope.$on('$locationChangeSuccess', () => {
|
||||
// Ensure that the changeListener hasn't been called yet
|
||||
expect(changeListenerCalled).toBe(false);
|
||||
locationChangeSuccessEmitted = true;
|
||||
});
|
||||
|
||||
// Update state and run watchers
|
||||
const stateValue = {foo: 'bar'};
|
||||
$location.state(stateValue);
|
||||
mock$rootScope.runWatchers();
|
||||
|
||||
// Ensure that change listeners are called and location events are emitted
|
||||
expect(changeListenerCalled).toBe(true);
|
||||
expect(locationChangeSuccessEmitted).toBe(true);
|
||||
});
|
||||
|
||||
it('should call forward errors to error handler', () => {
|
||||
|
||||
let error !: Error;
|
||||
@ -696,10 +725,8 @@ describe('$location.onChange()', () => {
|
||||
|
||||
$location.onChange(changeListener, errorHandler);
|
||||
|
||||
// Mock out setting browserUrl
|
||||
($location as any).browserUrl = (url: string, replace: boolean, state: unknown) => {};
|
||||
|
||||
($location as any).setBrowserUrlWithFallback('/newUrl');
|
||||
$location.url('/newUrl');
|
||||
mock$rootScope.runWatchers();
|
||||
expect(error.message).toBe('Handle error');
|
||||
});
|
||||
|
||||
|
@ -11,9 +11,28 @@ const shx = require('shelljs');
|
||||
const os = require('os');
|
||||
const {runCommand, setupTestDirectory} = require('./test_helpers');
|
||||
|
||||
// Nodejs toolchains were included in nodejs rules 0.33.0 so the
|
||||
// repository name for the nodejs toolchain now depends on the platform
|
||||
// being run on. The following function returns the nodejs repository
|
||||
// name of the runtime platform platform. These come from
|
||||
// https://github.com/bazelbuild/rules_nodejs/blob/2a0be492c5d506665798f04673ab1a646c883626/internal/node/node_repositories.bzl#L598.
|
||||
function nodejs_repository() {
|
||||
switch (os.platform()) {
|
||||
case 'darwin':
|
||||
return 'nodejs_darwin_amd64';
|
||||
case 'linux':
|
||||
return 'nodejs_linux_amd64';
|
||||
case 'win32':
|
||||
return 'nodejs_windows_amd64';
|
||||
default:
|
||||
throw 'Platform not supported';
|
||||
}
|
||||
}
|
||||
|
||||
const ngcBin = require.resolve('./ngc_bin');
|
||||
const xi18nBin = require.resolve('./ng_xi18n');
|
||||
const nodeBin = require.resolve(`nodejs/bin/node${(os.platform() === 'win32' ? '.cmd' : '')}`);
|
||||
const nodeBin =
|
||||
require.resolve(`${nodejs_repository()}/bin/node${(os.platform() === 'win32' ? '.cmd' : '')}`);
|
||||
const jasmineBin = require.resolve('npm/node_modules/jasmine/bin/jasmine.js');
|
||||
|
||||
// Prepare the test directory before building the integration test output. This ensures that
|
||||
|
@ -75,7 +75,7 @@ export class DecorationAnalyzer {
|
||||
new BaseDefDecoratorHandler(this.reflectionHost, this.evaluator, this.isCore),
|
||||
new ComponentDecoratorHandler(
|
||||
this.reflectionHost, this.evaluator, this.fullRegistry, this.fullMetaReader,
|
||||
this.scopeRegistry, this.isCore, this.resourceManager, this.rootDirs,
|
||||
this.scopeRegistry, this.scopeRegistry, this.isCore, this.resourceManager, this.rootDirs,
|
||||
/* defaultPreserveWhitespaces */ false,
|
||||
/* i18nUseExternalIds */ true, this.moduleResolver, this.cycleAnalyzer, this.refEmitter,
|
||||
NOOP_DEFAULT_IMPORT_RECORDER),
|
||||
|
@ -9,9 +9,11 @@
|
||||
import {DepGraph} from 'dependency-graph';
|
||||
import {AbsoluteFsPath, FileSystem, resolve} from '../../../src/ngtsc/file_system';
|
||||
import {Logger} from '../logging/logger';
|
||||
import {EntryPoint, EntryPointFormat, EntryPointJsonProperty, getEntryPointFormat} from '../packages/entry_point';
|
||||
import {EntryPoint, EntryPointFormat, EntryPointJsonProperty, SUPPORTED_FORMAT_PROPERTIES, getEntryPointFormat} from '../packages/entry_point';
|
||||
import {DependencyHost, DependencyInfo} from './dependency_host';
|
||||
|
||||
const builtinNodeJsModules = new Set<string>(require('module').builtinModules);
|
||||
|
||||
/**
|
||||
* Holds information about entry points that are removed because
|
||||
* they have dependencies that are missing (directly or transitively).
|
||||
@ -81,7 +83,7 @@ export class DependencyResolver {
|
||||
|
||||
let sortedEntryPointNodes: string[];
|
||||
if (target) {
|
||||
if (target.compiledByAngular) {
|
||||
if (target.compiledByAngular && graph.hasNode(target.path)) {
|
||||
sortedEntryPointNodes = graph.dependenciesOf(target.path);
|
||||
sortedEntryPointNodes.push(target.path);
|
||||
} else {
|
||||
@ -128,10 +130,12 @@ export class DependencyResolver {
|
||||
angularEntryPoints.forEach(entryPoint => {
|
||||
const {dependencies, missing, deepImports} = this.getEntryPointDependencies(entryPoint);
|
||||
|
||||
if (missing.size > 0) {
|
||||
const missingDependencies = Array.from(missing).filter(dep => !builtinNodeJsModules.has(dep));
|
||||
|
||||
if (missingDependencies.length > 0) {
|
||||
// This entry point has dependencies that are missing
|
||||
// so remove it from the graph.
|
||||
removeNodes(entryPoint, Array.from(missing));
|
||||
removeNodes(entryPoint, missingDependencies);
|
||||
} else {
|
||||
dependencies.forEach(dependencyPath => {
|
||||
if (!graph.hasNode(entryPoint.path)) {
|
||||
@ -173,16 +177,16 @@ export class DependencyResolver {
|
||||
|
||||
private getEntryPointFormatInfo(entryPoint: EntryPoint):
|
||||
{format: EntryPointFormat, path: AbsoluteFsPath} {
|
||||
const properties = Object.keys(entryPoint.packageJson);
|
||||
for (let i = 0; i < properties.length; i++) {
|
||||
const property = properties[i] as EntryPointJsonProperty;
|
||||
const format = getEntryPointFormat(this.fs, entryPoint, property);
|
||||
for (const property of SUPPORTED_FORMAT_PROPERTIES) {
|
||||
const formatPath = entryPoint.packageJson[property];
|
||||
if (formatPath === undefined) continue;
|
||||
|
||||
if (format === 'esm2015' || format === 'esm5' || format === 'umd' || format === 'commonjs') {
|
||||
const formatPath = entryPoint.packageJson[property] !;
|
||||
return {format, path: resolve(entryPoint.path, formatPath)};
|
||||
}
|
||||
const format = getEntryPointFormat(this.fs, entryPoint, property);
|
||||
if (format === undefined) continue;
|
||||
|
||||
return {format, path: resolve(entryPoint.path, formatPath)};
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`There is no appropriate source code format in '${entryPoint.path}' entry-point.`);
|
||||
}
|
||||
|
74
packages/compiler-cli/ngcc/src/execution/api.ts
Normal file
74
packages/compiler-cli/ngcc/src/execution/api.ts
Normal file
@ -0,0 +1,74 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. 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 {EntryPoint, EntryPointJsonProperty} from '../packages/entry_point';
|
||||
|
||||
/** The type of the function that analyzes entry-points and creates the list of tasks. */
|
||||
export type AnalyzeFn = () => {
|
||||
processingMetadataPerEntryPoint: Map<string, EntryPointProcessingMetadata>;
|
||||
tasks: Task[];
|
||||
};
|
||||
|
||||
/**
|
||||
* The type of the function that creates the `compile()` function, which in turn can be used to
|
||||
* process tasks.
|
||||
*/
|
||||
export type CreateCompileFn =
|
||||
(onTaskCompleted: (task: Task, outcome: TaskProcessingOutcome) => void) => (task: Task) => void;
|
||||
|
||||
/**
|
||||
* The type of the function that orchestrates and executes the required work (i.e. analyzes the
|
||||
* entry-points, processes the resulting tasks, does book-keeping and validates the final outcome).
|
||||
*/
|
||||
export type ExecuteFn = (analyzeFn: AnalyzeFn, createCompileFn: CreateCompileFn) => void;
|
||||
|
||||
/** Represents metadata related to the processing of an entry-point. */
|
||||
export interface EntryPointProcessingMetadata {
|
||||
/**
|
||||
* Whether the typings for the entry-point have been successfully processed (or were already
|
||||
* processed).
|
||||
*/
|
||||
hasProcessedTypings: boolean;
|
||||
|
||||
/**
|
||||
* Whether at least one format has been successfully processed (or was already processed) for the
|
||||
* entry-point.
|
||||
*/
|
||||
hasAnyProcessedFormat: boolean;
|
||||
}
|
||||
|
||||
/** Represents a unit of work: processing a specific format property of an entry-point. */
|
||||
export interface Task {
|
||||
/** The `EntryPoint` which needs to be processed as part of the task. */
|
||||
entryPoint: EntryPoint;
|
||||
|
||||
/**
|
||||
* The `package.json` format property to process (i.e. the property which points to the file that
|
||||
* is the program entry-point).
|
||||
*/
|
||||
formatProperty: EntryPointJsonProperty;
|
||||
|
||||
/**
|
||||
* The list of all format properties (including `task.formatProperty`) that should be marked as
|
||||
* processed once the taksk has been completed, because they point to the format-path that will be
|
||||
* processed as part of the task.
|
||||
*/
|
||||
formatPropertiesToMarkAsProcessed: EntryPointJsonProperty[];
|
||||
|
||||
/** Whether to also process typings for this entry-point as part of the task. */
|
||||
processDts: boolean;
|
||||
}
|
||||
|
||||
/** Represents the outcome of processing a `Task`. */
|
||||
export const enum TaskProcessingOutcome {
|
||||
/** The target format property was already processed - didn't have to do anything. */
|
||||
AlreadyProcessed,
|
||||
|
||||
/** Successfully processed the target format property. */
|
||||
Processed,
|
||||
}
|
@ -9,10 +9,10 @@
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {AbsoluteFsPath} from '../../../src/ngtsc/file_system';
|
||||
import {ClassDeclaration, ClassMember, ClassMemberKind, ClassSymbol, CtorParameter, Declaration, Decorator, Import, TypeScriptReflectionHost, isDecoratorIdentifier, reflectObjectLiteral} from '../../../src/ngtsc/reflection';
|
||||
import {ClassDeclaration, ClassMember, ClassMemberKind, ClassSymbol, CtorParameter, Declaration, Decorator, TypeScriptReflectionHost, isDecoratorIdentifier, reflectObjectLiteral} from '../../../src/ngtsc/reflection';
|
||||
import {Logger} from '../logging/logger';
|
||||
import {BundleProgram} from '../packages/bundle_program';
|
||||
import {findAll, getNameText, hasNameIdentifier, isDefined} from '../utils';
|
||||
import {findAll, getNameText, hasNameIdentifier, isDefined, stripDollarSuffix} from '../utils';
|
||||
|
||||
import {ModuleWithProvidersFunction, NgccReflectionHost, PRE_R3_MARKER, SwitchableVariableDeclaration, isSwitchableVariableDeclaration} from './ngcc_host';
|
||||
|
||||
@ -73,6 +73,14 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
*/
|
||||
protected aliasedClassDeclarations = new Map<ts.Declaration, ts.Identifier>();
|
||||
|
||||
/**
|
||||
* Caches the information of the decorators on a class, as the work involved with extracting
|
||||
* decorators is complex and frequently used.
|
||||
*
|
||||
* This map is lazily populated during the first call to `acquireDecoratorInfo` for a given class.
|
||||
*/
|
||||
protected decoratorCache = new Map<ClassDeclaration, DecoratorInfo>();
|
||||
|
||||
constructor(
|
||||
protected logger: Logger, protected isCore: boolean, checker: ts.TypeChecker,
|
||||
dts?: BundleProgram|null) {
|
||||
@ -247,12 +255,8 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
|
||||
/** Gets all decorators of the given class symbol. */
|
||||
getDecoratorsOfSymbol(symbol: ClassSymbol): Decorator[]|null {
|
||||
const decoratorsProperty = this.getStaticProperty(symbol, DECORATORS);
|
||||
if (decoratorsProperty) {
|
||||
return this.getClassDecoratorsFromStaticProperty(decoratorsProperty);
|
||||
} else {
|
||||
return this.getClassDecoratorsFromHelperCall(symbol);
|
||||
}
|
||||
const {classDecorators} = this.acquireDecoratorInfo(symbol);
|
||||
return classDecorators;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -542,6 +546,72 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
return symbol.exports && symbol.exports.get(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the main entry-point for obtaining information on the decorators of a given class. This
|
||||
* information is computed either from static properties if present, or using `tslib.__decorate`
|
||||
* helper calls otherwise. The computed result is cached per class.
|
||||
*
|
||||
* @param classSymbol the class for which decorators should be acquired.
|
||||
* @returns all information of the decorators on the class.
|
||||
*/
|
||||
protected acquireDecoratorInfo(classSymbol: ClassSymbol): DecoratorInfo {
|
||||
if (this.decoratorCache.has(classSymbol.valueDeclaration)) {
|
||||
return this.decoratorCache.get(classSymbol.valueDeclaration) !;
|
||||
}
|
||||
|
||||
// First attempt extracting decorators from static properties.
|
||||
let decoratorInfo = this.computeDecoratorInfoFromStaticProperties(classSymbol);
|
||||
if (decoratorInfo === null) {
|
||||
// If none were present, use the `__decorate` helper calls instead.
|
||||
decoratorInfo = this.computeDecoratorInfoFromHelperCalls(classSymbol);
|
||||
}
|
||||
|
||||
this.decoratorCache.set(classSymbol.valueDeclaration, decoratorInfo);
|
||||
return decoratorInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to compute decorator information from static properties "decorators", "propDecorators"
|
||||
* and "ctorParameters" on the class. If neither of these static properties is present the
|
||||
* library is likely not compiled using tsickle for usage with Closure compiler, in which case
|
||||
* `null` is returned.
|
||||
*
|
||||
* @param classSymbol The class symbol to compute the decorators information for.
|
||||
* @returns All information on the decorators as extracted from static properties, or `null` if
|
||||
* none of the static properties exist.
|
||||
*/
|
||||
protected computeDecoratorInfoFromStaticProperties(classSymbol: ClassSymbol): DecoratorInfo|null {
|
||||
let classDecorators: Decorator[]|null = null;
|
||||
let memberDecorators: Map<string, Decorator[]>|null = null;
|
||||
let constructorParamInfo: ParamInfo[]|null = null;
|
||||
|
||||
const decoratorsProperty = this.getStaticProperty(classSymbol, DECORATORS);
|
||||
if (decoratorsProperty !== undefined) {
|
||||
classDecorators = this.getClassDecoratorsFromStaticProperty(decoratorsProperty);
|
||||
}
|
||||
|
||||
const propDecoratorsProperty = this.getStaticProperty(classSymbol, PROP_DECORATORS);
|
||||
if (propDecoratorsProperty !== undefined) {
|
||||
memberDecorators = this.getMemberDecoratorsFromStaticProperty(propDecoratorsProperty);
|
||||
}
|
||||
|
||||
const constructorParamsProperty = this.getStaticProperty(classSymbol, CONSTRUCTOR_PARAMS);
|
||||
if (constructorParamsProperty !== undefined) {
|
||||
constructorParamInfo = this.getParamInfoFromStaticProperty(constructorParamsProperty);
|
||||
}
|
||||
|
||||
// If none of the static properties were present, no decorator info could be computed.
|
||||
if (classDecorators === null && memberDecorators === null && constructorParamInfo === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
classDecorators,
|
||||
memberDecorators: memberDecorators || new Map<string, Decorator[]>(),
|
||||
constructorParamInfo: constructorParamInfo || [],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all class decorators for the given class, where the decorators are declared
|
||||
* via a static property. For example:
|
||||
@ -570,32 +640,6 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all class decorators for the given class, where the decorators are declared
|
||||
* via the `__decorate` helper method. For example:
|
||||
*
|
||||
* ```
|
||||
* let SomeDirective = class SomeDirective {}
|
||||
* SomeDirective = __decorate([
|
||||
* Directive({ selector: '[someDirective]' }),
|
||||
* ], SomeDirective);
|
||||
* ```
|
||||
*
|
||||
* @param symbol the class whose decorators we want to get.
|
||||
* @returns an array of decorators or null if none where found.
|
||||
*/
|
||||
protected getClassDecoratorsFromHelperCall(symbol: ClassSymbol): Decorator[]|null {
|
||||
const decorators: Decorator[] = [];
|
||||
const helperCalls = this.getHelperCallsForClass(symbol, '__decorate');
|
||||
helperCalls.forEach(helperCall => {
|
||||
const {classDecorators} =
|
||||
this.reflectDecoratorsFromHelperCall(helperCall, makeClassTargetFilter(symbol.name));
|
||||
classDecorators.filter(decorator => this.isFromCore(decorator))
|
||||
.forEach(decorator => decorators.push(decorator));
|
||||
});
|
||||
return decorators.length ? decorators : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Examine a symbol which should be of a class, and return metadata about its members.
|
||||
*
|
||||
@ -606,7 +650,11 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
const members: ClassMember[] = [];
|
||||
|
||||
// The decorators map contains all the properties that are decorated
|
||||
const decoratorsMap = this.getMemberDecorators(symbol);
|
||||
const {memberDecorators} = this.acquireDecoratorInfo(symbol);
|
||||
|
||||
// Make a copy of the decorators as successfully reflected members delete themselves from the
|
||||
// map, so that any leftovers can be easily dealt with.
|
||||
const decoratorsMap = new Map(memberDecorators);
|
||||
|
||||
// The member map contains all the method (instance and static); and any instance properties
|
||||
// that are initialized in the class.
|
||||
@ -675,21 +723,6 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
return members;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the member decorators for the given class.
|
||||
* @param classSymbol the class whose member decorators we are interested in.
|
||||
* @returns a map whose keys are the name of the members and whose values are collections of
|
||||
* decorators for the given member.
|
||||
*/
|
||||
protected getMemberDecorators(classSymbol: ClassSymbol): Map<string, Decorator[]> {
|
||||
const decoratorsProperty = this.getStaticProperty(classSymbol, PROP_DECORATORS);
|
||||
if (decoratorsProperty) {
|
||||
return this.getMemberDecoratorsFromStaticProperty(decoratorsProperty);
|
||||
} else {
|
||||
return this.getMemberDecoratorsFromHelperCalls(classSymbol);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Member decorators may be declared as static properties of the class:
|
||||
*
|
||||
@ -724,7 +757,21 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
}
|
||||
|
||||
/**
|
||||
* Member decorators may be declared via helper call statements.
|
||||
* For a given class symbol, collects all decorator information from tslib helper methods, as
|
||||
* generated by TypeScript into emitted JavaScript files.
|
||||
*
|
||||
* Class decorators are extracted from calls to `tslib.__decorate` that look as follows:
|
||||
*
|
||||
* ```
|
||||
* let SomeDirective = class SomeDirective {}
|
||||
* SomeDirective = __decorate([
|
||||
* Directive({ selector: '[someDirective]' }),
|
||||
* ], SomeDirective);
|
||||
* ```
|
||||
*
|
||||
* The extraction of member decorators is similar, with the distinction that its 2nd and 3rd
|
||||
* argument correspond with a "prototype" target and the name of the member to which the
|
||||
* decorators apply.
|
||||
*
|
||||
* ```
|
||||
* __decorate([
|
||||
@ -733,102 +780,188 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
* ], SomeDirective.prototype, "input1", void 0);
|
||||
* ```
|
||||
*
|
||||
* @param classSymbol the class whose member decorators we are interested in.
|
||||
* @returns a map whose keys are the name of the members and whose values are collections of
|
||||
* decorators for the given member.
|
||||
* @param classSymbol The class symbol for which decorators should be extracted.
|
||||
* @returns All information on the decorators of the class.
|
||||
*/
|
||||
protected getMemberDecoratorsFromHelperCalls(classSymbol: ClassSymbol): Map<string, Decorator[]> {
|
||||
const memberDecoratorMap = new Map<string, Decorator[]>();
|
||||
const helperCalls = this.getHelperCallsForClass(classSymbol, '__decorate');
|
||||
helperCalls.forEach(helperCall => {
|
||||
const {memberDecorators} = this.reflectDecoratorsFromHelperCall(
|
||||
helperCall, makeMemberTargetFilter(classSymbol.name));
|
||||
memberDecorators.forEach((decorators, memberName) => {
|
||||
if (memberName) {
|
||||
const memberDecorators =
|
||||
memberDecoratorMap.has(memberName) ? memberDecoratorMap.get(memberName) ! : [];
|
||||
const coreDecorators = decorators.filter(decorator => this.isFromCore(decorator));
|
||||
memberDecoratorMap.set(memberName, memberDecorators.concat(coreDecorators));
|
||||
}
|
||||
});
|
||||
});
|
||||
return memberDecoratorMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract decorator info from `__decorate` helper function calls.
|
||||
* @param helperCall the call to a helper that may contain decorator calls
|
||||
* @param targetFilter a function to filter out targets that we are not interested in.
|
||||
* @returns a mapping from member name to decorators, where the key is either the name of the
|
||||
* member or `undefined` if it refers to decorators on the class as a whole.
|
||||
*/
|
||||
protected reflectDecoratorsFromHelperCall(
|
||||
helperCall: ts.CallExpression, targetFilter: TargetFilter):
|
||||
{classDecorators: Decorator[], memberDecorators: Map<string, Decorator[]>} {
|
||||
const classDecorators: Decorator[] = [];
|
||||
protected computeDecoratorInfoFromHelperCalls(classSymbol: ClassSymbol): DecoratorInfo {
|
||||
let classDecorators: Decorator[]|null = null;
|
||||
const memberDecorators = new Map<string, Decorator[]>();
|
||||
const constructorParamInfo: ParamInfo[] = [];
|
||||
|
||||
// First check that the `target` argument is correct
|
||||
if (targetFilter(helperCall.arguments[1])) {
|
||||
// Grab the `decorators` argument which should be an array of calls
|
||||
const decoratorCalls = helperCall.arguments[0];
|
||||
if (decoratorCalls && ts.isArrayLiteralExpression(decoratorCalls)) {
|
||||
decoratorCalls.elements.forEach(element => {
|
||||
// We only care about those elements that are actual calls
|
||||
if (ts.isCallExpression(element)) {
|
||||
const decorator = this.reflectDecoratorCall(element);
|
||||
if (decorator) {
|
||||
const keyArg = helperCall.arguments[2];
|
||||
const keyName = keyArg && ts.isStringLiteral(keyArg) ? keyArg.text : undefined;
|
||||
if (keyName === undefined) {
|
||||
classDecorators.push(decorator);
|
||||
} else {
|
||||
const decorators =
|
||||
memberDecorators.has(keyName) ? memberDecorators.get(keyName) ! : [];
|
||||
decorators.push(decorator);
|
||||
memberDecorators.set(keyName, decorators);
|
||||
}
|
||||
}
|
||||
const getConstructorParamInfo = (index: number) => {
|
||||
let param = constructorParamInfo[index];
|
||||
if (param === undefined) {
|
||||
param = constructorParamInfo[index] = {decorators: null, typeExpression: null};
|
||||
}
|
||||
return param;
|
||||
};
|
||||
|
||||
// All relevant information can be extracted from calls to `__decorate`, obtain these first.
|
||||
// Note that although the helper calls are retrieved using the class symbol, the result may
|
||||
// contain helper calls corresponding with unrelated classes. Therefore, each helper call still
|
||||
// has to be checked to actually correspond with the class symbol.
|
||||
const helperCalls = this.getHelperCallsForClass(classSymbol, '__decorate');
|
||||
|
||||
for (const helperCall of helperCalls) {
|
||||
if (isClassDecorateCall(helperCall, classSymbol.name)) {
|
||||
// This `__decorate` call is targeting the class itself.
|
||||
const helperArgs = helperCall.arguments[0];
|
||||
|
||||
for (const element of helperArgs.elements) {
|
||||
const entry = this.reflectDecorateHelperEntry(element);
|
||||
if (entry === null) {
|
||||
continue;
|
||||
}
|
||||
});
|
||||
|
||||
if (entry.type === 'decorator') {
|
||||
// The helper arg was reflected to represent an actual decorator
|
||||
if (this.isFromCore(entry.decorator)) {
|
||||
(classDecorators || (classDecorators = [])).push(entry.decorator);
|
||||
}
|
||||
} else if (entry.type === 'param:decorators') {
|
||||
// The helper arg represents a decorator for a parameter. Since it's applied to the
|
||||
// class, it corresponds with a constructor parameter of the class.
|
||||
const param = getConstructorParamInfo(entry.index);
|
||||
(param.decorators || (param.decorators = [])).push(entry.decorator);
|
||||
} else if (entry.type === 'params') {
|
||||
// The helper arg represents the types of the parameters. Since it's applied to the
|
||||
// class, it corresponds with the constructor parameters of the class.
|
||||
entry.types.forEach(
|
||||
(type, index) => getConstructorParamInfo(index).typeExpression = type);
|
||||
}
|
||||
}
|
||||
} else if (isMemberDecorateCall(helperCall, classSymbol.name)) {
|
||||
// The `__decorate` call is targeting a member of the class
|
||||
const helperArgs = helperCall.arguments[0];
|
||||
const memberName = helperCall.arguments[2].text;
|
||||
|
||||
for (const element of helperArgs.elements) {
|
||||
const entry = this.reflectDecorateHelperEntry(element);
|
||||
if (entry === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.type === 'decorator') {
|
||||
// The helper arg was reflected to represent an actual decorator.
|
||||
if (this.isFromCore(entry.decorator)) {
|
||||
const decorators =
|
||||
memberDecorators.has(memberName) ? memberDecorators.get(memberName) ! : [];
|
||||
decorators.push(entry.decorator);
|
||||
memberDecorators.set(memberName, decorators);
|
||||
}
|
||||
} else {
|
||||
// Information on decorated parameters is not interesting for ngcc, so it's ignored.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {classDecorators, memberDecorators};
|
||||
|
||||
return {classDecorators, memberDecorators, constructorParamInfo};
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the decorator information from a call to a decorator as a function.
|
||||
* This happens when the decorators has been used in a `__decorate` helper call.
|
||||
* For example:
|
||||
* Extract the details of an entry within a `__decorate` helper call. For example, given the
|
||||
* following code:
|
||||
*
|
||||
* ```
|
||||
* __decorate([
|
||||
* Directive({ selector: '[someDirective]' }),
|
||||
* tslib_1.__param(2, Inject(INJECTED_TOKEN)),
|
||||
* tslib_1.__metadata("design:paramtypes", [ViewContainerRef, TemplateRef, String])
|
||||
* ], SomeDirective);
|
||||
* ```
|
||||
*
|
||||
* Here the `Directive` decorator is decorating `SomeDirective` and the options for
|
||||
* the decorator are passed as arguments to the `Directive()` call.
|
||||
* it can be seen that there are calls to regular decorators (the `Directive`) and calls into
|
||||
* `tslib` functions which have been inserted by TypeScript. Therefore, this function classifies
|
||||
* a call to correspond with
|
||||
* 1. a real decorator like `Directive` above, or
|
||||
* 2. a decorated parameter, corresponding with `__param` calls from `tslib`, or
|
||||
* 3. the type information of parameters, corresponding with `__metadata` call from `tslib`
|
||||
*
|
||||
* @param call the call to the decorator.
|
||||
* @returns a decorator containing the reflected information, or null if the call
|
||||
* is not a valid decorator call.
|
||||
* @param expression the expression that needs to be reflected into a `DecorateHelperEntry`
|
||||
* @returns an object that indicates which of the three categories the call represents, together
|
||||
* with the reflected information of the call, or null if the call is not a valid decorate call.
|
||||
*/
|
||||
protected reflectDecoratorCall(call: ts.CallExpression): Decorator|null {
|
||||
const decoratorExpression = call.expression;
|
||||
if (isDecoratorIdentifier(decoratorExpression)) {
|
||||
// We found a decorator!
|
||||
const decoratorIdentifier =
|
||||
ts.isIdentifier(decoratorExpression) ? decoratorExpression : decoratorExpression.name;
|
||||
protected reflectDecorateHelperEntry(expression: ts.Expression): DecorateHelperEntry|null {
|
||||
// We only care about those elements that are actual calls
|
||||
if (!ts.isCallExpression(expression)) {
|
||||
return null;
|
||||
}
|
||||
const call = expression;
|
||||
|
||||
const helperName = getCalleeName(call);
|
||||
if (helperName === '__metadata') {
|
||||
// This is a `tslib.__metadata` call, reflect to arguments into a `ParameterTypes` object
|
||||
// if the metadata key is "design:paramtypes".
|
||||
const key = call.arguments[0];
|
||||
if (key === undefined || !ts.isStringLiteral(key) || key.text !== 'design:paramtypes') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const value = call.arguments[1];
|
||||
if (value === undefined || !ts.isArrayLiteralExpression(value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
name: decoratorIdentifier.text,
|
||||
identifier: decoratorIdentifier,
|
||||
import: this.getImportOfIdentifier(decoratorIdentifier),
|
||||
node: call,
|
||||
args: Array.from(call.arguments)
|
||||
type: 'params',
|
||||
types: Array.from(value.elements),
|
||||
};
|
||||
}
|
||||
return null;
|
||||
|
||||
if (helperName === '__param') {
|
||||
// This is a `tslib.__param` call that is reflected into a `ParameterDecorators` object.
|
||||
const indexArg = call.arguments[0];
|
||||
const index = indexArg && ts.isNumericLiteral(indexArg) ? parseInt(indexArg.text, 10) : NaN;
|
||||
if (isNaN(index)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const decoratorCall = call.arguments[1];
|
||||
if (decoratorCall === undefined || !ts.isCallExpression(decoratorCall)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const decorator = this.reflectDecoratorCall(decoratorCall);
|
||||
if (decorator === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'param:decorators',
|
||||
index,
|
||||
decorator,
|
||||
};
|
||||
}
|
||||
|
||||
// Otherwise attempt to reflect it as a regular decorator.
|
||||
const decorator = this.reflectDecoratorCall(call);
|
||||
if (decorator === null) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
type: 'decorator',
|
||||
decorator,
|
||||
};
|
||||
}
|
||||
|
||||
protected reflectDecoratorCall(call: ts.CallExpression): Decorator|null {
|
||||
const decoratorExpression = call.expression;
|
||||
if (!isDecoratorIdentifier(decoratorExpression)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// We found a decorator!
|
||||
const decoratorIdentifier =
|
||||
ts.isIdentifier(decoratorExpression) ? decoratorExpression : decoratorExpression.name;
|
||||
|
||||
return {
|
||||
name: decoratorIdentifier.text,
|
||||
identifier: decoratorExpression,
|
||||
import: this.getImportOfIdentifier(decoratorIdentifier),
|
||||
node: call,
|
||||
args: Array.from(call.arguments),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1070,14 +1203,11 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
*/
|
||||
protected getConstructorParamInfo(
|
||||
classSymbol: ClassSymbol, parameterNodes: ts.ParameterDeclaration[]): CtorParameter[] {
|
||||
const paramsProperty = this.getStaticProperty(classSymbol, CONSTRUCTOR_PARAMS);
|
||||
const paramInfo: ParamInfo[]|null = paramsProperty ?
|
||||
this.getParamInfoFromStaticProperty(paramsProperty) :
|
||||
this.getParamInfoFromHelperCall(classSymbol, parameterNodes);
|
||||
const {constructorParamInfo} = this.acquireDecoratorInfo(classSymbol);
|
||||
|
||||
return parameterNodes.map((node, index) => {
|
||||
const {decorators, typeExpression} = paramInfo && paramInfo[index] ?
|
||||
paramInfo[index] :
|
||||
const {decorators, typeExpression} = constructorParamInfo[index] ?
|
||||
constructorParamInfo[index] :
|
||||
{decorators: null, typeExpression: null};
|
||||
const nameNode = node.name;
|
||||
return {
|
||||
@ -1153,58 +1283,6 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parameter type and decorators for a class where the information is stored via
|
||||
* calls to `__decorate` helpers.
|
||||
*
|
||||
* Reflect over the helpers to find the decorators and types about each of
|
||||
* the class's constructor parameters.
|
||||
*
|
||||
* @param classSymbol the class whose parameter info we want to get.
|
||||
* @param parameterNodes the array of TypeScript parameter nodes for this class's constructor.
|
||||
* @returns an array of objects containing the type and decorators for each parameter.
|
||||
*/
|
||||
protected getParamInfoFromHelperCall(
|
||||
classSymbol: ClassSymbol, parameterNodes: ts.ParameterDeclaration[]): ParamInfo[] {
|
||||
const parameters: ParamInfo[] =
|
||||
parameterNodes.map(() => ({typeExpression: null, decorators: null}));
|
||||
const helperCalls = this.getHelperCallsForClass(classSymbol, '__decorate');
|
||||
helperCalls.forEach(helperCall => {
|
||||
const {classDecorators} =
|
||||
this.reflectDecoratorsFromHelperCall(helperCall, makeClassTargetFilter(classSymbol.name));
|
||||
classDecorators.forEach(call => {
|
||||
switch (call.name) {
|
||||
case '__metadata':
|
||||
const metadataArg = call.args && call.args[0];
|
||||
const typesArg = call.args && call.args[1];
|
||||
const isParamTypeDecorator = metadataArg && ts.isStringLiteral(metadataArg) &&
|
||||
metadataArg.text === 'design:paramtypes';
|
||||
const types = typesArg && ts.isArrayLiteralExpression(typesArg) && typesArg.elements;
|
||||
if (isParamTypeDecorator && types) {
|
||||
types.forEach((type, index) => parameters[index].typeExpression = type);
|
||||
}
|
||||
break;
|
||||
case '__param':
|
||||
const paramIndexArg = call.args && call.args[0];
|
||||
const decoratorCallArg = call.args && call.args[1];
|
||||
const paramIndex = paramIndexArg && ts.isNumericLiteral(paramIndexArg) ?
|
||||
parseInt(paramIndexArg.text, 10) :
|
||||
NaN;
|
||||
const decorator = decoratorCallArg && ts.isCallExpression(decoratorCallArg) ?
|
||||
this.reflectDecoratorCall(decoratorCallArg) :
|
||||
null;
|
||||
if (!isNaN(paramIndex) && decorator) {
|
||||
const decorators = parameters[paramIndex].decorators =
|
||||
parameters[paramIndex].decorators || [];
|
||||
decorators.push(decorator);
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
return parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search statements related to the given class for calls to the specified helper.
|
||||
* @param classSymbol the class whose helper calls we are interested in.
|
||||
@ -1377,6 +1455,72 @@ export type ParamInfo = {
|
||||
typeExpression: ts.Expression | null
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a call to `tslib.__metadata` as present in `tslib.__decorate` calls. This is a
|
||||
* synthetic decorator inserted by TypeScript that contains reflection information about the
|
||||
* target of the decorator, i.e. the class or property.
|
||||
*/
|
||||
export interface ParameterTypes {
|
||||
type: 'params';
|
||||
types: ts.Expression[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a call to `tslib.__param` as present in `tslib.__decorate` calls. This contains
|
||||
* information on any decorators were applied to a certain parameter.
|
||||
*/
|
||||
export interface ParameterDecorators {
|
||||
type: 'param:decorators';
|
||||
index: number;
|
||||
decorator: Decorator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a call to a decorator as it was present in the original source code, as present in
|
||||
* `tslib.__decorate` calls.
|
||||
*/
|
||||
export interface DecoratorCall {
|
||||
type: 'decorator';
|
||||
decorator: Decorator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the different kinds of decorate helpers that may be present as first argument to
|
||||
* `tslib.__decorate`, as follows:
|
||||
*
|
||||
* ```
|
||||
* __decorate([
|
||||
* Directive({ selector: '[someDirective]' }),
|
||||
* tslib_1.__param(2, Inject(INJECTED_TOKEN)),
|
||||
* tslib_1.__metadata("design:paramtypes", [ViewContainerRef, TemplateRef, String])
|
||||
* ], SomeDirective);
|
||||
* ```
|
||||
*/
|
||||
export type DecorateHelperEntry = ParameterTypes | ParameterDecorators | DecoratorCall;
|
||||
|
||||
/**
|
||||
* The recorded decorator information of a single class. This information is cached in the host.
|
||||
*/
|
||||
interface DecoratorInfo {
|
||||
/**
|
||||
* All decorators that were present on the class. If no decorators were present, this is `null`
|
||||
*/
|
||||
classDecorators: Decorator[]|null;
|
||||
|
||||
/**
|
||||
* All decorators per member of the class they were present on.
|
||||
*/
|
||||
memberDecorators: Map<string, Decorator[]>;
|
||||
|
||||
/**
|
||||
* Represents the constructor parameter information, such as the type of a parameter and all
|
||||
* decorators for a certain parameter. Indices in this array correspond with the parameter's index
|
||||
* in the constructor. Note that this array may be sparse, i.e. certain constructor parameters may
|
||||
* not have any info recorded.
|
||||
*/
|
||||
constructorParamInfo: ParamInfo[];
|
||||
}
|
||||
|
||||
/**
|
||||
* A statement node that represents an assignment.
|
||||
*/
|
||||
@ -1397,27 +1541,55 @@ export function isAssignment(node: ts.Node): node is ts.AssignmentExpression<ts.
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of a function that can be used to filter out helpers based on their target.
|
||||
* This is used in `reflectDecoratorsFromHelperCall()`.
|
||||
* Tests whether the provided call expression targets a class, by verifying its arguments are
|
||||
* according to the following form:
|
||||
*
|
||||
* ```
|
||||
* __decorate([], SomeDirective);
|
||||
* ```
|
||||
*
|
||||
* @param call the call expression that is tested to represent a class decorator call.
|
||||
* @param className the name of the class that the call needs to correspond with.
|
||||
*/
|
||||
export type TargetFilter = (target: ts.Expression) => boolean;
|
||||
export function isClassDecorateCall(call: ts.CallExpression, className: string):
|
||||
call is ts.CallExpression&{arguments: [ts.ArrayLiteralExpression, ts.Expression]} {
|
||||
const helperArgs = call.arguments[0];
|
||||
if (helperArgs === undefined || !ts.isArrayLiteralExpression(helperArgs)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a function that tests whether the given expression is a class target.
|
||||
* @param className the name of the class we want to target.
|
||||
*/
|
||||
export function makeClassTargetFilter(className: string): TargetFilter {
|
||||
return (target: ts.Expression): boolean => ts.isIdentifier(target) && target.text === className;
|
||||
const target = call.arguments[1];
|
||||
return target !== undefined && ts.isIdentifier(target) && target.text === className;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a function that tests whether the given expression is a class member target.
|
||||
* @param className the name of the class we want to target.
|
||||
* Tests whether the provided call expression targets a member of the class, by verifying its
|
||||
* arguments are according to the following form:
|
||||
*
|
||||
* ```
|
||||
* __decorate([], SomeDirective.prototype, "member", void 0);
|
||||
* ```
|
||||
*
|
||||
* @param call the call expression that is tested to represent a member decorator call.
|
||||
* @param className the name of the class that the call needs to correspond with.
|
||||
*/
|
||||
export function makeMemberTargetFilter(className: string): TargetFilter {
|
||||
return (target: ts.Expression): boolean => ts.isPropertyAccessExpression(target) &&
|
||||
ts.isIdentifier(target.expression) && target.expression.text === className &&
|
||||
target.name.text === 'prototype';
|
||||
export function isMemberDecorateCall(call: ts.CallExpression, className: string):
|
||||
call is ts.CallExpression&
|
||||
{arguments: [ts.ArrayLiteralExpression, ts.StringLiteral, ts.StringLiteral]} {
|
||||
const helperArgs = call.arguments[0];
|
||||
if (helperArgs === undefined || !ts.isArrayLiteralExpression(helperArgs)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const target = call.arguments[1];
|
||||
if (target === undefined || !ts.isPropertyAccessExpression(target) ||
|
||||
!ts.isIdentifier(target.expression) || target.expression.text !== className ||
|
||||
target.name.text !== 'prototype') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const memberName = call.arguments[2];
|
||||
return memberName !== undefined && ts.isStringLiteral(memberName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1435,10 +1607,10 @@ export function getPropertyValueFromSymbol(propSymbol: ts.Symbol): ts.Expression
|
||||
*/
|
||||
function getCalleeName(call: ts.CallExpression): string|null {
|
||||
if (ts.isIdentifier(call.expression)) {
|
||||
return call.expression.text;
|
||||
return stripDollarSuffix(call.expression.text);
|
||||
}
|
||||
if (ts.isPropertyAccessExpression(call.expression)) {
|
||||
return call.expression.name.text;
|
||||
return stripDollarSuffix(call.expression.name.text);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import * as ts from 'typescript';
|
||||
|
||||
import {ClassDeclaration, ClassMember, ClassMemberKind, ClassSymbol, CtorParameter, Declaration, Decorator, FunctionDefinition, Parameter, TsHelperFn, isNamedVariableDeclaration, reflectObjectLiteral} from '../../../src/ngtsc/reflection';
|
||||
import {isFromDtsFile} from '../../../src/ngtsc/util/src/typescript';
|
||||
import {getNameText, hasNameIdentifier} from '../utils';
|
||||
import {getNameText, hasNameIdentifier, stripDollarSuffix} from '../utils';
|
||||
|
||||
import {Esm2015ReflectionHost, ParamInfo, getPropertyValueFromSymbol, isAssignmentStatement} from './esm2015_host';
|
||||
|
||||
@ -659,7 +659,9 @@ function reflectArrayElement(element: ts.Expression) {
|
||||
* helper.
|
||||
*/
|
||||
function getTsHelperFn(node: ts.NamedDeclaration): TsHelperFn|null {
|
||||
const name = node.name !== undefined && ts.isIdentifier(node.name) && node.name.text;
|
||||
const name = node.name !== undefined && ts.isIdentifier(node.name) ?
|
||||
stripDollarSuffix(node.name.text) :
|
||||
null;
|
||||
|
||||
if (name === '__spread') {
|
||||
return TsHelperFn.Spread;
|
||||
|
@ -6,6 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {AbsoluteFsPath, FileSystem, absoluteFrom, dirname, getFileSystem, resolve} from '../../src/ngtsc/file_system';
|
||||
|
||||
import {CommonJsDependencyHost} from './dependencies/commonjs_dependency_host';
|
||||
import {DependencyResolver, InvalidEntryPoint, SortedEntryPointsInfo} from './dependencies/dependency_resolver';
|
||||
import {EsmDependencyHost} from './dependencies/esm_dependency_host';
|
||||
@ -13,11 +14,12 @@ import {ModuleResolver} from './dependencies/module_resolver';
|
||||
import {UmdDependencyHost} from './dependencies/umd_dependency_host';
|
||||
import {DirectoryWalkerEntryPointFinder} from './entry_point_finder/directory_walker_entry_point_finder';
|
||||
import {TargetedEntryPointFinder} from './entry_point_finder/targeted_entry_point_finder';
|
||||
import {AnalyzeFn, CreateCompileFn, EntryPointProcessingMetadata, ExecuteFn, Task, TaskProcessingOutcome} from './execution/api';
|
||||
import {ConsoleLogger, LogLevel} from './logging/console_logger';
|
||||
import {Logger} from './logging/logger';
|
||||
import {hasBeenProcessed, markAsProcessed} from './packages/build_marker';
|
||||
import {NgccConfiguration} from './packages/configuration';
|
||||
import {EntryPoint, EntryPointFormat, EntryPointJsonProperty, SUPPORTED_FORMAT_PROPERTIES, getEntryPointFormat} from './packages/entry_point';
|
||||
import {EntryPoint, EntryPointJsonProperty, EntryPointPackageJson, SUPPORTED_FORMAT_PROPERTIES, getEntryPointFormat} from './packages/entry_point';
|
||||
import {makeEntryPointBundle} from './packages/entry_point_bundle';
|
||||
import {Transformer} from './packages/transformer';
|
||||
import {PathMappings} from './utils';
|
||||
@ -25,6 +27,7 @@ import {FileWriter} from './writing/file_writer';
|
||||
import {InPlaceFileWriter} from './writing/in_place_file_writer';
|
||||
import {NewEntryPointFileWriter} from './writing/new_entry_point_file_writer';
|
||||
|
||||
|
||||
/**
|
||||
* The options to configure the ngcc compiler.
|
||||
*/
|
||||
@ -68,8 +71,6 @@ export interface NgccOptions {
|
||||
fileSystem?: FileSystem;
|
||||
}
|
||||
|
||||
const SUPPORTED_FORMATS: EntryPointFormat[] = ['esm5', 'esm2015', 'umd', 'commonjs'];
|
||||
|
||||
/**
|
||||
* This is the main entry-point into ngcc (aNGular Compatibility Compiler).
|
||||
*
|
||||
@ -83,82 +84,171 @@ export function mainNgcc(
|
||||
compileAllFormats = true, createNewEntryPointFormats = false,
|
||||
logger = new ConsoleLogger(LogLevel.info), pathMappings}: NgccOptions): void {
|
||||
const fileSystem = getFileSystem();
|
||||
const transformer = new Transformer(fileSystem, logger);
|
||||
const moduleResolver = new ModuleResolver(fileSystem, pathMappings);
|
||||
const esmDependencyHost = new EsmDependencyHost(fileSystem, moduleResolver);
|
||||
const umdDependencyHost = new UmdDependencyHost(fileSystem, moduleResolver);
|
||||
const commonJsDependencyHost = new CommonJsDependencyHost(fileSystem, moduleResolver);
|
||||
const resolver = new DependencyResolver(fileSystem, logger, {
|
||||
esm5: esmDependencyHost,
|
||||
esm2015: esmDependencyHost,
|
||||
umd: umdDependencyHost,
|
||||
commonjs: commonJsDependencyHost
|
||||
});
|
||||
const absBasePath = absoluteFrom(basePath);
|
||||
const config = new NgccConfiguration(fileSystem, dirname(absBasePath));
|
||||
const fileWriter = getFileWriter(fileSystem, createNewEntryPointFormats);
|
||||
const entryPoints = getEntryPoints(
|
||||
fileSystem, config, logger, resolver, absBasePath, targetEntryPointPath, pathMappings,
|
||||
propertiesToConsider, compileAllFormats);
|
||||
for (const entryPoint of entryPoints) {
|
||||
// Are we compiling the Angular core?
|
||||
const isCore = entryPoint.name === '@angular/core';
|
||||
|
||||
const compiledFormats = new Set<string>();
|
||||
const entryPointPackageJson = entryPoint.packageJson;
|
||||
const entryPointPackageJsonPath = fileSystem.resolve(entryPoint.path, 'package.json');
|
||||
// The function for performing the analysis.
|
||||
const analyzeFn: AnalyzeFn = () => {
|
||||
const supportedPropertiesToConsider = ensureSupportedProperties(propertiesToConsider);
|
||||
|
||||
const hasProcessedDts = hasBeenProcessed(entryPointPackageJson, 'typings');
|
||||
const moduleResolver = new ModuleResolver(fileSystem, pathMappings);
|
||||
const esmDependencyHost = new EsmDependencyHost(fileSystem, moduleResolver);
|
||||
const umdDependencyHost = new UmdDependencyHost(fileSystem, moduleResolver);
|
||||
const commonJsDependencyHost = new CommonJsDependencyHost(fileSystem, moduleResolver);
|
||||
const dependencyResolver = new DependencyResolver(fileSystem, logger, {
|
||||
esm5: esmDependencyHost,
|
||||
esm2015: esmDependencyHost,
|
||||
umd: umdDependencyHost,
|
||||
commonjs: commonJsDependencyHost
|
||||
});
|
||||
|
||||
for (let i = 0; i < propertiesToConsider.length; i++) {
|
||||
const property = propertiesToConsider[i] as EntryPointJsonProperty;
|
||||
const formatPath = entryPointPackageJson[property];
|
||||
const format = getEntryPointFormat(fileSystem, entryPoint, property);
|
||||
const absBasePath = absoluteFrom(basePath);
|
||||
const config = new NgccConfiguration(fileSystem, dirname(absBasePath));
|
||||
const entryPoints = getEntryPoints(
|
||||
fileSystem, config, logger, dependencyResolver, absBasePath, targetEntryPointPath,
|
||||
pathMappings, supportedPropertiesToConsider, compileAllFormats);
|
||||
|
||||
// No format then this property is not supposed to be compiled.
|
||||
if (!formatPath || !format || SUPPORTED_FORMATS.indexOf(format) === -1) continue;
|
||||
const processingMetadataPerEntryPoint = new Map<string, EntryPointProcessingMetadata>();
|
||||
const tasks: Task[] = [];
|
||||
|
||||
if (hasBeenProcessed(entryPointPackageJson, property)) {
|
||||
compiledFormats.add(formatPath);
|
||||
logger.debug(`Skipping ${entryPoint.name} : ${property} (already compiled).`);
|
||||
continue;
|
||||
for (const entryPoint of entryPoints) {
|
||||
const packageJson = entryPoint.packageJson;
|
||||
const hasProcessedTypings = hasBeenProcessed(packageJson, 'typings');
|
||||
const {propertiesToProcess, propertyToPropertiesToMarkAsProcessed} =
|
||||
getPropertiesToProcessAndMarkAsProcessed(packageJson, supportedPropertiesToConsider);
|
||||
let processDts = !hasProcessedTypings;
|
||||
|
||||
for (const formatProperty of propertiesToProcess) {
|
||||
const formatPropertiesToMarkAsProcessed =
|
||||
propertyToPropertiesToMarkAsProcessed.get(formatProperty) !;
|
||||
tasks.push({entryPoint, formatProperty, formatPropertiesToMarkAsProcessed, processDts});
|
||||
|
||||
// Only process typings for the first property (if not already processed).
|
||||
processDts = false;
|
||||
}
|
||||
|
||||
const isFirstFormat = compiledFormats.size === 0;
|
||||
const processDts = !hasProcessedDts && isFirstFormat;
|
||||
|
||||
// We don't break if this if statement fails because we still want to mark
|
||||
// the property as processed even if its underlying format has been built already.
|
||||
if (!compiledFormats.has(formatPath) && (compileAllFormats || isFirstFormat)) {
|
||||
const bundle = makeEntryPointBundle(
|
||||
fileSystem, entryPoint, formatPath, isCore, property, format, processDts, pathMappings,
|
||||
true);
|
||||
if (bundle) {
|
||||
logger.info(`Compiling ${entryPoint.name} : ${property} as ${format}`);
|
||||
const transformedFiles = transformer.transform(bundle);
|
||||
fileWriter.writeBundle(entryPoint, bundle, transformedFiles);
|
||||
compiledFormats.add(formatPath);
|
||||
} else {
|
||||
logger.warn(
|
||||
`Skipping ${entryPoint.name} : ${format} (no valid entry point file for this format).`);
|
||||
}
|
||||
}
|
||||
|
||||
// Either this format was just compiled or its underlying format was compiled because of a
|
||||
// previous property.
|
||||
if (compiledFormats.has(formatPath)) {
|
||||
markAsProcessed(fileSystem, entryPointPackageJson, entryPointPackageJsonPath, property);
|
||||
if (processDts) {
|
||||
markAsProcessed(fileSystem, entryPointPackageJson, entryPointPackageJsonPath, 'typings');
|
||||
}
|
||||
}
|
||||
processingMetadataPerEntryPoint.set(entryPoint.path, {
|
||||
hasProcessedTypings,
|
||||
hasAnyProcessedFormat: false,
|
||||
});
|
||||
}
|
||||
|
||||
if (compiledFormats.size === 0) {
|
||||
return {processingMetadataPerEntryPoint, tasks};
|
||||
};
|
||||
|
||||
// The function for creating the `compile()` function.
|
||||
const createCompileFn: CreateCompileFn = onTaskCompleted => {
|
||||
const fileWriter = getFileWriter(fileSystem, createNewEntryPointFormats);
|
||||
const transformer = new Transformer(fileSystem, logger);
|
||||
|
||||
return (task: Task) => {
|
||||
const {entryPoint, formatProperty, formatPropertiesToMarkAsProcessed, processDts} = task;
|
||||
|
||||
const isCore = entryPoint.name === '@angular/core'; // Are we compiling the Angular core?
|
||||
const packageJson = entryPoint.packageJson;
|
||||
const formatPath = packageJson[formatProperty];
|
||||
const format = getEntryPointFormat(fileSystem, entryPoint, formatProperty);
|
||||
|
||||
// All properties listed in `propertiesToProcess` are guaranteed to point to a format-path
|
||||
// (i.e. they exist in `entryPointPackageJson`). Furthermore, they are also guaranteed to be
|
||||
// among `SUPPORTED_FORMAT_PROPERTIES`.
|
||||
// Based on the above, `formatPath` should always be defined and `getEntryPointFormat()`
|
||||
// should always return a format here (and not `undefined`).
|
||||
if (!formatPath || !format) {
|
||||
// This should never happen.
|
||||
throw new Error(
|
||||
`Invariant violated: No format-path or format for ${entryPoint.path} : ` +
|
||||
`${formatProperty} (formatPath: ${formatPath} | format: ${format})`);
|
||||
}
|
||||
|
||||
// The format-path which the property maps to is already processed - nothing to do.
|
||||
if (hasBeenProcessed(packageJson, formatProperty)) {
|
||||
logger.debug(`Skipping ${entryPoint.name} : ${formatProperty} (already compiled).`);
|
||||
onTaskCompleted(task, TaskProcessingOutcome.AlreadyProcessed);
|
||||
return;
|
||||
}
|
||||
|
||||
const bundle = makeEntryPointBundle(
|
||||
fileSystem, entryPoint, formatPath, isCore, format, processDts, pathMappings, true);
|
||||
|
||||
logger.info(`Compiling ${entryPoint.name} : ${formatProperty} as ${format}`);
|
||||
|
||||
const transformedFiles = transformer.transform(bundle);
|
||||
fileWriter.writeBundle(bundle, transformedFiles, formatPropertiesToMarkAsProcessed);
|
||||
|
||||
onTaskCompleted(task, TaskProcessingOutcome.Processed);
|
||||
};
|
||||
};
|
||||
|
||||
// The function for actually planning and getting the work done.
|
||||
const executeFn: ExecuteFn = (analyzeFn: AnalyzeFn, createCompileFn: CreateCompileFn) => {
|
||||
const {processingMetadataPerEntryPoint, tasks} = analyzeFn();
|
||||
const compile = createCompileFn((task, outcome) => {
|
||||
const {entryPoint, formatPropertiesToMarkAsProcessed, processDts} = task;
|
||||
const processingMeta = processingMetadataPerEntryPoint.get(entryPoint.path) !;
|
||||
processingMeta.hasAnyProcessedFormat = true;
|
||||
|
||||
if (outcome === TaskProcessingOutcome.Processed) {
|
||||
const packageJsonPath = fileSystem.resolve(entryPoint.path, 'package.json');
|
||||
const propsToMarkAsProcessed: (EntryPointJsonProperty | 'typings')[] =
|
||||
[...formatPropertiesToMarkAsProcessed];
|
||||
|
||||
if (processDts) {
|
||||
processingMeta.hasProcessedTypings = true;
|
||||
propsToMarkAsProcessed.push('typings');
|
||||
}
|
||||
|
||||
markAsProcessed(
|
||||
fileSystem, entryPoint.packageJson, packageJsonPath, propsToMarkAsProcessed);
|
||||
}
|
||||
});
|
||||
|
||||
// Process all tasks.
|
||||
for (const task of tasks) {
|
||||
const processingMeta = processingMetadataPerEntryPoint.get(task.entryPoint.path) !;
|
||||
|
||||
// If we only need one format processed and we already have one for the corresponding
|
||||
// entry-point, skip the task.
|
||||
if (!compileAllFormats && processingMeta.hasAnyProcessedFormat) continue;
|
||||
|
||||
compile(task);
|
||||
}
|
||||
|
||||
// Check for entry-points for which we could not process any format at all.
|
||||
const unprocessedEntryPointPaths =
|
||||
Array.from(processingMetadataPerEntryPoint.entries())
|
||||
.filter(([, processingMeta]) => !processingMeta.hasAnyProcessedFormat)
|
||||
.map(([entryPointPath]) => `\n - ${entryPointPath}`)
|
||||
.join('');
|
||||
|
||||
if (unprocessedEntryPointPaths) {
|
||||
throw new Error(
|
||||
`Failed to compile any formats for entry-point at (${entryPoint.path}). Tried ${propertiesToConsider}.`);
|
||||
'Failed to compile any formats for the following entry-points (tried ' +
|
||||
`${propertiesToConsider.join(', ')}): ${unprocessedEntryPointPaths}`);
|
||||
}
|
||||
};
|
||||
|
||||
return executeFn(analyzeFn, createCompileFn);
|
||||
}
|
||||
|
||||
function ensureSupportedProperties(properties: string[]): EntryPointJsonProperty[] {
|
||||
// Short-circuit the case where `properties` has fallen back to the default value:
|
||||
// `SUPPORTED_FORMAT_PROPERTIES`
|
||||
if (properties === SUPPORTED_FORMAT_PROPERTIES) return SUPPORTED_FORMAT_PROPERTIES;
|
||||
|
||||
const supportedProperties: EntryPointJsonProperty[] = [];
|
||||
|
||||
for (const prop of properties as EntryPointJsonProperty[]) {
|
||||
if (SUPPORTED_FORMAT_PROPERTIES.indexOf(prop) !== -1) {
|
||||
supportedProperties.push(prop);
|
||||
}
|
||||
}
|
||||
|
||||
if (supportedProperties.length === 0) {
|
||||
throw new Error(
|
||||
`No supported format property to consider among [${properties.join(', ')}]. ` +
|
||||
`Supported properties: ${SUPPORTED_FORMAT_PROPERTIES.join(', ')}`);
|
||||
}
|
||||
|
||||
return supportedProperties;
|
||||
}
|
||||
|
||||
function getFileWriter(fs: FileSystem, createNewEntryPointFormats: boolean): FileWriter {
|
||||
@ -192,8 +282,15 @@ function getTargetedEntryPoints(
|
||||
const finder = new TargetedEntryPointFinder(
|
||||
fs, config, logger, resolver, basePath, absoluteTargetEntryPointPath, pathMappings);
|
||||
const entryPointInfo = finder.findEntryPoints();
|
||||
const invalidTarget = entryPointInfo.invalidEntryPoints.find(
|
||||
i => i.entryPoint.path === absoluteTargetEntryPointPath);
|
||||
if (invalidTarget !== undefined) {
|
||||
throw new Error(
|
||||
`The target entry-point "${invalidTarget.entryPoint.name}" has missing dependencies:\n` +
|
||||
invalidTarget.missingDependencies.map(dep => ` - ${dep}\n`));
|
||||
}
|
||||
if (entryPointInfo.entryPoints.length === 0) {
|
||||
markNonAngularPackageAsProcessed(fs, absoluteTargetEntryPointPath, propertiesToConsider);
|
||||
markNonAngularPackageAsProcessed(fs, absoluteTargetEntryPointPath);
|
||||
}
|
||||
return entryPointInfo;
|
||||
}
|
||||
@ -242,14 +339,13 @@ function hasProcessedTargetEntryPoint(
|
||||
* So mark all formats in this entry-point as processed so that clients of ngcc can avoid
|
||||
* triggering ngcc for this entry-point in the future.
|
||||
*/
|
||||
function markNonAngularPackageAsProcessed(
|
||||
fs: FileSystem, path: AbsoluteFsPath, propertiesToConsider: string[]) {
|
||||
function markNonAngularPackageAsProcessed(fs: FileSystem, path: AbsoluteFsPath) {
|
||||
const packageJsonPath = resolve(path, 'package.json');
|
||||
const packageJson = JSON.parse(fs.readFile(packageJsonPath));
|
||||
propertiesToConsider.forEach(formatProperty => {
|
||||
if (packageJson[formatProperty])
|
||||
markAsProcessed(fs, packageJson, packageJsonPath, formatProperty as EntryPointJsonProperty);
|
||||
});
|
||||
|
||||
// Note: We are marking all supported properties as processed, even if they don't exist in the
|
||||
// `package.json` file. While this is redundant, it is also harmless.
|
||||
markAsProcessed(fs, packageJson, packageJsonPath, SUPPORTED_FORMAT_PROPERTIES);
|
||||
}
|
||||
|
||||
function logInvalidEntryPoints(logger: Logger, invalidEntryPoints: InvalidEntryPoint[]): void {
|
||||
@ -260,3 +356,60 @@ function logInvalidEntryPoints(logger: Logger, invalidEntryPoints: InvalidEntryP
|
||||
invalidEntryPoint.missingDependencies.map(dep => ` - ${dep}`).join('\n'));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This function computes and returns the following:
|
||||
* - `propertiesToProcess`: An (ordered) list of properties that exist and need to be processed,
|
||||
* based on the specified `propertiesToConsider`, the properties in `package.json` and their
|
||||
* corresponding format-paths. NOTE: Only one property per format-path needs to be processed.
|
||||
* - `propertyToPropertiesToMarkAsProcessed`: A mapping from each property in `propertiesToProcess`
|
||||
* to the list of other properties in `package.json` that need to be marked as processed as soon
|
||||
* as of the former being processed.
|
||||
*/
|
||||
function getPropertiesToProcessAndMarkAsProcessed(
|
||||
packageJson: EntryPointPackageJson, propertiesToConsider: EntryPointJsonProperty[]): {
|
||||
propertiesToProcess: EntryPointJsonProperty[];
|
||||
propertyToPropertiesToMarkAsProcessed: Map<EntryPointJsonProperty, EntryPointJsonProperty[]>;
|
||||
} {
|
||||
const formatPathsToConsider = new Set<string>();
|
||||
|
||||
const propertiesToProcess: EntryPointJsonProperty[] = [];
|
||||
for (const prop of propertiesToConsider) {
|
||||
// Ignore properties that are not in `package.json`.
|
||||
if (!packageJson.hasOwnProperty(prop)) continue;
|
||||
|
||||
const formatPath = packageJson[prop] !;
|
||||
|
||||
// Ignore properties that map to the same format-path as a preceding property.
|
||||
if (formatPathsToConsider.has(formatPath)) continue;
|
||||
|
||||
// Process this property, because it is the first one to map to this format-path.
|
||||
formatPathsToConsider.add(formatPath);
|
||||
propertiesToProcess.push(prop);
|
||||
}
|
||||
|
||||
const formatPathToProperties: {[formatPath: string]: EntryPointJsonProperty[]} = {};
|
||||
for (const prop of SUPPORTED_FORMAT_PROPERTIES) {
|
||||
// Ignore properties that are not in `package.json`.
|
||||
if (!packageJson.hasOwnProperty(prop)) continue;
|
||||
|
||||
const formatPath = packageJson[prop] !;
|
||||
|
||||
// Ignore properties that do not map to a format-path that will be considered.
|
||||
if (!formatPathsToConsider.has(formatPath)) continue;
|
||||
|
||||
// Add this property to the map.
|
||||
const list = formatPathToProperties[formatPath] || (formatPathToProperties[formatPath] = []);
|
||||
list.push(prop);
|
||||
}
|
||||
|
||||
const propertyToPropertiesToMarkAsProcessed =
|
||||
new Map<EntryPointJsonProperty, EntryPointJsonProperty[]>();
|
||||
for (const prop of propertiesToConsider) {
|
||||
const formatPath = packageJson[prop] !;
|
||||
const propertiesToMarkAsProcessed = formatPathToProperties[formatPath];
|
||||
propertyToPropertiesToMarkAsProcessed.set(prop, propertiesToMarkAsProcessed);
|
||||
}
|
||||
|
||||
return {propertiesToProcess, propertyToPropertiesToMarkAsProcessed};
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ export const NGCC_VERSION = '0.0.0-PLACEHOLDER';
|
||||
* @throws Error if the entry-point has already been processed with a different ngcc version.
|
||||
*/
|
||||
export function hasBeenProcessed(
|
||||
packageJson: EntryPointPackageJson, format: EntryPointJsonProperty): boolean {
|
||||
packageJson: EntryPointPackageJson, format: EntryPointJsonProperty | 'typings'): boolean {
|
||||
if (!packageJson.__processed_by_ivy_ngcc__) {
|
||||
return false;
|
||||
}
|
||||
@ -38,17 +38,36 @@ export function hasBeenProcessed(
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a build marker for the given entry-point and format property, to indicate that it has
|
||||
* Write a build marker for the given entry-point and format properties, to indicate that they have
|
||||
* been compiled by this version of ngcc.
|
||||
*
|
||||
* @param entryPoint the entry-point to write a marker.
|
||||
* @param format the property in the package.json of the format for which we are writing the marker.
|
||||
* @param fs The current file-system being used.
|
||||
* @param packageJson The parsed contents of the `package.json` file for the entry-point.
|
||||
* @param packageJsonPath The absolute path to the `package.json` file.
|
||||
* @param properties The properties in the `package.json` of the formats for which we are writing
|
||||
* the marker.
|
||||
*/
|
||||
export function markAsProcessed(
|
||||
fs: FileSystem, packageJson: EntryPointPackageJson, packageJsonPath: AbsoluteFsPath,
|
||||
format: EntryPointJsonProperty) {
|
||||
if (!packageJson.__processed_by_ivy_ngcc__) packageJson.__processed_by_ivy_ngcc__ = {};
|
||||
packageJson.__processed_by_ivy_ngcc__[format] = NGCC_VERSION;
|
||||
properties: (EntryPointJsonProperty | 'typings')[]) {
|
||||
const processed =
|
||||
packageJson.__processed_by_ivy_ngcc__ || (packageJson.__processed_by_ivy_ngcc__ = {});
|
||||
|
||||
for (const prop of properties) {
|
||||
processed[prop] = NGCC_VERSION;
|
||||
}
|
||||
|
||||
const scripts = packageJson.scripts || (packageJson.scripts = {});
|
||||
scripts.prepublishOnly__ivy_ngcc_bak =
|
||||
scripts.prepublishOnly__ivy_ngcc_bak || scripts.prepublishOnly;
|
||||
|
||||
scripts.prepublishOnly = 'node --eval \"console.error(\'' +
|
||||
'ERROR: Trying to publish a package that has been compiled by NGCC. This is not allowed.\\n' +
|
||||
'Please delete and rebuild the package, without compiling with NGCC, before attempting to publish.\\n' +
|
||||
'Note that NGCC may have been run by importing this package into another project that is being built with Ivy enabled.\\n' +
|
||||
'\')\" ' +
|
||||
'&& exit 1';
|
||||
|
||||
// Just in case this package.json was synthesized due to a custom configuration
|
||||
// we will ensure that the path to the containing folder exists before we write the file.
|
||||
fs.ensureDir(dirname(packageJsonPath));
|
||||
|
@ -55,10 +55,11 @@ export interface PackageJsonFormatProperties {
|
||||
*/
|
||||
export interface EntryPointPackageJson extends PackageJsonFormatProperties {
|
||||
name: string;
|
||||
__processed_by_ivy_ngcc__?: {[key: string]: string};
|
||||
scripts?: Record<string, string>;
|
||||
__processed_by_ivy_ngcc__?: Record<string, string>;
|
||||
}
|
||||
|
||||
export type EntryPointJsonProperty = keyof(PackageJsonFormatProperties);
|
||||
export type EntryPointJsonProperty = Exclude<keyof PackageJsonFormatProperties, 'types'|'typings'>;
|
||||
// We need to keep the elements of this const and the `EntryPointJsonProperty` type in sync.
|
||||
export const SUPPORTED_FORMAT_PROPERTIES: EntryPointJsonProperty[] =
|
||||
['fesm2015', 'fesm5', 'es2015', 'esm2015', 'esm5', 'main', 'module'];
|
||||
@ -122,7 +123,8 @@ export function getEntryPointInfo(
|
||||
* @returns An entry-point format or `undefined` if none match the given property.
|
||||
*/
|
||||
export function getEntryPointFormat(
|
||||
fs: FileSystem, entryPoint: EntryPoint, property: string): EntryPointFormat|undefined {
|
||||
fs: FileSystem, entryPoint: EntryPoint, property: EntryPointJsonProperty): EntryPointFormat|
|
||||
undefined {
|
||||
switch (property) {
|
||||
case 'fesm2015':
|
||||
return 'esm2015';
|
||||
|
@ -10,7 +10,7 @@ import {AbsoluteFsPath, FileSystem, absoluteFrom} from '../../../src/ngtsc/file_
|
||||
import {NgtscCompilerHost} from '../../../src/ngtsc/file_system/src/compiler_host';
|
||||
import {PathMappings} from '../utils';
|
||||
import {BundleProgram, makeBundleProgram} from './bundle_program';
|
||||
import {EntryPoint, EntryPointFormat, EntryPointJsonProperty} from './entry_point';
|
||||
import {EntryPoint, EntryPointFormat} from './entry_point';
|
||||
import {NgccSourcesCompilerHost} from './ngcc_compiler_host';
|
||||
|
||||
/**
|
||||
@ -19,7 +19,6 @@ import {NgccSourcesCompilerHost} from './ngcc_compiler_host';
|
||||
*/
|
||||
export interface EntryPointBundle {
|
||||
entryPoint: EntryPoint;
|
||||
formatProperty: EntryPointJsonProperty;
|
||||
format: EntryPointFormat;
|
||||
isCore: boolean;
|
||||
isFlatCore: boolean;
|
||||
@ -34,7 +33,6 @@ export interface EntryPointBundle {
|
||||
* @param entryPoint The entry-point that contains the bundle.
|
||||
* @param formatPath The path to the source files for this bundle.
|
||||
* @param isCore This entry point is the Angular core package.
|
||||
* @param formatProperty The property in the package.json that holds the formatPath.
|
||||
* @param format The underlying format of the bundle.
|
||||
* @param transformDts Whether to transform the typings along with this bundle.
|
||||
* @param pathMappings An optional set of mappings to use when compiling files.
|
||||
@ -43,8 +41,8 @@ export interface EntryPointBundle {
|
||||
*/
|
||||
export function makeEntryPointBundle(
|
||||
fs: FileSystem, entryPoint: EntryPoint, formatPath: string, isCore: boolean,
|
||||
formatProperty: EntryPointJsonProperty, format: EntryPointFormat, transformDts: boolean,
|
||||
pathMappings?: PathMappings, mirrorDtsFromSrc: boolean = false): EntryPointBundle|null {
|
||||
format: EntryPointFormat, transformDts: boolean, pathMappings?: PathMappings,
|
||||
mirrorDtsFromSrc: boolean = false): EntryPointBundle {
|
||||
// Create the TS program and necessary helpers.
|
||||
const options: ts.CompilerOptions = {
|
||||
allowJs: true,
|
||||
@ -69,7 +67,7 @@ export function makeEntryPointBundle(
|
||||
null;
|
||||
const isFlatCore = isCore && src.r3SymbolsFile === null;
|
||||
|
||||
return {entryPoint, format, formatProperty, rootDirs, isCore, isFlatCore, src, dts};
|
||||
return {entryPoint, format, rootDirs, isCore, isFlatCore, src, dts};
|
||||
}
|
||||
|
||||
function computePotentialDtsFilesFromJsFiles(
|
||||
@ -88,4 +86,4 @@ function computePotentialDtsFilesFromJsFiles(
|
||||
}
|
||||
}
|
||||
return additionalFiles;
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user