├── .env.example ├── .gitattributes ├── .gitignore ├── README.md ├── app ├── Console │ └── Kernel.php ├── Exceptions │ └── Handler.php ├── Http │ ├── Controllers │ │ ├── Auth │ │ │ ├── ForgotPasswordController.php │ │ │ ├── LoginController.php │ │ │ ├── RegisterController.php │ │ │ └── ResetPasswordController.php │ │ └── Controller.php │ ├── Kernel.php │ └── Middleware │ │ ├── EncryptCookies.php │ │ ├── RedirectIfAuthenticated.php │ │ └── VerifyCsrfToken.php ├── Providers │ ├── AppServiceProvider.php │ ├── AuthServiceProvider.php │ ├── BroadcastServiceProvider.php │ ├── EventServiceProvider.php │ └── RouteServiceProvider.php └── User.php ├── artisan ├── bootstrap ├── app.php ├── autoload.php └── cache │ └── .gitignore ├── composer.json ├── composer.lock ├── config ├── app.php ├── auth.php ├── broadcasting.php ├── cache.php ├── compile.php ├── database.php ├── filesystems.php ├── mail.php ├── queue.php ├── services.php ├── session.php └── view.php ├── database ├── .gitignore ├── factories │ └── ModelFactory.php ├── migrations │ ├── .gitkeep │ ├── 2014_10_12_000000_create_users_table.php │ └── 2014_10_12_100000_create_password_resets_table.php └── seeds │ ├── .gitkeep │ └── DatabaseSeeder.php ├── gulpfile.js ├── package.json ├── phpunit.xml ├── public ├── .htaccess ├── app │ ├── app.component.js │ ├── app.component.js.map │ ├── app.module.js │ ├── app.module.js.map │ ├── main.js │ └── main.js.map ├── css │ ├── app.css │ └── app.css.map ├── favicon.ico ├── index.php ├── js │ └── app.js ├── robots.txt ├── systemjs.config.js └── web.config ├── readme.md ├── resources ├── assets │ ├── js │ │ ├── app.js │ │ ├── bootstrap.js │ │ └── components │ │ │ └── Example.vue │ ├── sass │ │ ├── _variables.scss │ │ └── app.scss │ └── typescript │ │ ├── app.component.ts │ │ ├── app.module.ts │ │ └── main.ts ├── lang │ └── en │ │ ├── auth.php │ │ ├── pagination.php │ │ ├── passwords.php │ │ └── validation.php └── views │ ├── errors │ └── 503.blade.php │ ├── vendor │ └── .gitkeep │ └── welcome.blade.php ├── routes ├── api.php ├── console.php └── web.php ├── server.php ├── storage ├── app │ ├── .gitignore │ └── public │ │ └── .gitignore ├── framework │ ├── .gitignore │ ├── cache │ │ └── .gitignore │ ├── sessions │ │ └── .gitignore │ └── views │ │ └── .gitignore └── logs │ └── .gitignore ├── tests ├── ExampleTest.php └── TestCase.php ├── tsconfig.json ├── typings.json ├── typings ├── globals │ ├── core-js │ │ ├── index.d.ts │ │ └── typings.json │ ├── jasmine │ │ ├── index.d.ts │ │ └── typings.json │ └── node │ │ ├── index.d.ts │ │ └── typings.json └── index.d.ts └── zone ├── LICENSE ├── LICENSE.wrapped ├── README.md ├── dist ├── async-test.js ├── fake-async-test.js ├── jasmine-patch.js ├── jasmine-patch.min.js ├── long-stack-trace-zone.js ├── long-stack-trace-zone.min.js ├── proxy.js ├── proxy.min.js ├── sync-test.js ├── task-tracking.js ├── task-tracking.min.js ├── wtf.js ├── wtf.min.js ├── zone-node.js ├── zone.js ├── zone.js.d.ts └── zone.min.js ├── lib ├── browser │ ├── browser.ts │ ├── define-property.ts │ ├── event-target.ts │ ├── property-descriptor.ts │ ├── register-element.ts │ └── websocket.ts ├── common │ ├── timers.ts │ └── utils.ts ├── jasmine │ └── jasmine.ts ├── node │ ├── events.ts │ ├── fs.ts │ └── node.ts ├── zone-spec │ ├── async-test.ts │ ├── fake-async-test.ts │ ├── long-stack-trace.ts │ ├── proxy.ts │ ├── sync-test.ts │ ├── task-tracking.ts │ └── wtf.ts └── zone.ts └── package.json /.env.example: -------------------------------------------------------------------------------- 1 | APP_ENV=local 2 | APP_KEY= 3 | APP_DEBUG=true 4 | APP_LOG_LEVEL=debug 5 | APP_URL=http://localhost 6 | 7 | DB_CONNECTION=mysql 8 | DB_HOST=127.0.0.1 9 | DB_PORT=3306 10 | DB_DATABASE=homestead 11 | DB_USERNAME=homestead 12 | DB_PASSWORD=secret 13 | 14 | BROADCAST_DRIVER=log 15 | CACHE_DRIVER=file 16 | SESSION_DRIVER=file 17 | QUEUE_DRIVER=sync 18 | 19 | REDIS_HOST=127.0.0.1 20 | REDIS_PASSWORD=null 21 | REDIS_PORT=6379 22 | 23 | MAIL_DRIVER=smtp 24 | MAIL_HOST=mailtrap.io 25 | MAIL_PORT=2525 26 | MAIL_USERNAME=null 27 | MAIL_PASSWORD=null 28 | MAIL_ENCRYPTION=null 29 | 30 | PUSHER_APP_ID= 31 | PUSHER_KEY= 32 | PUSHER_SECRET= 33 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.css linguist-vendored 3 | *.scss linguist-vendored 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /public/storage 3 | /vendor 4 | /.idea 5 | Homestead.json 6 | Homestead.yaml 7 | .env 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # laravel5.3-angular2 2 | This is initial setup of Angular 2 with Laravel 5.3. 3 | -------------------------------------------------------------------------------- /app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('inspire') 28 | // ->hourly(); 29 | } 30 | 31 | /** 32 | * Register the Closure based commands for the application. 33 | * 34 | * @return void 35 | */ 36 | protected function commands() 37 | { 38 | require base_path('routes/console.php'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/Exceptions/Handler.php: -------------------------------------------------------------------------------- 1 | expectsJson()) { 60 | return response()->json(['error' => 'Unauthenticated.'], 401); 61 | } 62 | 63 | return redirect()->guest('login'); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/ForgotPasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/LoginController.php: -------------------------------------------------------------------------------- 1 | middleware('guest', ['except' => 'logout']); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/RegisterController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 40 | } 41 | 42 | /** 43 | * Get a validator for an incoming registration request. 44 | * 45 | * @param array $data 46 | * @return \Illuminate\Contracts\Validation\Validator 47 | */ 48 | protected function validator(array $data) 49 | { 50 | return Validator::make($data, [ 51 | 'name' => 'required|max:255', 52 | 'email' => 'required|email|max:255|unique:users', 53 | 'password' => 'required|min:6|confirmed', 54 | ]); 55 | } 56 | 57 | /** 58 | * Create a new user instance after a valid registration. 59 | * 60 | * @param array $data 61 | * @return User 62 | */ 63 | protected function create(array $data) 64 | { 65 | return User::create([ 66 | 'name' => $data['name'], 67 | 'email' => $data['email'], 68 | 'password' => bcrypt($data['password']), 69 | ]); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/ResetPasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | [ 27 | \App\Http\Middleware\EncryptCookies::class, 28 | \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, 29 | \Illuminate\Session\Middleware\StartSession::class, 30 | \Illuminate\View\Middleware\ShareErrorsFromSession::class, 31 | \App\Http\Middleware\VerifyCsrfToken::class, 32 | \Illuminate\Routing\Middleware\SubstituteBindings::class, 33 | ], 34 | 35 | 'api' => [ 36 | 'throttle:60,1', 37 | 'bindings', 38 | ], 39 | ]; 40 | 41 | /** 42 | * The application's route middleware. 43 | * 44 | * These middleware may be assigned to groups or used individually. 45 | * 46 | * @var array 47 | */ 48 | protected $routeMiddleware = [ 49 | 'auth' => \Illuminate\Auth\Middleware\Authenticate::class, 50 | 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 51 | 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 52 | 'can' => \Illuminate\Auth\Middleware\Authorize::class, 53 | 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 54 | 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 55 | ]; 56 | } 57 | -------------------------------------------------------------------------------- /app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | check()) { 21 | return redirect('/home'); 22 | } 23 | 24 | return $next($request); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Http/Middleware/VerifyCsrfToken.php: -------------------------------------------------------------------------------- 1 | 'App\Policies\ModelPolicy', 17 | ]; 18 | 19 | /** 20 | * Register any authentication / authorization services. 21 | * 22 | * @return void 23 | */ 24 | public function boot() 25 | { 26 | $this->registerPolicies(); 27 | 28 | // 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | id === (int) $userId; 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Providers/EventServiceProvider.php: -------------------------------------------------------------------------------- 1 | [ 17 | 'App\Listeners\EventListener', 18 | ], 19 | ]; 20 | 21 | /** 22 | * Register any events for your application. 23 | * 24 | * @return void 25 | */ 26 | public function boot() 27 | { 28 | parent::boot(); 29 | 30 | // 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/Providers/RouteServiceProvider.php: -------------------------------------------------------------------------------- 1 | mapApiRoutes(); 39 | 40 | $this->mapWebRoutes(); 41 | 42 | // 43 | } 44 | 45 | /** 46 | * Define the "web" routes for the application. 47 | * 48 | * These routes all receive session state, CSRF protection, etc. 49 | * 50 | * @return void 51 | */ 52 | protected function mapWebRoutes() 53 | { 54 | Route::group([ 55 | 'middleware' => 'web', 56 | 'namespace' => $this->namespace, 57 | ], function ($router) { 58 | require base_path('routes/web.php'); 59 | }); 60 | } 61 | 62 | /** 63 | * Define the "api" routes for the application. 64 | * 65 | * These routes are typically stateless. 66 | * 67 | * @return void 68 | */ 69 | protected function mapApiRoutes() 70 | { 71 | Route::group([ 72 | 'middleware' => 'api', 73 | 'namespace' => $this->namespace, 74 | 'prefix' => 'api', 75 | ], function ($router) { 76 | require base_path('routes/api.php'); 77 | }); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/User.php: -------------------------------------------------------------------------------- 1 | make(Illuminate\Contracts\Console\Kernel::class); 32 | 33 | $status = $kernel->handle( 34 | $input = new Symfony\Component\Console\Input\ArgvInput, 35 | new Symfony\Component\Console\Output\ConsoleOutput 36 | ); 37 | 38 | /* 39 | |-------------------------------------------------------------------------- 40 | | Shutdown The Application 41 | |-------------------------------------------------------------------------- 42 | | 43 | | Once Artisan has finished running. We will fire off the shutdown events 44 | | so that any final work may be done by the application before we shut 45 | | down the process. This is the last thing to happen to the request. 46 | | 47 | */ 48 | 49 | $kernel->terminate($input, $status); 50 | 51 | exit($status); 52 | -------------------------------------------------------------------------------- /bootstrap/app.php: -------------------------------------------------------------------------------- 1 | singleton( 30 | Illuminate\Contracts\Http\Kernel::class, 31 | App\Http\Kernel::class 32 | ); 33 | 34 | $app->singleton( 35 | Illuminate\Contracts\Console\Kernel::class, 36 | App\Console\Kernel::class 37 | ); 38 | 39 | $app->singleton( 40 | Illuminate\Contracts\Debug\ExceptionHandler::class, 41 | App\Exceptions\Handler::class 42 | ); 43 | 44 | /* 45 | |-------------------------------------------------------------------------- 46 | | Return The Application 47 | |-------------------------------------------------------------------------- 48 | | 49 | | This script returns the application instance. The instance is given to 50 | | the calling script so we can separate the building of the instances 51 | | from the actual running of the application and sending responses. 52 | | 53 | */ 54 | 55 | return $app; 56 | -------------------------------------------------------------------------------- /bootstrap/autoload.php: -------------------------------------------------------------------------------- 1 | =5.6.4", 9 | "laravel/framework": "5.3.*", 10 | "laravelcollective/html": "^5.3" 11 | }, 12 | "require-dev": { 13 | "fzaninotto/faker": "~1.4", 14 | "mockery/mockery": "0.9.*", 15 | "phpunit/phpunit": "~5.0", 16 | "symfony/css-selector": "3.1.*", 17 | "symfony/dom-crawler": "3.1.*" 18 | }, 19 | "autoload": { 20 | "classmap": [ 21 | "database" 22 | ], 23 | "psr-4": { 24 | "App\\": "app/" 25 | } 26 | }, 27 | "autoload-dev": { 28 | "classmap": [ 29 | "tests/TestCase.php" 30 | ] 31 | }, 32 | "scripts": { 33 | "post-root-package-install": [ 34 | "php -r \"file_exists('.env') || copy('.env.example', '.env');\"" 35 | ], 36 | "post-create-project-cmd": [ 37 | "php artisan key:generate" 38 | ], 39 | "post-install-cmd": [ 40 | "Illuminate\\Foundation\\ComposerScripts::postInstall", 41 | "php artisan optimize" 42 | ], 43 | "post-update-cmd": [ 44 | "Illuminate\\Foundation\\ComposerScripts::postUpdate", 45 | "php artisan optimize" 46 | ] 47 | }, 48 | "config": { 49 | "preferred-install": "dist" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /config/auth.php: -------------------------------------------------------------------------------- 1 | [ 17 | 'guard' => 'web', 18 | 'passwords' => 'users', 19 | ], 20 | 21 | /* 22 | |-------------------------------------------------------------------------- 23 | | Authentication Guards 24 | |-------------------------------------------------------------------------- 25 | | 26 | | Next, you may define every authentication guard for your application. 27 | | Of course, a great default configuration has been defined for you 28 | | here which uses session storage and the Eloquent user provider. 29 | | 30 | | All authentication drivers have a user provider. This defines how the 31 | | users are actually retrieved out of your database or other storage 32 | | mechanisms used by this application to persist your user's data. 33 | | 34 | | Supported: "session", "token" 35 | | 36 | */ 37 | 38 | 'guards' => [ 39 | 'web' => [ 40 | 'driver' => 'session', 41 | 'provider' => 'users', 42 | ], 43 | 44 | 'api' => [ 45 | 'driver' => 'token', 46 | 'provider' => 'users', 47 | ], 48 | ], 49 | 50 | /* 51 | |-------------------------------------------------------------------------- 52 | | User Providers 53 | |-------------------------------------------------------------------------- 54 | | 55 | | All authentication drivers have a user provider. This defines how the 56 | | users are actually retrieved out of your database or other storage 57 | | mechanisms used by this application to persist your user's data. 58 | | 59 | | If you have multiple user tables or models you may configure multiple 60 | | sources which represent each model / table. These sources may then 61 | | be assigned to any extra authentication guards you have defined. 62 | | 63 | | Supported: "database", "eloquent" 64 | | 65 | */ 66 | 67 | 'providers' => [ 68 | 'users' => [ 69 | 'driver' => 'eloquent', 70 | 'model' => App\User::class, 71 | ], 72 | 73 | // 'users' => [ 74 | // 'driver' => 'database', 75 | // 'table' => 'users', 76 | // ], 77 | ], 78 | 79 | /* 80 | |-------------------------------------------------------------------------- 81 | | Resetting Passwords 82 | |-------------------------------------------------------------------------- 83 | | 84 | | You may specify multiple password reset configurations if you have more 85 | | than one user table or model in the application and you want to have 86 | | separate password reset settings based on the specific user types. 87 | | 88 | | The expire time is the number of minutes that the reset token should be 89 | | considered valid. This security feature keeps tokens short-lived so 90 | | they have less time to be guessed. You may change this as needed. 91 | | 92 | */ 93 | 94 | 'passwords' => [ 95 | 'users' => [ 96 | 'provider' => 'users', 97 | 'table' => 'password_resets', 98 | 'expire' => 60, 99 | ], 100 | ], 101 | 102 | ]; 103 | -------------------------------------------------------------------------------- /config/broadcasting.php: -------------------------------------------------------------------------------- 1 | env('BROADCAST_DRIVER', 'null'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Broadcast Connections 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may define all of the broadcast connections that will be used 26 | | to broadcast events to other systems or over websockets. Samples of 27 | | each available type of connection are provided inside this array. 28 | | 29 | */ 30 | 31 | 'connections' => [ 32 | 33 | 'pusher' => [ 34 | 'driver' => 'pusher', 35 | 'key' => env('PUSHER_KEY'), 36 | 'secret' => env('PUSHER_SECRET'), 37 | 'app_id' => env('PUSHER_APP_ID'), 38 | 'options' => [ 39 | // 40 | ], 41 | ], 42 | 43 | 'redis' => [ 44 | 'driver' => 'redis', 45 | 'connection' => 'default', 46 | ], 47 | 48 | 'log' => [ 49 | 'driver' => 'log', 50 | ], 51 | 52 | 'null' => [ 53 | 'driver' => 'null', 54 | ], 55 | 56 | ], 57 | 58 | ]; 59 | -------------------------------------------------------------------------------- /config/cache.php: -------------------------------------------------------------------------------- 1 | env('CACHE_DRIVER', 'file'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Cache Stores 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may define all of the cache "stores" for your application as 26 | | well as their drivers. You may even define multiple stores for the 27 | | same cache driver to group types of items stored in your caches. 28 | | 29 | */ 30 | 31 | 'stores' => [ 32 | 33 | 'apc' => [ 34 | 'driver' => 'apc', 35 | ], 36 | 37 | 'array' => [ 38 | 'driver' => 'array', 39 | ], 40 | 41 | 'database' => [ 42 | 'driver' => 'database', 43 | 'table' => 'cache', 44 | 'connection' => null, 45 | ], 46 | 47 | 'file' => [ 48 | 'driver' => 'file', 49 | 'path' => storage_path('framework/cache'), 50 | ], 51 | 52 | 'memcached' => [ 53 | 'driver' => 'memcached', 54 | 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), 55 | 'sasl' => [ 56 | env('MEMCACHED_USERNAME'), 57 | env('MEMCACHED_PASSWORD'), 58 | ], 59 | 'options' => [ 60 | // Memcached::OPT_CONNECT_TIMEOUT => 2000, 61 | ], 62 | 'servers' => [ 63 | [ 64 | 'host' => env('MEMCACHED_HOST', '127.0.0.1'), 65 | 'port' => env('MEMCACHED_PORT', 11211), 66 | 'weight' => 100, 67 | ], 68 | ], 69 | ], 70 | 71 | 'redis' => [ 72 | 'driver' => 'redis', 73 | 'connection' => 'default', 74 | ], 75 | 76 | ], 77 | 78 | /* 79 | |-------------------------------------------------------------------------- 80 | | Cache Key Prefix 81 | |-------------------------------------------------------------------------- 82 | | 83 | | When utilizing a RAM based store such as APC or Memcached, there might 84 | | be other applications utilizing the same cache. So, we'll specify a 85 | | value to get prefixed to all our keys so we can avoid collisions. 86 | | 87 | */ 88 | 89 | 'prefix' => 'laravel', 90 | 91 | ]; 92 | -------------------------------------------------------------------------------- /config/compile.php: -------------------------------------------------------------------------------- 1 | [ 17 | // 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled File Providers 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may list service providers which define a "compiles" function 26 | | that returns additional files that should be compiled, providing an 27 | | easy way to get common files from any packages you are utilizing. 28 | | 29 | */ 30 | 31 | 'providers' => [ 32 | // 33 | ], 34 | 35 | ]; 36 | -------------------------------------------------------------------------------- /config/database.php: -------------------------------------------------------------------------------- 1 | PDO::FETCH_OBJ, 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Default Database Connection Name 21 | |-------------------------------------------------------------------------- 22 | | 23 | | Here you may specify which of the database connections below you wish 24 | | to use as your default connection for all database work. Of course 25 | | you may use many connections at once using the Database library. 26 | | 27 | */ 28 | 29 | 'default' => env('DB_CONNECTION', 'mysql'), 30 | 31 | /* 32 | |-------------------------------------------------------------------------- 33 | | Database Connections 34 | |-------------------------------------------------------------------------- 35 | | 36 | | Here are each of the database connections setup for your application. 37 | | Of course, examples of configuring each database platform that is 38 | | supported by Laravel is shown below to make development simple. 39 | | 40 | | 41 | | All database work in Laravel is done through the PHP PDO facilities 42 | | so make sure you have the driver for your particular database of 43 | | choice installed on your machine before you begin development. 44 | | 45 | */ 46 | 47 | 'connections' => [ 48 | 49 | 'sqlite' => [ 50 | 'driver' => 'sqlite', 51 | 'database' => env('DB_DATABASE', database_path('database.sqlite')), 52 | 'prefix' => '', 53 | ], 54 | 55 | 'mysql' => [ 56 | 'driver' => 'mysql', 57 | 'host' => env('DB_HOST', 'localhost'), 58 | 'port' => env('DB_PORT', '3306'), 59 | 'database' => env('DB_DATABASE', 'forge'), 60 | 'username' => env('DB_USERNAME', 'forge'), 61 | 'password' => env('DB_PASSWORD', ''), 62 | 'charset' => 'utf8', 63 | 'collation' => 'utf8_unicode_ci', 64 | 'prefix' => '', 65 | 'strict' => true, 66 | 'engine' => null, 67 | ], 68 | 69 | 'pgsql' => [ 70 | 'driver' => 'pgsql', 71 | 'host' => env('DB_HOST', 'localhost'), 72 | 'port' => env('DB_PORT', '5432'), 73 | 'database' => env('DB_DATABASE', 'forge'), 74 | 'username' => env('DB_USERNAME', 'forge'), 75 | 'password' => env('DB_PASSWORD', ''), 76 | 'charset' => 'utf8', 77 | 'prefix' => '', 78 | 'schema' => 'public', 79 | 'sslmode' => 'prefer', 80 | ], 81 | 82 | ], 83 | 84 | /* 85 | |-------------------------------------------------------------------------- 86 | | Migration Repository Table 87 | |-------------------------------------------------------------------------- 88 | | 89 | | This table keeps track of all the migrations that have already run for 90 | | your application. Using this information, we can determine which of 91 | | the migrations on disk haven't actually been run in the database. 92 | | 93 | */ 94 | 95 | 'migrations' => 'migrations', 96 | 97 | /* 98 | |-------------------------------------------------------------------------- 99 | | Redis Databases 100 | |-------------------------------------------------------------------------- 101 | | 102 | | Redis is an open source, fast, and advanced key-value store that also 103 | | provides a richer set of commands than a typical key-value systems 104 | | such as APC or Memcached. Laravel makes it easy to dig right in. 105 | | 106 | */ 107 | 108 | 'redis' => [ 109 | 110 | 'cluster' => false, 111 | 112 | 'default' => [ 113 | 'host' => env('REDIS_HOST', 'localhost'), 114 | 'password' => env('REDIS_PASSWORD', null), 115 | 'port' => env('REDIS_PORT', 6379), 116 | 'database' => 0, 117 | ], 118 | 119 | ], 120 | 121 | ]; 122 | -------------------------------------------------------------------------------- /config/filesystems.php: -------------------------------------------------------------------------------- 1 | 'local', 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Default Cloud Filesystem Disk 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Many applications store files both locally and in the cloud. For this 26 | | reason, you may specify a default "cloud" driver here. This driver 27 | | will be bound as the Cloud disk implementation in the container. 28 | | 29 | */ 30 | 31 | 'cloud' => 's3', 32 | 33 | /* 34 | |-------------------------------------------------------------------------- 35 | | Filesystem Disks 36 | |-------------------------------------------------------------------------- 37 | | 38 | | Here you may configure as many filesystem "disks" as you wish, and you 39 | | may even configure multiple disks of the same driver. Defaults have 40 | | been setup for each driver as an example of the required options. 41 | | 42 | */ 43 | 44 | 'disks' => [ 45 | 46 | 'local' => [ 47 | 'driver' => 'local', 48 | 'root' => storage_path('app'), 49 | ], 50 | 51 | 'public' => [ 52 | 'driver' => 'local', 53 | 'root' => storage_path('app/public'), 54 | 'visibility' => 'public', 55 | ], 56 | 57 | 's3' => [ 58 | 'driver' => 's3', 59 | 'key' => 'your-key', 60 | 'secret' => 'your-secret', 61 | 'region' => 'your-region', 62 | 'bucket' => 'your-bucket', 63 | ], 64 | 65 | ], 66 | 67 | ]; 68 | -------------------------------------------------------------------------------- /config/mail.php: -------------------------------------------------------------------------------- 1 | env('MAIL_DRIVER', 'smtp'), 20 | 21 | /* 22 | |-------------------------------------------------------------------------- 23 | | SMTP Host Address 24 | |-------------------------------------------------------------------------- 25 | | 26 | | Here you may provide the host address of the SMTP server used by your 27 | | applications. A default option is provided that is compatible with 28 | | the Mailgun mail service which will provide reliable deliveries. 29 | | 30 | */ 31 | 32 | 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), 33 | 34 | /* 35 | |-------------------------------------------------------------------------- 36 | | SMTP Host Port 37 | |-------------------------------------------------------------------------- 38 | | 39 | | This is the SMTP port used by your application to deliver e-mails to 40 | | users of the application. Like the host we have set this value to 41 | | stay compatible with the Mailgun e-mail application by default. 42 | | 43 | */ 44 | 45 | 'port' => env('MAIL_PORT', 587), 46 | 47 | /* 48 | |-------------------------------------------------------------------------- 49 | | Global "From" Address 50 | |-------------------------------------------------------------------------- 51 | | 52 | | You may wish for all e-mails sent by your application to be sent from 53 | | the same address. Here, you may specify a name and address that is 54 | | used globally for all e-mails that are sent by your application. 55 | | 56 | */ 57 | 58 | 'from' => [ 59 | 'address' => 'hello@example.com', 60 | 'name' => 'Example', 61 | ], 62 | 63 | /* 64 | |-------------------------------------------------------------------------- 65 | | E-Mail Encryption Protocol 66 | |-------------------------------------------------------------------------- 67 | | 68 | | Here you may specify the encryption protocol that should be used when 69 | | the application send e-mail messages. A sensible default using the 70 | | transport layer security protocol should provide great security. 71 | | 72 | */ 73 | 74 | 'encryption' => env('MAIL_ENCRYPTION', 'tls'), 75 | 76 | /* 77 | |-------------------------------------------------------------------------- 78 | | SMTP Server Username 79 | |-------------------------------------------------------------------------- 80 | | 81 | | If your SMTP server requires a username for authentication, you should 82 | | set it here. This will get used to authenticate with your server on 83 | | connection. You may also set the "password" value below this one. 84 | | 85 | */ 86 | 87 | 'username' => env('MAIL_USERNAME'), 88 | 89 | /* 90 | |-------------------------------------------------------------------------- 91 | | SMTP Server Password 92 | |-------------------------------------------------------------------------- 93 | | 94 | | Here you may set the password required by your SMTP server to send out 95 | | messages from your application. This will be given to the server on 96 | | connection so that the application will be able to send messages. 97 | | 98 | */ 99 | 100 | 'password' => env('MAIL_PASSWORD'), 101 | 102 | /* 103 | |-------------------------------------------------------------------------- 104 | | Sendmail System Path 105 | |-------------------------------------------------------------------------- 106 | | 107 | | When using the "sendmail" driver to send e-mails, we will need to know 108 | | the path to where Sendmail lives on this server. A default path has 109 | | been provided here, which will work well on most of your systems. 110 | | 111 | */ 112 | 113 | 'sendmail' => '/usr/sbin/sendmail -bs', 114 | 115 | ]; 116 | -------------------------------------------------------------------------------- /config/queue.php: -------------------------------------------------------------------------------- 1 | env('QUEUE_DRIVER', 'sync'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Queue Connections 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may configure the connection information for each server that 26 | | is used by your application. A default configuration has been added 27 | | for each back-end shipped with Laravel. You are free to add more. 28 | | 29 | */ 30 | 31 | 'connections' => [ 32 | 33 | 'sync' => [ 34 | 'driver' => 'sync', 35 | ], 36 | 37 | 'database' => [ 38 | 'driver' => 'database', 39 | 'table' => 'jobs', 40 | 'queue' => 'default', 41 | 'retry_after' => 90, 42 | ], 43 | 44 | 'beanstalkd' => [ 45 | 'driver' => 'beanstalkd', 46 | 'host' => 'localhost', 47 | 'queue' => 'default', 48 | 'retry_after' => 90, 49 | ], 50 | 51 | 'sqs' => [ 52 | 'driver' => 'sqs', 53 | 'key' => 'your-public-key', 54 | 'secret' => 'your-secret-key', 55 | 'prefix' => 'https://sqs.us-east-1.amazonaws.com/your-account-id', 56 | 'queue' => 'your-queue-name', 57 | 'region' => 'us-east-1', 58 | ], 59 | 60 | 'redis' => [ 61 | 'driver' => 'redis', 62 | 'connection' => 'default', 63 | 'queue' => 'default', 64 | 'retry_after' => 90, 65 | ], 66 | 67 | ], 68 | 69 | /* 70 | |-------------------------------------------------------------------------- 71 | | Failed Queue Jobs 72 | |-------------------------------------------------------------------------- 73 | | 74 | | These options configure the behavior of failed queue job logging so you 75 | | can control which database and table are used to store the jobs that 76 | | have failed. You may change them to any database / table you wish. 77 | | 78 | */ 79 | 80 | 'failed' => [ 81 | 'database' => env('DB_CONNECTION', 'mysql'), 82 | 'table' => 'failed_jobs', 83 | ], 84 | 85 | ]; 86 | -------------------------------------------------------------------------------- /config/services.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => env('MAILGUN_DOMAIN'), 19 | 'secret' => env('MAILGUN_SECRET'), 20 | ], 21 | 22 | 'ses' => [ 23 | 'key' => env('SES_KEY'), 24 | 'secret' => env('SES_SECRET'), 25 | 'region' => 'us-east-1', 26 | ], 27 | 28 | 'sparkpost' => [ 29 | 'secret' => env('SPARKPOST_SECRET'), 30 | ], 31 | 32 | 'stripe' => [ 33 | 'model' => App\User::class, 34 | 'key' => env('STRIPE_KEY'), 35 | 'secret' => env('STRIPE_SECRET'), 36 | ], 37 | 38 | ]; 39 | -------------------------------------------------------------------------------- /config/session.php: -------------------------------------------------------------------------------- 1 | env('SESSION_DRIVER', 'file'), 20 | 21 | /* 22 | |-------------------------------------------------------------------------- 23 | | Session Lifetime 24 | |-------------------------------------------------------------------------- 25 | | 26 | | Here you may specify the number of minutes that you wish the session 27 | | to be allowed to remain idle before it expires. If you want them 28 | | to immediately expire on the browser closing, set that option. 29 | | 30 | */ 31 | 32 | 'lifetime' => 120, 33 | 34 | 'expire_on_close' => false, 35 | 36 | /* 37 | |-------------------------------------------------------------------------- 38 | | Session Encryption 39 | |-------------------------------------------------------------------------- 40 | | 41 | | This option allows you to easily specify that all of your session data 42 | | should be encrypted before it is stored. All encryption will be run 43 | | automatically by Laravel and you can use the Session like normal. 44 | | 45 | */ 46 | 47 | 'encrypt' => false, 48 | 49 | /* 50 | |-------------------------------------------------------------------------- 51 | | Session File Location 52 | |-------------------------------------------------------------------------- 53 | | 54 | | When using the native session driver, we need a location where session 55 | | files may be stored. A default has been set for you but a different 56 | | location may be specified. This is only needed for file sessions. 57 | | 58 | */ 59 | 60 | 'files' => storage_path('framework/sessions'), 61 | 62 | /* 63 | |-------------------------------------------------------------------------- 64 | | Session Database Connection 65 | |-------------------------------------------------------------------------- 66 | | 67 | | When using the "database" or "redis" session drivers, you may specify a 68 | | connection that should be used to manage these sessions. This should 69 | | correspond to a connection in your database configuration options. 70 | | 71 | */ 72 | 73 | 'connection' => null, 74 | 75 | /* 76 | |-------------------------------------------------------------------------- 77 | | Session Database Table 78 | |-------------------------------------------------------------------------- 79 | | 80 | | When using the "database" session driver, you may specify the table we 81 | | should use to manage the sessions. Of course, a sensible default is 82 | | provided for you; however, you are free to change this as needed. 83 | | 84 | */ 85 | 86 | 'table' => 'sessions', 87 | 88 | /* 89 | |-------------------------------------------------------------------------- 90 | | Session Cache Store 91 | |-------------------------------------------------------------------------- 92 | | 93 | | When using the "apc" or "memcached" session drivers, you may specify a 94 | | cache store that should be used for these sessions. This value must 95 | | correspond with one of the application's configured cache stores. 96 | | 97 | */ 98 | 99 | 'store' => null, 100 | 101 | /* 102 | |-------------------------------------------------------------------------- 103 | | Session Sweeping Lottery 104 | |-------------------------------------------------------------------------- 105 | | 106 | | Some session drivers must manually sweep their storage location to get 107 | | rid of old sessions from storage. Here are the chances that it will 108 | | happen on a given request. By default, the odds are 2 out of 100. 109 | | 110 | */ 111 | 112 | 'lottery' => [2, 100], 113 | 114 | /* 115 | |-------------------------------------------------------------------------- 116 | | Session Cookie Name 117 | |-------------------------------------------------------------------------- 118 | | 119 | | Here you may change the name of the cookie used to identify a session 120 | | instance by ID. The name specified here will get used every time a 121 | | new session cookie is created by the framework for every driver. 122 | | 123 | */ 124 | 125 | 'cookie' => 'laravel_session', 126 | 127 | /* 128 | |-------------------------------------------------------------------------- 129 | | Session Cookie Path 130 | |-------------------------------------------------------------------------- 131 | | 132 | | The session cookie path determines the path for which the cookie will 133 | | be regarded as available. Typically, this will be the root path of 134 | | your application but you are free to change this when necessary. 135 | | 136 | */ 137 | 138 | 'path' => '/', 139 | 140 | /* 141 | |-------------------------------------------------------------------------- 142 | | Session Cookie Domain 143 | |-------------------------------------------------------------------------- 144 | | 145 | | Here you may change the domain of the cookie used to identify a session 146 | | in your application. This will determine which domains the cookie is 147 | | available to in your application. A sensible default has been set. 148 | | 149 | */ 150 | 151 | 'domain' => env('SESSION_DOMAIN', null), 152 | 153 | /* 154 | |-------------------------------------------------------------------------- 155 | | HTTPS Only Cookies 156 | |-------------------------------------------------------------------------- 157 | | 158 | | By setting this option to true, session cookies will only be sent back 159 | | to the server if the browser has a HTTPS connection. This will keep 160 | | the cookie from being sent to you if it can not be done securely. 161 | | 162 | */ 163 | 164 | 'secure' => env('SESSION_SECURE_COOKIE', false), 165 | 166 | /* 167 | |-------------------------------------------------------------------------- 168 | | HTTP Access Only 169 | |-------------------------------------------------------------------------- 170 | | 171 | | Setting this value to true will prevent JavaScript from accessing the 172 | | value of the cookie and the cookie will only be accessible through 173 | | the HTTP protocol. You are free to modify this option if needed. 174 | | 175 | */ 176 | 177 | 'http_only' => true, 178 | 179 | ]; 180 | -------------------------------------------------------------------------------- /config/view.php: -------------------------------------------------------------------------------- 1 | [ 17 | realpath(base_path('resources/views')), 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled View Path 23 | |-------------------------------------------------------------------------- 24 | | 25 | | This option determines where all the compiled Blade templates will be 26 | | stored for your application. Typically, this is within the storage 27 | | directory. However, as usual, you are free to change this value. 28 | | 29 | */ 30 | 31 | 'compiled' => realpath(storage_path('framework/views')), 32 | 33 | ]; 34 | -------------------------------------------------------------------------------- /database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite 2 | -------------------------------------------------------------------------------- /database/factories/ModelFactory.php: -------------------------------------------------------------------------------- 1 | define(App\User::class, function (Faker\Generator $faker) { 15 | static $password; 16 | 17 | return [ 18 | 'name' => $faker->name, 19 | 'email' => $faker->unique()->safeEmail, 20 | 'password' => $password ?: $password = bcrypt('secret'), 21 | 'remember_token' => str_random(10), 22 | ]; 23 | }); 24 | -------------------------------------------------------------------------------- /database/migrations/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->string('name'); 19 | $table->string('email')->unique(); 20 | $table->string('password'); 21 | $table->rememberToken(); 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::drop('users'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_100000_create_password_resets_table.php: -------------------------------------------------------------------------------- 1 | string('email')->index(); 18 | $table->string('token')->index(); 19 | $table->timestamp('created_at')->nullable(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::drop('password_resets'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/seeds/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /database/seeds/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | call(UsersTableSeeder::class); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const elixir = require('laravel-elixir'); 2 | 3 | require('laravel-elixir-vue'); 4 | require('elixir-typescript'); 5 | 6 | 7 | /* 8 | |-------------------------------------------------------------------------- 9 | | Elixir Asset Management 10 | |-------------------------------------------------------------------------- 11 | | 12 | | Elixir provides a clean, fluent API for defining some basic Gulp tasks 13 | | for your Laravel application. By default, we are compiling the Sass 14 | | file for our application, as well as publishing vendor resources. 15 | | 16 | */ 17 | 18 | elixir(mix => { 19 | mix.sass('app.scss') 20 | .webpack('app.js') 21 | .copy('node_modules/@angular', 'public/@angular') 22 | .copy('node_modules/anular2-in-memory-web-api', 'public/anular2-in-memory-web-api') 23 | .copy('node_modules/core-js', 'public/core-js') 24 | .copy('node_modules/reflect-metadata', 'public/reflect-metadata') 25 | .copy('node_modules/systemjs', 'public/systemjs') 26 | .copy('node_modules/rxjs', 'public/rxjs') 27 | .copy('node_modules/zone.js', 'public/zone.js') 28 | 29 | .typescript( 30 | [ 31 | 'app.component.ts', 32 | 'app.module.ts', 33 | 'main.ts' 34 | ], 35 | 'public/app', 36 | { 37 | "target": "es5", 38 | "module": "system", 39 | "moduleResolution": "node", 40 | "sourceMap": true, 41 | "emitDecoratorMetadata": true, 42 | "experimentalDecorators": true, 43 | "removeComments": false, 44 | "noImplicitAny": false 45 | } 46 | ); 47 | }) 48 | ; 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laravel5.3-angular2", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "prod": "gulp --production", 7 | "dev": "gulp watch", 8 | "start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" ", 9 | "lite": "lite-server", 10 | "postinstall": "typings install", 11 | "tsc": "tsc", 12 | "tsc:w": "tsc -w", 13 | "typings": "typings" 14 | }, 15 | "license": "ISC", 16 | "dependencies": { 17 | "@angular/common": "2.0.0", 18 | "@angular/compiler": "2.0.0", 19 | "@angular/core": "2.0.0", 20 | "@angular/forms": "2.0.0", 21 | "@angular/http": "2.0.0", 22 | "@angular/platform-browser": "2.0.0", 23 | "@angular/platform-browser-dynamic": "2.0.0", 24 | "@angular/router": "3.0.0", 25 | "@angular/upgrade": "2.0.0", 26 | "core-js": "^2.4.1", 27 | "reflect-metadata": "^0.1.3", 28 | "rxjs": "5.0.0-beta.12", 29 | "systemjs": "0.19.27", 30 | "zone.js": "^0.6.23", 31 | "angular2-in-memory-web-api": "0.0.20", 32 | "bootstrap": "^4.0.0" 33 | }, 34 | "devDependencies": { 35 | "bootstrap-sass": "^4.0.0", 36 | "gulp": "^3.9.1", 37 | "jquery": "^3.1.0", 38 | "laravel-elixir": "^6.0.0-9", 39 | "laravel-elixir-vue": "^0.1.4", 40 | "laravel-elixir-webpack-official": "^1.0.2", 41 | "lodash": "^4.14.0", 42 | "vue": "^1.0.26", 43 | "vue-resource": "^0.9.3", 44 | "elixir-typescript": "2.0.0", 45 | 46 | "concurrently": "^2.2.0", 47 | "lite-server": "^2.2.2", 48 | "typescript": "^2.0.2", 49 | "typings":"^1.3.2" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | ./tests 14 | 15 | 16 | 17 | 18 | ./app 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Redirect Trailing Slashes If Not A Folder... 9 | RewriteCond %{REQUEST_FILENAME} !-d 10 | RewriteRule ^(.*)/$ /$1 [L,R=301] 11 | 12 | # Handle Front Controller... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_FILENAME} !-f 15 | RewriteRule ^ index.php [L] 16 | 17 | # Handle Authorization Header 18 | RewriteCond %{HTTP:Authorization} . 19 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 20 | 21 | -------------------------------------------------------------------------------- /public/app/app.component.js: -------------------------------------------------------------------------------- 1 | System.register(['@angular/core'], function(exports_1, context_1) { 2 | "use strict"; 3 | var __moduleName = context_1 && context_1.id; 4 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 5 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 6 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 7 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 8 | return c > 3 && r && Object.defineProperty(target, key, r), r; 9 | }; 10 | var __metadata = (this && this.__metadata) || function (k, v) { 11 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); 12 | }; 13 | var core_1; 14 | var AppComponent; 15 | return { 16 | setters:[ 17 | function (core_1_1) { 18 | core_1 = core_1_1; 19 | }], 20 | execute: function() { 21 | AppComponent = (function () { 22 | function AppComponent() { 23 | } 24 | AppComponent = __decorate([ 25 | core_1.Component({ 26 | selector: 'my-app', 27 | template: '

My First Angular App

' 28 | }), 29 | __metadata('design:paramtypes', []) 30 | ], AppComponent); 31 | return AppComponent; 32 | }()); 33 | exports_1("AppComponent", AppComponent); 34 | } 35 | } 36 | }); 37 | 38 | //# sourceMappingURL=app.component.js.map 39 | -------------------------------------------------------------------------------- /public/app/app.component.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["app.component.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;YAKA;gBAAA;gBAA4B,CAAC;gBAJ7B;oBAAC,gBAAS,CAAC;wBACP,QAAQ,EAAE,QAAQ;wBAClB,QAAQ,EAAE,+BAA+B;qBAC5C,CAAC;;gCAAA;gBAC0B,mBAAC;YAAD,CAA5B,AAA6B,IAAA;YAA7B,uCAA6B,CAAA","file":"app.component.js","sourcesContent":["import { Component } from '@angular/core';\r\n@Component({\r\n selector: 'my-app',\r\n template: '

My First Angular App

'\r\n})\r\nexport class AppComponent { }\r\n"],"sourceRoot":"/source/"} -------------------------------------------------------------------------------- /public/app/app.module.js: -------------------------------------------------------------------------------- 1 | System.register(['@angular/core', '@angular/platform-browser', './app.component'], function(exports_1, context_1) { 2 | "use strict"; 3 | var __moduleName = context_1 && context_1.id; 4 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 5 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 6 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 7 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 8 | return c > 3 && r && Object.defineProperty(target, key, r), r; 9 | }; 10 | var __metadata = (this && this.__metadata) || function (k, v) { 11 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); 12 | }; 13 | var core_1, platform_browser_1, app_component_1; 14 | var AppModule; 15 | return { 16 | setters:[ 17 | function (core_1_1) { 18 | core_1 = core_1_1; 19 | }, 20 | function (platform_browser_1_1) { 21 | platform_browser_1 = platform_browser_1_1; 22 | }, 23 | function (app_component_1_1) { 24 | app_component_1 = app_component_1_1; 25 | }], 26 | execute: function() { 27 | AppModule = (function () { 28 | function AppModule() { 29 | } 30 | AppModule = __decorate([ 31 | core_1.NgModule({ 32 | imports: [platform_browser_1.BrowserModule], 33 | declarations: [app_component_1.AppComponent], 34 | bootstrap: [app_component_1.AppComponent] 35 | }), 36 | __metadata('design:paramtypes', []) 37 | ], AppModule); 38 | return AppModule; 39 | }()); 40 | exports_1("AppModule", AppModule); 41 | } 42 | } 43 | }); 44 | 45 | //# sourceMappingURL=app.module.js.map 46 | -------------------------------------------------------------------------------- /public/app/app.module.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["app.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;YASA;gBAAA;gBAAyB,CAAC;gBAL1B;oBAAC,eAAQ,CAAC;wBACN,OAAO,EAAO,CAAE,gCAAa,CAAE;wBAC/B,YAAY,EAAE,CAAE,4BAAY,CAAE;wBAC9B,SAAS,EAAK,CAAE,4BAAY,CAAE;qBACjC,CAAC;;6BAAA;gBACuB,gBAAC;YAAD,CAAzB,AAA0B,IAAA;YAA1B,iCAA0B,CAAA","file":"app.module.js","sourcesContent":["///\r\nimport { NgModule } from '@angular/core';\r\nimport { BrowserModule } from '@angular/platform-browser';\r\nimport { AppComponent } from './app.component';\r\n@NgModule({\r\n imports: [ BrowserModule ],\r\n declarations: [ AppComponent ],\r\n bootstrap: [ AppComponent ]\r\n})\r\nexport class AppModule { }\r\n\r\n\r\n\r\n"],"sourceRoot":"/source/"} -------------------------------------------------------------------------------- /public/app/main.js: -------------------------------------------------------------------------------- 1 | System.register(['@angular/platform-browser-dynamic', './app.module'], function(exports_1, context_1) { 2 | "use strict"; 3 | var __moduleName = context_1 && context_1.id; 4 | var platform_browser_dynamic_1, app_module_1; 5 | var platform; 6 | return { 7 | setters:[ 8 | function (platform_browser_dynamic_1_1) { 9 | platform_browser_dynamic_1 = platform_browser_dynamic_1_1; 10 | }, 11 | function (app_module_1_1) { 12 | app_module_1 = app_module_1_1; 13 | }], 14 | execute: function() { 15 | platform = platform_browser_dynamic_1.platformBrowserDynamic(); 16 | platform.bootstrapModule(app_module_1.AppModule); 17 | } 18 | } 19 | }); 20 | 21 | //# sourceMappingURL=main.js.map 22 | -------------------------------------------------------------------------------- /public/app/main.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["main.ts"],"names":[],"mappings":";;;;QAEM,QAAQ;;;;;;;;;;YAAR,QAAQ,GAAG,iDAAsB,EAAE,CAAC;YAC1C,QAAQ,CAAC,eAAe,CAAC,sBAAS,CAAC,CAAC","file":"main.js","sourcesContent":["import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';\r\nimport { AppModule } from './app.module';\r\nconst platform = platformBrowserDynamic();\r\nplatform.bootstrapModule(AppModule);\r\n"],"sourceRoot":"/source/"} -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eliyas5044/laravel5.3-angular2/58b4c60acc9de0beba6bf132c7842f41d58db6b3/public/favicon.ico -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | /* 11 | |-------------------------------------------------------------------------- 12 | | Register The Auto Loader 13 | |-------------------------------------------------------------------------- 14 | | 15 | | Composer provides a convenient, automatically generated class loader for 16 | | our application. We just need to utilize it! We'll simply require it 17 | | into the script here so that we don't have to worry about manual 18 | | loading any of our classes later on. It feels nice to relax. 19 | | 20 | */ 21 | 22 | require __DIR__.'/../bootstrap/autoload.php'; 23 | 24 | /* 25 | |-------------------------------------------------------------------------- 26 | | Turn On The Lights 27 | |-------------------------------------------------------------------------- 28 | | 29 | | We need to illuminate PHP development, so let us turn on the lights. 30 | | This bootstraps the framework and gets it ready for use, then it 31 | | will load up this application so that we can run it and send 32 | | the responses back to the browser and delight our users. 33 | | 34 | */ 35 | 36 | $app = require_once __DIR__.'/../bootstrap/app.php'; 37 | 38 | /* 39 | |-------------------------------------------------------------------------- 40 | | Run The Application 41 | |-------------------------------------------------------------------------- 42 | | 43 | | Once we have the application, we can handle the incoming request 44 | | through the kernel, and send the associated response back to 45 | | the client's browser allowing them to enjoy the creative 46 | | and wonderful application we have prepared for them. 47 | | 48 | */ 49 | 50 | $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); 51 | 52 | $response = $kernel->handle( 53 | $request = Illuminate\Http\Request::capture() 54 | ); 55 | 56 | $response->send(); 57 | 58 | $kernel->terminate($request, $response); 59 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /public/systemjs.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * System configuration for Angular samples 3 | * Adjust as necessary for your application needs. 4 | */ 5 | (function (global) { 6 | System.config({ 7 | 8 | // map tells the System loader where to look for things 9 | map: { 10 | // our app is within the app folder 11 | app: 'app', 12 | // angular bundles 13 | '@angular/core': '@angular/core/bundles/core.umd.js', 14 | '@angular/common': '@angular/common/bundles/common.umd.js', 15 | '@angular/compiler': '@angular/compiler/bundles/compiler.umd.js', 16 | '@angular/platform-browser': '@angular/platform-browser/bundles/platform-browser.umd.js', 17 | '@angular/platform-browser-dynamic': '@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', 18 | '@angular/http': '@angular/http/bundles/http.umd.js', 19 | '@angular/router': '@angular/router/bundles/router.umd.js', 20 | '@angular/forms': '@angular/forms/bundles/forms.umd.js', 21 | // other libraries 22 | 'rxjs': 'rxjs', 23 | 'angular2-in-memory-web-api': 'angular2-in-memory-web-api', 24 | }, 25 | // packages tells the System loader how to load when no filename and/or no extension 26 | packages: { 27 | app: { 28 | main: './main.js', 29 | defaultExtension: 'js' 30 | }, 31 | rxjs: { 32 | defaultExtension: 'js' 33 | }, 34 | 'angular2-in-memory-web-api': { 35 | main: './index.js', 36 | defaultExtension: 'js' 37 | } 38 | } 39 | }); 40 | })(this); 41 | -------------------------------------------------------------------------------- /public/web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # laravel5.3-angular2 2 | This is initial setup of Angular 2 with Laravel 5.3. 3 | 4 | 1. First clone it or download it. 5 | 2. Run this command in your terminal- 6 | ``` 7 | composer install 8 | ``` 9 | 3. Rename .env.example to .env 10 | 4. Run this command in your terminal- 11 | ``` 12 | php artisan key:generate 13 | npm install 14 | ``` 15 | 5. Go **_node_modules>elixer-typescript>index.js_** and comment this line 16 | ``` 17 | //.pipe($.concat(paths.output.name)) 18 | ``` 19 | 6. Run this command in your terminal- 20 | ``` 21 | gulp 22 | ``` 23 | 7. Launch it into your browser with localhost or php artisan command - 24 | ``` 25 | php artisan serve 26 | ``` -------------------------------------------------------------------------------- /resources/assets/js/app.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * First we will load all of this project's JavaScript dependencies which 4 | * include Vue and Vue Resource. This gives a great starting point for 5 | * building robust, powerful web applications using Vue and Laravel. 6 | */ 7 | 8 | require('./bootstrap'); 9 | 10 | /** 11 | * Next, we will create a fresh Vue application instance and attach it to 12 | * the body of the page. From here, you may begin adding components to 13 | * the application, or feel free to tweak this setup for your needs. 14 | */ 15 | 16 | Vue.component('example', require('./components/Example.vue')); 17 | 18 | const app = new Vue({ 19 | el: 'body' 20 | }); 21 | -------------------------------------------------------------------------------- /resources/assets/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | 2 | window._ = require('lodash'); 3 | 4 | /** 5 | * We'll load jQuery and the Bootstrap jQuery plugin which provides support 6 | * for JavaScript based Bootstrap features such as modals and tabs. This 7 | * code may be modified to fit the specific needs of your application. 8 | */ 9 | 10 | window.$ = window.jQuery = require('jquery'); 11 | require('bootstrap-sass'); 12 | 13 | /** 14 | * Vue is a modern JavaScript library for building interactive web interfaces 15 | * using reactive data binding and reusable components. Vue's API is clean 16 | * and simple, leaving you to focus on building your next great project. 17 | */ 18 | 19 | window.Vue = require('vue'); 20 | require('vue-resource'); 21 | 22 | /** 23 | * We'll register a HTTP interceptor to attach the "CSRF" header to each of 24 | * the outgoing requests issued by this application. The CSRF middleware 25 | * included with Laravel will automatically verify the header's value. 26 | */ 27 | 28 | Vue.http.interceptors.push((request, next) => { 29 | request.headers.set('X-CSRF-TOKEN', Laravel.csrfToken); 30 | 31 | next(); 32 | }); 33 | 34 | /** 35 | * Echo exposes an expressive API for subscribing to channels and listening 36 | * for events that are broadcast by Laravel. Echo and event broadcasting 37 | * allows your team to easily build robust real-time web applications. 38 | */ 39 | 40 | // import Echo from "laravel-echo" 41 | 42 | // window.Echo = new Echo({ 43 | // broadcaster: 'pusher', 44 | // key: 'your-pusher-key' 45 | // }); 46 | -------------------------------------------------------------------------------- /resources/assets/js/components/Example.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 24 | -------------------------------------------------------------------------------- /resources/assets/sass/_variables.scss: -------------------------------------------------------------------------------- 1 | 2 | // Body 3 | $body-bg: #f5f8fa; 4 | 5 | // Borders 6 | $laravel-border-color: darken($body-bg, 10%); 7 | $list-group-border: $laravel-border-color; 8 | $navbar-default-border: $laravel-border-color; 9 | $panel-default-border: $laravel-border-color; 10 | $panel-inner-border: $laravel-border-color; 11 | 12 | // Brands 13 | $brand-primary: #3097D1; 14 | $brand-info: #8eb4cb; 15 | $brand-success: #2ab27b; 16 | $brand-warning: #cbb956; 17 | $brand-danger: #bf5329; 18 | 19 | // Typography 20 | $font-family-sans-serif: "Raleway", sans-serif; 21 | $font-size-base: 14px; 22 | $line-height-base: 1.6; 23 | $text-color: #636b6f; 24 | 25 | // Navbar 26 | $navbar-default-bg: #fff; 27 | 28 | // Buttons 29 | $btn-default-color: $text-color; 30 | 31 | // Inputs 32 | $input-border: lighten($text-color, 40%); 33 | $input-border-focus: lighten($brand-primary, 25%); 34 | $input-color-placeholder: lighten($text-color, 30%); 35 | 36 | // Panels 37 | $panel-default-heading-bg: #fff; 38 | -------------------------------------------------------------------------------- /resources/assets/sass/app.scss: -------------------------------------------------------------------------------- 1 | 2 | // Fonts 3 | @import url(https://fonts.googleapis.com/css?family=Raleway:300,400,600); 4 | 5 | // Variables 6 | @import "variables"; 7 | 8 | // Bootstrap 9 | @import "node_modules/bootstrap-sass/assets/stylesheets/bootstrap"; 10 | -------------------------------------------------------------------------------- /resources/assets/typescript/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | @Component({ 3 | selector: 'my-app', 4 | template: '

My First Angular App

' 5 | }) 6 | export class AppComponent { } 7 | -------------------------------------------------------------------------------- /resources/assets/typescript/app.module.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { NgModule } from '@angular/core'; 3 | import { BrowserModule } from '@angular/platform-browser'; 4 | import { AppComponent } from './app.component'; 5 | @NgModule({ 6 | imports: [ BrowserModule ], 7 | declarations: [ AppComponent ], 8 | bootstrap: [ AppComponent ] 9 | }) 10 | export class AppModule { } 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /resources/assets/typescript/main.ts: -------------------------------------------------------------------------------- 1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 2 | import { AppModule } from './app.module'; 3 | const platform = platformBrowserDynamic(); 4 | platform.bootstrapModule(AppModule); 5 | -------------------------------------------------------------------------------- /resources/lang/en/auth.php: -------------------------------------------------------------------------------- 1 | 'These credentials do not match our records.', 17 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /resources/lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | '« Previous', 17 | 'next' => 'Next »', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /resources/lang/en/passwords.php: -------------------------------------------------------------------------------- 1 | 'Passwords must be at least six characters and match the confirmation.', 17 | 'reset' => 'Your password has been reset!', 18 | 'sent' => 'We have e-mailed your password reset link!', 19 | 'token' => 'This password reset token is invalid.', 20 | 'user' => "We can't find a user with that e-mail address.", 21 | 22 | ]; 23 | -------------------------------------------------------------------------------- /resources/lang/en/validation.php: -------------------------------------------------------------------------------- 1 | 'The :attribute must be accepted.', 17 | 'active_url' => 'The :attribute is not a valid URL.', 18 | 'after' => 'The :attribute must be a date after :date.', 19 | 'alpha' => 'The :attribute may only contain letters.', 20 | 'alpha_dash' => 'The :attribute may only contain letters, numbers, and dashes.', 21 | 'alpha_num' => 'The :attribute may only contain letters and numbers.', 22 | 'array' => 'The :attribute must be an array.', 23 | 'before' => 'The :attribute must be a date before :date.', 24 | 'between' => [ 25 | 'numeric' => 'The :attribute must be between :min and :max.', 26 | 'file' => 'The :attribute must be between :min and :max kilobytes.', 27 | 'string' => 'The :attribute must be between :min and :max characters.', 28 | 'array' => 'The :attribute must have between :min and :max items.', 29 | ], 30 | 'boolean' => 'The :attribute field must be true or false.', 31 | 'confirmed' => 'The :attribute confirmation does not match.', 32 | 'date' => 'The :attribute is not a valid date.', 33 | 'date_format' => 'The :attribute does not match the format :format.', 34 | 'different' => 'The :attribute and :other must be different.', 35 | 'digits' => 'The :attribute must be :digits digits.', 36 | 'digits_between' => 'The :attribute must be between :min and :max digits.', 37 | 'dimensions' => 'The :attribute has invalid image dimensions.', 38 | 'distinct' => 'The :attribute field has a duplicate value.', 39 | 'email' => 'The :attribute must be a valid email address.', 40 | 'exists' => 'The selected :attribute is invalid.', 41 | 'file' => 'The :attribute must be a file.', 42 | 'filled' => 'The :attribute field is required.', 43 | 'image' => 'The :attribute must be an image.', 44 | 'in' => 'The selected :attribute is invalid.', 45 | 'in_array' => 'The :attribute field does not exist in :other.', 46 | 'integer' => 'The :attribute must be an integer.', 47 | 'ip' => 'The :attribute must be a valid IP address.', 48 | 'json' => 'The :attribute must be a valid JSON string.', 49 | 'max' => [ 50 | 'numeric' => 'The :attribute may not be greater than :max.', 51 | 'file' => 'The :attribute may not be greater than :max kilobytes.', 52 | 'string' => 'The :attribute may not be greater than :max characters.', 53 | 'array' => 'The :attribute may not have more than :max items.', 54 | ], 55 | 'mimes' => 'The :attribute must be a file of type: :values.', 56 | 'mimetypes' => 'The :attribute must be a file of type: :values.', 57 | 'min' => [ 58 | 'numeric' => 'The :attribute must be at least :min.', 59 | 'file' => 'The :attribute must be at least :min kilobytes.', 60 | 'string' => 'The :attribute must be at least :min characters.', 61 | 'array' => 'The :attribute must have at least :min items.', 62 | ], 63 | 'not_in' => 'The selected :attribute is invalid.', 64 | 'numeric' => 'The :attribute must be a number.', 65 | 'present' => 'The :attribute field must be present.', 66 | 'regex' => 'The :attribute format is invalid.', 67 | 'required' => 'The :attribute field is required.', 68 | 'required_if' => 'The :attribute field is required when :other is :value.', 69 | 'required_unless' => 'The :attribute field is required unless :other is in :values.', 70 | 'required_with' => 'The :attribute field is required when :values is present.', 71 | 'required_with_all' => 'The :attribute field is required when :values is present.', 72 | 'required_without' => 'The :attribute field is required when :values is not present.', 73 | 'required_without_all' => 'The :attribute field is required when none of :values are present.', 74 | 'same' => 'The :attribute and :other must match.', 75 | 'size' => [ 76 | 'numeric' => 'The :attribute must be :size.', 77 | 'file' => 'The :attribute must be :size kilobytes.', 78 | 'string' => 'The :attribute must be :size characters.', 79 | 'array' => 'The :attribute must contain :size items.', 80 | ], 81 | 'string' => 'The :attribute must be a string.', 82 | 'timezone' => 'The :attribute must be a valid zone.', 83 | 'unique' => 'The :attribute has already been taken.', 84 | 'uploaded' => 'The :attribute failed to upload.', 85 | 'url' => 'The :attribute format is invalid.', 86 | 87 | /* 88 | |-------------------------------------------------------------------------- 89 | | Custom Validation Language Lines 90 | |-------------------------------------------------------------------------- 91 | | 92 | | Here you may specify custom validation messages for attributes using the 93 | | convention "attribute.rule" to name the lines. This makes it quick to 94 | | specify a specific custom language line for a given attribute rule. 95 | | 96 | */ 97 | 98 | 'custom' => [ 99 | 'attribute-name' => [ 100 | 'rule-name' => 'custom-message', 101 | ], 102 | ], 103 | 104 | /* 105 | |-------------------------------------------------------------------------- 106 | | Custom Validation Attributes 107 | |-------------------------------------------------------------------------- 108 | | 109 | | The following language lines are used to swap attribute place-holders 110 | | with something more reader friendly such as E-Mail Address instead 111 | | of "email". This simply helps us make messages a little cleaner. 112 | | 113 | */ 114 | 115 | 'attributes' => [], 116 | 117 | ]; 118 | -------------------------------------------------------------------------------- /resources/views/errors/503.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Be right back. 5 | 6 | 7 | 8 | 39 | 40 | 41 |
42 |
43 |
Be right back.
44 |
45 |
46 | 47 | 48 | -------------------------------------------------------------------------------- /resources/views/vendor/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/views/welcome.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Laravel 5.3 - Angular 2 9 | 10 | 11 | 12 | {{ Html::script('core-js/client/shim.min.js') }} 13 | {{ Html::script('zone.js/dist/zone.js') }} 14 | {{ Html::script('reflect-metadata/Reflect.js') }} 15 | {{ Html::script('systemjs/dist/system.src.js') }} 16 | {{ Html::script('systemjs.config.js') }} 17 | 18 | 21 | 22 | 23 | 24 | Loading... 25 | 26 | -------------------------------------------------------------------------------- /routes/api.php: -------------------------------------------------------------------------------- 1 | user(); 18 | })->middleware('auth:api'); 19 | -------------------------------------------------------------------------------- /routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 18 | })->describe('Display an inspiring quote'); 19 | -------------------------------------------------------------------------------- /routes/web.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | $uri = urldecode( 11 | parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) 12 | ); 13 | 14 | // This file allows us to emulate Apache's "mod_rewrite" functionality from the 15 | // built-in PHP web server. This provides a convenient way to test a Laravel 16 | // application without having installed a "real" web server software here. 17 | if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) { 18 | return false; 19 | } 20 | 21 | require_once __DIR__.'/public/index.php'; 22 | -------------------------------------------------------------------------------- /storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/.gitignore: -------------------------------------------------------------------------------- 1 | config.php 2 | routes.php 3 | schedule-* 4 | compiled.php 5 | services.json 6 | events.scanned.php 7 | routes.scanned.php 8 | down 9 | -------------------------------------------------------------------------------- /storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /tests/ExampleTest.php: -------------------------------------------------------------------------------- 1 | visit('/') 17 | ->see('Laravel'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | make(Illuminate\Contracts\Console\Kernel::class)->bootstrap(); 22 | 23 | return $app; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "globalDependencies": { 3 | "core-js": "registry:dt/core-js#0.0.0+20160725163759", 4 | "jasmine": "registry:dt/jasmine#2.2.0+20160621224255", 5 | "node": "registry:dt/node#6.0.0+20160909174046" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /typings/globals/core-js/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/25e18b592470e3dddccc826fde2bb8e7610ef863/core-js/core-js.d.ts", 5 | "raw": "registry:dt/core-js#0.0.0+20160725163759", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/25e18b592470e3dddccc826fde2bb8e7610ef863/core-js/core-js.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /typings/globals/jasmine/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/c49913aa9ea419ea46c1c684e488cf2a10303b1a/jasmine/jasmine.d.ts", 5 | "raw": "registry:dt/jasmine#2.2.0+20160621224255", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/c49913aa9ea419ea46c1c684e488cf2a10303b1a/jasmine/jasmine.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /typings/globals/node/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/4008a51db44dabcdc368097a39a01ab7a5f9587f/node/node.d.ts", 5 | "raw": "registry:dt/node#6.0.0+20160909174046", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/4008a51db44dabcdc368097a39a01ab7a5f9587f/node/node.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /typings/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | -------------------------------------------------------------------------------- /zone/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2016 Google, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /zone/LICENSE.wrapped: -------------------------------------------------------------------------------- 1 | /** 2 | @license 3 | The MIT License 4 | 5 | Copyright (c) 2016 Google, Inc. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | 25 | */ 26 | -------------------------------------------------------------------------------- /zone/README.md: -------------------------------------------------------------------------------- 1 | # Zone.js 2 | 3 | [![Build Status](https://travis-ci.org/angular/zone.js.png)](https://travis-ci.org/angular/zone.js) 4 | 5 | Implements _Zones_ for JavaScript, inspired by [Dart](https://www.dartlang.org/articles/zones/). 6 | 7 | > If you're using zone.js via unpkg please provide a query param `?main=browser` 8 | `https://unpkg.com/zone.js?main=browser` 9 | 10 | # NEW Zone.js POST-v0.6.0 11 | 12 | See the new API [here](./dist/zone.js.d.ts). 13 | 14 | # DEPRECATED Zone.js PRE-v0.5.15 15 | 16 | ## What's a Zone? 17 | 18 | A Zone is an execution context that persists across async tasks. 19 | You can think of it as [thread-local storage](http://en.wikipedia.org/wiki/Thread-local_storage) for JavaScript VMs. 20 | 21 | See this video from ng-conf 2014 for a detailed explanation: 22 | 23 | [![screenshot of the zone.js presentation and ng-conf 2014](/presentation.png)](//www.youtube.com/watch?v=3IqtmUscE_U) 24 | 25 | ### Running Within a Zone 26 | 27 | You can run code within a zone with `zone.run`. 28 | Tasks scheduled (with `setTimeout`, `setInterval`, or event listeners) stay within that zone. 29 | 30 | ```javascript 31 | Zone.current.fork({}).run(function () { 32 | Zone.current.inTheZone = true; 33 | 34 | setTimeout(function () { 35 | console.log('in the zone: ' + !!Zone.current.inTheZone); 36 | }, 0); 37 | }); 38 | 39 | console.log('in the zone: ' + !!Zone.current.inTheZone); 40 | ``` 41 | 42 | The above will log: 43 | 44 | ``` 45 | 'in the zone: false' 46 | 'in the zone: true' 47 | ``` 48 | 49 | Note that the function delayed by `setTimeout` stays inside the zone. 50 | 51 | ### Forking a Zone 52 | 53 | Zones have a set of hooks that allow you to change the behavior of code running within that zone. 54 | To change a zone, you _fork_ it to get a new one. 55 | 56 | ```javascript 57 | zone.fork({ 58 | beforeTask: function () { 59 | console.log('hi'); 60 | } 61 | }).run(function () { 62 | // do stuff 63 | }); 64 | ``` 65 | 66 | Hooks that you don't override when forking a zone are inherited from the existing one. 67 | 68 | See the [API docs](#api) below for more. 69 | 70 | 71 | ## Usage 72 | 73 | To start using Zones, you need to include the `zone.js` script in this package onto 74 | your page. This script should appear in the `` of your HTML file before any other 75 | scripts, including shims/polyfills. 76 | 77 | 78 | ## Examples 79 | 80 | There are two kinds of examples: 81 | 82 | 1. The kind you have to run 83 | 2. Illustrative code snippets in this README 84 | 85 | ### Running the ones that you have to run 86 | 87 | For fully working examples: 88 | 89 | 1. Spawn a webserver in the root of the directory in which this repo lives. 90 | (I like to use `python -m SimpleHTTPServer 3000`). 91 | 2. Open `http://localhost:3000/example` in your browser 92 | 93 | Below are the aforementioned snippets. 94 | 95 | ### Overriding A Zone's Hook 96 | 97 | ```javascript 98 | var someZone = zone.fork({ 99 | afterTask: function () { 100 | console.log('goodbye'); 101 | } 102 | }); 103 | 104 | someZone.fork({ 105 | afterTask: function () { 106 | console.log('cya l8r'); 107 | } 108 | }).run(function () { 109 | // do stuff 110 | }); 111 | 112 | // logs: cya l8r 113 | ``` 114 | 115 | ### Augmenting A Zone's Hook 116 | 117 | When you fork a zone, you'll often want to control how the parent zone's 118 | hook gets called. 119 | 120 | Prefixing a hook with `$` means that the hook will be passed the 121 | parent zone's hook, and the hook will be expected to return the function to 122 | be invoked rather than be the function itself. 123 | 124 | ```javascript 125 | var someZone = zone.fork({ 126 | afterTask: function () { 127 | console.log('goodbye'); 128 | } 129 | }); 130 | 131 | someZone.fork({ 132 | $afterTask: function (parentOnLeave) { 133 | // return the hook 134 | return function afterTask() { 135 | parentOnLeave(); 136 | console.log('cya l8r'); 137 | }; 138 | } 139 | }).run(function () { 140 | // do stuff 141 | }); 142 | 143 | // logs: goodbye 144 | // cya l8r 145 | ``` 146 | 147 | #### `+` and `-` Sugar 148 | Most of the time, you'll want to run a hook before or after the parent's implementation. 149 | You can prefix a hook with `-` for running before, and `+` for running after. 150 | 151 | The above can be written like this: 152 | 153 | ```javascript 154 | var someZone = zone.fork({ 155 | afterTask: function () { 156 | console.log('goodbye'); 157 | } 158 | }); 159 | 160 | someZone.fork({ 161 | '+afterTask': function () { 162 | console.log('cya l8r'); 163 | } 164 | }).run(function () { 165 | // do stuff 166 | }); 167 | 168 | // logs: goodbye 169 | // cya l8r 170 | ``` 171 | 172 | This frees you from writing boilerplate to compose a new hook. 173 | 174 | ## API 175 | 176 | Zone.js exports a single object: `window.zone`. 177 | 178 | ### `zone.run` 179 | 180 | Runs a given function within the zone. 181 | Explained above. 182 | 183 | ### `zone.bind` 184 | 185 | Transforms a function to run within the given zone. 186 | 187 | ### `zone.fork` 188 | 189 | ```javascript 190 | var myZone = zone.fork({ 191 | onZoneCreated: function () {}, 192 | beforeTask: function () {}, 193 | afterTask: function () {}, 194 | onError: function () {}, 195 | enqueueTask: function() {}, 196 | dequeueTask: function() {}, 197 | setTimeout: function () {}, 198 | setInterval: function () {}, 199 | alert: function () {}, 200 | prompt: function () {}, 201 | }); 202 | myZone.run(function () { 203 | // woo! 204 | }); 205 | ``` 206 | 207 | Below describes the behavior of each of these hooks. 208 | 209 | ### `zone.onZoneCreated` 210 | 211 | Runs when a zone is forked. 212 | 213 | ### `zone.beforeTask` 214 | 215 | Before a function invoked with `zone.run`, this hook runs. 216 | If `zone.beforeTask` throws, the function passed to `run` will not be invoked. 217 | 218 | ### `zone.afterTask` 219 | 220 | After a function in a zone runs, the `afterTask` hook runs. 221 | This hook will run even if the function passed to `run` throws. 222 | 223 | ### `zone.onError` 224 | 225 | This hook is called when the function passed to `run` or the `beforeTask` hook throws. 226 | 227 | ### `zone.enqueueTask` 228 | 229 | This hook is called when a function is registered with the VM. 230 | For instance `setTimeout` and `addEventListener`. 231 | 232 | ### `zone.dequeueTask` 233 | 234 | This hook is called when a function is unregistered with the VM. 235 | For instance `clearTimeout` and `removeEventListener`. 236 | 237 | ### `zone.setTimeout`, `zone.setInterval`, `zone.alert`, `zone.prompt` 238 | 239 | These hooks allow you to change the behavior of `window.setTimeout`, `window.setInterval`, etc. 240 | While in this zone, calls to `window.setTimeout` will redirect to `zone.setTimeout`. 241 | 242 | ### `zone.requestAnimationFrame`, `zone.webkitRequestAnimationFrame`, `zone.mozRequestAnimationFrame` 243 | 244 | These hooks allow you to change the behavior of `window.requestAnimationFrame()`, 245 | `window.webkitRequestAnimationFrame`, and `window.mozRequestAnimationFrame`. 246 | 247 | By default the wrapCallback is executed in the zone where those methods have been called to avoid 248 | growing the stack size on each recursive call. 249 | 250 | ### `zone.addEventListener` 251 | 252 | This hook allows you to intercept calls to `EventTarget#addEventListener`. 253 | 254 | ````javascript 255 | var clickListenerCount = 0; 256 | 257 | zone.fork( 258 | $addEventListener: function(parentAddEventListener) { 259 | return function (type, listener) { 260 | if (type === 'click') clickListenerCount++; 261 | return parentAddEventListener.apply(this, arguments); 262 | }; 263 | } 264 | ); 265 | 266 | zone.run(function() { 267 | myElement.addEventListener('click', listener); 268 | myOtherElement.addEventListener('click', listener); 269 | 270 | console.log(clickListenerCount); // 2 271 | }); 272 | ```` 273 | 274 | ### `zone.removeEventListener` 275 | 276 | This hook allows you to intercept calls to `EventTarget#removeEventListener`. 277 | 278 | ````javascript 279 | var clickListenerCount = 0; 280 | 281 | zone.fork( 282 | $removeEventListener: function(parentRemoveEventListener) { 283 | return function (type, listener) { 284 | if (type === 'click') clickListenerCount--; 285 | return parentRemoveEventListener.apply(this, arguments); 286 | }; 287 | } 288 | ); 289 | 290 | zone.run(function() { 291 | myElement.addEventListener('click', listener); 292 | myElement.removeEventListener('click', listener); 293 | 294 | console.log(clickListenerCount); // 0 295 | }); 296 | ```` 297 | 298 | 299 | ## Status 300 | 301 | * `setTimeout`, `setInterval`, and `addEventListener` work in FF23, IE10, and Chrome. 302 | * stack trace rewrite is kinda ugly and may contain extraneous calls. 303 | * `elt.onevent` works in FF23, IE10, but not Chrome. There's [a fix in the works though](https://code.google.com/p/chromium/issues/detail?id=43394)! 304 | 305 | 306 | ## See also 307 | * [async-listener](https://github.com/othiym23/async-listener) - a similar library for node 308 | * [Async stack traces in Chrome](http://www.html5rocks.com/en/tutorials/developertools/async-call-stack/) 309 | * [strongloop/zone](https://github.com/strongloop/zone) 310 | * [vizone](https://github.com/gilbox/vizone) - control flow visualizer that uses zone.js 311 | 312 | 313 | ## License 314 | MIT 315 | -------------------------------------------------------------------------------- /zone/dist/async-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright Google Inc. All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file at https://angular.io/license 7 | */ 8 | (function (global, factory) { 9 | typeof exports === 'object' && typeof module !== 'undefined' ? factory() : 10 | typeof define === 'function' && define.amd ? define(factory) : 11 | (factory()); 12 | }(this, (function () { 'use strict'; 13 | 14 | var AsyncTestZoneSpec = (function () { 15 | function AsyncTestZoneSpec(finishCallback, failCallback, namePrefix) { 16 | this._pendingMicroTasks = false; 17 | this._pendingMacroTasks = false; 18 | this._alreadyErrored = false; 19 | this.runZone = Zone.current; 20 | this._finishCallback = finishCallback; 21 | this._failCallback = failCallback; 22 | this.name = 'asyncTestZone for ' + namePrefix; 23 | } 24 | AsyncTestZoneSpec.prototype._finishCallbackIfDone = function () { 25 | var _this = this; 26 | if (!(this._pendingMicroTasks || this._pendingMacroTasks)) { 27 | // We do this because we would like to catch unhandled rejected promises. 28 | this.runZone.run(function () { 29 | setTimeout(function () { 30 | if (!_this._alreadyErrored && !(_this._pendingMicroTasks || _this._pendingMacroTasks)) { 31 | _this._finishCallback(); 32 | } 33 | }, 0); 34 | }); 35 | } 36 | }; 37 | // Note - we need to use onInvoke at the moment to call finish when a test is 38 | // fully synchronous. TODO(juliemr): remove this when the logic for 39 | // onHasTask changes and it calls whenever the task queues are dirty. 40 | AsyncTestZoneSpec.prototype.onInvoke = function (parentZoneDelegate, currentZone, targetZone, delegate, applyThis, applyArgs, source) { 41 | try { 42 | return parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source); 43 | } 44 | finally { 45 | this._finishCallbackIfDone(); 46 | } 47 | }; 48 | AsyncTestZoneSpec.prototype.onHandleError = function (parentZoneDelegate, currentZone, targetZone, error) { 49 | // Let the parent try to handle the error. 50 | var result = parentZoneDelegate.handleError(targetZone, error); 51 | if (result) { 52 | this._failCallback(error); 53 | this._alreadyErrored = true; 54 | } 55 | return false; 56 | }; 57 | AsyncTestZoneSpec.prototype.onScheduleTask = function (delegate, currentZone, targetZone, task) { 58 | if (task.type == 'macroTask' && task.source == 'setInterval') { 59 | this._failCallback('Cannot use setInterval from within an async zone test.'); 60 | return; 61 | } 62 | return delegate.scheduleTask(targetZone, task); 63 | }; 64 | AsyncTestZoneSpec.prototype.onHasTask = function (delegate, current, target, hasTaskState) { 65 | delegate.hasTask(target, hasTaskState); 66 | if (hasTaskState.change == 'microTask') { 67 | this._pendingMicroTasks = hasTaskState.microTask; 68 | this._finishCallbackIfDone(); 69 | } 70 | else if (hasTaskState.change == 'macroTask') { 71 | this._pendingMacroTasks = hasTaskState.macroTask; 72 | this._finishCallbackIfDone(); 73 | } 74 | }; 75 | return AsyncTestZoneSpec; 76 | }()); 77 | // Export the class so that new instances can be created with proper 78 | // constructor params. 79 | Zone['AsyncTestZoneSpec'] = AsyncTestZoneSpec; 80 | 81 | }))); 82 | -------------------------------------------------------------------------------- /zone/dist/jasmine-patch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright Google Inc. All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file at https://angular.io/license 7 | */ 8 | (function (global, factory) { 9 | typeof exports === 'object' && typeof module !== 'undefined' ? factory() : 10 | typeof define === 'function' && define.amd ? define(factory) : 11 | (factory()); 12 | }(this, (function () { 'use strict'; 13 | 14 | var __extends = (undefined && undefined.__extends) || function (d, b) { 15 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 16 | function __() { this.constructor = d; } 17 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 18 | }; 19 | (function () { 20 | // Patch jasmine's describe/it/beforeEach/afterEach functions so test code always runs 21 | // in a testZone (ProxyZone). (See: angular/zone.js#91 & angular/angular#10503) 22 | if (!Zone) 23 | throw new Error("Missing: zone.js"); 24 | if (typeof jasmine == 'undefined') 25 | throw new Error("Missing: jasmine.js"); 26 | if (jasmine['__zone_patch__']) 27 | throw new Error("'jasmine' has already been patched with 'Zone'."); 28 | jasmine['__zone_patch__'] = true; 29 | var SyncTestZoneSpec = Zone['SyncTestZoneSpec']; 30 | var ProxyZoneSpec = Zone['ProxyZoneSpec']; 31 | if (!SyncTestZoneSpec) 32 | throw new Error("Missing: SyncTestZoneSpec"); 33 | if (!ProxyZoneSpec) 34 | throw new Error("Missing: ProxyZoneSpec"); 35 | var ambientZone = Zone.current; 36 | // Create a synchronous-only zone in which to run `describe` blocks in order to raise an 37 | // error if any asynchronous operations are attempted inside of a `describe` but outside of 38 | // a `beforeEach` or `it`. 39 | var syncZone = ambientZone.fork(new SyncTestZoneSpec('jasmine.describe')); 40 | // This is the zone which will be used for running individual tests. 41 | // It will be a proxy zone, so that the tests function can retroactively install 42 | // different zones. 43 | // Example: 44 | // - In beforeEach() do childZone = Zone.current.fork(...); 45 | // - In it() try to do fakeAsync(). The issue is that because the beforeEach forked the 46 | // zone outside of fakeAsync it will be able to escope the fakeAsync rules. 47 | // - Because ProxyZone is parent fo `childZone` fakeAsync can retroactively add 48 | // fakeAsync behavior to the childZone. 49 | var testProxyZone = null; 50 | // Monkey patch all of the jasmine DSL so that each function runs in appropriate zone. 51 | var jasmineEnv = jasmine.getEnv(); 52 | ['describe', 'xdescribe', 'fdescribe'].forEach(function (methodName) { 53 | var originalJasmineFn = jasmineEnv[methodName]; 54 | jasmineEnv[methodName] = function (description, specDefinitions) { 55 | return originalJasmineFn.call(this, description, wrapDescribeInZone(specDefinitions)); 56 | }; 57 | }); 58 | ['it', 'xit', 'fit'].forEach(function (methodName) { 59 | var originalJasmineFn = jasmineEnv[methodName]; 60 | jasmineEnv[methodName] = function (description, specDefinitions, timeout) { 61 | arguments[1] = wrapTestInZone(specDefinitions); 62 | return originalJasmineFn.apply(this, arguments); 63 | }; 64 | }); 65 | ['beforeEach', 'afterEach'].forEach(function (methodName) { 66 | var originalJasmineFn = jasmineEnv[methodName]; 67 | jasmineEnv[methodName] = function (specDefinitions, timeout) { 68 | arguments[0] = wrapTestInZone(specDefinitions); 69 | return originalJasmineFn.apply(this, arguments); 70 | }; 71 | }); 72 | /** 73 | * Gets a function wrapping the body of a Jasmine `describe` block to execute in a 74 | * synchronous-only zone. 75 | */ 76 | function wrapDescribeInZone(describeBody) { 77 | return function () { 78 | return syncZone.run(describeBody, this, arguments); 79 | }; 80 | } 81 | /** 82 | * Gets a function wrapping the body of a Jasmine `it/beforeEach/afterEach` block to 83 | * execute in a ProxyZone zone. 84 | * This will run in `testProxyZone`. The `testProxyZone` will be reset by the `ZoneQueueRunner` 85 | */ 86 | function wrapTestInZone(testBody) { 87 | // The `done` callback is only passed through if the function expects at least one argument. 88 | // Note we have to make a function with correct number of arguments, otherwise jasmine will 89 | // think that all functions are sync or async. 90 | return (testBody.length == 0) 91 | ? function () { return testProxyZone.run(testBody, this); } 92 | : function (done) { return testProxyZone.run(testBody, this, [done]); }; 93 | } 94 | var QueueRunner = jasmine.QueueRunner; 95 | jasmine.QueueRunner = (function (_super) { 96 | __extends(ZoneQueueRunner, _super); 97 | function ZoneQueueRunner(attrs) { 98 | attrs.onComplete = (function (fn) { return function () { 99 | // All functions are done, clear the test zone. 100 | testProxyZone = null; 101 | ambientZone.scheduleMicroTask('jasmine.onComplete', fn); 102 | }; })(attrs.onComplete); 103 | _super.call(this, attrs); 104 | } 105 | ZoneQueueRunner.prototype.execute = function () { 106 | var _this = this; 107 | if (Zone.current !== ambientZone) 108 | throw new Error("Unexpected Zone: " + Zone.current.name); 109 | testProxyZone = ambientZone.fork(new ProxyZoneSpec()); 110 | if (!Zone.currentTask) { 111 | // if we are not running in a task then if someone would register a 112 | // element.addEventListener and then calling element.click() the 113 | // addEventListener callback would think that it is the top most task and would 114 | // drain the microtask queue on element.click() which would be incorrect. 115 | // For this reason we always force a task when running jasmine tests. 116 | Zone.current.scheduleMicroTask('jasmine.execute().forceTask', function () { return _super.prototype.execute.call(_this); }); 117 | } 118 | else { 119 | _super.prototype.execute.call(this); 120 | } 121 | }; 122 | return ZoneQueueRunner; 123 | }(QueueRunner)); 124 | })(); 125 | 126 | }))); 127 | -------------------------------------------------------------------------------- /zone/dist/jasmine-patch.min.js: -------------------------------------------------------------------------------- 1 | !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n():"function"==typeof define&&define.amd?define(n):n()}(this,function(){"use strict";var e=function(e,n){function r(){this.constructor=e}for(var t in n)n.hasOwnProperty(t)&&(e[t]=n[t]);e.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)};!function(){function n(e){return function(){return c.run(e,this,arguments)}}function r(e){return 0==e.length?function(){return u.run(e,this)}:function(n){return u.run(e,this,[n])}}if(!Zone)throw new Error("Missing: zone.js");if("undefined"==typeof jasmine)throw new Error("Missing: jasmine.js");if(jasmine.__zone_patch__)throw new Error("'jasmine' has already been patched with 'Zone'.");jasmine.__zone_patch__=!0;var t=Zone.SyncTestZoneSpec,o=Zone.ProxyZoneSpec;if(!t)throw new Error("Missing: SyncTestZoneSpec");if(!o)throw new Error("Missing: ProxyZoneSpec");var i=Zone.current,c=i.fork(new t("jasmine.describe")),u=null,s=jasmine.getEnv();["describe","xdescribe","fdescribe"].forEach(function(e){var r=s[e];s[e]=function(e,t){return r.call(this,e,n(t))}}),["it","xit","fit"].forEach(function(e){var n=s[e];s[e]=function(e,t,o){return arguments[1]=r(t),n.apply(this,arguments)}}),["beforeEach","afterEach"].forEach(function(e){var n=s[e];s[e]=function(e,t){return arguments[0]=r(e),n.apply(this,arguments)}});var f=jasmine.QueueRunner;jasmine.QueueRunner=function(n){function r(e){e.onComplete=function(e){return function(){u=null,i.scheduleMicroTask("jasmine.onComplete",e)}}(e.onComplete),n.call(this,e)}return e(r,n),r.prototype.execute=function(){var e=this;if(Zone.current!==i)throw new Error("Unexpected Zone: "+Zone.current.name);u=i.fork(new o),Zone.currentTask?n.prototype.execute.call(this):Zone.current.scheduleMicroTask("jasmine.execute().forceTask",function(){return n.prototype.execute.call(e)})},r}(f)}()}); -------------------------------------------------------------------------------- /zone/dist/long-stack-trace-zone.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright Google Inc. All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file at https://angular.io/license 7 | */ 8 | (function (global, factory) { 9 | typeof exports === 'object' && typeof module !== 'undefined' ? factory() : 10 | typeof define === 'function' && define.amd ? define(factory) : 11 | (factory()); 12 | }(this, (function () { 'use strict'; 13 | 14 | var NEWLINE = '\n'; 15 | var SEP = ' ------------- '; 16 | var IGNORE_FRAMES = []; 17 | var creationTrace = '__creationTrace__'; 18 | var LongStackTrace = (function () { 19 | function LongStackTrace() { 20 | this.error = getStacktrace(); 21 | this.timestamp = new Date(); 22 | } 23 | return LongStackTrace; 24 | }()); 25 | function getStacktraceWithUncaughtError() { 26 | return new Error('STACKTRACE TRACKING'); 27 | } 28 | function getStacktraceWithCaughtError() { 29 | try { 30 | throw getStacktraceWithUncaughtError(); 31 | } 32 | catch (e) { 33 | return e; 34 | } 35 | } 36 | // Some implementations of exception handling don't create a stack trace if the exception 37 | // isn't thrown, however it's faster not to actually throw the exception. 38 | var error = getStacktraceWithUncaughtError(); 39 | var coughtError = getStacktraceWithCaughtError(); 40 | var getStacktrace = error.stack 41 | ? getStacktraceWithUncaughtError 42 | : (coughtError.stack ? getStacktraceWithCaughtError : getStacktraceWithUncaughtError); 43 | function getFrames(error) { 44 | return error.stack ? error.stack.split(NEWLINE) : []; 45 | } 46 | function addErrorStack(lines, error) { 47 | var trace = getFrames(error); 48 | for (var i = 0; i < trace.length; i++) { 49 | var frame = trace[i]; 50 | // Filter out the Frames which are part of stack capturing. 51 | if (!(i < IGNORE_FRAMES.length && IGNORE_FRAMES[i] === frame)) { 52 | lines.push(trace[i]); 53 | } 54 | } 55 | } 56 | function renderLongStackTrace(frames, stack) { 57 | var longTrace = [stack]; 58 | if (frames) { 59 | var timestamp = new Date().getTime(); 60 | for (var i = 0; i < frames.length; i++) { 61 | var traceFrames = frames[i]; 62 | var lastTime = traceFrames.timestamp; 63 | longTrace.push(SEP + " Elapsed: " + (timestamp - lastTime.getTime()) + " ms; At: " + lastTime + " " + SEP); 64 | addErrorStack(longTrace, traceFrames.error); 65 | timestamp = lastTime.getTime(); 66 | } 67 | } 68 | return longTrace.join(NEWLINE); 69 | } 70 | Zone['longStackTraceZoneSpec'] = { 71 | name: 'long-stack-trace', 72 | longStackTraceLimit: 10, 73 | onScheduleTask: function (parentZoneDelegate, currentZone, targetZone, task) { 74 | var currentTask = Zone.currentTask; 75 | var trace = currentTask && currentTask.data && currentTask.data[creationTrace] || []; 76 | trace = [new LongStackTrace()].concat(trace); 77 | if (trace.length > this.longStackTraceLimit) { 78 | trace.length = this.longStackTraceLimit; 79 | } 80 | if (!task.data) 81 | task.data = {}; 82 | task.data[creationTrace] = trace; 83 | return parentZoneDelegate.scheduleTask(targetZone, task); 84 | }, 85 | onHandleError: function (parentZoneDelegate, currentZone, targetZone, error) { 86 | var parentTask = Zone.currentTask || error.task; 87 | if (error instanceof Error && parentTask) { 88 | var stackSetSucceded = null; 89 | try { 90 | var descriptor = Object.getOwnPropertyDescriptor(error, 'stack'); 91 | if (descriptor && descriptor.configurable) { 92 | var delegateGet_1 = descriptor.get; 93 | var value_1 = descriptor.value; 94 | descriptor = { 95 | get: function () { 96 | return renderLongStackTrace(parentTask.data && parentTask.data[creationTrace], delegateGet_1 ? delegateGet_1.apply(this) : value_1); 97 | } 98 | }; 99 | Object.defineProperty(error, 'stack', descriptor); 100 | stackSetSucceded = true; 101 | } 102 | } 103 | catch (e) { } 104 | var longStack = stackSetSucceded ? null : renderLongStackTrace(parentTask.data && parentTask.data[creationTrace], error.stack); 105 | if (!stackSetSucceded) { 106 | try { 107 | stackSetSucceded = error.stack = longStack; 108 | } 109 | catch (e) { } 110 | } 111 | if (!stackSetSucceded) { 112 | try { 113 | stackSetSucceded = error.longStack = longStack; 114 | } 115 | catch (e) { } 116 | } 117 | } 118 | return parentZoneDelegate.handleError(targetZone, error); 119 | } 120 | }; 121 | function captureStackTraces(stackTraces, count) { 122 | if (count > 0) { 123 | stackTraces.push(getFrames((new LongStackTrace()).error)); 124 | captureStackTraces(stackTraces, count - 1); 125 | } 126 | } 127 | function computeIgnoreFrames() { 128 | var frames = []; 129 | captureStackTraces(frames, 2); 130 | var frames1 = frames[0]; 131 | var frames2 = frames[1]; 132 | for (var i = 0; i < frames1.length; i++) { 133 | var frame1 = frames1[i]; 134 | var frame2 = frames2[i]; 135 | if (frame1 === frame2) { 136 | IGNORE_FRAMES.push(frame1); 137 | } 138 | else { 139 | break; 140 | } 141 | } 142 | } 143 | computeIgnoreFrames(); 144 | 145 | }))); 146 | -------------------------------------------------------------------------------- /zone/dist/long-stack-trace-zone.min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e():"function"==typeof define&&define.amd?define(e):e()}(this,function(){"use strict";function t(){return new Error("STACKTRACE TRACKING")}function e(){try{throw t()}catch(e){return e}}function n(t){return t.stack?t.stack.split(i):[]}function r(t,e){for(var r=n(e),a=0;a0&&(t.push(n((new l).error)),c(t,e-1))}function o(){var t=[];c(t,2);for(var e=t[0],n=t[1],r=0;rthis.longStackTraceLimit&&(c.length=this.longStackTraceLimit),r.data||(r.data={}),r.data[f]=c,t.scheduleTask(n,r)},onHandleError:function(t,e,n,r){var c=Zone.currentTask||r.task;if(r instanceof Error&&c){var o=null;try{var i=Object.getOwnPropertyDescriptor(r,"stack");if(i&&i.configurable){var u=i.get,s=i.value;i={get:function(){return a(c.data&&c.data[f],u?u.apply(this):s)}},Object.defineProperty(r,"stack",i),o=!0}}catch(l){}var h=o?null:a(c.data&&c.data[f],r.stack);if(!o)try{o=r.stack=h}catch(l){}if(!o)try{o=r.longStack=h}catch(l){}}return t.handleError(n,r)}},o()}); -------------------------------------------------------------------------------- /zone/dist/proxy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright Google Inc. All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file at https://angular.io/license 7 | */ 8 | (function (global, factory) { 9 | typeof exports === 'object' && typeof module !== 'undefined' ? factory() : 10 | typeof define === 'function' && define.amd ? define(factory) : 11 | (factory()); 12 | }(this, (function () { 'use strict'; 13 | 14 | var ProxyZoneSpec = (function () { 15 | function ProxyZoneSpec(defaultSpecDelegate) { 16 | if (defaultSpecDelegate === void 0) { defaultSpecDelegate = null; } 17 | this.defaultSpecDelegate = defaultSpecDelegate; 18 | this.name = 'ProxyZone'; 19 | this.properties = { 'ProxyZoneSpec': this }; 20 | this.propertyKeys = null; 21 | this.setDelegate(defaultSpecDelegate); 22 | } 23 | ProxyZoneSpec.get = function () { 24 | return Zone.current.get('ProxyZoneSpec'); 25 | }; 26 | ProxyZoneSpec.isLoaded = function () { 27 | return ProxyZoneSpec.get() instanceof ProxyZoneSpec; 28 | }; 29 | ProxyZoneSpec.assertPresent = function () { 30 | if (!this.isLoaded()) { 31 | throw new Error("Expected to be running in 'ProxyZone', but it was not found."); 32 | } 33 | return ProxyZoneSpec.get(); 34 | }; 35 | ProxyZoneSpec.prototype.setDelegate = function (delegateSpec) { 36 | var _this = this; 37 | this._delegateSpec = delegateSpec; 38 | this.propertyKeys && this.propertyKeys.forEach(function (key) { return delete _this.properties[key]; }); 39 | this.propertyKeys = null; 40 | if (delegateSpec && delegateSpec.properties) { 41 | this.propertyKeys = Object.keys(delegateSpec.properties); 42 | this.propertyKeys.forEach(function (k) { return _this.properties[k] = delegateSpec.properties[k]; }); 43 | } 44 | }; 45 | ProxyZoneSpec.prototype.getDelegate = function () { 46 | return this._delegateSpec; 47 | }; 48 | ProxyZoneSpec.prototype.resetDelegate = function () { 49 | this.setDelegate(this.defaultSpecDelegate); 50 | }; 51 | ProxyZoneSpec.prototype.onFork = function (parentZoneDelegate, currentZone, targetZone, zoneSpec) { 52 | if (this._delegateSpec && this._delegateSpec.onFork) { 53 | return this._delegateSpec.onFork(parentZoneDelegate, currentZone, targetZone, zoneSpec); 54 | } 55 | else { 56 | return parentZoneDelegate.fork(targetZone, zoneSpec); 57 | } 58 | }; 59 | ProxyZoneSpec.prototype.onIntercept = function (parentZoneDelegate, currentZone, targetZone, delegate, source) { 60 | if (this._delegateSpec && this._delegateSpec.onIntercept) { 61 | return this._delegateSpec.onIntercept(parentZoneDelegate, currentZone, targetZone, delegate, source); 62 | } 63 | else { 64 | return parentZoneDelegate.intercept(targetZone, delegate, source); 65 | } 66 | }; 67 | ProxyZoneSpec.prototype.onInvoke = function (parentZoneDelegate, currentZone, targetZone, delegate, applyThis, applyArgs, source) { 68 | if (this._delegateSpec && this._delegateSpec.onInvoke) { 69 | return this._delegateSpec.onInvoke(parentZoneDelegate, currentZone, targetZone, delegate, applyThis, applyArgs, source); 70 | } 71 | else { 72 | return parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source); 73 | } 74 | }; 75 | ProxyZoneSpec.prototype.onHandleError = function (parentZoneDelegate, currentZone, targetZone, error) { 76 | if (this._delegateSpec && this._delegateSpec.onHandleError) { 77 | return this._delegateSpec.onHandleError(parentZoneDelegate, currentZone, targetZone, error); 78 | } 79 | else { 80 | return parentZoneDelegate.handleError(targetZone, error); 81 | } 82 | }; 83 | ProxyZoneSpec.prototype.onScheduleTask = function (parentZoneDelegate, currentZone, targetZone, task) { 84 | if (this._delegateSpec && this._delegateSpec.onScheduleTask) { 85 | return this._delegateSpec.onScheduleTask(parentZoneDelegate, currentZone, targetZone, task); 86 | } 87 | else { 88 | return parentZoneDelegate.scheduleTask(targetZone, task); 89 | } 90 | }; 91 | ProxyZoneSpec.prototype.onInvokeTask = function (parentZoneDelegate, currentZone, targetZone, task, applyThis, applyArgs) { 92 | if (this._delegateSpec && this._delegateSpec.onFork) { 93 | return this._delegateSpec.onInvokeTask(parentZoneDelegate, currentZone, targetZone, task, applyThis, applyArgs); 94 | } 95 | else { 96 | return parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs); 97 | } 98 | }; 99 | ProxyZoneSpec.prototype.onCancelTask = function (parentZoneDelegate, currentZone, targetZone, task) { 100 | if (this._delegateSpec && this._delegateSpec.onCancelTask) { 101 | return this._delegateSpec.onCancelTask(parentZoneDelegate, currentZone, targetZone, task); 102 | } 103 | else { 104 | return parentZoneDelegate.cancelTask(targetZone, task); 105 | } 106 | }; 107 | ProxyZoneSpec.prototype.onHasTask = function (delegate, current, target, hasTaskState) { 108 | if (this._delegateSpec && this._delegateSpec.onHasTask) { 109 | this._delegateSpec.onHasTask(delegate, current, target, hasTaskState); 110 | } 111 | else { 112 | delegate.hasTask(target, hasTaskState); 113 | } 114 | }; 115 | return ProxyZoneSpec; 116 | }()); 117 | // Export the class so that new instances can be created with proper 118 | // constructor params. 119 | Zone['ProxyZoneSpec'] = ProxyZoneSpec; 120 | 121 | }))); 122 | -------------------------------------------------------------------------------- /zone/dist/proxy.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t():"function"==typeof define&&define.amd?define(t):t()}(this,function(){"use strict";var e=function(){function e(e){void 0===e&&(e=null),this.defaultSpecDelegate=e,this.name="ProxyZone",this.properties={ProxyZoneSpec:this},this.propertyKeys=null,this.setDelegate(e)}return e.get=function(){return Zone.current.get("ProxyZoneSpec")},e.isLoaded=function(){return e.get()instanceof e},e.assertPresent=function(){if(!this.isLoaded())throw new Error("Expected to be running in 'ProxyZone', but it was not found.");return e.get()},e.prototype.setDelegate=function(e){var t=this;this._delegateSpec=e,this.propertyKeys&&this.propertyKeys.forEach(function(e){return delete t.properties[e]}),this.propertyKeys=null,e&&e.properties&&(this.propertyKeys=Object.keys(e.properties),this.propertyKeys.forEach(function(n){return t.properties[n]=e.properties[n]}))},e.prototype.getDelegate=function(){return this._delegateSpec},e.prototype.resetDelegate=function(){this.setDelegate(this.defaultSpecDelegate)},e.prototype.onFork=function(e,t,n,o){return this._delegateSpec&&this._delegateSpec.onFork?this._delegateSpec.onFork(e,t,n,o):e.fork(n,o)},e.prototype.onIntercept=function(e,t,n,o,r){return this._delegateSpec&&this._delegateSpec.onIntercept?this._delegateSpec.onIntercept(e,t,n,o,r):e.intercept(n,o,r)},e.prototype.onInvoke=function(e,t,n,o,r,s,p){return this._delegateSpec&&this._delegateSpec.onInvoke?this._delegateSpec.onInvoke(e,t,n,o,r,s,p):e.invoke(n,o,r,s,p)},e.prototype.onHandleError=function(e,t,n,o){return this._delegateSpec&&this._delegateSpec.onHandleError?this._delegateSpec.onHandleError(e,t,n,o):e.handleError(n,o)},e.prototype.onScheduleTask=function(e,t,n,o){return this._delegateSpec&&this._delegateSpec.onScheduleTask?this._delegateSpec.onScheduleTask(e,t,n,o):e.scheduleTask(n,o)},e.prototype.onInvokeTask=function(e,t,n,o,r,s){return this._delegateSpec&&this._delegateSpec.onFork?this._delegateSpec.onInvokeTask(e,t,n,o,r,s):e.invokeTask(n,o,r,s)},e.prototype.onCancelTask=function(e,t,n,o){return this._delegateSpec&&this._delegateSpec.onCancelTask?this._delegateSpec.onCancelTask(e,t,n,o):e.cancelTask(n,o)},e.prototype.onHasTask=function(e,t,n,o){this._delegateSpec&&this._delegateSpec.onHasTask?this._delegateSpec.onHasTask(e,t,n,o):e.hasTask(n,o)},e}();Zone.ProxyZoneSpec=e}); -------------------------------------------------------------------------------- /zone/dist/sync-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright Google Inc. All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file at https://angular.io/license 7 | */ 8 | (function (global, factory) { 9 | typeof exports === 'object' && typeof module !== 'undefined' ? factory() : 10 | typeof define === 'function' && define.amd ? define(factory) : 11 | (factory()); 12 | }(this, (function () { 'use strict'; 13 | 14 | var SyncTestZoneSpec = (function () { 15 | function SyncTestZoneSpec(namePrefix) { 16 | this.runZone = Zone.current; 17 | this.name = 'syncTestZone for ' + namePrefix; 18 | } 19 | SyncTestZoneSpec.prototype.onScheduleTask = function (delegate, current, target, task) { 20 | switch (task.type) { 21 | case 'microTask': 22 | case 'macroTask': 23 | throw new Error("Cannot call " + task.source + " from within a sync test."); 24 | case 'eventTask': 25 | task = delegate.scheduleTask(target, task); 26 | break; 27 | } 28 | return task; 29 | }; 30 | return SyncTestZoneSpec; 31 | }()); 32 | // Export the class so that new instances can be created with proper 33 | // constructor params. 34 | Zone['SyncTestZoneSpec'] = SyncTestZoneSpec; 35 | 36 | }))); 37 | -------------------------------------------------------------------------------- /zone/dist/task-tracking.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright Google Inc. All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file at https://angular.io/license 7 | */ 8 | (function (global, factory) { 9 | typeof exports === 'object' && typeof module !== 'undefined' ? factory() : 10 | typeof define === 'function' && define.amd ? define(factory) : 11 | (factory()); 12 | }(this, (function () { 'use strict'; 13 | 14 | /** 15 | * A `TaskTrackingZoneSpec` allows one to track all outstanding Tasks. 16 | * 17 | * This is useful in tests. For example to see which tasks are preventing a test from completing 18 | * or an automated way of releasing all of the event listeners at the end of the test. 19 | */ 20 | var TaskTrackingZoneSpec = (function () { 21 | function TaskTrackingZoneSpec() { 22 | this.name = 'TaskTrackingZone'; 23 | this.microTasks = []; 24 | this.macroTasks = []; 25 | this.eventTasks = []; 26 | this.properties = { 'TaskTrackingZone': this }; 27 | } 28 | TaskTrackingZoneSpec.get = function () { 29 | return Zone.current.get('TaskTrackingZone'); 30 | }; 31 | TaskTrackingZoneSpec.prototype.getTasksFor = function (type) { 32 | switch (type) { 33 | case 'microTask': return this.microTasks; 34 | case 'macroTask': return this.macroTasks; 35 | case 'eventTask': return this.eventTasks; 36 | } 37 | throw new Error('Unknown task format: ' + type); 38 | }; 39 | TaskTrackingZoneSpec.prototype.onScheduleTask = function (parentZoneDelegate, currentZone, targetZone, task) { 40 | task['creationLocation'] = new Error("Task '" + task.type + "' from '" + task.source + "'."); 41 | var tasks = this.getTasksFor(task.type); 42 | tasks.push(task); 43 | return parentZoneDelegate.scheduleTask(targetZone, task); 44 | }; 45 | TaskTrackingZoneSpec.prototype.onCancelTask = function (parentZoneDelegate, currentZone, targetZone, task) { 46 | var tasks = this.getTasksFor(task.type); 47 | for (var i = 0; i < tasks.length; i++) { 48 | if (tasks[i] == task) { 49 | tasks.splice(i, 1); 50 | break; 51 | } 52 | } 53 | return parentZoneDelegate.cancelTask(targetZone, task); 54 | }; 55 | TaskTrackingZoneSpec.prototype.onInvokeTask = function (parentZoneDelegate, currentZone, targetZone, task, applyThis, applyArgs) { 56 | if (task.type === 'eventTask') 57 | return parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs); 58 | var tasks = this.getTasksFor(task.type); 59 | for (var i = 0; i < tasks.length; i++) { 60 | if (tasks[i] == task) { 61 | tasks.splice(i, 1); 62 | break; 63 | } 64 | } 65 | return parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs); 66 | }; 67 | TaskTrackingZoneSpec.prototype.clearEvents = function () { 68 | while (this.eventTasks.length) { 69 | Zone.current.cancelTask(this.eventTasks[0]); 70 | } 71 | }; 72 | return TaskTrackingZoneSpec; 73 | }()); 74 | // Export the class so that new instances can be created with proper 75 | // constructor params. 76 | Zone['TaskTrackingZoneSpec'] = TaskTrackingZoneSpec; 77 | 78 | }))); 79 | -------------------------------------------------------------------------------- /zone/dist/task-tracking.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t():"function"==typeof define&&define.amd?define(t):t()}(this,function(){"use strict";var e=function(){function e(){this.name="TaskTrackingZone",this.microTasks=[],this.macroTasks=[],this.eventTasks=[],this.properties={TaskTrackingZone:this}}return e.get=function(){return Zone.current.get("TaskTrackingZone")},e.prototype.getTasksFor=function(e){switch(e){case"microTask":return this.microTasks;case"macroTask":return this.macroTasks;case"eventTask":return this.eventTasks}throw new Error("Unknown task format: "+e)},e.prototype.onScheduleTask=function(e,t,n,s){s.creationLocation=new Error("Task '"+s.type+"' from '"+s.source+"'.");var r=this.getTasksFor(s.type);return r.push(s),e.scheduleTask(n,s)},e.prototype.onCancelTask=function(e,t,n,s){for(var r=this.getTasksFor(s.type),o=0;o { 24 | return function (s:any, args: any[]) { 25 | return Zone.current.run(delegate, _global, args, name) 26 | } 27 | }); 28 | } 29 | 30 | eventTargetPatch(_global); 31 | propertyDescriptorPatch(_global); 32 | patchClass('MutationObserver'); 33 | patchClass('WebKitMutationObserver'); 34 | patchClass('FileReader'); 35 | propertyPatch(); 36 | registerElementPatch(_global); 37 | 38 | // Treat XMLHTTPRequest as a macrotask. 39 | patchXHR(_global); 40 | 41 | const XHR_TASK = zoneSymbol('xhrTask'); 42 | const XHR_SYNC = zoneSymbol('xhrSync'); 43 | 44 | interface XHROptions extends TaskData { 45 | target: any; 46 | args: any[]; 47 | aborted: boolean; 48 | } 49 | 50 | function patchXHR(window: any) { 51 | function findPendingTask(target: any) { 52 | var pendingTask: Task = target[XHR_TASK]; 53 | return pendingTask; 54 | } 55 | 56 | function scheduleTask(task: Task) { 57 | var data = task.data; 58 | data.target.addEventListener('readystatechange', () => { 59 | if (data.target.readyState === data.target.DONE) { 60 | if (!data.aborted) { 61 | task.invoke(); 62 | } 63 | } 64 | }); 65 | var storedTask: Task = data.target[XHR_TASK]; 66 | if (!storedTask) { 67 | data.target[XHR_TASK] = task; 68 | } 69 | sendNative.apply(data.target, data.args); 70 | return task; 71 | } 72 | 73 | function placeholderCallback() { 74 | } 75 | 76 | function clearTask(task: Task) { 77 | var data = task.data; 78 | // Note - ideally, we would call data.target.removeEventListener here, but it's too late 79 | // to prevent it from firing. So instead, we store info for the event listener. 80 | data.aborted = true; 81 | return abortNative.apply(data.target, data.args); 82 | } 83 | 84 | var openNative = patchMethod(window.XMLHttpRequest.prototype, 'open', () => function(self: any, args: any[]) { 85 | self[XHR_SYNC] = args[2] == false; 86 | return openNative.apply(self, args); 87 | }); 88 | 89 | var sendNative = patchMethod(window.XMLHttpRequest.prototype, 'send', () => function(self: any, args: any[]) { 90 | var zone = Zone.current; 91 | if (self[XHR_SYNC]) { 92 | // if the XHR is sync there is no task to schedule, just execute the code. 93 | return sendNative.apply(self, args); 94 | } else { 95 | var options: XHROptions = { 96 | target: self, 97 | isPeriodic: false, 98 | delay: null, 99 | args: args, 100 | aborted: false 101 | }; 102 | return zone.scheduleMacroTask('XMLHttpRequest.send', placeholderCallback, options, scheduleTask, clearTask); 103 | } 104 | }); 105 | 106 | var abortNative = patchMethod(window.XMLHttpRequest.prototype, 'abort', (delegate: Function) => function(self: any, args: any[]) { 107 | var task: Task = findPendingTask(self); 108 | if (task && typeof task.type == 'string') { 109 | // If the XHR has already completed, do nothing. 110 | if (task.cancelFn == null) { 111 | return; 112 | } 113 | task.zone.cancelTask(task); 114 | } 115 | // Otherwise, we are trying to abort an XHR which has not yet been sent, so there is no task to cancel. Do nothing. 116 | }); 117 | } 118 | 119 | /// GEO_LOCATION 120 | if (_global['navigator'] && _global['navigator'].geolocation) { 121 | patchPrototype(_global['navigator'].geolocation, [ 122 | 'getCurrentPosition', 123 | 'watchPosition' 124 | ]); 125 | } 126 | -------------------------------------------------------------------------------- /zone/lib/browser/define-property.ts: -------------------------------------------------------------------------------- 1 | import {zoneSymbol} from "../common/utils"; 2 | /* 3 | * This is necessary for Chrome and Chrome mobile, to enable 4 | * things like redefining `createdCallback` on an element. 5 | */ 6 | 7 | const _defineProperty = Object[zoneSymbol('defineProperty')] = Object.defineProperty; 8 | const _getOwnPropertyDescriptor = Object[zoneSymbol('getOwnPropertyDescriptor')] = Object.getOwnPropertyDescriptor; 9 | const _create = Object.create; 10 | const unconfigurablesKey = zoneSymbol('unconfigurables'); 11 | 12 | export function propertyPatch() { 13 | Object.defineProperty = function (obj, prop, desc) { 14 | if (isUnconfigurable(obj, prop)) { 15 | throw new TypeError('Cannot assign to read only property \'' + prop + '\' of ' + obj); 16 | } 17 | const originalConfigurableFlag = desc.configurable; 18 | if (prop !== 'prototype') { 19 | desc = rewriteDescriptor(obj, prop, desc); 20 | } 21 | return _tryDefineProperty(obj, prop, desc, originalConfigurableFlag); 22 | }; 23 | 24 | Object.defineProperties = function (obj, props) { 25 | Object.keys(props).forEach(function (prop) { 26 | Object.defineProperty(obj, prop, props[prop]); 27 | }); 28 | return obj; 29 | }; 30 | 31 | Object.create = function (obj, proto) { 32 | if (typeof proto === 'object' && !Object.isFrozen(proto)) { 33 | Object.keys(proto).forEach(function (prop) { 34 | proto[prop] = rewriteDescriptor(obj, prop, proto[prop]); 35 | }); 36 | } 37 | return _create(obj, proto); 38 | }; 39 | 40 | Object.getOwnPropertyDescriptor = function (obj, prop) { 41 | const desc = _getOwnPropertyDescriptor(obj, prop); 42 | if (isUnconfigurable(obj, prop)) { 43 | desc.configurable = false; 44 | } 45 | return desc; 46 | }; 47 | }; 48 | 49 | export function _redefineProperty(obj, prop, desc) { 50 | const originalConfigurableFlag = desc.configurable; 51 | desc = rewriteDescriptor(obj, prop, desc); 52 | return _tryDefineProperty(obj, prop, desc, originalConfigurableFlag); 53 | }; 54 | 55 | function isUnconfigurable (obj, prop) { 56 | return obj && obj[unconfigurablesKey] && obj[unconfigurablesKey][prop]; 57 | } 58 | 59 | function rewriteDescriptor (obj, prop, desc) { 60 | desc.configurable = true; 61 | if (!desc.configurable) { 62 | if (!obj[unconfigurablesKey]) { 63 | _defineProperty(obj, unconfigurablesKey, { writable: true, value: {} }); 64 | } 65 | obj[unconfigurablesKey][prop] = true; 66 | } 67 | return desc; 68 | } 69 | 70 | function _tryDefineProperty (obj, prop, desc, originalConfigurableFlag) { 71 | try { 72 | return _defineProperty(obj, prop, desc); 73 | } 74 | catch(e) { 75 | if (desc.configurable) { 76 | // In case of errors, when the configurable flag was likely set by rewriteDescriptor(), let's retry with the original flag value 77 | if (typeof originalConfigurableFlag == 'undefined') { 78 | delete desc.configurable; 79 | } else { 80 | desc.configurable = originalConfigurableFlag; 81 | } 82 | try { 83 | return _defineProperty(obj, prop, desc); 84 | } catch (e) { 85 | var descJson: string = null; 86 | try { descJson = JSON.stringify(desc); } catch (e) { descJson = descJson.toString(); } 87 | console.log(`Attempting to configure '${prop}' with descriptor '${descJson}' on object '${obj}' and got error, giving up: ${e}`); 88 | } 89 | } else { 90 | throw e; 91 | } 92 | } 93 | } 94 | 95 | 96 | -------------------------------------------------------------------------------- /zone/lib/browser/event-target.ts: -------------------------------------------------------------------------------- 1 | import {patchEventTargetMethods} from '../common/utils'; 2 | 3 | const WTF_ISSUE_555 = 'Anchor,Area,Audio,BR,Base,BaseFont,Body,Button,Canvas,Content,DList,Directory,Div,Embed,FieldSet,Font,Form,Frame,FrameSet,HR,Head,Heading,Html,IFrame,Image,Input,Keygen,LI,Label,Legend,Link,Map,Marquee,Media,Menu,Meta,Meter,Mod,OList,Object,OptGroup,Option,Output,Paragraph,Pre,Progress,Quote,Script,Select,Source,Span,Style,TableCaption,TableCell,TableCol,Table,TableRow,TableSection,TextArea,Title,Track,UList,Unknown,Video'; 4 | const NO_EVENT_TARGET = 'ApplicationCache,EventSource,FileReader,InputMethodContext,MediaController,MessagePort,Node,Performance,SVGElementInstance,SharedWorker,TextTrack,TextTrackCue,TextTrackList,WebKitNamedFlow,Window,Worker,WorkerGlobalScope,XMLHttpRequest,XMLHttpRequestEventTarget,XMLHttpRequestUpload,IDBRequest,IDBOpenDBRequest,IDBDatabase,IDBTransaction,IDBCursor,DBIndex'.split(','); 5 | const EVENT_TARGET = 'EventTarget'; 6 | 7 | export function eventTargetPatch(_global) { 8 | var apis = []; 9 | var isWtf = _global['wtf']; 10 | if (isWtf) { 11 | // Workaround for: https://github.com/google/tracing-framework/issues/555 12 | apis = WTF_ISSUE_555.split(',').map((v) => 'HTML' + v + 'Element').concat(NO_EVENT_TARGET); 13 | } else if (_global[EVENT_TARGET]) { 14 | apis.push(EVENT_TARGET); 15 | } else { 16 | // Note: EventTarget is not available in all browsers, 17 | // if it's not available, we instead patch the APIs in the IDL that inherit from EventTarget 18 | apis = NO_EVENT_TARGET; 19 | } 20 | 21 | for (var i = 0; i < apis.length; i++) { 22 | var type = _global[apis[i]]; 23 | patchEventTargetMethods(type && type.prototype); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /zone/lib/browser/property-descriptor.ts: -------------------------------------------------------------------------------- 1 | import * as webSocketPatch from './websocket'; 2 | import {zoneSymbol, patchOnProperties, patchClass, isBrowser, isNode} from '../common/utils'; 3 | 4 | const eventNames = 'copy cut paste abort blur focus canplay canplaythrough change click contextmenu dblclick drag dragend dragenter dragleave dragover dragstart drop durationchange emptied ended input invalid keydown keypress keyup load loadeddata loadedmetadata loadstart message mousedown mouseenter mouseleave mousemove mouseout mouseover mouseup pause play playing progress ratechange reset scroll seeked seeking select show stalled submit suspend timeupdate volumechange waiting mozfullscreenchange mozfullscreenerror mozpointerlockchange mozpointerlockerror error webglcontextrestored webglcontextlost webglcontextcreationerror'.split(' '); 5 | 6 | export function propertyDescriptorPatch(_global) { 7 | if (isNode){ 8 | return; 9 | } 10 | 11 | const supportsWebSocket = typeof WebSocket !== 'undefined'; 12 | if (canPatchViaPropertyDescriptor()) { 13 | // for browsers that we can patch the descriptor: Chrome & Firefox 14 | if (isBrowser) { 15 | patchOnProperties(HTMLElement.prototype, eventNames); 16 | } 17 | patchOnProperties(XMLHttpRequest.prototype, null); 18 | if (typeof IDBIndex !== 'undefined') { 19 | patchOnProperties(IDBIndex.prototype, null); 20 | patchOnProperties(IDBRequest.prototype, null); 21 | patchOnProperties(IDBOpenDBRequest.prototype, null); 22 | patchOnProperties(IDBDatabase.prototype, null); 23 | patchOnProperties(IDBTransaction.prototype, null); 24 | patchOnProperties(IDBCursor.prototype, null); 25 | } 26 | if (supportsWebSocket) { 27 | patchOnProperties(WebSocket.prototype, null); 28 | } 29 | } else { 30 | // Safari, Android browsers (Jelly Bean) 31 | patchViaCapturingAllTheEvents(); 32 | patchClass('XMLHttpRequest'); 33 | if (supportsWebSocket) { 34 | webSocketPatch.apply(_global); 35 | } 36 | } 37 | } 38 | 39 | function canPatchViaPropertyDescriptor() { 40 | if (isBrowser && !Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'onclick') 41 | && typeof Element !== 'undefined') { 42 | // WebKit https://bugs.webkit.org/show_bug.cgi?id=134364 43 | // IDL interface attributes are not configurable 44 | const desc = Object.getOwnPropertyDescriptor(Element.prototype, 'onclick'); 45 | if (desc && !desc.configurable) return false; 46 | } 47 | 48 | Object.defineProperty(XMLHttpRequest.prototype, 'onreadystatechange', { 49 | get: function () { 50 | return true; 51 | } 52 | }); 53 | const req = new XMLHttpRequest(); 54 | const result = !!req.onreadystatechange; 55 | Object.defineProperty(XMLHttpRequest.prototype, 'onreadystatechange', {}); 56 | return result; 57 | }; 58 | 59 | const unboundKey = zoneSymbol('unbound'); 60 | 61 | // Whenever any eventListener fires, we check the eventListener target and all parents 62 | // for `onwhatever` properties and replace them with zone-bound functions 63 | // - Chrome (for now) 64 | function patchViaCapturingAllTheEvents() { 65 | for(let i = 0; i < eventNames.length; i++) { 66 | const property = eventNames[i]; 67 | const onproperty = 'on' + property; 68 | document.addEventListener(property, function (event) { 69 | let elt = event.target, bound, source; 70 | if (elt) { 71 | source = elt.constructor['name'] + '.' + onproperty; 72 | } else { 73 | source = 'unknown.' + onproperty; 74 | } 75 | while (elt) { 76 | if (elt[onproperty] && !elt[onproperty][unboundKey]) { 77 | bound = Zone.current.wrap(elt[onproperty], source); 78 | bound[unboundKey] = elt[onproperty]; 79 | elt[onproperty] = bound; 80 | } 81 | elt = elt.parentElement; 82 | } 83 | }, true); 84 | }; 85 | }; 86 | -------------------------------------------------------------------------------- /zone/lib/browser/register-element.ts: -------------------------------------------------------------------------------- 1 | import {_redefineProperty} from './define-property'; 2 | import {isBrowser} from '../common/utils'; 3 | 4 | export function registerElementPatch(_global: any) { 5 | if (!isBrowser || !('registerElement' in (_global).document)) { 6 | return; 7 | } 8 | 9 | const _registerElement = (document).registerElement; 10 | const callbacks = [ 11 | 'createdCallback', 12 | 'attachedCallback', 13 | 'detachedCallback', 14 | 'attributeChangedCallback' 15 | ]; 16 | 17 | (document).registerElement = function (name, opts) { 18 | if (opts && opts.prototype) { 19 | callbacks.forEach(function (callback) { 20 | const source = 'Document.registerElement::' + callback; 21 | if (opts.prototype.hasOwnProperty(callback)) { 22 | const descriptor = Object.getOwnPropertyDescriptor(opts.prototype, callback); 23 | if (descriptor && descriptor.value) { 24 | descriptor.value = Zone.current.wrap(descriptor.value, source); 25 | _redefineProperty(opts.prototype, callback, descriptor); 26 | } else { 27 | opts.prototype[callback] = Zone.current.wrap(opts.prototype[callback], source); 28 | } 29 | } else if (opts.prototype[callback]) { 30 | opts.prototype[callback] = Zone.current.wrap(opts.prototype[callback], source); 31 | } 32 | }); 33 | } 34 | 35 | return _registerElement.apply(document, [name, opts]); 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /zone/lib/browser/websocket.ts: -------------------------------------------------------------------------------- 1 | import {patchEventTargetMethods, patchOnProperties} from '../common/utils'; 2 | 3 | // we have to patch the instance since the proto is non-configurable 4 | export function apply(_global: any) { 5 | const WS = (_global).WebSocket; 6 | // On Safari window.EventTarget doesn't exist so need to patch WS add/removeEventListener 7 | // On older Chrome, no need since EventTarget was already patched 8 | if (!(_global).EventTarget) { 9 | patchEventTargetMethods(WS.prototype); 10 | } 11 | (_global).WebSocket = function(a, b) { 12 | const socket = arguments.length > 1 ? new WS(a, b) : new WS(a); 13 | let proxySocket; 14 | 15 | // Safari 7.0 has non-configurable own 'onmessage' and friends properties on the socket instance 16 | const onmessageDesc = Object.getOwnPropertyDescriptor(socket, 'onmessage'); 17 | if (onmessageDesc && onmessageDesc.configurable === false) { 18 | proxySocket = Object.create(socket); 19 | ['addEventListener', 'removeEventListener', 'send', 'close'].forEach(function(propName) { 20 | proxySocket[propName] = function() { 21 | return socket[propName].apply(socket, arguments); 22 | }; 23 | }); 24 | } else { 25 | // we can patch the real socket 26 | proxySocket = socket; 27 | } 28 | 29 | patchOnProperties(proxySocket, ['close', 'error', 'message', 'open']); 30 | 31 | return proxySocket; 32 | }; 33 | for (var prop in WS) { _global.WebSocket[prop] = WS[prop]; } 34 | } 35 | -------------------------------------------------------------------------------- /zone/lib/common/timers.ts: -------------------------------------------------------------------------------- 1 | import {patchMethod} from './utils'; 2 | 3 | interface TimerOptions extends TaskData { 4 | handleId: number; 5 | args: any[]; 6 | } 7 | 8 | export function patchTimer( 9 | window: any, 10 | setName: string, 11 | cancelName: string, 12 | nameSuffix: string) { 13 | 14 | var setNative = null; 15 | var clearNative = null; 16 | setName += nameSuffix; 17 | cancelName += nameSuffix; 18 | 19 | function scheduleTask(task: Task) { 20 | const data = task.data; 21 | data.args[0] = task.invoke; 22 | data.handleId = setNative.apply(window, data.args); 23 | return task; 24 | } 25 | 26 | function clearTask(task: Task) { 27 | return clearNative((task.data).handleId); 28 | } 29 | 30 | setNative = patchMethod(window, setName, (delegate: Function) => function(self: any, args: any[]) { 31 | if (typeof args[0] === 'function') { 32 | var zone = Zone.current; 33 | var options: TimerOptions = { 34 | handleId: null, 35 | isPeriodic: nameSuffix === 'Interval', 36 | delay: (nameSuffix === 'Timeout' || nameSuffix === 'Interval') ? args[1] || 0 : null, 37 | args: args 38 | }; 39 | var task = zone.scheduleMacroTask(setName, args[0], options, scheduleTask, clearTask) ; 40 | if (!task) { 41 | return task; 42 | } 43 | // Node.js must additionally support the ref and unref functions. 44 | var handle = (task.data).handleId; 45 | if ((handle).ref && (handle).unref) { 46 | (task).ref = (handle).ref.bind(handle); 47 | (task).unref = (handle).unref.bind(handle); 48 | } 49 | return task; 50 | } else { 51 | // cause an error by calling it directly. 52 | return delegate.apply(window, args); 53 | } 54 | }); 55 | 56 | clearNative = patchMethod(window, cancelName, (delegate: Function) => function(self: any, args: any[]) { 57 | var task: Task = args[0]; 58 | if (task && typeof task.type === 'string') { 59 | if (task.cancelFn && task.data.isPeriodic || task.runCount === 0) { 60 | // Do not cancel already canceled functions 61 | task.zone.cancelTask(task); 62 | } 63 | } else { 64 | // cause an error by calling it directly. 65 | delegate.apply(window, args); 66 | } 67 | }); 68 | } 69 | -------------------------------------------------------------------------------- /zone/lib/jasmine/jasmine.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | (() => { 3 | // Patch jasmine's describe/it/beforeEach/afterEach functions so test code always runs 4 | // in a testZone (ProxyZone). (See: angular/zone.js#91 & angular/angular#10503) 5 | if (!Zone) throw new Error("Missing: zone.js"); 6 | if (typeof jasmine == 'undefined') throw new Error("Missing: jasmine.js"); 7 | if (jasmine['__zone_patch__']) throw new Error("'jasmine' has already been patched with 'Zone'."); 8 | jasmine['__zone_patch__'] = true; 9 | 10 | const SyncTestZoneSpec: {new (name: string): ZoneSpec} = Zone['SyncTestZoneSpec']; 11 | const ProxyZoneSpec: {new (): ZoneSpec} = Zone['ProxyZoneSpec']; 12 | if (!SyncTestZoneSpec) throw new Error("Missing: SyncTestZoneSpec"); 13 | if (!ProxyZoneSpec) throw new Error("Missing: ProxyZoneSpec"); 14 | 15 | const ambientZone = Zone.current; 16 | // Create a synchronous-only zone in which to run `describe` blocks in order to raise an 17 | // error if any asynchronous operations are attempted inside of a `describe` but outside of 18 | // a `beforeEach` or `it`. 19 | const syncZone = ambientZone.fork(new SyncTestZoneSpec('jasmine.describe')); 20 | 21 | // This is the zone which will be used for running individual tests. 22 | // It will be a proxy zone, so that the tests function can retroactively install 23 | // different zones. 24 | // Example: 25 | // - In beforeEach() do childZone = Zone.current.fork(...); 26 | // - In it() try to do fakeAsync(). The issue is that because the beforeEach forked the 27 | // zone outside of fakeAsync it will be able to escope the fakeAsync rules. 28 | // - Because ProxyZone is parent fo `childZone` fakeAsync can retroactively add 29 | // fakeAsync behavior to the childZone. 30 | let testProxyZone: Zone = null; 31 | 32 | // Monkey patch all of the jasmine DSL so that each function runs in appropriate zone. 33 | const jasmineEnv = jasmine.getEnv(); 34 | ['describe', 'xdescribe', 'fdescribe'].forEach((methodName) => { 35 | let originalJasmineFn: Function = jasmineEnv[methodName]; 36 | jasmineEnv[methodName] = function(description: string, specDefinitions: Function) { 37 | return originalJasmineFn.call(this, description, wrapDescribeInZone(specDefinitions)); 38 | } 39 | }); 40 | ['it', 'xit', 'fit'].forEach((methodName) => { 41 | let originalJasmineFn: Function = jasmineEnv[methodName]; 42 | jasmineEnv[methodName] = function(description: string, specDefinitions: Function, timeout: number) { 43 | arguments[1] = wrapTestInZone(specDefinitions); 44 | return originalJasmineFn.apply(this, arguments); 45 | } 46 | }); 47 | ['beforeEach', 'afterEach'].forEach((methodName) => { 48 | let originalJasmineFn: Function = jasmineEnv[methodName]; 49 | jasmineEnv[methodName] = function(specDefinitions: Function, timeout: number) { 50 | arguments[0] = wrapTestInZone(specDefinitions); 51 | return originalJasmineFn.apply(this, arguments); 52 | } 53 | }); 54 | 55 | /** 56 | * Gets a function wrapping the body of a Jasmine `describe` block to execute in a 57 | * synchronous-only zone. 58 | */ 59 | function wrapDescribeInZone(describeBody: Function): Function { 60 | return function() { 61 | return syncZone.run(describeBody, this, arguments as any as any[]); 62 | } 63 | } 64 | 65 | /** 66 | * Gets a function wrapping the body of a Jasmine `it/beforeEach/afterEach` block to 67 | * execute in a ProxyZone zone. 68 | * This will run in `testProxyZone`. The `testProxyZone` will be reset by the `ZoneQueueRunner` 69 | */ 70 | function wrapTestInZone(testBody: Function): Function { 71 | // The `done` callback is only passed through if the function expects at least one argument. 72 | // Note we have to make a function with correct number of arguments, otherwise jasmine will 73 | // think that all functions are sync or async. 74 | return (testBody.length == 0) 75 | ? function() { return testProxyZone.run(testBody, this); } 76 | : function(done) { return testProxyZone.run(testBody, this, [done]); }; 77 | } 78 | interface QueueRunner { 79 | execute(): void; 80 | } 81 | interface QueueRunnerAttrs { 82 | queueableFns: {fn: Function}[]; 83 | onComplete: () => void; 84 | clearStack: (fn) => void; 85 | onException: (error) => void; 86 | catchException: () => boolean; 87 | userContext: any; 88 | timeout: {setTimeout: Function, clearTimeout: Function}; 89 | fail: ()=> void; 90 | } 91 | 92 | const QueueRunner = (jasmine as any).QueueRunner as { new(attrs: QueueRunnerAttrs): QueueRunner }; 93 | (jasmine as any).QueueRunner = class ZoneQueueRunner extends QueueRunner { 94 | constructor(attrs: QueueRunnerAttrs) { 95 | attrs.onComplete = ((fn) => () => { 96 | // All functions are done, clear the test zone. 97 | testProxyZone = null; 98 | ambientZone.scheduleMicroTask('jasmine.onComplete', fn); 99 | })(attrs.onComplete); 100 | super(attrs); 101 | } 102 | 103 | execute() { 104 | if(Zone.current !== ambientZone) throw new Error("Unexpected Zone: " + Zone.current.name); 105 | testProxyZone = ambientZone.fork(new ProxyZoneSpec()); 106 | if (!Zone.currentTask) { 107 | // if we are not running in a task then if someone would register a 108 | // element.addEventListener and then calling element.click() the 109 | // addEventListener callback would think that it is the top most task and would 110 | // drain the microtask queue on element.click() which would be incorrect. 111 | // For this reason we always force a task when running jasmine tests. 112 | Zone.current.scheduleMicroTask('jasmine.execute().forceTask', () => super.execute()); 113 | } else { 114 | super.execute(); 115 | } 116 | } 117 | }; 118 | })(); 119 | -------------------------------------------------------------------------------- /zone/lib/node/events.ts: -------------------------------------------------------------------------------- 1 | import {makeZoneAwareAddListener, makeZoneAwareListeners, makeZoneAwareRemoveListener, patchMethod} from '../common/utils'; 2 | 3 | 4 | // For EventEmitter 5 | const EE_ADD_LISTENER = 'addListener'; 6 | const EE_PREPEND_LISTENER = 'prependListener'; 7 | const EE_REMOVE_LISTENER = 'removeListener'; 8 | const EE_LISTENERS = 'listeners'; 9 | const EE_ON = 'on'; 10 | 11 | 12 | const zoneAwareAddListener = makeZoneAwareAddListener(EE_ADD_LISTENER, EE_REMOVE_LISTENER, false, true); 13 | const zoneAwarePrependListener = makeZoneAwareAddListener(EE_PREPEND_LISTENER, EE_REMOVE_LISTENER, false, true); 14 | const zoneAwareRemoveListener = makeZoneAwareRemoveListener(EE_REMOVE_LISTENER, false); 15 | const zoneAwareListeners = makeZoneAwareListeners(EE_LISTENERS); 16 | 17 | export function patchEventEmitterMethods(obj: any): boolean { 18 | if (obj && obj.addListener) { 19 | patchMethod(obj, EE_ADD_LISTENER, () => zoneAwareAddListener); 20 | patchMethod(obj, EE_PREPEND_LISTENER, () => zoneAwarePrependListener); 21 | patchMethod(obj, EE_REMOVE_LISTENER, () => zoneAwareRemoveListener); 22 | patchMethod(obj, EE_LISTENERS, () => zoneAwareListeners); 23 | obj[EE_ON] = obj[EE_ADD_LISTENER]; 24 | return true; 25 | } else { 26 | return false; 27 | } 28 | } 29 | 30 | // EventEmitter 31 | let events; 32 | try { 33 | events = require('events'); 34 | } catch (err) {} 35 | 36 | if (events && events.EventEmitter) { 37 | patchEventEmitterMethods(events.EventEmitter.prototype); 38 | } -------------------------------------------------------------------------------- /zone/lib/node/fs.ts: -------------------------------------------------------------------------------- 1 | import {bindArguments} from '../common/utils'; 2 | 3 | let fs; 4 | try { 5 | fs = require('fs'); 6 | } catch (err) {} 7 | 8 | // TODO(alxhub): Patch `watch` and `unwatchFile`. 9 | const TO_PATCH = [ 10 | 'access', 11 | 'appendFile', 12 | 'chmod', 13 | 'chown', 14 | 'close', 15 | 'exists', 16 | 'fchmod', 17 | 'fchown', 18 | 'fdatasync', 19 | 'fstat', 20 | 'fsync', 21 | 'ftruncate', 22 | 'futimes', 23 | 'lchmod', 24 | 'lchown', 25 | 'link', 26 | 'lstat', 27 | 'mkdir', 28 | 'mkdtemp', 29 | 'open', 30 | 'read', 31 | 'readdir', 32 | 'readFile', 33 | 'readlink', 34 | 'realpath', 35 | 'rename', 36 | 'rmdir', 37 | 'stat', 38 | 'symlink', 39 | 'truncate', 40 | 'unlink', 41 | 'utimes', 42 | 'write', 43 | 'writeFile', 44 | ]; 45 | 46 | if (fs) { 47 | TO_PATCH 48 | .filter(name => !!fs[name] && typeof fs[name] === 'function') 49 | .forEach(name => { 50 | fs[name] = ((delegate: Function) => { 51 | return function() { 52 | return delegate.apply(this, bindArguments(arguments, 'fs.' + name)); 53 | }; 54 | })(fs[name]); 55 | }); 56 | } 57 | -------------------------------------------------------------------------------- /zone/lib/node/node.ts: -------------------------------------------------------------------------------- 1 | import '../zone'; 2 | import {patchTimer} from '../common/timers'; 3 | 4 | import './events'; 5 | import './fs'; 6 | 7 | const set = 'set'; 8 | const clear = 'clear'; 9 | const _global = typeof window === 'object' && window || typeof self === 'object' && self || global; 10 | 11 | // Timers 12 | const timers = require('timers'); 13 | patchTimer(timers, set, clear, 'Timeout'); 14 | patchTimer(timers, set, clear, 'Interval'); 15 | patchTimer(timers, set, clear, 'Immediate'); 16 | 17 | const shouldPatchGlobalTimers = global.setTimeout !== timers.setTimeout; 18 | 19 | if (shouldPatchGlobalTimers) { 20 | patchTimer(_global, set, clear, 'Timeout'); 21 | patchTimer(_global, set, clear, 'Interval'); 22 | patchTimer(_global, set, clear, 'Immediate'); 23 | } 24 | 25 | 26 | // Crypto 27 | let crypto; 28 | try { 29 | crypto = require('crypto'); 30 | } catch (err) {} 31 | 32 | // TODO(gdi2290): implement a better way to patch these methods 33 | if (crypto) { 34 | let nativeRandomBytes = crypto.randomBytes; 35 | crypto.randomBytes = function randomBytesZone(size: number, callback?: Function) { 36 | if (!callback) { 37 | return nativeRandomBytes(size); 38 | } else { 39 | let zone = Zone.current; 40 | var source = crypto.constructor.name + '.randomBytes'; 41 | return nativeRandomBytes(size, zone.wrap(callback, source)); 42 | } 43 | }.bind(crypto); 44 | 45 | let nativePbkdf2 = crypto.pbkdf2; 46 | crypto.pbkdf2 = function pbkdf2Zone(...args: any[]) { 47 | let fn = args[args.length - 1]; 48 | if (typeof fn === 'function') { 49 | let zone = Zone.current; 50 | var source = crypto.constructor.name + '.pbkdf2'; 51 | args[args.length - 1] = zone.wrap(fn, source); 52 | return nativePbkdf2(...args); 53 | } else { 54 | return nativePbkdf2(...args); 55 | } 56 | }.bind(crypto); 57 | } 58 | 59 | // HTTP Client 60 | let httpClient; 61 | try { 62 | httpClient = require('_http_client'); 63 | } catch (err) {} 64 | 65 | if (httpClient && httpClient.ClientRequest) { 66 | let ClientRequest = httpClient.ClientRequest.bind(httpClient); 67 | httpClient.ClientRequest = function(options: any, callback?: Function) { 68 | if (!callback) { 69 | return new ClientRequest(options); 70 | } else { 71 | let zone = Zone.current; 72 | return new ClientRequest(options, zone.wrap(callback, 'http.ClientRequest')); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /zone/lib/zone-spec/async-test.ts: -------------------------------------------------------------------------------- 1 | class AsyncTestZoneSpec implements ZoneSpec { 2 | _finishCallback: Function; 3 | _failCallback: Function; 4 | _pendingMicroTasks: boolean = false; 5 | _pendingMacroTasks: boolean = false; 6 | _alreadyErrored: boolean = false; 7 | runZone = Zone.current; 8 | 9 | constructor(finishCallback: Function, failCallback: Function, namePrefix: string) { 10 | this._finishCallback = finishCallback; 11 | this._failCallback = failCallback; 12 | this.name = 'asyncTestZone for ' + namePrefix; 13 | } 14 | 15 | _finishCallbackIfDone() { 16 | if (!(this._pendingMicroTasks || this._pendingMacroTasks)) { 17 | // We do this because we would like to catch unhandled rejected promises. 18 | this.runZone.run(() => { 19 | setTimeout(() => { 20 | if (!this._alreadyErrored && !(this._pendingMicroTasks || this._pendingMacroTasks)) { 21 | this._finishCallback(); 22 | } 23 | }, 0); 24 | }); 25 | } 26 | } 27 | 28 | // ZoneSpec implementation below. 29 | 30 | name: string; 31 | 32 | // Note - we need to use onInvoke at the moment to call finish when a test is 33 | // fully synchronous. TODO(juliemr): remove this when the logic for 34 | // onHasTask changes and it calls whenever the task queues are dirty. 35 | onInvoke(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 36 | delegate: Function, applyThis: any, applyArgs: any[], source: string): any { 37 | try { 38 | return parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source); 39 | } finally { 40 | this._finishCallbackIfDone(); 41 | } 42 | } 43 | 44 | onHandleError(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 45 | error: any): boolean { 46 | // Let the parent try to handle the error. 47 | const result = parentZoneDelegate.handleError(targetZone, error); 48 | if (result) { 49 | this._failCallback(error); 50 | this._alreadyErrored = true; 51 | } 52 | return false; 53 | } 54 | 55 | onScheduleTask(delegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task): Task { 56 | if (task.type == 'macroTask' && task.source == 'setInterval') { 57 | this._failCallback('Cannot use setInterval from within an async zone test.'); 58 | return; 59 | } 60 | 61 | return delegate.scheduleTask(targetZone, task); 62 | } 63 | 64 | onHasTask(delegate: ZoneDelegate, current: Zone, target: Zone, hasTaskState: HasTaskState) { 65 | delegate.hasTask(target, hasTaskState); 66 | if (hasTaskState.change == 'microTask') { 67 | this._pendingMicroTasks = hasTaskState.microTask; 68 | this._finishCallbackIfDone(); 69 | } else if (hasTaskState.change == 'macroTask') { 70 | this._pendingMacroTasks = hasTaskState.macroTask; 71 | this._finishCallbackIfDone(); 72 | } 73 | } 74 | } 75 | 76 | // Export the class so that new instances can be created with proper 77 | // constructor params. 78 | Zone['AsyncTestZoneSpec'] = AsyncTestZoneSpec; 79 | -------------------------------------------------------------------------------- /zone/lib/zone-spec/long-stack-trace.ts: -------------------------------------------------------------------------------- 1 | const NEWLINE = '\n'; 2 | const SEP = ' ------------- '; 3 | const IGNORE_FRAMES = []; 4 | const creationTrace = '__creationTrace__'; 5 | 6 | class LongStackTrace { 7 | error: Error = getStacktrace(); 8 | timestamp: Date = new Date(); 9 | 10 | } 11 | 12 | function getStacktraceWithUncaughtError (): Error { 13 | return new Error('STACKTRACE TRACKING'); 14 | } 15 | 16 | function getStacktraceWithCaughtError(): Error { 17 | try { 18 | throw getStacktraceWithUncaughtError(); 19 | } catch (e) { 20 | return e; 21 | } 22 | } 23 | 24 | // Some implementations of exception handling don't create a stack trace if the exception 25 | // isn't thrown, however it's faster not to actually throw the exception. 26 | const error = getStacktraceWithUncaughtError(); 27 | const coughtError = getStacktraceWithCaughtError(); 28 | const getStacktrace = error.stack 29 | ? getStacktraceWithUncaughtError 30 | : (coughtError.stack ? getStacktraceWithCaughtError: getStacktraceWithUncaughtError); 31 | 32 | function getFrames(error: Error): string[] { 33 | return error.stack ? error.stack.split(NEWLINE) : []; 34 | } 35 | 36 | function addErrorStack(lines:string[], error:Error):void { 37 | let trace: string[] = getFrames(error); 38 | for (let i = 0; i < trace.length; i++) { 39 | const frame = trace[i]; 40 | // Filter out the Frames which are part of stack capturing. 41 | if (! (i < IGNORE_FRAMES.length && IGNORE_FRAMES[i] === frame)) { 42 | lines.push(trace[i]); 43 | } 44 | } 45 | } 46 | 47 | function renderLongStackTrace(frames: LongStackTrace[], stack: string): string { 48 | const longTrace: string[] = [stack]; 49 | 50 | if (frames) { 51 | let timestamp = new Date().getTime(); 52 | for (let i = 0; i < frames.length; i++) { 53 | const traceFrames: LongStackTrace = frames[i]; 54 | const lastTime = traceFrames.timestamp; 55 | longTrace.push(`${SEP} Elapsed: ${timestamp - lastTime.getTime()} ms; At: ${lastTime} ${SEP}`); 56 | addErrorStack(longTrace, traceFrames.error); 57 | 58 | timestamp = lastTime.getTime(); 59 | } 60 | } 61 | 62 | return longTrace.join(NEWLINE); 63 | } 64 | 65 | Zone['longStackTraceZoneSpec'] = { 66 | name: 'long-stack-trace', 67 | longStackTraceLimit: 10, // Max number of task to keep the stack trace for. 68 | 69 | onScheduleTask: function(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 70 | task: Task): any 71 | { 72 | const currentTask = Zone.currentTask; 73 | let trace = currentTask && currentTask.data && currentTask.data[creationTrace] || []; 74 | trace = [new LongStackTrace()].concat(trace); 75 | if (trace.length > this.longStackTraceLimit) { 76 | trace.length = this.longStackTraceLimit; 77 | } 78 | if (!task.data) task.data = {}; 79 | task.data[creationTrace] = trace; 80 | return parentZoneDelegate.scheduleTask(targetZone, task); 81 | }, 82 | 83 | onHandleError: function(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 84 | error: any): any 85 | { 86 | const parentTask = Zone.currentTask || error.task; 87 | if (error instanceof Error && parentTask) { 88 | var stackSetSucceded: string|boolean = null; 89 | try { 90 | let descriptor = Object.getOwnPropertyDescriptor(error, 'stack'); 91 | if (descriptor && descriptor.configurable) { 92 | const delegateGet = descriptor.get; 93 | const value = descriptor.value; 94 | descriptor = { 95 | get: function () { 96 | return renderLongStackTrace(parentTask.data && parentTask.data[creationTrace], 97 | delegateGet ? delegateGet.apply(this) : value); 98 | } 99 | }; 100 | Object.defineProperty(error, 'stack', descriptor); 101 | stackSetSucceded = true; 102 | } 103 | } catch (e) { } 104 | var longStack: string = stackSetSucceded ? null : renderLongStackTrace( 105 | parentTask.data && parentTask.data[creationTrace], error.stack); 106 | if (!stackSetSucceded) { 107 | try { 108 | stackSetSucceded = error.stack = longStack; 109 | } catch (e) { } 110 | } 111 | if (!stackSetSucceded) { 112 | try { 113 | stackSetSucceded = (error as any).longStack = longStack; 114 | } catch (e) { } 115 | } 116 | } 117 | return parentZoneDelegate.handleError(targetZone, error); 118 | } 119 | }; 120 | 121 | function captureStackTraces(stackTraces: string[][], count: number): void { 122 | if (count > 0) { 123 | stackTraces.push(getFrames((new LongStackTrace()).error)); 124 | captureStackTraces(stackTraces, count - 1); 125 | } 126 | } 127 | 128 | function computeIgnoreFrames() { 129 | const frames: string[][] = []; 130 | captureStackTraces(frames, 2); 131 | const frames1 = frames[0]; 132 | const frames2 = frames[1]; 133 | for (let i = 0; i < frames1.length; i++) { 134 | const frame1 = frames1[i]; 135 | const frame2 = frames2[i]; 136 | if (frame1 === frame2) { 137 | IGNORE_FRAMES.push(frame1); 138 | } else { 139 | break; 140 | } 141 | } 142 | } 143 | computeIgnoreFrames(); 144 | -------------------------------------------------------------------------------- /zone/lib/zone-spec/proxy.ts: -------------------------------------------------------------------------------- 1 | class ProxyZoneSpec implements ZoneSpec { 2 | name: string = 'ProxyZone'; 3 | 4 | private _delegateSpec: ZoneSpec; 5 | 6 | properties: {[k: string]: any} = {'ProxyZoneSpec': this}; 7 | propertyKeys: string[] = null; 8 | 9 | static get(): ProxyZoneSpec { 10 | return Zone.current.get('ProxyZoneSpec'); 11 | } 12 | 13 | static isLoaded(): boolean { 14 | return ProxyZoneSpec.get() instanceof ProxyZoneSpec; 15 | } 16 | 17 | static assertPresent(): ProxyZoneSpec { 18 | if (!this.isLoaded()) { 19 | throw new Error(`Expected to be running in 'ProxyZone', but it was not found.`); 20 | } 21 | return ProxyZoneSpec.get(); 22 | } 23 | 24 | constructor(private defaultSpecDelegate: ZoneSpec = null) { 25 | this.setDelegate(defaultSpecDelegate); 26 | } 27 | 28 | 29 | setDelegate(delegateSpec: ZoneSpec) { 30 | this._delegateSpec = delegateSpec; 31 | this.propertyKeys && this.propertyKeys.forEach((key) => delete this.properties[key]); 32 | this.propertyKeys = null; 33 | if (delegateSpec && delegateSpec.properties) { 34 | this.propertyKeys = Object.keys(delegateSpec.properties); 35 | this.propertyKeys.forEach((k) => this.properties[k] = delegateSpec.properties[k]); 36 | } 37 | } 38 | 39 | getDelegate() { 40 | return this._delegateSpec; 41 | } 42 | 43 | 44 | resetDelegate() { 45 | this.setDelegate(this.defaultSpecDelegate); 46 | } 47 | 48 | 49 | onFork(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 50 | zoneSpec: ZoneSpec): Zone { 51 | if (this._delegateSpec && this._delegateSpec.onFork) { 52 | return this._delegateSpec.onFork(parentZoneDelegate, currentZone, targetZone, zoneSpec); 53 | } else { 54 | return parentZoneDelegate.fork(targetZone, zoneSpec); 55 | } 56 | } 57 | 58 | 59 | onIntercept(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 60 | delegate: Function, source: string): Function { 61 | if (this._delegateSpec && this._delegateSpec.onIntercept) { 62 | return this._delegateSpec.onIntercept(parentZoneDelegate, currentZone, targetZone, delegate, source); 63 | } else { 64 | return parentZoneDelegate.intercept(targetZone, delegate, source); 65 | } 66 | } 67 | 68 | 69 | onInvoke(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 70 | delegate: Function, applyThis: any, applyArgs: any[], source: string): any { 71 | if (this._delegateSpec && this._delegateSpec.onInvoke) { 72 | return this._delegateSpec.onInvoke(parentZoneDelegate, currentZone, targetZone, delegate, applyThis, applyArgs, source); 73 | } else { 74 | return parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source); 75 | } 76 | } 77 | 78 | onHandleError(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 79 | error: any): boolean { 80 | if (this._delegateSpec && this._delegateSpec.onHandleError) { 81 | return this._delegateSpec.onHandleError(parentZoneDelegate, currentZone, targetZone, error); 82 | } else { 83 | return parentZoneDelegate.handleError(targetZone, error); 84 | } 85 | } 86 | 87 | onScheduleTask(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 88 | task: Task): Task { 89 | if (this._delegateSpec && this._delegateSpec.onScheduleTask) { 90 | return this._delegateSpec.onScheduleTask(parentZoneDelegate, currentZone, targetZone, task); 91 | } else { 92 | return parentZoneDelegate.scheduleTask(targetZone, task); 93 | } 94 | } 95 | 96 | onInvokeTask(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 97 | task: Task, applyThis: any, applyArgs: any): any { 98 | if (this._delegateSpec && this._delegateSpec.onFork) { 99 | return this._delegateSpec.onInvokeTask(parentZoneDelegate, currentZone, targetZone, task, applyThis, applyArgs); 100 | } else { 101 | return parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs); 102 | } 103 | } 104 | 105 | onCancelTask(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 106 | task: Task): any { 107 | if (this._delegateSpec && this._delegateSpec.onCancelTask) { 108 | return this._delegateSpec.onCancelTask(parentZoneDelegate, currentZone, targetZone, task); 109 | } else { 110 | return parentZoneDelegate.cancelTask(targetZone, task); 111 | } 112 | } 113 | 114 | onHasTask(delegate: ZoneDelegate, current: Zone, target: Zone, 115 | hasTaskState: HasTaskState): void { 116 | if (this._delegateSpec && this._delegateSpec.onHasTask) { 117 | this._delegateSpec.onHasTask(delegate, current, target, hasTaskState); 118 | } else { 119 | delegate.hasTask(target, hasTaskState); 120 | } 121 | } 122 | } 123 | 124 | // Export the class so that new instances can be created with proper 125 | // constructor params. 126 | Zone['ProxyZoneSpec'] = ProxyZoneSpec; 127 | -------------------------------------------------------------------------------- /zone/lib/zone-spec/sync-test.ts: -------------------------------------------------------------------------------- 1 | class SyncTestZoneSpec implements ZoneSpec { 2 | runZone = Zone.current; 3 | 4 | constructor(namePrefix: string) { 5 | this.name = 'syncTestZone for ' + namePrefix; 6 | } 7 | 8 | // ZoneSpec implementation below. 9 | 10 | name: string; 11 | 12 | onScheduleTask(delegate: ZoneDelegate, current: Zone, target: Zone, task: Task): Task { 13 | switch (task.type) { 14 | case 'microTask': 15 | case 'macroTask': 16 | throw new Error(`Cannot call ${task.source} from within a sync test.`); 17 | case 'eventTask': 18 | task = delegate.scheduleTask(target, task); 19 | break; 20 | } 21 | return task; 22 | } 23 | } 24 | 25 | // Export the class so that new instances can be created with proper 26 | // constructor params. 27 | Zone['SyncTestZoneSpec'] = SyncTestZoneSpec; 28 | -------------------------------------------------------------------------------- /zone/lib/zone-spec/task-tracking.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A `TaskTrackingZoneSpec` allows one to track all outstanding Tasks. 3 | * 4 | * This is useful in tests. For example to see which tasks are preventing a test from completing 5 | * or an automated way of releasing all of the event listeners at the end of the test. 6 | */ 7 | class TaskTrackingZoneSpec implements ZoneSpec { 8 | name = 'TaskTrackingZone'; 9 | microTasks: Task[] = []; 10 | macroTasks: Task[] = []; 11 | eventTasks: Task[] = []; 12 | properties: {[key: string]: any} = {'TaskTrackingZone': this}; 13 | 14 | static get() { 15 | return Zone.current.get('TaskTrackingZone'); 16 | } 17 | 18 | private getTasksFor(type: string): Task [] { 19 | switch (type) { 20 | case 'microTask': return this.microTasks; 21 | case 'macroTask': return this.macroTasks; 22 | case 'eventTask': return this.eventTasks; 23 | } 24 | throw new Error('Unknown task format: ' + type); 25 | } 26 | 27 | onScheduleTask(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task): Task { 28 | task['creationLocation'] = new Error(`Task '${task.type}' from '${task.source}'.`); 29 | const tasks = this.getTasksFor(task.type); 30 | tasks.push(task); 31 | return parentZoneDelegate.scheduleTask(targetZone, task); 32 | } 33 | 34 | onCancelTask(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task): any { 35 | const tasks = this.getTasksFor(task.type); 36 | for(var i = 0; i < tasks.length; i++) { 37 | if (tasks[i] == task) { 38 | tasks.splice(i, 1); 39 | break; 40 | } 41 | } 42 | return parentZoneDelegate.cancelTask(targetZone, task); 43 | } 44 | 45 | onInvokeTask(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 46 | task: Task, applyThis: any, applyArgs: any): any 47 | { 48 | if (task.type === 'eventTask') return parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs); 49 | const tasks = this.getTasksFor(task.type); 50 | for(var i = 0; i < tasks.length; i++) { 51 | if (tasks[i] == task) { 52 | tasks.splice(i, 1); 53 | break; 54 | } 55 | } 56 | return parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs); 57 | } 58 | 59 | clearEvents() { 60 | while (this.eventTasks.length) { 61 | Zone.current.cancelTask(this.eventTasks[0]); 62 | } 63 | } 64 | } 65 | 66 | // Export the class so that new instances can be created with proper 67 | // constructor params. 68 | Zone['TaskTrackingZoneSpec'] = TaskTrackingZoneSpec; 69 | -------------------------------------------------------------------------------- /zone/lib/zone-spec/wtf.ts: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | interface Wtf { trace: WtfTrace; } 3 | interface WtfScope {}; 4 | interface WtfRange {}; 5 | interface WtfTrace { 6 | events: WtfEvents; 7 | leaveScope(scope: WtfScope, returnValue?: any): void; 8 | beginTimeRange(rangeType: string, action: string): WtfRange; 9 | endTimeRange(range: WtfRange): void; 10 | } 11 | interface WtfEvents { 12 | createScope(signature: string, flags?: any): WtfScopeFn; 13 | createInstance(signature: string, flags?: any): WtfEventFn; 14 | } 15 | 16 | type WtfScopeFn = (...args: any[]) => WtfScope; 17 | type WtfEventFn = (...args: any[]) => any; 18 | 19 | // Detect and setup WTF. 20 | let wtfTrace: WtfTrace = null; 21 | let wtfEvents: WtfEvents = null; 22 | const wtfEnabled: boolean = (function (): boolean { 23 | const wtf: Wtf = global['wtf']; 24 | if (wtf) { 25 | wtfTrace = wtf.trace; 26 | if (wtfTrace) { 27 | wtfEvents = wtfTrace.events; 28 | return true; 29 | } 30 | } 31 | return false; 32 | })(); 33 | 34 | class WtfZoneSpec implements ZoneSpec { 35 | name: string = 'WTF'; 36 | 37 | static forkInstance = wtfEnabled && wtfEvents.createInstance('Zone:fork(ascii zone, ascii newZone)'); 38 | static scheduleInstance: {[key: string]: WtfEventFn} = {}; 39 | static cancelInstance: {[key: string]: WtfEventFn} = {}; 40 | static invokeScope: {[key: string]: WtfEventFn} = {}; 41 | static invokeTaskScope: {[key: string]: WtfEventFn} = {}; 42 | 43 | onFork(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 44 | zoneSpec: ZoneSpec): Zone { 45 | const retValue = parentZoneDelegate.fork(targetZone, zoneSpec); 46 | WtfZoneSpec.forkInstance(zonePathName(targetZone), retValue.name); 47 | return retValue; 48 | } 49 | 50 | onInvoke(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 51 | delegate: Function, applyThis: any, applyArgs: any[], source: string): any { 52 | let scope = WtfZoneSpec.invokeScope[source]; 53 | if (!scope) { 54 | scope = WtfZoneSpec.invokeScope[source] 55 | = wtfEvents.createScope(`Zone:invoke:${source}(ascii zone)`); 56 | } 57 | return wtfTrace.leaveScope(scope(zonePathName(targetZone)), 58 | parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source)); 59 | } 60 | 61 | 62 | onHandleError(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 63 | error: any): boolean { 64 | return parentZoneDelegate.handleError(targetZone, error); 65 | } 66 | 67 | onScheduleTask(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 68 | task: Task): any { 69 | const key = task.type + ':' + task.source; 70 | let instance = WtfZoneSpec.scheduleInstance[key]; 71 | if (!instance) { 72 | instance = WtfZoneSpec.scheduleInstance[key] 73 | = wtfEvents.createInstance(`Zone:schedule:${key}(ascii zone, any data)`); 74 | } 75 | const retValue = parentZoneDelegate.scheduleTask(targetZone, task); 76 | instance(zonePathName(targetZone), shallowObj(task.data, 2)); 77 | return retValue; 78 | } 79 | 80 | 81 | onInvokeTask(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 82 | task: Task, applyThis: any, applyArgs: any[]): any 83 | { 84 | const source = task.source; 85 | let scope = WtfZoneSpec.invokeTaskScope[source]; 86 | if (!scope) { 87 | scope = WtfZoneSpec.invokeTaskScope[source] 88 | = wtfEvents.createScope(`Zone:invokeTask:${source}(ascii zone)`); 89 | } 90 | return wtfTrace.leaveScope(scope(zonePathName(targetZone)), 91 | parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs)); 92 | } 93 | 94 | onCancelTask(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 95 | task: Task): any { 96 | const key = task.source; 97 | let instance = WtfZoneSpec.cancelInstance[key]; 98 | if (!instance) { 99 | instance = WtfZoneSpec.cancelInstance[key] 100 | = wtfEvents.createInstance(`Zone:cancel:${key}(ascii zone, any options)`); 101 | } 102 | const retValue = parentZoneDelegate.cancelTask(targetZone, task); 103 | instance(zonePathName(targetZone), shallowObj(task.data, 2)); 104 | return retValue; 105 | }; 106 | } 107 | 108 | function shallowObj(obj: any, depth: number): any { 109 | if (!depth) return null; 110 | const out = {}; 111 | for(const key in obj) { 112 | if (obj.hasOwnProperty(key)) { 113 | let value = obj[key]; 114 | switch (typeof value) { 115 | case 'object': 116 | const name = value && value.constructor && (value.constructor).name; 117 | value = name == (Object).name ? shallowObj(value, depth - 1) : name; 118 | break; 119 | case 'function': 120 | value = value.name || undefined; 121 | break; 122 | } 123 | out[key] = value; 124 | } 125 | } 126 | return out; 127 | } 128 | 129 | function zonePathName(zone: Zone) { 130 | let name: string = zone.name; 131 | zone = zone.parent; 132 | while(zone != null) { 133 | name = zone.name + '::' + name; 134 | zone = zone.parent; 135 | } 136 | return name; 137 | } 138 | 139 | Zone['wtfZoneSpec'] = !wtfEnabled ? null : new WtfZoneSpec(); 140 | })(typeof window === 'object' && window || typeof self === 'object' && self || global); 141 | -------------------------------------------------------------------------------- /zone/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_args": [ 3 | [ 4 | { 5 | "raw": "zone.js@^0.6.23", 6 | "scope": null, 7 | "escapedName": "zone.js", 8 | "name": "zone.js", 9 | "rawSpec": "^0.6.23", 10 | "spec": ">=0.6.23 <0.7.0", 11 | "type": "range" 12 | }, 13 | "C:\\xampp\\htdocs\\laravel5.3_angular2" 14 | ] 15 | ], 16 | "_from": "zone.js@>=0.6.23 <0.7.0", 17 | "_id": "zone.js@0.6.25", 18 | "_inCache": true, 19 | "_installable": true, 20 | "_location": "/zone.js", 21 | "_nodeVersion": "5.11.0", 22 | "_npmOperationalInternal": { 23 | "host": "packages-12-west.internal.npmjs.com", 24 | "tmp": "tmp/zone.js-0.6.25.tgz_1474330836843_0.8244900833815336" 25 | }, 26 | "_npmUser": { 27 | "name": "angularcore", 28 | "email": "angular-core+npm@google.com" 29 | }, 30 | "_npmVersion": "3.8.6", 31 | "_phantomChildren": {}, 32 | "_requested": { 33 | "raw": "zone.js@^0.6.23", 34 | "scope": null, 35 | "escapedName": "zone.js", 36 | "name": "zone.js", 37 | "rawSpec": "^0.6.23", 38 | "spec": ">=0.6.23 <0.7.0", 39 | "type": "range" 40 | }, 41 | "_requiredBy": [ 42 | "/" 43 | ], 44 | "_resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.6.25.tgz", 45 | "_shasum": "a41b57fe8c0ff3b8f077de3b193a86a234420301", 46 | "_shrinkwrap": null, 47 | "_spec": "zone.js@^0.6.23", 48 | "_where": "C:\\xampp\\htdocs\\laravel5.3_angular2", 49 | "author": { 50 | "name": "Brian Ford" 51 | }, 52 | "browser": "dist/zone.js", 53 | "bugs": { 54 | "url": "https://github.com/angular/zone.js/issues" 55 | }, 56 | "dependencies": {}, 57 | "description": "Zones for JavaScript", 58 | "devDependencies": { 59 | "@types/jasmine": "^2.2.33", 60 | "@types/node": "^6.0.38", 61 | "@types/systemjs": "^0.19.30", 62 | "concurrently": "^2.2.0", 63 | "es6-promise": "^3.0.2", 64 | "gulp": "^3.8.11", 65 | "gulp-rename": "^1.2.2", 66 | "gulp-rollup": "^2.3.0", 67 | "gulp-tsc": "^1.1.4", 68 | "gulp-uglify": "^1.2.0", 69 | "gulp-util": "^3.0.7", 70 | "jasmine": "^2.4.1", 71 | "jasmine-core": "^2.2.0", 72 | "karma": "^0.13.14", 73 | "karma-chrome-launcher": "^0.2.1", 74 | "karma-firefox-launcher": "^0.1.4", 75 | "karma-jasmine": "^0.3.6", 76 | "karma-safari-launcher": "^0.1.1", 77 | "karma-sauce-launcher": "^0.2.10", 78 | "karma-sourcemap-loader": "^0.3.6", 79 | "nodejs-websocket": "^1.2.0", 80 | "pump": "^1.0.1", 81 | "systemjs": "^0.19.37", 82 | "ts-loader": "^0.6.0", 83 | "typescript": "^2.0.2" 84 | }, 85 | "directories": { 86 | "lib": "lib", 87 | "test": "test" 88 | }, 89 | "dist": { 90 | "shasum": "a41b57fe8c0ff3b8f077de3b193a86a234420301", 91 | "tarball": "https://registry.npmjs.org/zone.js/-/zone.js-0.6.25.tgz" 92 | }, 93 | "files": [ 94 | "lib", 95 | "dist" 96 | ], 97 | "gitHead": "0c3ce2e170ffc2b3b2d41dc8d0b4820391606a3b", 98 | "homepage": "https://github.com/angular/zone.js#readme", 99 | "license": "MIT", 100 | "main": "dist/zone-node.js", 101 | "maintainers": [ 102 | { 103 | "name": "angularcore", 104 | "email": "angular-core+npm@google.com" 105 | }, 106 | { 107 | "name": "btford", 108 | "email": "briantford@gmail.com" 109 | } 110 | ], 111 | "name": "zone.js", 112 | "optionalDependencies": {}, 113 | "readme": "ERROR: No README data found!", 114 | "repository": { 115 | "type": "git", 116 | "url": "git://github.com/angular/zone.js.git" 117 | }, 118 | "scripts": { 119 | "prepublish": "tsc && gulp build", 120 | "serve": "python -m SimpleHTTPServer 8000", 121 | "test": "npm run tsc && concurrently \"npm run tsc:w\" \"npm run ws-server\" \"karma start karma.conf.js\"", 122 | "test-node": "gulp test/node", 123 | "tsc": "tsc", 124 | "tsc:w": "tsc -w", 125 | "ws-server": "node ./test/ws-server.js" 126 | }, 127 | "typings": "dist/zone.js.d.ts", 128 | "version": "0.6.25" 129 | } 130 | --------------------------------------------------------------------------------