Skip to content

Commit 9d1ce48

Browse files
authored
Merge pull request #2728 from angular-fullstack/rc3
Various tweaks towards final release
2 parents a3f392c + dd0faa6 commit 9d1ce48

18 files changed

+331
-401
lines changed

Diff for: templates/app/.eslintrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@
224224

225225
//ECMAScript 6
226226
"arrow-body-style": [2, "as-needed"], //require braces in arrow function body
227-
"arrow-parens": [2, "as-needed"], //require parens in arrow function arguments
227+
"arrow-parens": 0, //require parens in arrow function arguments
228228
"arrow-spacing": 2, //require space before/after arrow function's arrow
229229
"constructor-super": 2, //verify calls of super() in constructors
230230
"generator-star-spacing": 0, //enforce spacing around the * in generator functions

Diff for: templates/app/_package.json

+20-20
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"sequelize": "^3.23.6",
3737
"sqlite3": "~3.1.1",
3838
"connect-session-sequelize": "^4.1.0",<% } %><% if(filters.auth) { %>
39-
"jsonwebtoken": "^7.0.0",
39+
"jsonwebtoken": "^8.3.0",
4040
"express-jwt": "^5.0.0",
4141
"passport": "~0.4.0",
4242
"passport-local": "^1.0.0",<% } %><% if(filters.facebookAuth) { %>
@@ -52,16 +52,15 @@
5252
<%# CLIENT %>
5353
"@angularclass/hmr-loader": "^3.0.4",
5454
"reflect-metadata": "^0.1.3",
55-
"rxjs": "^5.5.2",
55+
"rxjs": "^6.0.0",
5656
"zone.js": "^0.8.12",
57-
"@angular/common": "^5.0.1",
58-
"@angular/compiler": "^5.0.1",
59-
"@angular/core": "^5.0.1",
60-
"@angular/forms": "^5.0.1",
61-
"@angular/http": "^5.0.1",
62-
"@angular/platform-browser": "^5.0.1",
63-
"@angular/platform-browser-dynamic": "^5.0.1",
64-
"@angular/router": "^5.0.1",
57+
"@angular/common": "^6.0.4",
58+
"@angular/compiler": "^6.0.4",
59+
"@angular/core": "^6.0.4",
60+
"@angular/forms": "^6.0.4",
61+
"@angular/platform-browser": "^6.0.4",
62+
"@angular/platform-browser-dynamic": "^6.0.4",
63+
"@angular/router": "^6.0.4",
6564
<%#"@angular/material": "5.0.0-rc0",%>
6665
"@angularclass/hmr": "^2.1.3",
6766
<%_ if(filters.ts) { -%>
@@ -80,7 +79,7 @@
8079
"@types/selenium-webdriver": "^3.0.3",
8180
"@types/webpack": "^3.0.10",
8281
<%_ } -%>
83-
"angular2-jwt": "^0.2.3",
82+
"@auth0/angular-jwt": "^2.0.0",
8483
<% if(filters.auth) { %>
8584
"angular-validation-match": "^1.9.0",<% } %>
8685
<% if(filters.uirouter) { %>
@@ -89,7 +88,7 @@
8988
<% if(filters.bootstrap) { %>
9089
"bootstrap": "~3.3.7",
9190
<% if(filters.uibootstrap) { %>
92-
"ngx-bootstrap": "~1.6.3",<% } %>
91+
"ngx-bootstrap": "^3.0.0",<% } %>
9392
<% if(filters.sass) { %>
9493
"bootstrap-sass": "~3.3.7",<% } %>
9594
<% if(filters.stylus) { %>
@@ -106,7 +105,7 @@
106105
<%# END CLIENT %>
107106

108107
"autoprefixer": "^7.1.3",
109-
"babel-eslint": "^7.2.3",
108+
"babel-eslint": "^8.2.3",
110109
"babel-register": "^6.16.0",
111110
"bs-fullscreen-message": "^1.0.0",
112111
<%_ if(filters.flow) { -%>
@@ -117,7 +116,7 @@
117116
"babel-plugin-istanbul": "^4.1.4",
118117
"babel-preset-env": "^1.6.1",
119118
"cross-env": "^5.1.1",
120-
"eslint": "^2.12.0",
119+
"eslint": "^4.19.1",
121120
"del": "^3.0.0",
122121
"gulp": "^3.9.1",
123122
"gulp-babel": "^7.0.0",<% if(filters.ts) { %>
@@ -148,11 +147,12 @@
148147
"run-sequence": "^2.1.0",
149148
"lazypipe": "^1.0.1",
150149
<%# WEBPACK %>
151-
"webpack": "^3.5.5",
152-
"webpack-dev-server": "^2.4.2",
153-
"extract-text-webpack-plugin": "3.0.0",
154-
"html-webpack-plugin": "^2.24.1",
155-
"html-webpack-harddisk-plugin": "~0.1.0",
150+
"webpack": "^4.12.0",
151+
"webpack-cli": "^3.0.6",
152+
"webpack-dev-server": "^3.1.4",
153+
"extract-text-webpack-plugin": "4.0.0-beta.0",
154+
"html-webpack-plugin": "^3.2.0",
155+
"html-webpack-harddisk-plugin": "~0.2.0",
156156
<%_ if(filters.pug) { _%>
157157
"pug-html-loader": "^1.1.5",<% } %>
158158
"typescript": "~2.6.1",
@@ -175,7 +175,7 @@
175175
<%_ if(filters.stylus) { _%>
176176
"stylus": "^0.54.5",
177177
"stylus-loader": "^3.0.1",<% } %>
178-
"karma-webpack": "^2.0.3",
178+
"karma-webpack": "4.0.0-beta.0",
179179
"to-string-loader": "^1.1.5",
180180
<%# END WEBPACK %>
181181
"through2": "^2.0.1",

Diff for: templates/app/client/app/app.module.js

+12-40
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,9 @@
11
import {
22
NgModule,
3-
Injectable,
4-
ApplicationRef,<% if(filters.ts || filters.flow) { %>
5-
Provider,<% } %>
3+
ApplicationRef,
64
} from '@angular/core';
75
import { BrowserModule } from '@angular/platform-browser';
8-
import {
9-
Http,
10-
HttpModule,
11-
BaseRequestOptions,<% if(filters.ts || filters.flow) { %>
12-
RequestOptions,
13-
RequestOptionsArgs,<% } %>
14-
} from '@angular/http';
6+
import { HttpClientModule } from '@angular/common/http';
157
import {
168
removeNgStyles,
179
createNewHosts,
@@ -21,40 +13,16 @@ import {
2113
import { UIRouterModule } from 'ui-router-ng2';<% } %>
2214
<%_ if (filters.ngroute) { -%>
2315
import { RouterModule, Routes } from '@angular/router';<% } %>
24-
import { AuthHttp, AuthConfig } from 'angular2-jwt';
2516

2617
import { AppComponent } from './app.component';
2718
import { MainModule } from './main/main.module';
2819
import { DirectivesModule } from '../components/directives.module';<% if(filters.auth) { %>
20+
import { JwtModule } from '@auth0/angular-jwt';
2921
import { AccountModule } from './account/account.module';
3022
import { AdminModule } from './admin/admin.module';<% } %>
3123

32-
import constants from './app.constants';
33-
34-
export function getAuthHttp(http) {
35-
return new AuthHttp(new AuthConfig({
36-
noJwtError: true,
37-
globalHeaders: [{'Accept': 'application/json'}],
38-
tokenGetter: (() => localStorage.getItem('id_token')),
39-
}), http);
40-
}
41-
42-
let providers: Provider[] = [{
43-
provide: AuthHttp,
44-
useFactory: getAuthHttp,
45-
deps: [Http]
46-
}];
47-
48-
if(constants.env === 'development') {
49-
@Injectable()
50-
class HttpOptions extends BaseRequestOptions {
51-
merge(options: RequestOptionsArgs): RequestOptions {
52-
options.url = `http://localhost:9000${options.url}`;
53-
return super.merge(options);
54-
}
55-
}
56-
57-
providers.push({ provide: RequestOptions, useClass: HttpOptions });
24+
export function tokenGetter() {
25+
return localStorage.getItem('id_token');
5826
}
5927

6028
const appRoutes: Routes = [{ path: '',
@@ -63,10 +31,14 @@ const appRoutes: Routes = [{ path: '',
6331
}];
6432

6533
@NgModule({
66-
providers,
6734
imports: [
6835
BrowserModule,
69-
HttpModule,
36+
HttpClientModule,<% if(filters.auth) { %>
37+
JwtModule.forRoot({
38+
config: {
39+
tokenGetter,
40+
}
41+
}),<% } %>
7042
<%_ if (filters.uirouter) { -%>
7143
UIRouterModule.forRoot(),<% } %>
7244
<%_ if (filters.ngroute) { -%>
@@ -79,7 +51,7 @@ const appRoutes: Routes = [{ path: '',
7951
declarations: [
8052
AppComponent,
8153
],
82-
bootstrap: [AppComponent]
54+
bootstrap: [AppComponent],
8355
})
8456
export class AppModule {
8557
static parameters = [ApplicationRef];

Diff for: templates/app/client/app/main/main.component.js

+20-21
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,39 @@
11
import { Component, OnInit<% if(filters.ws) { %>, OnDestroy<% } %> } from '@angular/core';
2-
import { Http } from '@angular/http';
3-
import { Observable } from 'rxjs/Observable';
4-
import 'rxjs/add/operator/map';<% if(filters.ws) { %>
5-
import { SocketService } from '../../components/socket/socket.service';<% } %>
2+
import { HttpClient } from '@angular/common/http';<% if(filters.ws) { %>
3+
import { SocketService } from '../../components/socket/socket.service';<% } %><% if(filters.ts) { %>
4+
5+
interface Thing {
6+
name: string;
7+
info?: string;
8+
}<% } %><% if(filters.flow) { %>
9+
type Thing = {
10+
name: string;
11+
info?: string;
12+
};<% } %>
613

714
@Component({
815
selector: 'main',
916
template: require('./main.<%=templateExt%>'),
1017
styles: [require('./main.<%=styleExt%>')],
1118
})
1219
export class MainComponent implements OnInit<% if(filters.ws) { %>, OnDestroy<% } %> {
13-
Http;
1420
<%_ if(filters.ws) { -%>
1521
SocketService;<% } %>
16-
awesomeThings = [];
22+
awesomeThings: Thing[] = [];
1723
<%_ if(filters.models) { -%>
1824
newThing = '';<% } %>
1925

20-
static parameters = [Http<% if(filters.ws) { %>, SocketService<% } %>];
21-
constructor(<%= private() %>http: Http<% if(filters.ws) { %>, <%= private() %>socketService: SocketService<% } %>) {
22-
this.Http = http;
26+
static parameters = [HttpClient<% if(filters.ws) { %>, SocketService<% } %>];
27+
constructor(<%= private() %>http: HttpClient<% if(filters.ws) { %>, <%= private() %>socketService: SocketService<% } %>) {
28+
this.http = http;
2329
<%_ if(filters.ws) { -%>
2430
this.SocketService = socketService;<% } %>
2531
}
2632

2733
ngOnInit() {
28-
return this.Http.get('/api/things')
29-
.map(res => res.json())
30-
// .catch(err => Observable.throw(err.json().error || 'Server error'))
31-
.subscribe(things => {
32-
this.awesomeThings = things;
33-
<%_ if(filters.ws) { -%>
34+
return this.http.get('/api/things')
35+
.subscribe((things: Thing[]) => {
36+
this.awesomeThings = things;<% if(filters.ws) { %>
3437
this.SocketService.syncUpdates('thing', this.awesomeThings);<% } %>
3538
});
3639
}<% if (filters.models) { %>
@@ -45,19 +48,15 @@ export class MainComponent implements OnInit<% if(filters.ws) { %>, OnDestroy<%
4548
let text = this.newThing;
4649
this.newThing = '';
4750

48-
return this.Http.post('/api/things', { name: text })
49-
.map(res => res.json())
50-
.catch(err => Observable.throw(err.json().error || 'Server error'))
51+
return this.http.post('/api/things', { name: text })
5152
.subscribe(thing => {
5253
console.log('Added Thing:', thing);
5354
});
5455
}
5556
}
5657

5758
deleteThing(thing) {
58-
return this.Http.delete(`/api/things/${thing._id}`)
59-
.map(res => res.json())
60-
.catch(err => Observable.throw(err.json().error || 'Server error'))
59+
return this.http.delete(`/api/things/${thing._id}`)
6160
.subscribe(() => {
6261
console.log('Deleted Thing');
6362
});

Diff for: templates/app/client/app/main/main.component.spec.js

+24-35
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,7 @@ import {
55
inject,
66
TestBed,
77
} from '@angular/core/testing';
8-
import {
9-
BaseRequestOptions,
10-
ConnectionBackend,
11-
Http,
12-
HttpModule,
13-
Response,
14-
ResponseOptions,
15-
} from '@angular/http';
16-
import { MockBackend } from '@angular/http/testing';
17-
<%_ if(filters.mocha && filters.expect) { -%>
8+
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';<% if(filters.mocha && filters.expect) { %>
189
import { expect } from 'chai';<% } %><% if(filters.uibootstrap) { %>
1910
import { TooltipModule } from 'ngx-bootstrap';<% } %>
2011
import { FormsModule } from '@angular/forms';<% if(filters.ws) { %>
@@ -25,51 +16,49 @@ import { MainComponent } from './main.component';
2516
describe('Component: MainComponent', function() {
2617
let comp: MainComponent;
2718
let fixture: ComponentFixture<MainComponent>;
19+
let httpTestingController: HttpTestingController;
20+
const mockThings = ['HTML5 Boilerplate', 'AngularJS', 'Karma', 'Express'];
2821

2922
beforeEach(async(() => {
3023
TestBed.configureTestingModule({
3124
imports: [
3225
FormsModule,<% if(filters.uibootstrap) { %>
3326
TooltipModule.forRoot(),<% } %>
34-
HttpModule,
27+
HttpClientTestingModule,
3528
],
36-
declarations: [ MainComponent ], // declare the test component
29+
declarations: [ MainComponent ], // declare the test component<% if(filters.ws) { %>
3730
providers: [
38-
BaseRequestOptions,
39-
MockBackend,
40-
{
41-
provide: Http,
42-
useFactory: (backend: ConnectionBackend, defaultOptions: BaseRequestOptions) => {
43-
return new Http(backend, defaultOptions);
44-
},
45-
deps: [MockBackend, BaseRequestOptions]
46-
},<% if(filters.ws) { %>
47-
{ provide: SocketService, useClass: SocketServiceStub },<% } %>
48-
],
31+
{ provide: SocketService, useClass: SocketServiceStub },
32+
],<% } %>
4933
}).compileComponents();
50-
}));
5134

52-
beforeEach(async(inject([MockBackend], (mockBackend) => {
53-
mockBackend.connections.subscribe(conn => {
54-
conn.mockRespond(new Response(new ResponseOptions({
55-
body: JSON.stringify(['HTML5 Boilerplate', 'AngularJS', 'Karma', 'Express'])
56-
})));
57-
});
58-
})));
35+
httpTestingController = TestBed.get(HttpTestingController);
36+
}));
5937

6038
beforeEach(async(() => {
6139
fixture = TestBed.createComponent(MainComponent);
6240
// MainComponent test instance
6341
comp = fixture.componentInstance;
6442

6543
/**
66-
* Trigger initial data binding.
44+
* Trigger initial data binding and run lifecycle hooks
6745
*/
6846
fixture.detectChanges();
6947
}));
7048

71-
it('should attach a list of things to the controller', () => {<% if(filters.jasmine) { %>
72-
expect(comp.awesomeThings.length).toEqual(4);<% } else if(filters.mocha) { %>
73-
<%= expect() %>comp.awesomeThings.length<%= to() %>.equal(4);<% } %>
49+
it('should attach a list of things to the controller', () => {
50+
// `GET /api/things` should be made once
51+
const req = httpTestingController.expectOne('/api/things');<% if(filters.jasmine) { %>
52+
expect(req.request.method).toEqual('GET');<% } else if(filters.mocha) { %>
53+
<%= expect() %>req.request.method<%= to() %>.equal('GET');<% } %>
54+
55+
// Respond with mock data
56+
req.flush(mockThings);
57+
58+
// assert that there are no outstanding requests
59+
httpTestingController.verify();
60+
61+
<%_ if(filters.jasmine) { -%>expect(comp.awesomeThings).toEqual(mockThings);<%_ } else if(filters.mocha) { -%>
62+
<%= expect() %>comp.awesomeThings<%= to() %>.equal(mockThings);<% } %>
7463
});
7564
});

Diff for: templates/app/client/app/polyfills.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
import 'core-js/es6';
2-
import 'core-js/es7/reflect';
1+
// Enable certain polyfills depending on which browsers you need to support
2+
// import 'core-js/es6';
3+
// import 'core-js/es7/reflect';
4+
35
import 'zone.js/dist/zone';
46

57
<%_ if(filters.ts) { -%>

0 commit comments

Comments
 (0)