Compare commits

..

87 Commits

Author SHA1 Message Date
Ryan Brandenburg
cdc621d428 Merge branch 'rybrande/release22ToSrc' into rybrande/masterToSrc 2018-11-20 16:26:40 -08:00
Ryan Brandenburg
128562955e Merge branch 'rybrande/release21ToSrc' into rybrande/release22ToSrc 2018-11-20 11:04:30 -08:00
Ryan Brandenburg
964498a69d Reorganize source code in preparation to move into aspnet/AspNetCore
Prior to reorganization, this source code was found in 7819c2f950
2018-11-20 11:04:10 -08:00
Ryan Brandenburg
f6f7628718 Reorganize source code in preparation to move into aspnet/AspNetCore
Prior to reorganization, this source code was found in ea3a7bc897
2018-11-19 16:14:42 -08:00
Nate McMaster
e657e7d79a Upgrade projects and packages to netcoreapp3.0 (aspnet/JavaScriptServices#1793) 2018-11-16 16:02:57 -08:00
Pavel Krymets
160d822f52 Do not fallback to creating console logger (#1789) 2018-11-13 09:48:28 -08:00
Pavel Krymets
8027397d67 Merge branch 'merge/release/2.2-to-master' 2018-11-06 15:12:04 -08:00
Pavel Krymets
f024e779a6 Merge branch 'merge/release/2.2-to-master' of https://github.com/dotnet-maestro-bot/JavaScriptServices into merge/release/2.2-to-master 2018-11-06 15:11:14 -08:00
Pavel Krymets
7819c2f950 Remove obsolete API usage (#1784) 2018-11-06 14:10:24 -08:00
Pranav K
f47c5901b6 React to Razor.Design package removal 2018-10-31 14:41:57 -07:00
ASP.NET CI
cdfa5d85f6 Update package branding for 2.2 RTM 2018-10-16 12:48:16 -07:00
ASP.NET CI
3265b92086 Update dependencies.props
[auto-updated: dependencies]
2018-10-07 19:22:47 +00:00
ASP.NET CI
9c6a1b577f Update dependencies.props
[auto-updated: dependencies]
2018-10-07 12:21:37 -07:00
Nate McMaster
25e9c50585 Add missing version variable that was not merged correctly during automated merge 2018-10-01 11:25:14 -07:00
ASP.NET CI
ef999a57fd Update dependencies.props
[auto-updated: dependencies]
2018-09-30 12:22:07 -07:00
Nate McMaster
0050b505ec automated: merge branch release/2.2 2018-09-28 17:27:32 -07:00
Nate McMaster
e231b29e58 automated: bulk infrastructure updates. Update bootstrapper scripts and remove unnecessary signing properties 2018-09-28 17:10:35 -07:00
Eilon Lipton
ec82df4287 Update LICENSE.txt 2018-09-27 15:32:48 -07:00
Steve Sanderson
e9621c8add Update aspnet-webpack-react type declarations 2018-09-26 17:24:02 +01:00
Tomasz Jaskula
59ca023f46 Deleting references to 'react-hot-loader/webpack' and 'react-hot-loader/patch' as it was removed in v4 of react-hot-loader. Bumping peer dependency of webpack to 3 and 4 2018-09-26 16:50:43 +01:00
ASP.NET CI
d8662392a0 Update dependencies.props
[auto-updated: dependencies]
2018-09-23 19:21:56 +00:00
ASP.NET CI
78a8bbf783 Update dependencies.props
[auto-updated: dependencies]
2018-09-23 12:20:04 -07:00
Pranav K
587ead92e4 Reference Microsoft.NET.Sdk.Razor in projects with Razor files 2018-09-20 13:55:13 -07:00
ASP.NET CI
28798452a9 Update dependencies.props
[auto-updated: dependencies]
2018-09-16 19:21:12 +00:00
ASP.NET CI
622be9084a Update dependencies.props
[auto-updated: dependencies]
2018-09-16 12:19:15 -07:00
ASP.NET CI
cd009006c8 Update dependencies.props
[auto-updated: dependencies]
2018-09-09 19:22:11 +00:00
ASP.NET CI
817c0e4f24 Update dependencies.props
[auto-updated: dependencies]
2018-09-09 12:20:43 -07:00
Ryan Brandenburg
f0e66325c3 Merge branch 'merge/release/2.2-to-master' 2018-09-06 15:21:29 -07:00
Ryan Brandenburg
c2f15f4199 Don't use depricated constructor 2018-09-06 11:39:34 -07:00
ASP.NET CI
cfd3a19279 Update dependencies.props
[auto-updated: dependencies]
2018-09-05 23:52:20 +00:00
ASP.NET CI
24ebd9ff3e Update branding to 2.2.0-preview3 2018-09-05 16:34:59 -07:00
ASP.NET CI
a4be7b3898 Update dependencies.props
[auto-updated: dependencies]
2018-09-02 19:20:08 +00:00
ASP.NET CI
15884cbadb Update dependencies.props
[auto-updated: dependencies]
2018-09-02 12:18:24 -07:00
Steve Sanderson
ae7b7c2663 Update NodeServices/SpaServices/NodeServices.Sockets to build using latest TypeScript and Webpack (#1748) 2018-08-30 07:51:56 +01:00
ASP.NET CI
e47f15fdc8 Update dependencies.props
[auto-updated: dependencies]
2018-08-26 19:20:09 +00:00
ASP.NET CI
4bc67d6a60 Update package branding for 2.2.0-preview2 2018-08-21 13:33:50 -07:00
ASP.NET CI
bc50741043 Update dependencies.props
[auto-updated: dependencies]
2018-08-19 19:20:30 +00:00
ASP.NET CI
1af86b7ba8 Update dependencies.props
[auto-updated: dependencies]
2018-08-12 20:05:46 +00:00
ASP.NET CI
9281cbaf72 Update dependencies.props
[auto-updated: dependencies]
2018-08-12 19:19:23 +00:00
ASP.NET CI
cd2b52bbd0 Update dependencies.props
[auto-updated: dependencies]
2018-08-06 20:42:28 +00:00
ASP.NET CI
97022a1ff2 Update dependencies.props
[auto-updated: dependencies]
2018-08-05 19:55:53 +00:00
ASP.NET CI
78dd174aed Update dependencies.props
[auto-updated: dependencies]
2018-08-05 19:19:50 +00:00
ASP.NET CI
040a58578c Update dependencies.props
[auto-updated: dependencies]
2018-07-29 20:01:19 +00:00
ASP.NET CI
4d7485bba2 Update dependencies.props
[auto-updated: dependencies]
2018-07-29 12:17:46 -07:00
Nate McMaster
02383cd614 Merge branch release/2.2 2018-07-24 13:20:06 -07:00
Nate McMaster
a4bb72e58c Merge branch 'release/2.1' into release/2.2 2018-07-24 12:07:21 -07:00
ASP.NET CI
df85010938 Update dependencies.props
[auto-updated: dependencies]
2018-07-22 13:04:21 -07:00
ASP.NET CI
9c741600d2 Update dependencies.props
[auto-updated: dependencies]
2018-07-22 12:18:10 -07:00
Eilon Lipton
4763ad5b8c Merge pull request #1727 from ChinShengHao/patch-1
Update README.md
2018-07-19 10:15:53 -07:00
Eilon Lipton
dd9957bc39 Merge branch 'master' into patch-1 2018-07-19 10:15:36 -07:00
Michael Seifert
601909865f Fix links that assumed branch "dev" exists (which doesn't) (#1725)
* Fix links that assumed branch "dev" exists (which doesn't)

* Adressed comments [skip ci]
2018-07-19 18:12:44 +01:00
ChinShengHao
d9d4359a1e Update README.md
Fixing some hyperlinks that direct to a non-existing url.
2018-07-19 22:54:41 +08:00
ASP.NET CI
5f44de86f6 Update dependencies.props
[auto-updated: dependencies]
2018-07-15 20:02:46 +00:00
ASP.NET CI
c8342594a8 Update dependencies.props
[auto-updated: dependencies]
2018-07-15 12:18:43 -07:00
Nate McMaster
ea3a7bc897 Pin version variables to the ASP.NET Core 2.1.2 baseline
This reverts our previous policy of cascading versions on all servicing updates.
This moves variables into the 'pinned' section, and points them to the latest
stable release (versions that were used at the time of the 2.1.2 release).
2018-07-12 11:54:22 -07:00
Nate McMaster
578124e1ce Updating dependencies to 2.1.2 and adding a section for pinned variable versions 2018-07-11 18:49:03 -07:00
Nate McMaster
0da7460fa2 Reverting version from 2.1.2 back to 2.1.1
As a result of changing the way we apply servicing updates to aspnet core, this repo did not need the version bump because there are no planned product changes in this repo.
2018-07-11 15:06:34 -07:00
ASP.NET CI
0dc570a0c8 Update dependencies.props
[auto-updated: dependencies]
2018-07-08 19:59:49 +00:00
ASP.NET CI
5fa87a0313 Update dependencies.props
[auto-updated: dependencies]
2018-07-08 12:19:17 -07:00
ASP.NET CI
b1d04c99c9 Update dependencies.props
[auto-updated: dependencies]
2018-07-03 16:18:15 +00:00
Nate McMaster (automated)
d742bea01e [automated] Change default branch to master 2018-07-02 12:40:25 -07:00
Nate McMaster
7a04134345 Merge branch 'release/2.2' into dev 2018-06-28 16:53:47 -07:00
Nate McMaster
c177cc001c Bumping version from 2.2.0 to 3.0.0 2018-06-28 16:48:53 -07:00
Nate McMaster
067298bead Update infrastructure for the 2.2 release 2018-06-28 16:20:26 -07:00
ASP.NET CI
cf659b3fda Update dependencies.props
[auto-updated: dependencies]
2018-06-25 11:20:23 -07:00
Ryan Brandenburg
1e85713d75 Set 2.1 baselines 2018-06-14 11:29:34 -07:00
Ryan Brandenburg
a04813edc3 Set 2.1 baselines 2018-06-14 11:29:25 -07:00
Nate McMaster
e49b0e439e Bumping version from 2.1.1 to 2.1.2 2018-06-12 14:01:30 -07:00
ASP.NET CI
d65a4f3b6d Update dependencies.props
[auto-updated: dependencies]
2018-06-12 19:25:28 +00:00
Ryan Brandenburg
47828ee727 Adding VSTS file 2018-06-08 09:53:25 -07:00
ASP.NET CI
0d1c99c1d1 Update dependencies.props
[auto-updated: dependencies]
2018-06-07 19:40:16 +00:00
Nate McMaster
240dd82473 Add certificate names for code signing 2018-06-05 22:32:57 -07:00
ASP.NET CI
b616db4918 Update dependencies.props
[auto-updated: dependencies]
2018-06-03 19:19:20 +00:00
Steve Sanderson
447359af84 Bump aspnet-webpack version to 3.0.0 2018-05-29 10:02:23 +01:00
Matt Perry
823630c508 Add webpack 4 support to aspnet-webpack 2018-05-29 09:58:04 +01:00
ASP.NET CI
c35a3a17c0 Update dependencies.props
[auto-updated: dependencies]
2018-05-27 19:20:08 +00:00
Nate McMaster (automated)
98c47a1c70 Update bootstrapper scripts (automated commit) [ci skip] 2018-05-25 16:15:48 -07:00
ASP.NET CI
0a1c83ab81 Update dependencies.props
[auto-updated: dependencies]
2018-05-20 19:37:28 +00:00
ASP.NET CI
2167b28ffd Update dependencies.props
[auto-updated: dependencies]
2018-05-13 14:14:19 -07:00
Ryan Brandenburg
966bfcb172 Upgrade to netcoreapp22 2018-05-07 16:30:25 -07:00
ASP.NET CI
b8f85dc2d9 Update dependencies.props
[auto-updated: dependencies]
2018-05-06 12:21:32 -07:00
Nate McMaster (automated)
944e8d396d Merge branch release/2.1 into dev 2018-04-30 15:53:06 -07:00
ASP.NET CI
961619c5c9 Update dependencies.props
[auto-updated: dependencies]
2018-04-29 12:22:20 -07:00
ASP.NET CI
da66cc1fee Update dependencies.props
[auto-updated: dependencies]
2018-04-23 12:15:04 -07:00
Nate McMaster
b7ba837d6e Merge branch release/2.1 into dev 2018-04-20 15:08:38 -07:00
Ryan Brandenburg
67267eabf7 Update version number to 2.2.0 2018-04-16 16:58:37 -07:00
Ryan Brandenburg
1e5b6f864e Merge branch 'release/2.1' into dev 2018-04-16 16:58:37 -07:00
230 changed files with 18024 additions and 3283 deletions

View File

@@ -1,19 +0,0 @@
init:
- git config --global core.autocrlf true
install:
- ps: Install-Product node 6.9.2 x64
branches:
only:
- dev
- /^release\/.*$/
- /^(.*\/)?ci-.*$/
build_script:
- ps: .\run.ps1 default-build
clone_depth: 1
environment:
global:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
DOTNET_CLI_TELEMETRY_OPTOUT: 1
test: 'off'
deploy: 'off'
os: Visual Studio 2017

51
.gitattributes vendored
View File

@@ -1,51 +0,0 @@
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
*.jpg binary
*.png binary
*.gif binary
*.cs text=auto diff=csharp
*.vb text=auto
*.resx text=auto
*.c text=auto
*.cpp text=auto
*.cxx text=auto
*.h text=auto
*.hxx text=auto
*.py text=auto
*.rb text=auto
*.java text=auto
*.html text=auto
*.htm text=auto
*.css text=auto
*.scss text=auto
*.sass text=auto
*.less text=auto
*.js text=auto
*.lisp text=auto
*.clj text=auto
*.sql text=auto
*.php text=auto
*.lua text=auto
*.m text=auto
*.asm text=auto
*.erl text=auto
*.fs text=auto
*.fsx text=auto
*.hs text=auto
*.csproj text=auto
*.vbproj text=auto
*.fsproj text=auto
*.dbproj text=auto
*.sln text=auto eol=crlf
*.sh eol=lf

View File

@@ -1,24 +0,0 @@
language: csharp
sudo: required
dist: trusty
addons:
apt:
packages:
- gettext
- libcurl4-openssl-dev
- libicu-dev
- libssl-dev
- libunwind8
- zlib1g
mono: none
os:
- linux
- osx
osx_image: xcode7.1
script:
- ./build.sh
branches:
only:
- dev
- /^release\/.*$/
- /^(.*\/)?ci-.*$/

View File

@@ -1,4 +0,0 @@
Contributing
======
Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/dev/CONTRIBUTING.md) in the Home repo.

View File

@@ -1,14 +0,0 @@
Copyright (c) .NET Foundation and Contributors
All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<!-- Restore sources should be defined in build/sources.props. -->
</packageSources>
</configuration>

View File

@@ -1,2 +0,0 @@
@ECHO OFF
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' default-build %*; exit $LASTEXITCODE"

View File

@@ -1,8 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Call "sync" between "chmod" and execution to prevent "text file busy" error in Docker (aufs)
chmod +x "$DIR/run.sh"; sync
"$DIR/run.sh" default-build "$@"

View File

@@ -1,28 +0,0 @@
<Project>
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
</PropertyGroup>
<PropertyGroup Label="Package Versions">
<InternalAspNetCoreSdkPackageVersion>2.1.1-rtm-15790</InternalAspNetCoreSdkPackageVersion>
<MicrosoftAspNetCoreDiagnosticsPackageVersion>2.1.0</MicrosoftAspNetCoreDiagnosticsPackageVersion>
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>2.1.0</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
<MicrosoftAspNetCoreHostingPackageVersion>2.1.0</MicrosoftAspNetCoreHostingPackageVersion>
<MicrosoftAspNetCoreMvcPackageVersion>2.1.0</MicrosoftAspNetCoreMvcPackageVersion>
<MicrosoftAspNetCoreMvcTagHelpersPackageVersion>2.1.0</MicrosoftAspNetCoreMvcTagHelpersPackageVersion>
<MicrosoftAspNetCoreMvcViewFeaturesPackageVersion>2.1.0</MicrosoftAspNetCoreMvcViewFeaturesPackageVersion>
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>2.1.0</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
<MicrosoftAspNetCoreServerKestrelPackageVersion>2.1.0</MicrosoftAspNetCoreServerKestrelPackageVersion>
<MicrosoftAspNetCoreStaticFilesPackageVersion>2.1.0</MicrosoftAspNetCoreStaticFilesPackageVersion>
<MicrosoftAspNetCoreWebSocketsPackageVersion>2.1.0</MicrosoftAspNetCoreWebSocketsPackageVersion>
<MicrosoftExtensionsDependencyInjectionPackageVersion>2.1.0</MicrosoftExtensionsDependencyInjectionPackageVersion>
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>2.1.0</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
<MicrosoftExtensionsLoggingConsolePackageVersion>2.1.0</MicrosoftExtensionsLoggingConsolePackageVersion>
<MicrosoftExtensionsLoggingDebugPackageVersion>2.1.0</MicrosoftExtensionsLoggingDebugPackageVersion>
<MicrosoftNETCoreApp20PackageVersion>2.0.0</MicrosoftNETCoreApp20PackageVersion>
<MicrosoftNETCoreApp21PackageVersion>2.1.0</MicrosoftNETCoreApp21PackageVersion>
<NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion>
<NewtonsoftJsonPackageVersion>11.0.2</NewtonsoftJsonPackageVersion>
<SystemThreadingTasksDataflowPackageVersion>4.9.0</SystemThreadingTasksDataflowPackageVersion>
</PropertyGroup>
<Import Project="$(DotNetPackageVersionPropsPath)" Condition=" '$(DotNetPackageVersionPropsPath)' != '' " />
</Project>

View File

@@ -1,2 +0,0 @@
version:2.1.1-rtm-15790
commithash:274c65868e735f29f4078c1884c61c4371ee1fc0

View File

@@ -1,10 +0,0 @@
{
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/release/2.1/tools/korebuild.schema.json",
"channel": "release/2.1",
"toolsets": {
"nodejs": {
"required": true,
"minVersion": "6.9"
}
}
}

View File

@@ -1,2 +0,0 @@
@ECHO OFF
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE"

196
run.ps1
View File

@@ -1,196 +0,0 @@
#!/usr/bin/env powershell
#requires -version 4
<#
.SYNOPSIS
Executes KoreBuild commands.
.DESCRIPTION
Downloads korebuild if required. Then executes the KoreBuild command. To see available commands, execute with `-Command help`.
.PARAMETER Command
The KoreBuild command to run.
.PARAMETER Path
The folder to build. Defaults to the folder containing this script.
.PARAMETER Channel
The channel of KoreBuild to download. Overrides the value from the config file.
.PARAMETER DotNetHome
The directory where .NET Core tools will be stored.
.PARAMETER ToolsSource
The base url where build tools can be downloaded. Overrides the value from the config file.
.PARAMETER Update
Updates KoreBuild to the latest version even if a lock file is present.
.PARAMETER ConfigFile
The path to the configuration file that stores values. Defaults to korebuild.json.
.PARAMETER ToolsSourceSuffix
The Suffix to append to the end of the ToolsSource. Useful for query strings in blob stores.
.PARAMETER Arguments
Arguments to be passed to the command
.NOTES
This function will create a file $PSScriptRoot/korebuild-lock.txt. This lock file can be committed to source, but does not have to be.
When the lockfile is not present, KoreBuild will create one using latest available version from $Channel.
The $ConfigFile is expected to be an JSON file. It is optional, and the configuration values in it are optional as well. Any options set
in the file are overridden by command line parameters.
.EXAMPLE
Example config file:
```json
{
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json",
"channel": "dev",
"toolsSource": "https://aspnetcore.blob.core.windows.net/buildtools"
}
```
#>
[CmdletBinding(PositionalBinding = $false)]
param(
[Parameter(Mandatory = $true, Position = 0)]
[string]$Command,
[string]$Path = $PSScriptRoot,
[Alias('c')]
[string]$Channel,
[Alias('d')]
[string]$DotNetHome,
[Alias('s')]
[string]$ToolsSource,
[Alias('u')]
[switch]$Update,
[string]$ConfigFile,
[string]$ToolsSourceSuffix,
[Parameter(ValueFromRemainingArguments = $true)]
[string[]]$Arguments
)
Set-StrictMode -Version 2
$ErrorActionPreference = 'Stop'
#
# Functions
#
function Get-KoreBuild {
$lockFile = Join-Path $Path 'korebuild-lock.txt'
if (!(Test-Path $lockFile) -or $Update) {
Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile $ToolsSourceSuffix
}
$version = Get-Content $lockFile | Where-Object { $_ -like 'version:*' } | Select-Object -first 1
if (!$version) {
Write-Error "Failed to parse version from $lockFile. Expected a line that begins with 'version:'"
}
$version = $version.TrimStart('version:').Trim()
$korebuildPath = Join-Paths $DotNetHome ('buildtools', 'korebuild', $version)
if (!(Test-Path $korebuildPath)) {
Write-Host -ForegroundColor Magenta "Downloading KoreBuild $version"
New-Item -ItemType Directory -Path $korebuildPath | Out-Null
$remotePath = "$ToolsSource/korebuild/artifacts/$version/korebuild.$version.zip"
try {
$tmpfile = Join-Path ([IO.Path]::GetTempPath()) "KoreBuild-$([guid]::NewGuid()).zip"
Get-RemoteFile $remotePath $tmpfile $ToolsSourceSuffix
if (Get-Command -Name 'Expand-Archive' -ErrorAction Ignore) {
# Use built-in commands where possible as they are cross-plat compatible
Expand-Archive -Path $tmpfile -DestinationPath $korebuildPath
}
else {
# Fallback to old approach for old installations of PowerShell
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::ExtractToDirectory($tmpfile, $korebuildPath)
}
}
catch {
Remove-Item -Recurse -Force $korebuildPath -ErrorAction Ignore
throw
}
finally {
Remove-Item $tmpfile -ErrorAction Ignore
}
}
return $korebuildPath
}
function Join-Paths([string]$path, [string[]]$childPaths) {
$childPaths | ForEach-Object { $path = Join-Path $path $_ }
return $path
}
function Get-RemoteFile([string]$RemotePath, [string]$LocalPath, [string]$RemoteSuffix) {
if ($RemotePath -notlike 'http*') {
Copy-Item $RemotePath $LocalPath
return
}
$retries = 10
while ($retries -gt 0) {
$retries -= 1
try {
Invoke-WebRequest -UseBasicParsing -Uri $($RemotePath + $RemoteSuffix) -OutFile $LocalPath
return
}
catch {
Write-Verbose "Request failed. $retries retries remaining"
}
}
Write-Error "Download failed: '$RemotePath'."
}
#
# Main
#
# Load configuration or set defaults
$Path = Resolve-Path $Path
if (!$ConfigFile) { $ConfigFile = Join-Path $Path 'korebuild.json' }
if (Test-Path $ConfigFile) {
try {
$config = Get-Content -Raw -Encoding UTF8 -Path $ConfigFile | ConvertFrom-Json
if ($config) {
if (!($Channel) -and (Get-Member -Name 'channel' -InputObject $config)) { [string] $Channel = $config.channel }
if (!($ToolsSource) -and (Get-Member -Name 'toolsSource' -InputObject $config)) { [string] $ToolsSource = $config.toolsSource}
}
}
catch {
Write-Warning "$ConfigFile could not be read. Its settings will be ignored."
Write-Warning $Error[0]
}
}
if (!$DotNetHome) {
$DotNetHome = if ($env:DOTNET_HOME) { $env:DOTNET_HOME } `
elseif ($env:USERPROFILE) { Join-Path $env:USERPROFILE '.dotnet'} `
elseif ($env:HOME) {Join-Path $env:HOME '.dotnet'}`
else { Join-Path $PSScriptRoot '.dotnet'}
}
if (!$Channel) { $Channel = 'dev' }
if (!$ToolsSource) { $ToolsSource = 'https://aspnetcore.blob.core.windows.net/buildtools' }
# Execute
$korebuildPath = Get-KoreBuild
Import-Module -Force -Scope Local (Join-Path $korebuildPath 'KoreBuild.psd1')
try {
Set-KoreBuildSettings -ToolsSource $ToolsSource -DotNetHome $DotNetHome -RepoPath $Path -ConfigFile $ConfigFile
Invoke-KoreBuildCommand $Command @Arguments
}
finally {
Remove-Module 'KoreBuild' -ErrorAction Ignore
}

231
run.sh
View File

@@ -1,231 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
#
# variables
#
RESET="\033[0m"
RED="\033[0;31m"
YELLOW="\033[0;33m"
MAGENTA="\033[0;95m"
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
[ -z "${DOTNET_HOME:-}" ] && DOTNET_HOME="$HOME/.dotnet"
verbose=false
update=false
repo_path="$DIR"
channel=''
tools_source=''
tools_source_suffix=''
#
# Functions
#
__usage() {
echo "Usage: $(basename "${BASH_SOURCE[0]}") command [options] [[--] <Arguments>...]"
echo ""
echo "Arguments:"
echo " command The command to be run."
echo " <Arguments>... Arguments passed to the command. Variable number of arguments allowed."
echo ""
echo "Options:"
echo " --verbose Show verbose output."
echo " -c|--channel <CHANNEL> The channel of KoreBuild to download. Overrides the value from the config file.."
echo " --config-file <FILE> The path to the configuration file that stores values. Defaults to korebuild.json."
echo " -d|--dotnet-home <DIR> The directory where .NET Core tools will be stored. Defaults to '\$DOTNET_HOME' or '\$HOME/.dotnet."
echo " --path <PATH> The directory to build. Defaults to the directory containing the script."
echo " -s|--tools-source|-ToolsSource <URL> The base url where build tools can be downloaded. Overrides the value from the config file."
echo " --tools-source-suffix|-ToolsSourceSuffix <SUFFIX> The suffix to append to tools-source. Useful for query strings."
echo " -u|--update Update to the latest KoreBuild even if the lock file is present."
echo ""
echo "Description:"
echo " This function will create a file \$DIR/korebuild-lock.txt. This lock file can be committed to source, but does not have to be."
echo " When the lockfile is not present, KoreBuild will create one using latest available version from \$channel."
if [[ "${1:-}" != '--no-exit' ]]; then
exit 2
fi
}
get_korebuild() {
local version
local lock_file="$repo_path/korebuild-lock.txt"
if [ ! -f "$lock_file" ] || [ "$update" = true ]; then
__get_remote_file "$tools_source/korebuild/channels/$channel/latest.txt" "$lock_file" "$tools_source_suffix"
fi
version="$(grep 'version:*' -m 1 "$lock_file")"
if [[ "$version" == '' ]]; then
__error "Failed to parse version from $lock_file. Expected a line that begins with 'version:'"
return 1
fi
version="$(echo "${version#version:}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
local korebuild_path="$DOTNET_HOME/buildtools/korebuild/$version"
{
if [ ! -d "$korebuild_path" ]; then
mkdir -p "$korebuild_path"
local remote_path="$tools_source/korebuild/artifacts/$version/korebuild.$version.zip"
tmpfile="$(mktemp)"
echo -e "${MAGENTA}Downloading KoreBuild ${version}${RESET}"
if __get_remote_file "$remote_path" "$tmpfile" "$tools_source_suffix"; then
unzip -q -d "$korebuild_path" "$tmpfile"
fi
rm "$tmpfile" || true
fi
source "$korebuild_path/KoreBuild.sh"
} || {
if [ -d "$korebuild_path" ]; then
echo "Cleaning up after failed installation"
rm -rf "$korebuild_path" || true
fi
return 1
}
}
__error() {
echo -e "${RED}error: $*${RESET}" 1>&2
}
__warn() {
echo -e "${YELLOW}warning: $*${RESET}"
}
__machine_has() {
hash "$1" > /dev/null 2>&1
return $?
}
__get_remote_file() {
local remote_path=$1
local local_path=$2
local remote_path_suffix=$3
if [[ "$remote_path" != 'http'* ]]; then
cp "$remote_path" "$local_path"
return 0
fi
local failed=false
if __machine_has wget; then
wget --tries 10 --quiet -O "$local_path" "${remote_path}${remote_path_suffix}" || failed=true
else
failed=true
fi
if [ "$failed" = true ] && __machine_has curl; then
failed=false
curl --retry 10 -sSL -f --create-dirs -o "$local_path" "${remote_path}${remote_path_suffix}" || failed=true
fi
if [ "$failed" = true ]; then
__error "Download failed: $remote_path" 1>&2
return 1
fi
}
#
# main
#
command="${1:-}"
shift
while [[ $# -gt 0 ]]; do
case $1 in
-\?|-h|--help)
__usage --no-exit
exit 0
;;
-c|--channel|-Channel)
shift
channel="${1:-}"
[ -z "$channel" ] && __usage
;;
--config-file|-ConfigFile)
shift
config_file="${1:-}"
[ -z "$config_file" ] && __usage
if [ ! -f "$config_file" ]; then
__error "Invalid value for --config-file. $config_file does not exist."
exit 1
fi
;;
-d|--dotnet-home|-DotNetHome)
shift
DOTNET_HOME="${1:-}"
[ -z "$DOTNET_HOME" ] && __usage
;;
--path|-Path)
shift
repo_path="${1:-}"
[ -z "$repo_path" ] && __usage
;;
-s|--tools-source|-ToolsSource)
shift
tools_source="${1:-}"
[ -z "$tools_source" ] && __usage
;;
--tools-source-suffix|-ToolsSourceSuffix)
shift
tools_source_suffix="${1:-}"
[ -z "$tools_source_suffix" ] && __usage
;;
-u|--update|-Update)
update=true
;;
--verbose|-Verbose)
verbose=true
;;
--)
shift
break
;;
*)
break
;;
esac
shift
done
if ! __machine_has unzip; then
__error 'Missing required command: unzip'
exit 1
fi
if ! __machine_has curl && ! __machine_has wget; then
__error 'Missing required command. Either wget or curl is required.'
exit 1
fi
[ -z "${config_file:-}" ] && config_file="$repo_path/korebuild.json"
if [ -f "$config_file" ]; then
if __machine_has jq ; then
if jq '.' "$config_file" >/dev/null ; then
config_channel="$(jq -r 'select(.channel!=null) | .channel' "$config_file")"
config_tools_source="$(jq -r 'select(.toolsSource!=null) | .toolsSource' "$config_file")"
else
__warn "$config_file is invalid JSON. Its settings will be ignored."
fi
elif __machine_has python ; then
if python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'))" >/dev/null ; then
config_channel="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")"
config_tools_source="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")"
else
__warn "$config_file is invalid JSON. Its settings will be ignored."
fi
else
__warn 'Missing required command: jq or pyton. Could not parse the JSON file. Its settings will be ignored.'
fi
[ ! -z "${config_channel:-}" ] && channel="$config_channel"
[ ! -z "${config_tools_source:-}" ] && tools_source="$config_tools_source"
fi
[ -z "$channel" ] && channel='dev'
[ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools'
get_korebuild
set_korebuildsettings "$tools_source" "$DOTNET_HOME" "$repo_path" "$config_file"
invoke_korebuild_command "$command" "$@"

View File

@@ -10,7 +10,6 @@
<RepositoryRoot>$(MSBuildThisFileDirectory)</RepositoryRoot>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)build\Key.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
</Project>

View File

@@ -1,7 +1,6 @@
<Project>
<Project>
<PropertyGroup>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">$(MicrosoftNETCoreApp20PackageVersion)</RuntimeFrameworkVersion>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.1' ">$(MicrosoftNETCoreApp21PackageVersion)</RuntimeFrameworkVersion>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp3.0' ">$(MicrosoftNETCoreAppPackageVersion)</RuntimeFrameworkVersion>
<NETStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard2.0' ">$(NETStandardLibrary20PackageVersion)</NETStandardImplicitPackageVersion>
</PropertyGroup>
</Project>

View File

@@ -17,11 +17,11 @@ Read [Building Single Page Applications on ASP.NET Core with JavaScriptServices]
This repo contains:
* A set of NuGet/NPM packages that implement functionality for:
* Invoking arbitrary NPM packages at runtime from .NET code ([docs](https://github.com/aspnet/JavaScriptServices/tree/dev/src/Microsoft.AspNetCore.NodeServices#simple-usage-example))
* Server-side prerendering of SPA components ([docs](https://github.com/aspnet/JavaScriptServices/tree/dev/src/Microsoft.AspNetCore.SpaServices#server-side-prerendering))
* Webpack dev middleware ([docs](https://github.com/aspnet/JavaScriptServices/tree/dev/src/Microsoft.AspNetCore.SpaServices#webpack-dev-middleware))
* Hot module replacement (HMR) ([docs](https://github.com/aspnet/JavaScriptServices/tree/dev/src/Microsoft.AspNetCore.SpaServices#webpack-hot-module-replacement))
* Server-side and client-side routing integration ([docs](https://github.com/aspnet/JavaScriptServices/tree/dev/src/Microsoft.AspNetCore.SpaServices#routing-helper-mapspafallbackroute))
* Invoking arbitrary NPM packages at runtime from .NET code ([docs](/src/Microsoft.AspNetCore.NodeServices#simple-usage-example))
* Server-side prerendering of SPA components ([docs](/src/Microsoft.AspNetCore.SpaServices#server-side-prerendering))
* Webpack dev middleware ([docs](/src/Microsoft.AspNetCore.SpaServices#webpack-dev-middleware))
* Hot module replacement (HMR) ([docs](/src/Microsoft.AspNetCore.SpaServices#webpack-hot-module-replacement))
* Server-side and client-side routing integration ([docs](/src/Microsoft.AspNetCore.SpaServices#routing-helper-mapspafallbackroute))
* Server-side and client-side validation integration
* "Lazy loading" for Knockout apps
* Samples and docs
@@ -63,10 +63,10 @@ If you have an existing ASP.NET Core application, or if you just want to use the
* `Microsoft.AspNetCore.NodeServices`
* This provides a fast and robust way for .NET code to run JavaScript on the server inside a Node.js environment. You can use this to consume arbitrary functionality from NPM packages at runtime in your ASP.NET Core app.
* Most applications developers don't need to use this directly, but you can do so if you want to implement your own functionality that involves calling Node.js code from .NET at runtime.
* Find [documentation and usage examples here](https://github.com/aspnet/JavaScriptServices/tree/dev/src/Microsoft.AspNetCore.NodeServices#microsoftaspnetcorenodeservices).
* Find [documentation and usage examples here](/src/Microsoft.AspNetCore.NodeServices#microsoftaspnetcorenodeservices).
* `Microsoft.AspNetCore.SpaServices`
* This provides infrastructure that's generally useful when building Single Page Applications (SPAs) with technologies such as Angular or React (for example, server-side prerendering and webpack middleware). Internally, it uses the `NodeServices` package to implement its features.
* Find [documentation and usage examples here](https://github.com/aspnet/JavaScriptServices/tree/dev/src/Microsoft.AspNetCore.SpaServices#microsoftaspnetcorespaservices)
* Find [documentation and usage examples here](/src/Microsoft.AspNetCore.SpaServices#microsoftaspnetcorespaservices)
There were previously other packages called `Microsoft.AspNetCore.AngularServices` and `Microsoft.AspNetCore.ReactServices` but these are not currently needed - all applicable functionality is in `Microsoft.AspNetCore.SpaServices`, because it's sufficiently general.
@@ -74,7 +74,7 @@ If you want to build a helper library for some other SPA framework, you can do s
## Samples
The [`samples` directory](https://github.com/aspnet/JavaScriptServices/tree/dev/samples) contains examples of:
The [`samples` directory](/samples) contains examples of:
- Using the JavaScript services family of packages with Angular and React.
- A standalone `NodeServices` usage for runtime code transpilation and image processing.

View File

@@ -0,0 +1,30 @@
<Project>
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
</PropertyGroup>
<PropertyGroup Label="Package Versions">
<InternalAspNetCoreSdkPackageVersion>3.0.0-build-20181114.5</InternalAspNetCoreSdkPackageVersion>
<MicrosoftAspNetCoreDiagnosticsPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreDiagnosticsPackageVersion>
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
<MicrosoftAspNetCoreHostingPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreHostingPackageVersion>
<MicrosoftAspNetCoreMvcPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreMvcPackageVersion>
<MicrosoftAspNetCoreMvcTagHelpersPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreMvcTagHelpersPackageVersion>
<MicrosoftAspNetCoreMvcViewFeaturesPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreMvcViewFeaturesPackageVersion>
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
<MicrosoftAspNetCoreServerKestrelPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreServerKestrelPackageVersion>
<MicrosoftAspNetCoreStaticFilesPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreStaticFilesPackageVersion>
<MicrosoftAspNetCoreWebSocketsPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreWebSocketsPackageVersion>
<MicrosoftExtensionsDependencyInjectionPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsDependencyInjectionPackageVersion>
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
<MicrosoftExtensionsLoggingConsolePackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsLoggingConsolePackageVersion>
<MicrosoftExtensionsLoggingDebugPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsLoggingDebugPackageVersion>
<MicrosoftNETCoreAppPackageVersion>3.0.0-preview1-26907-05</MicrosoftNETCoreAppPackageVersion>
<MicrosoftNETSdkRazorPackageVersion>3.0.0-alpha1-10742</MicrosoftNETSdkRazorPackageVersion>
<NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion>
<NewtonsoftJsonPackageVersion>11.0.2</NewtonsoftJsonPackageVersion>
<SystemThreadingTasksDataflowPackageVersion>4.10.0-preview1-26907-04</SystemThreadingTasksDataflowPackageVersion>
</PropertyGroup>
<Import Project="$(DotNetPackageVersionPropsPath)" Condition=" '$(DotNetPackageVersionPropsPath)' != '' " />
<PropertyGroup Label="Package Versions: Pinned" />
</Project>

View File

@@ -4,12 +4,10 @@
<PropertyGroup>
<!-- These properties are use by the automation that updates dependencies.props -->
<LineupPackageId>Internal.AspNetCore.Universe.Lineup</LineupPackageId>
<LineupPackageVersion>2.1.0-rc1-*</LineupPackageVersion>
<LineupPackageRestoreSource>https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json</LineupPackageRestoreSource>
</PropertyGroup>
<ItemGroup>
<DotNetCoreRuntime Include="$(MicrosoftNETCoreApp20PackageVersion)" />
<DotNetCoreRuntime Include="$(MicrosoftNETCoreApp21PackageVersion)" />
<DotNetCoreRuntime Include="$(MicrosoftNETCoreAppPackageVersion)" />
</ItemGroup>
</Project>

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.1;net461</TargetFrameworks>
<TargetFramework>netcoreapp3.0</TargetFramework>
<IsPackable>false</IsPackable>
<OutputType>exe</OutputType>
</PropertyGroup>
@@ -13,6 +13,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="$(MicrosoftExtensionsDependencyInjectionPackageVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsolePackageVersion)" />
</ItemGroup>
</Project>

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.1;net461</TargetFrameworks>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
<IsPackable>false</IsPackable>
</PropertyGroup>
@@ -18,6 +18,8 @@
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(MicrosoftAspNetCoreStaticFilesPackageVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(MicrosoftExtensionsLoggingDebugPackageVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsolePackageVersion)" />
<PackageReference Include="Microsoft.NET.Sdk.Razor" Version="$(MicrosoftNETSdkRazorPackageVersion)" PrivateAssets="All" />
</ItemGroup>
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.1;net461</TargetFrameworks>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
<IsPackable>false</IsPackable>
</PropertyGroup>
@@ -18,6 +18,8 @@
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(MicrosoftAspNetCoreStaticFilesPackageVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(MicrosoftExtensionsLoggingDebugPackageVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsolePackageVersion)" />
<PackageReference Include="Microsoft.NET.Sdk.Razor" Version="$(MicrosoftNETSdkRazorPackageVersion)" PrivateAssets="All" />
</ItemGroup>
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

@@ -0,0 +1,28 @@
[cmdletbinding(SupportsShouldProcess = $true)]
param(
)
$ErrorActionPreference = 'Stop'
Set-StrictMode -Version 2
Push-Location "src"
try {
$dirs = Get-ChildItem -Directory
foreach($dir in $dirs)
{
Push-Location $dir
try{
if(Test-Path -Path "package.json")
{
npm install
npm run build
}
}
finally{
Pop-Location
}
}
}
finally {
Pop-Location
}

View File

@@ -0,0 +1,626 @@
(function (e, a) { for (var i in a) e[i] = a[i]; }(exports, /******/(function (modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if (installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/
}
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/
};
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/
}
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function (exports, name, getter) {
/******/ if (!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/
}
/******/
};
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function (exports) {
/******/ if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/
}
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/
};
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function (value, mode) {
/******/ if (mode & 1) value = __webpack_require__(value);
/******/ if (mode & 8) return value;
/******/ if ((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if (mode & 2 && typeof value != 'string') for (var key in value) __webpack_require__.d(ns, key, function (key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/
};
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function (module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/
};
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function (object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/
})
/************************************************************************/
/******/([
/* 0 */
/***/ (function (module, exports, __webpack_require__) {
module.exports = __webpack_require__(1);
/***/
}),
/* 1 */
/***/ (function (module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
// Limit dependencies to core Node modules. This means the code in this file has to be very low-level and unattractive,
// but simplifies things for the consumer of this module.
__webpack_require__(2);
var net = __webpack_require__(3);
var path = __webpack_require__(4);
var readline = __webpack_require__(5);
var ArgsUtil_1 = __webpack_require__(6);
var ExitWhenParentExits_1 = __webpack_require__(7);
var virtualConnectionServer = __webpack_require__(8);
// Webpack doesn't support dynamic requires for files not present at compile time, so grab a direct
// reference to Node's runtime 'require' function.
var dynamicRequire = eval('require');
// Signal to the .NET side when we're ready to accept invocations
var server = net.createServer().on('listening', function () {
console.log('[Microsoft.AspNetCore.NodeServices:Listening]');
});
// Each virtual connection represents a separate invocation
virtualConnectionServer.createInterface(server).on('connection', function (connection) {
readline.createInterface(connection, null).on('line', function (line) {
try {
// Get a reference to the function to invoke
var invocation = JSON.parse(line);
var invokedModule = dynamicRequire(path.resolve(process.cwd(), invocation.moduleName));
var invokedFunction = invocation.exportedFunctionName ? invokedModule[invocation.exportedFunctionName] : invokedModule;
// Prepare a callback for accepting non-streamed JSON responses
var hasInvokedCallback_1 = false;
var invocationCallback = function (errorValue, successValue) {
if (hasInvokedCallback_1) {
throw new Error('Cannot supply more than one result. The callback has already been invoked,'
+ ' or the result stream has already been accessed');
}
hasInvokedCallback_1 = true;
connection.end(JSON.stringify({
result: successValue,
errorMessage: errorValue && (errorValue.message || errorValue),
errorDetails: errorValue && (errorValue.stack || null)
}));
};
// Also support streamed binary responses
Object.defineProperty(invocationCallback, 'stream', {
enumerable: true,
get: function () {
hasInvokedCallback_1 = true;
return connection;
}
});
// Actually invoke it, passing through any supplied args
invokedFunction.apply(null, [invocationCallback].concat(invocation.args));
}
catch (ex) {
connection.end(JSON.stringify({
errorMessage: ex.message,
errorDetails: ex.stack
}));
}
});
});
// Begin listening now. The underlying transport varies according to the runtime platform.
// On Windows it's Named Pipes; on Linux/OSX it's Domain Sockets.
var useWindowsNamedPipes = /^win/.test(process.platform);
var parsedArgs = ArgsUtil_1.parseArgs(process.argv);
var listenAddress = (useWindowsNamedPipes ? '\\\\.\\pipe\\' : '/tmp/') + parsedArgs.listenAddress;
server.listen(listenAddress);
ExitWhenParentExits_1.exitWhenParentExits(parseInt(parsedArgs.parentPid), /* ignoreSigint */ true);
/***/
}),
/* 2 */
/***/ (function (module, exports) {
// When Node writes to stdout/strerr, we capture that and convert the lines into calls on the
// active .NET ILogger. But by default, stdout/stderr don't have any way of distinguishing
// linebreaks inside log messages from the linebreaks that delimit separate log messages,
// so multiline strings will end up being written to the ILogger as multiple independent
// log messages. This makes them very hard to make sense of, especially when they represent
// something like stack traces.
//
// To fix this, we intercept stdout/stderr writes, and replace internal linebreaks with a
// marker token. When .NET receives the lines, it converts the marker tokens back to regular
// linebreaks within the logged messages.
//
// Note that it's better to do the interception at the stdout/stderr level, rather than at
// the console.log/console.error (etc.) level, because this takes place after any native
// message formatting has taken place (e.g., inserting values for % placeholders).
var findInternalNewlinesRegex = /\n(?!$)/g;
var encodedNewline = '__ns_newline__';
encodeNewlinesWrittenToStream(process.stdout);
encodeNewlinesWrittenToStream(process.stderr);
function encodeNewlinesWrittenToStream(outputStream) {
var origWriteFunction = outputStream.write;
outputStream.write = function (value) {
// Only interfere with the write if it's definitely a string
if (typeof value === 'string') {
var argsClone = Array.prototype.slice.call(arguments, 0);
argsClone[0] = encodeNewlinesInString(value);
origWriteFunction.apply(this, argsClone);
}
else {
origWriteFunction.apply(this, arguments);
}
};
}
function encodeNewlinesInString(str) {
return str.replace(findInternalNewlinesRegex, encodedNewline);
}
/***/
}),
/* 3 */
/***/ (function (module, exports) {
module.exports = require("net");
/***/
}),
/* 4 */
/***/ (function (module, exports) {
module.exports = require("path");
/***/
}),
/* 5 */
/***/ (function (module, exports) {
module.exports = require("readline");
/***/
}),
/* 6 */
/***/ (function (module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
function parseArgs(args) {
// Very simplistic parsing which is sufficient for the cases needed. We don't want to bring in any external
// dependencies (such as an args-parsing library) to this file.
var result = {};
var currentKey = null;
args.forEach(function (arg) {
if (arg.indexOf('--') === 0) {
var argName = arg.substring(2);
result[argName] = undefined;
currentKey = argName;
}
else if (currentKey) {
result[currentKey] = arg;
currentKey = null;
}
});
return result;
}
exports.parseArgs = parseArgs;
/***/
}),
/* 7 */
/***/ (function (module, exports, __webpack_require__) {
"use strict";
/*
In general, we want the Node child processes to be terminated as soon as the parent .NET processes exit,
because we have no further use for them. If the .NET process shuts down gracefully, it will run its
finalizers, one of which (in OutOfProcessNodeInstance.cs) will kill its associated Node process immediately.
But if the .NET process is terminated forcefully (e.g., on Linux/OSX with 'kill -9'), then it won't have
any opportunity to shut down its child processes, and by default they will keep running. In this case, it's
up to the child process to detect this has happened and terminate itself.
There are many possible approaches to detecting when a parent process has exited, most of which behave
differently between Windows and Linux/OS X:
- On Windows, the parent process can mark its child as being a 'job' that should auto-terminate when
the parent does (http://stackoverflow.com/a/4657392). Not cross-platform.
- The child Node process can get a callback when the parent disconnects (process.on('disconnect', ...)).
But despite http://stackoverflow.com/a/16487966, no callback fires in any case I've tested (Windows / OS X).
- The child Node process can get a callback when its stdin/stdout are disconnected, as described at
http://stackoverflow.com/a/15693934. This works well on OS X, but calling stdout.resume() on Windows
causes the process to terminate prematurely.
- I don't know why, but on Windows, it's enough to invoke process.stdin.resume(). For some reason this causes
the child Node process to exit as soon as the parent one does, but I don't see this documented anywhere.
- You can poll to see if the parent process, or your stdin/stdout connection to it, is gone
- You can directly pass a parent process PID to the child, and then have the child poll to see if it's
still running (e.g., using process.kill(pid, 0), which doesn't kill it but just tests whether it exists,
as per https://nodejs.org/api/process.html#process_process_kill_pid_signal)
- Or, on each poll, you can try writing to process.stdout. If the parent has died, then this will throw.
However I don't see this documented anywhere. It would be nice if you could just poll for whether or not
process.stdout is still connected (without actually writing to it) but I haven't found any property whose
value changes until you actually try to write to it.
Of these, the only cross-platform approach that is actually documented as a valid strategy is simply polling
to check whether the parent PID is still running. So that's what we do here.
*/
exports.__esModule = true;
var pollIntervalMs = 1000;
function exitWhenParentExits(parentPid, ignoreSigint) {
setInterval(function () {
if (!processExists(parentPid)) {
// Can't log anything at this point, because out stdout was connected to the parent,
// but the parent is gone.
process.exit();
}
}, pollIntervalMs);
if (ignoreSigint) {
// Pressing ctrl+c in the terminal sends a SIGINT to all processes in the foreground process tree.
// By default, the Node process would then exit before the .NET process, because ASP.NET implements
// a delayed shutdown to allow ongoing requests to complete.
//
// This is problematic, because if Node exits first, the CopyToAsync code in ConditionalProxyMiddleware
// will experience a read fault, and logs a huge load of errors. Fortunately, since the Node process is
// already set up to shut itself down if it detects the .NET process is terminated, all we have to do is
// ignore the SIGINT. The Node process will then terminate automatically after the .NET process does.
//
// A better solution would be to have WebpackDevMiddleware listen for SIGINT and gracefully close any
// ongoing EventSource connections before letting the Node process exit, independently of the .NET
// process exiting. However, doing this well in general is very nontrivial (see all the discussion at
// https://github.com/nodejs/node/issues/2642).
process.on('SIGINT', function () {
console.log('Received SIGINT. Waiting for .NET process to exit...');
});
}
}
exports.exitWhenParentExits = exitWhenParentExits;
function processExists(pid) {
try {
// Sending signal 0 - on all platforms - tests whether the process exists. As long as it doesn't
// throw, that means it does exist.
process.kill(pid, 0);
return true;
}
catch (ex) {
// If the reason for the error is that we don't have permission to ask about this process,
// report that as a separate problem.
if (ex.code === 'EPERM') {
throw new Error("Attempted to check whether process " + pid + " was running, but got a permissions error.");
}
return false;
}
}
/***/
}),
/* 8 */
/***/ (function (module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
var events_1 = __webpack_require__(9);
var VirtualConnection_1 = __webpack_require__(10);
// Keep this in sync with the equivalent constant in the .NET code. Both sides split up their transmissions into frames with this max length,
// and both will reject longer frames.
var MaxFrameBodyLength = 16 * 1024;
/**
* Accepts connections to a net.Server and adapts them to behave as multiplexed connections. That is, for each physical socket connection,
* we track a list of 'virtual connections' whose API is a Duplex stream. The remote clients may open and close as many virtual connections
* as they wish, reading and writing to them independently, without the overhead of establishing new physical connections each time.
*/
function createInterface(server) {
var emitter = new events_1.EventEmitter();
server.on('connection', function (socket) {
// For each physical socket connection, maintain a set of virtual connections. Issue a notification whenever
// a new virtual connections is opened.
var childSockets = new VirtualConnectionsCollection(socket, function (virtualConnection) {
emitter.emit('connection', virtualConnection);
});
});
return emitter;
}
exports.createInterface = createInterface;
/**
* Tracks the 'virtual connections' associated with a single physical socket connection.
*/
var VirtualConnectionsCollection = /** @class */ (function () {
function VirtualConnectionsCollection(_socket, _onVirtualConnectionCallback) {
var _this = this;
this._socket = _socket;
this._onVirtualConnectionCallback = _onVirtualConnectionCallback;
this._currentFrameHeader = null;
this._virtualConnections = {};
// If the remote end closes the physical socket, treat all the virtual connections as being closed remotely too
this._socket.on('close', function () {
Object.getOwnPropertyNames(_this._virtualConnections).forEach(function (id) {
// A 'null' frame signals that the connection was closed remotely
_this._virtualConnections[id].onReceivedData(null);
});
});
this._socket.on('readable', this._onIncomingDataAvailable.bind(this));
}
/**
* This is called whenever the underlying socket signals that it may have some data available to read. It will synchronously read as many
* message frames as it can from the underlying socket, opens virtual connections as needed, and dispatches data to them.
*/
VirtualConnectionsCollection.prototype._onIncomingDataAvailable = function () {
var exhaustedAllData = false;
while (!exhaustedAllData) {
// We might already have a pending frame header from the previous time this method ran, but if not, that's the next thing we need to read
if (this._currentFrameHeader === null) {
this._currentFrameHeader = this._readNextFrameHeader();
}
if (this._currentFrameHeader === null) {
// There's not enough data to fill a frameheader, so wait until more arrives later
// The next attempt to read from the socket will start from the same place this one did (incomplete reads don't consume any data)
exhaustedAllData = true;
}
else {
var frameBodyLength = this._currentFrameHeader.bodyLength;
var frameBodyOrNull = frameBodyLength > 0 ? this._socket.read(this._currentFrameHeader.bodyLength) : null;
if (frameBodyOrNull !== null || frameBodyLength === 0) {
// We have a complete frame header+body pair, so we can now dispatch this to a virtual connection. We set _currentFrameHeader back to null
// so that the next thing we try to read is the next frame header.
var headerCopy = this._currentFrameHeader;
this._currentFrameHeader = null;
this._onReceivedCompleteFrame(headerCopy, frameBodyOrNull);
}
else {
// There's not enough data to fill the pending frame body, so wait until more arrives later
// The next attempt to read from the socket will start from the same place this one did (incomplete reads don't consume any data)
exhaustedAllData = true;
}
}
}
};
VirtualConnectionsCollection.prototype._onReceivedCompleteFrame = function (header, bodyIfNotEmpty) {
// An incoming zero-length frame signals that there's no more data to read.
// Signal this to the Node stream APIs by pushing a 'null' chunk to it.
var virtualConnection = this._getOrOpenVirtualConnection(header);
virtualConnection.onReceivedData(header.bodyLength > 0 ? bodyIfNotEmpty : null);
};
VirtualConnectionsCollection.prototype._getOrOpenVirtualConnection = function (header) {
if (this._virtualConnections.hasOwnProperty(header.connectionIdString)) {
// It's an existing virtual connection
return this._virtualConnections[header.connectionIdString];
}
else {
// It's a new one
return this._openVirtualConnection(header);
}
};
VirtualConnectionsCollection.prototype._openVirtualConnection = function (header) {
var _this = this;
var beginWriteCallback = function (data, writeCompletedCallback) {
// Only send nonempty frames, since empty ones are a signal to close the virtual connection
if (data.length > 0) {
_this._sendFrame(header.connectionIdBinary, data, writeCompletedCallback);
}
};
var newVirtualConnection = new VirtualConnection_1.VirtualConnection(beginWriteCallback);
newVirtualConnection.on('end', function () {
// The virtual connection was closed remotely. Clean up locally.
_this._onVirtualConnectionWasClosed(header.connectionIdString);
});
newVirtualConnection.on('finish', function () {
// The virtual connection was closed locally. Clean up locally, and notify the remote that we're done.
_this._onVirtualConnectionWasClosed(header.connectionIdString);
_this._sendFrame(header.connectionIdBinary, Buffer.alloc(0));
});
this._virtualConnections[header.connectionIdString] = newVirtualConnection;
this._onVirtualConnectionCallback(newVirtualConnection);
return newVirtualConnection;
};
/**
* Attempts to read a complete frame header, synchronously, from the underlying socket.
* If not enough data is available synchronously, returns null without consuming any data from the socket.
*/
VirtualConnectionsCollection.prototype._readNextFrameHeader = function () {
var headerBuf = this._socket.read(12);
if (headerBuf !== null) {
// We have enough data synchronously
var connectionIdBinary = headerBuf.slice(0, 8);
var connectionIdString = connectionIdBinary.toString('hex');
var bodyLength = headerBuf.readInt32LE(8);
if (bodyLength < 0 || bodyLength > MaxFrameBodyLength) {
// Throwing here is going to bring down the whole process, so this cannot be allowed to happen in real use.
// But it won't happen in real use, because this is only used with our .NET client, which doesn't violate this rule.
throw new Error('Illegal frame body length: ' + bodyLength);
}
return { connectionIdBinary: connectionIdBinary, connectionIdString: connectionIdString, bodyLength: bodyLength };
}
else {
// Not enough bytes are available synchronously, so none were consumed
return null;
}
};
VirtualConnectionsCollection.prototype._sendFrame = function (connectionIdBinary, data, callback) {
// For all sends other than the last one, only invoke the callback if it failed.
// Also, only invoke the callback at most once.
var hasInvokedCallback = false;
var finalCallback = callback && (function (error) {
if (!hasInvokedCallback) {
hasInvokedCallback = true;
callback(error);
}
});
var notFinalCallback = callback && (function (error) {
if (error) {
finalCallback(error);
}
});
// The amount of data we're writing might exceed MaxFrameBodyLength, so split into frames as needed.
// Note that we always send at least one frame, even if it's empty (because that's the close-virtual-connection signal).
// If needed, this could be changed to send frames asynchronously, so that large sends could proceed in parallel
// (though that would involve making a clone of 'data', to avoid the risk of it being mutated during the send).
var bytesSent = 0;
do {
var nextFrameBodyLength = Math.min(MaxFrameBodyLength, data.length - bytesSent);
var isFinalChunk = (bytesSent + nextFrameBodyLength) === data.length;
this._socket.write(connectionIdBinary, notFinalCallback);
this._sendInt32LE(nextFrameBodyLength, notFinalCallback);
this._socket.write(data.slice(bytesSent, bytesSent + nextFrameBodyLength), isFinalChunk ? finalCallback : notFinalCallback);
bytesSent += nextFrameBodyLength;
} while (bytesSent < data.length);
};
/**
* Sends a number serialized in the correct format for .NET to receive as a System.Int32
*/
VirtualConnectionsCollection.prototype._sendInt32LE = function (value, callback) {
var buf = Buffer.alloc(4);
buf.writeInt32LE(value, 0);
this._socket.write(buf, callback);
};
VirtualConnectionsCollection.prototype._onVirtualConnectionWasClosed = function (id) {
if (this._virtualConnections.hasOwnProperty(id)) {
delete this._virtualConnections[id];
}
};
return VirtualConnectionsCollection;
}());
/***/
}),
/* 9 */
/***/ (function (module, exports) {
module.exports = require("events");
/***/
}),
/* 10 */
/***/ (function (module, exports, __webpack_require__) {
"use strict";
var __extends = (this && this.__extends) || (function () {
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);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
exports.__esModule = true;
var stream_1 = __webpack_require__(11);
/**
* Represents a virtual connection. Multiple virtual connections may be multiplexed over a single physical socket connection.
*/
var VirtualConnection = /** @class */ (function (_super) {
__extends(VirtualConnection, _super);
function VirtualConnection(_beginWriteCallback) {
var _this = _super.call(this) || this;
_this._beginWriteCallback = _beginWriteCallback;
_this._flowing = false;
_this._receivedDataQueue = [];
return _this;
}
VirtualConnection.prototype._read = function () {
this._flowing = true;
// Keep pushing data until we run out, or the underlying framework asks us to stop.
// When we finish, the 'flowing' state is detemined by whether more data is still being requested.
while (this._flowing && this._receivedDataQueue.length > 0) {
var nextChunk = this._receivedDataQueue.shift();
this._flowing = this.push(nextChunk);
}
};
VirtualConnection.prototype._write = function (chunk, encodingIfString, callback) {
if (typeof chunk === 'string') {
chunk = Buffer.from(chunk, encodingIfString);
}
this._beginWriteCallback(chunk, callback);
};
VirtualConnection.prototype.onReceivedData = function (dataOrNullToSignalEOF) {
if (this._flowing) {
this._flowing = this.push(dataOrNullToSignalEOF);
}
else {
this._receivedDataQueue.push(dataOrNullToSignalEOF);
}
};
return VirtualConnection;
}(stream_1.Duplex));
exports.VirtualConnection = VirtualConnection;
/***/
}),
/* 11 */
/***/ (function (module, exports) {
module.exports = require("stream");
/***/
})
/******/])));

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<Description>Socket-based RPC for Microsoft.AspNetCore.NodeServices.</Description>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
<ItemGroup>

View File

@@ -27,7 +27,7 @@ export class VirtualConnection extends Duplex {
public _write(chunk: Buffer | string, encodingIfString: string, callback: EndWriteCallback) {
if (typeof chunk === 'string') {
chunk = new Buffer(chunk as string, encodingIfString);
chunk = Buffer.from(chunk as string, encodingIfString);
}
this._beginWriteCallback(chunk as Buffer, callback);

View File

@@ -113,7 +113,7 @@ class VirtualConnectionsCollection {
newVirtualConnection.on('finish', () => {
// The virtual connection was closed locally. Clean up locally, and notify the remote that we're done.
this._onVirtualConnectionWasClosed(header.connectionIdString);
this._sendFrame(header.connectionIdBinary, new Buffer(0));
this._sendFrame(header.connectionIdBinary, Buffer.alloc(0));
});
this._virtualConnections[header.connectionIdString] = newVirtualConnection;
@@ -180,7 +180,7 @@ class VirtualConnectionsCollection {
* Sends a number serialized in the correct format for .NET to receive as a System.Int32
*/
private _sendInt32LE(value: number, callback?: EndWriteCallback) {
const buf = new Buffer(4);
const buf = Buffer.alloc(4);
buf.writeInt32LE(value, 0);
this._socket.write(buf, callback);
}

View File

@@ -1,5 +1,5 @@
{
"AssemblyIdentity": "Microsoft.AspNetCore.NodeServices.Sockets, Version=2.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60",
"AssemblyIdentity": "Microsoft.AspNetCore.NodeServices.Sockets, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60",
"Types": [
{
"Name": "Microsoft.AspNetCore.NodeServices.Sockets.NodeServicesOptionsExtensions",

File diff suppressed because it is too large Load Diff

View File

@@ -5,14 +5,15 @@
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "./node_modules/.bin/webpack"
"build": "webpack --mode production"
},
"author": "Microsoft",
"license": "Apache-2.0",
"devDependencies": {
"@types/node": "^6.0.42",
"ts-loader": "^0.8.2",
"typescript": "^2.0.0",
"webpack": "^1.13.1"
"@types/node": "^10.9.2",
"ts-loader": "^4.5.0",
"typescript": "^3.0.1",
"webpack": "^4.17.1",
"webpack-cli": "^3.1.0"
}
}

View File

@@ -1,12 +1,13 @@
const path = require('path');
module.exports = {
target: 'node',
externals: ['fs', 'net', 'events', 'readline', 'stream'],
resolve: {
extensions: [ '.ts' ]
},
module: {
loaders: [
{ test: /\.ts$/, loader: 'ts-loader' },
rules: [
{ test: /\.ts$/, use: 'ts-loader' },
]
},
entry: {
@@ -14,7 +15,10 @@ module.exports = {
},
output: {
libraryTarget: 'commonjs',
path: './Content/Node',
path: path.join(__dirname, 'Content', 'Node'),
filename: '[name].js'
},
optimization: {
minimize: false
}
};

View File

@@ -6,7 +6,7 @@ using Microsoft.AspNetCore.NodeServices.HostingModels;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging.Console;
using Microsoft.Extensions.Logging.Abstractions;
namespace Microsoft.AspNetCore.NodeServices
{
@@ -58,8 +58,7 @@ namespace Microsoft.AspNetCore.NodeServices
var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
NodeInstanceOutputLogger = loggerFactory != null
? loggerFactory.CreateLogger(LogCategoryName)
: new ConsoleLogger(LogCategoryName, null, false);
: NullLogger.Instance;
// By default, we use this package's built-in out-of-process-via-HTTP hosting/transport
this.UseHttpHosting();
}

View File

@@ -0,0 +1,416 @@
(function(e, a) { for(var i in a) e[i] = a[i]; }(exports, /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 1);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
module.exports = require("path");
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(2);
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
// Limit dependencies to core Node modules. This means the code in this file has to be very low-level and unattractive,
// but simplifies things for the consumer of this module.
__webpack_require__(3);
__webpack_require__(4);
var http = __webpack_require__(5);
var path = __webpack_require__(0);
var ArgsUtil_1 = __webpack_require__(6);
var ExitWhenParentExits_1 = __webpack_require__(7);
// Webpack doesn't support dynamic requires for files not present at compile time, so grab a direct
// reference to Node's runtime 'require' function.
var dynamicRequire = eval('require');
var server = http.createServer(function (req, res) {
readRequestBodyAsJson(req, function (bodyJson) {
var hasSentResult = false;
var callback = function (errorValue, successValue) {
if (!hasSentResult) {
hasSentResult = true;
if (errorValue) {
respondWithError(res, errorValue);
}
else if (typeof successValue !== 'string') {
// Arbitrary object/number/etc - JSON-serialize it
var successValueJson = void 0;
try {
successValueJson = JSON.stringify(successValue);
}
catch (ex) {
// JSON serialization error - pass it back to .NET
respondWithError(res, ex);
return;
}
res.setHeader('Content-Type', 'application/json');
res.end(successValueJson);
}
else {
// String - can bypass JSON-serialization altogether
res.setHeader('Content-Type', 'text/plain');
res.end(successValue);
}
}
};
// Support streamed responses
Object.defineProperty(callback, 'stream', {
enumerable: true,
get: function () {
if (!hasSentResult) {
hasSentResult = true;
res.setHeader('Content-Type', 'application/octet-stream');
}
return res;
}
});
try {
var resolvedPath = path.resolve(process.cwd(), bodyJson.moduleName);
var invokedModule = dynamicRequire(resolvedPath);
var func = bodyJson.exportedFunctionName ? invokedModule[bodyJson.exportedFunctionName] : invokedModule;
if (!func) {
throw new Error('The module "' + resolvedPath + '" has no export named "' + bodyJson.exportedFunctionName + '"');
}
func.apply(null, [callback].concat(bodyJson.args));
}
catch (synchronousException) {
callback(synchronousException, null);
}
});
});
var parsedArgs = ArgsUtil_1.parseArgs(process.argv);
var requestedPortOrZero = parsedArgs.port || 0; // 0 means 'let the OS decide'
server.listen(requestedPortOrZero, 'localhost', function () {
var addressInfo = server.address();
// Signal to HttpNodeHost which loopback IP address (IPv4 or IPv6) and port it should make its HTTP connections on
console.log('[Microsoft.AspNetCore.NodeServices.HttpNodeHost:Listening on {' + addressInfo.address + '} port ' + addressInfo.port + '\]');
// Signal to the NodeServices base class that we're ready to accept invocations
console.log('[Microsoft.AspNetCore.NodeServices:Listening]');
});
ExitWhenParentExits_1.exitWhenParentExits(parseInt(parsedArgs.parentPid), /* ignoreSigint */ true);
function readRequestBodyAsJson(request, callback) {
var requestBodyAsString = '';
request.on('data', function (chunk) { requestBodyAsString += chunk; });
request.on('end', function () { callback(JSON.parse(requestBodyAsString)); });
}
function respondWithError(res, errorValue) {
res.statusCode = 500;
res.end(JSON.stringify({
errorMessage: errorValue.message || errorValue,
errorDetails: errorValue.stack || null
}));
}
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
var path = __webpack_require__(0);
var startsWith = function (str, prefix) { return str.substring(0, prefix.length) === prefix; };
var appRootDir = process.cwd();
function patchedLStat(pathToStatLong, fsReqWrap) {
try {
// If the lstat completes without errors, we don't modify its behavior at all
return origLStat.apply(this, arguments);
}
catch (ex) {
var shouldOverrideError = startsWith(ex.message, 'EPERM') // It's a permissions error
&& typeof appRootDirLong === 'string'
&& startsWith(appRootDirLong, pathToStatLong) // ... for an ancestor directory
&& ex.stack.indexOf('Object.realpathSync ') >= 0; // ... during symlink resolution
if (shouldOverrideError) {
// Fake the result to give the same result as an 'lstat' on the app root dir.
// This stops Node failing to load modules just because it doesn't know whether
// ancestor directories are symlinks or not. If there's a genuine file
// permissions issue, it will still surface later when Node actually
// tries to read the file.
return origLStat.call(this, appRootDir, fsReqWrap);
}
else {
// In any other case, preserve the original error
throw ex;
}
}
}
;
// It's only necessary to apply this workaround on Windows
var appRootDirLong = null;
var origLStat = null;
if (/^win/.test(process.platform)) {
try {
// Get the app's root dir in Node's internal "long" format (e.g., \\?\C:\dir\subdir)
appRootDirLong = path._makeLong(appRootDir);
// Actually apply the patch, being as defensive as possible
var bindingFs = process.binding('fs');
origLStat = bindingFs.lstat;
if (typeof origLStat === 'function') {
bindingFs.lstat = patchedLStat;
}
}
catch (ex) {
// If some future version of Node throws (e.g., to prevent use of process.binding()),
// don't apply the patch, but still let the application run.
}
}
/***/ }),
/* 4 */
/***/ (function(module, exports) {
// When Node writes to stdout/strerr, we capture that and convert the lines into calls on the
// active .NET ILogger. But by default, stdout/stderr don't have any way of distinguishing
// linebreaks inside log messages from the linebreaks that delimit separate log messages,
// so multiline strings will end up being written to the ILogger as multiple independent
// log messages. This makes them very hard to make sense of, especially when they represent
// something like stack traces.
//
// To fix this, we intercept stdout/stderr writes, and replace internal linebreaks with a
// marker token. When .NET receives the lines, it converts the marker tokens back to regular
// linebreaks within the logged messages.
//
// Note that it's better to do the interception at the stdout/stderr level, rather than at
// the console.log/console.error (etc.) level, because this takes place after any native
// message formatting has taken place (e.g., inserting values for % placeholders).
var findInternalNewlinesRegex = /\n(?!$)/g;
var encodedNewline = '__ns_newline__';
encodeNewlinesWrittenToStream(process.stdout);
encodeNewlinesWrittenToStream(process.stderr);
function encodeNewlinesWrittenToStream(outputStream) {
var origWriteFunction = outputStream.write;
outputStream.write = function (value) {
// Only interfere with the write if it's definitely a string
if (typeof value === 'string') {
var argsClone = Array.prototype.slice.call(arguments, 0);
argsClone[0] = encodeNewlinesInString(value);
origWriteFunction.apply(this, argsClone);
}
else {
origWriteFunction.apply(this, arguments);
}
};
}
function encodeNewlinesInString(str) {
return str.replace(findInternalNewlinesRegex, encodedNewline);
}
/***/ }),
/* 5 */
/***/ (function(module, exports) {
module.exports = require("http");
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
function parseArgs(args) {
// Very simplistic parsing which is sufficient for the cases needed. We don't want to bring in any external
// dependencies (such as an args-parsing library) to this file.
var result = {};
var currentKey = null;
args.forEach(function (arg) {
if (arg.indexOf('--') === 0) {
var argName = arg.substring(2);
result[argName] = undefined;
currentKey = argName;
}
else if (currentKey) {
result[currentKey] = arg;
currentKey = null;
}
});
return result;
}
exports.parseArgs = parseArgs;
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*
In general, we want the Node child processes to be terminated as soon as the parent .NET processes exit,
because we have no further use for them. If the .NET process shuts down gracefully, it will run its
finalizers, one of which (in OutOfProcessNodeInstance.cs) will kill its associated Node process immediately.
But if the .NET process is terminated forcefully (e.g., on Linux/OSX with 'kill -9'), then it won't have
any opportunity to shut down its child processes, and by default they will keep running. In this case, it's
up to the child process to detect this has happened and terminate itself.
There are many possible approaches to detecting when a parent process has exited, most of which behave
differently between Windows and Linux/OS X:
- On Windows, the parent process can mark its child as being a 'job' that should auto-terminate when
the parent does (http://stackoverflow.com/a/4657392). Not cross-platform.
- The child Node process can get a callback when the parent disconnects (process.on('disconnect', ...)).
But despite http://stackoverflow.com/a/16487966, no callback fires in any case I've tested (Windows / OS X).
- The child Node process can get a callback when its stdin/stdout are disconnected, as described at
http://stackoverflow.com/a/15693934. This works well on OS X, but calling stdout.resume() on Windows
causes the process to terminate prematurely.
- I don't know why, but on Windows, it's enough to invoke process.stdin.resume(). For some reason this causes
the child Node process to exit as soon as the parent one does, but I don't see this documented anywhere.
- You can poll to see if the parent process, or your stdin/stdout connection to it, is gone
- You can directly pass a parent process PID to the child, and then have the child poll to see if it's
still running (e.g., using process.kill(pid, 0), which doesn't kill it but just tests whether it exists,
as per https://nodejs.org/api/process.html#process_process_kill_pid_signal)
- Or, on each poll, you can try writing to process.stdout. If the parent has died, then this will throw.
However I don't see this documented anywhere. It would be nice if you could just poll for whether or not
process.stdout is still connected (without actually writing to it) but I haven't found any property whose
value changes until you actually try to write to it.
Of these, the only cross-platform approach that is actually documented as a valid strategy is simply polling
to check whether the parent PID is still running. So that's what we do here.
*/
exports.__esModule = true;
var pollIntervalMs = 1000;
function exitWhenParentExits(parentPid, ignoreSigint) {
setInterval(function () {
if (!processExists(parentPid)) {
// Can't log anything at this point, because out stdout was connected to the parent,
// but the parent is gone.
process.exit();
}
}, pollIntervalMs);
if (ignoreSigint) {
// Pressing ctrl+c in the terminal sends a SIGINT to all processes in the foreground process tree.
// By default, the Node process would then exit before the .NET process, because ASP.NET implements
// a delayed shutdown to allow ongoing requests to complete.
//
// This is problematic, because if Node exits first, the CopyToAsync code in ConditionalProxyMiddleware
// will experience a read fault, and logs a huge load of errors. Fortunately, since the Node process is
// already set up to shut itself down if it detects the .NET process is terminated, all we have to do is
// ignore the SIGINT. The Node process will then terminate automatically after the .NET process does.
//
// A better solution would be to have WebpackDevMiddleware listen for SIGINT and gracefully close any
// ongoing EventSource connections before letting the Node process exit, independently of the .NET
// process exiting. However, doing this well in general is very nontrivial (see all the discussion at
// https://github.com/nodejs/node/issues/2642).
process.on('SIGINT', function () {
console.log('Received SIGINT. Waiting for .NET process to exit...');
});
}
}
exports.exitWhenParentExits = exitWhenParentExits;
function processExists(pid) {
try {
// Sending signal 0 - on all platforms - tests whether the process exists. As long as it doesn't
// throw, that means it does exist.
process.kill(pid, 0);
return true;
}
catch (ex) {
// If the reason for the error is that we don't have permission to ask about this process,
// report that as a separate problem.
if (ex.code === 'EPERM') {
throw new Error("Attempted to check whether process " + pid + " was running, but got a permissions error.");
}
return false;
}
}
/***/ })
/******/ ])));

Some files were not shown because too many files have changed in this diff Show More