Skip to content

Commit 33488cc

Browse files
author
William Welling
committed
extend environment and use injected app config
1 parent 71f5b46 commit 33488cc

25 files changed

+742
-1203
lines changed

.github/workflows/build.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ jobs:
7373
run: yarn run lint
7474

7575
- name: Run build
76-
run: yarn run build:ssr:ci
76+
run: yarn run build:prod
7777

7878
- name: Run specs (unit tests)
7979
run: yarn run test:headless

angular.json

-26
Original file line numberDiff line numberDiff line change
@@ -94,22 +94,6 @@
9494
"maximumError": "300kb"
9595
}
9696
]
97-
},
98-
"ci": {
99-
"fileReplacements": [
100-
{
101-
"replace": "src/environments/environment.ts",
102-
"with": "src/environments/environment.ci.ts"
103-
}
104-
],
105-
"optimization": true,
106-
"outputHashing": "all",
107-
"extractCss": true,
108-
"namedChunks": false,
109-
"aot": true,
110-
"extractLicenses": true,
111-
"vendorChunk": false,
112-
"buildOptimizer": true
11397
}
11498
}
11599
},
@@ -222,16 +206,6 @@
222206
"with": "src/environments/environment.prod.ts"
223207
}
224208
]
225-
},
226-
"ci": {
227-
"sourceMap": false,
228-
"optimization": true,
229-
"fileReplacements": [
230-
{
231-
"replace": "src/environments/environment.ts",
232-
"with": "src/environments/environment.ci.ts"
233-
}
234-
]
235209
}
236210
}
237211
},

nodemon.json

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"watch": [
3+
"config"
4+
],
5+
"ext": "json"
6+
}

package.json

+9-7
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,25 @@
33
"version": "0.0.0",
44
"scripts": {
55
"ng": "ng",
6+
"config:watch": "nodemon",
67
"test:rest": "ts-node --project ./tsconfig.ts-node.json scripts/test-rest.ts",
78
"start": "yarn run start:prod",
8-
"serve": "ts-node --project ./tsconfig.ts-node.json scripts/serve.ts",
9-
"start:dev": "yarn run serve",
9+
"start:dev": "nodemon --exec \"yarn run serve\"",
1010
"start:prod": "yarn run build:prod && yarn run serve:ssr",
1111
"start:mirador:prod": "yarn run build:mirador && yarn run start:prod",
12+
"serve": "ts-node --project ./tsconfig.ts-node.json scripts/serve.ts",
13+
"serve:ssr": "node dist/server/main",
1214
"analyze": "webpack-bundle-analyzer dist/browser/stats.json",
1315
"build": "ng build",
1416
"build:stats": "ng build --stats-json",
1517
"build:prod": "yarn run build:ssr",
1618
"build:ssr": "ng build --configuration production && ng run dspace-angular:server:production",
17-
"build:ssr:ci": "ng build --configuration ci && ng run dspace-angular:server:ci",
18-
"test": "ng test --sourceMap=true --watch=true --configuration test",
19+
"test": "ng test --sourceMap=true --watch=false --configuration test",
20+
"test:watch": "nodemon --exec \"ng test --sourceMap=true --watch=true --configuration test\"",
1921
"test:headless": "ng test --sourceMap=true --watch=false --configuration test --browsers=ChromeHeadless --code-coverage",
2022
"lint": "ng lint",
2123
"lint-fix": "ng lint --fix=true",
2224
"e2e": "ng e2e",
23-
"serve:ssr": "node dist/server/main",
2425
"clean:dev:config": "rimraf src/assets/appConfig.json",
2526
"clean:coverage": "rimraf coverage",
2627
"clean:dist": "rimraf dist",
@@ -86,8 +87,8 @@
8687
"file-saver": "^2.0.5",
8788
"filesize": "^6.1.0",
8889
"font-awesome": "4.7.0",
89-
"https": "1.0.0",
9090
"http-proxy-middleware": "^1.0.5",
91+
"https": "1.0.0",
9192
"js-cookie": "2.2.1",
9293
"json5": "^2.1.3",
9394
"jsonschema": "1.4.0",
@@ -162,6 +163,7 @@
162163
"karma-jasmine": "~4.0.0",
163164
"karma-jasmine-html-reporter": "^1.5.0",
164165
"karma-mocha-reporter": "2.2.5",
166+
"nodemon": "^2.0.15",
165167
"optimize-css-assets-webpack-plugin": "^5.0.4",
166168
"postcss-apply": "0.11.0",
167169
"postcss-import": "^12.0.1",
@@ -186,4 +188,4 @@
186188
"webpack-cli": "^4.2.0",
187189
"webpack-dev-server": "^4.5.0"
188190
}
189-
}
191+
}

scripts/serve.ts

+6-8
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
import * as child from 'child_process';
22

3-
import { environment } from '../src/environments/environment';
3+
import { AppConfig } from '../src/config/app-config.interface';
4+
import { buildAppConfig } from '../src/config/config.server';
45

5-
// import { AppConfig } from '../src/config/app-config.interface';
6-
// import { buildAppConfig } from '../src/config/config.server';
7-
8-
// const appConfig: AppConfig = buildAppConfig();
6+
const appConfig: AppConfig = buildAppConfig();
97

108
/**
11-
* Calls `ng serve` with the following arguments configured for the UI in the environment: host, port, nameSpace, ssl
9+
* Calls `ng serve` with the following arguments configured for the UI in the app config: host, port, nameSpace, ssl
1210
*/
1311
child.spawn(
14-
`ng serve --host ${environment.ui.host} --port ${environment.ui.port} --serve-path ${environment.ui.nameSpace} --ssl ${environment.ui.ssl}`,
15-
{ stdio:'inherit', shell: true }
12+
`ng serve --host ${appConfig.ui.host} --port ${appConfig.ui.port} --serve-path ${appConfig.ui.nameSpace} --ssl ${appConfig.ui.ssl}`,
13+
{ stdio: 'inherit', shell: true }
1614
);

scripts/test-rest.ts

+7-9
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,25 @@
11
import * as http from 'http';
22
import * as https from 'https';
33

4-
import { environment } from '../src/environments/environment';
5-
6-
// import { AppConfig } from '../src/config/app-config.interface';
7-
// import { buildAppConfig } from '../src/config/config.server';
4+
import { AppConfig } from '../src/config/app-config.interface';
5+
import { buildAppConfig } from '../src/config/config.server';
86

9-
// const appConfig: AppConfig = buildAppConfig();
7+
const appConfig: AppConfig = buildAppConfig();
108

119
/**
12-
* Script to test the connection with the configured REST API (in the 'rest' settings of your environment.*.ts)
10+
* Script to test the connection with the configured REST API (in the 'rest' settings of your appConfig.*.json)
1311
*
1412
* This script is useful to test for any Node.js connection issues with your REST API.
1513
*
1614
* Usage (see package.json): yarn test:rest
1715
*/
1816

1917
// Get root URL of configured REST API
20-
const restUrl = environment.rest.baseUrl + '/api';
18+
const restUrl = appConfig.rest.baseUrl + '/api';
2119
console.log(`...Testing connection to REST API at ${restUrl}...\n`);
2220

2321
// If SSL enabled, test via HTTPS, else via HTTP
24-
if (environment.rest.ssl) {
22+
if (appConfig.rest.ssl) {
2523
const req = https.request(restUrl, (res) => {
2624
console.log(`RESPONSE: ${res.statusCode} ${res.statusMessage} \n`);
2725
res.on('data', (data) => {
@@ -61,7 +59,7 @@ function checkJSONResponse(responseData: any): any {
6159
console.log(`\t"dspaceVersion" = ${parsedData.dspaceVersion}`);
6260
console.log(`\t"dspaceUI" = ${parsedData.dspaceUI}`);
6361
console.log(`\t"dspaceServer" = ${parsedData.dspaceServer}`);
64-
console.log(`\t"dspaceServer" property matches UI's "rest" config? ${(parsedData.dspaceServer === environment.rest.baseUrl)}`);
62+
console.log(`\t"dspaceServer" property matches UI's "rest" config? ${(parsedData.dspaceServer === appConfig.rest.baseUrl)}`);
6563
// Check for "authn" and "sites" in "_links" section as they should always exist (even if no data)!
6664
const linksFound: string[] = Object.keys(parsedData._links);
6765
console.log(`\tDoes "/api" endpoint have HAL links ("_links" section)? ${linksFound.includes('authn') && linksFound.includes('sites')}`);

server.ts

+19-12
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,33 @@ import 'zone.js/dist/zone-node';
1919
import 'reflect-metadata';
2020
import 'rxjs';
2121

22-
import * as fs from 'fs';
2322
import * as pem from 'pem';
2423
import * as https from 'https';
2524
import * as morgan from 'morgan';
2625
import * as express from 'express';
2726
import * as bodyParser from 'body-parser';
2827
import * as compression from 'compression';
28+
29+
import { existsSync, readFileSync } from 'fs';
2930
import { join } from 'path';
3031

32+
import { APP_BASE_HREF } from '@angular/common';
3133
import { enableProdMode } from '@angular/core';
32-
import { existsSync } from 'fs';
34+
3335
import { ngExpressEngine } from '@nguniversal/express-engine';
3436
import { REQUEST, RESPONSE } from '@nguniversal/express-engine/tokens';
37+
3538
import { environment } from './src/environments/environment';
3639
import { createProxyMiddleware } from 'http-proxy-middleware';
3740
import { hasValue, hasNoValue } from './src/app/shared/empty.util';
38-
import { APP_BASE_HREF } from '@angular/common';
41+
3942
import { UIServerConfig } from './src/config/ui-server-config.interface';
4043

4144
import { ServerAppModule } from './src/main.server';
4245

43-
// import { buildAppConfig } from './src/config/config.server';
44-
// import { AppConfig, APP_CONFIG } from './src/config/app-config.interface';
46+
import { buildAppConfig } from './src/config/config.server';
47+
import { AppConfig, APP_CONFIG } from './src/config/app-config.interface';
48+
import { extendEnvironmentWithAppConfig } from './src/config/config.util';
4549

4650
/*
4751
* Set path for the browser application's dist folder
@@ -54,7 +58,10 @@ const indexHtml = existsSync(join(DIST_FOLDER, 'index.html')) ? 'index.html' : '
5458

5559
const cookieParser = require('cookie-parser');
5660

57-
// const appConfig: AppConfig = buildAppConfig(join(DIST_FOLDER, 'assets/appConfig.json'));
61+
const appConfig: AppConfig = buildAppConfig(join(DIST_FOLDER, 'assets/appConfig.json'));
62+
63+
// extend environment with app config for server
64+
extendEnvironmentWithAppConfig(environment, appConfig);
5865

5966
// The Express app is exported so that it can be used by serverless Functions.
6067
export function app() {
@@ -105,10 +112,10 @@ export function app() {
105112
provide: RESPONSE,
106113
useValue: (options as any).req.res,
107114
},
108-
// {
109-
// provide: APP_CONFIG,
110-
// useValue: appConfig
111-
// }
115+
{
116+
provide: APP_CONFIG,
117+
useValue: environment
118+
}
112119
]
113120
})(_, (options as any), callback)
114121
);
@@ -246,14 +253,14 @@ function start() {
246253
if (environment.ui.ssl) {
247254
let serviceKey;
248255
try {
249-
serviceKey = fs.readFileSync('./config/ssl/key.pem');
256+
serviceKey = readFileSync('./config/ssl/key.pem');
250257
} catch (e) {
251258
console.warn('Service key not found at ./config/ssl/key.pem');
252259
}
253260

254261
let certificate;
255262
try {
256-
certificate = fs.readFileSync('./config/ssl/cert.pem');
263+
certificate = readFileSync('./config/ssl/cert.pem');
257264
} catch (e) {
258265
console.warn('Certificate not found at ./config/ssl/key.pem');
259266
}

src/app/app.component.spec.ts

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import { GoogleAnalyticsService } from './statistics/google-analytics.service';
3636
import { ThemeService } from './shared/theme-support/theme.service';
3737
import { getMockThemeService } from './shared/mocks/theme-service.mock';
3838
import { BreadcrumbsService } from './breadcrumbs/breadcrumbs.service';
39+
import { APP_CONFIG } from '../config/app-config.interface';
40+
import { environment } from '../environments/environment';
3941

4042
let comp: AppComponent;
4143
let fixture: ComponentFixture<AppComponent>;
@@ -83,6 +85,7 @@ describe('App component', () => {
8385
{ provide: LocaleService, useValue: getMockLocaleService() },
8486
{ provide: ThemeService, useValue: getMockThemeService() },
8587
{ provide: BreadcrumbsService, useValue: breadcrumbsServiceSpy },
88+
{ provide: APP_CONFIG, useValue: environment },
8689
provideMockStore({ initialState }),
8790
AppComponent,
8891
RouteService

src/app/app.component.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
Router,
1919
} from '@angular/router';
2020

21+
import { isEqual } from 'lodash';
2122
import { BehaviorSubject, Observable, of } from 'rxjs';
2223
import { select, Store } from '@ngrx/store';
2324
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
@@ -46,6 +47,7 @@ import { BASE_THEME_NAME } from './shared/theme-support/theme.constants';
4647
import { BreadcrumbsService } from './breadcrumbs/breadcrumbs.service';
4748
import { IdleModalComponent } from './shared/idle-modal/idle-modal.component';
4849
import { getDefaultThemeConfig } from '../config/config.util';
50+
import { AppConfig, APP_CONFIG } from 'src/config/app-config.interface';
4951

5052
@Component({
5153
selector: 'ds-app',
@@ -59,7 +61,7 @@ export class AppComponent implements OnInit, AfterViewInit {
5961
collapsedSidebarWidth: Observable<string>;
6062
totalSidebarWidth: Observable<string>;
6163
theme: Observable<ThemeConfig> = of({} as any);
62-
notificationOptions = environment.notifications;
64+
notificationOptions;
6365
models;
6466

6567
/**
@@ -88,6 +90,7 @@ export class AppComponent implements OnInit, AfterViewInit {
8890
@Inject(NativeWindowService) private _window: NativeWindowRef,
8991
@Inject(DOCUMENT) private document: any,
9092
@Inject(PLATFORM_ID) private platformId: any,
93+
@Inject(APP_CONFIG) private appConfig: AppConfig,
9194
private themeService: ThemeService,
9295
private translate: TranslateService,
9396
private store: Store<HostWindowState>,
@@ -106,6 +109,14 @@ export class AppComponent implements OnInit, AfterViewInit {
106109
@Optional() private googleAnalyticsService: GoogleAnalyticsService,
107110
) {
108111

112+
console.log(this.appConfig);
113+
114+
if (!isEqual(environment, this.appConfig)) {
115+
throw new Error('environment does not match app config!');
116+
}
117+
118+
this.notificationOptions = environment.notifications;
119+
109120
/* Use models object so all decorators are actually called */
110121
this.models = models;
111122

src/app/app.module.ts

+16-8
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,18 @@ import { IdleModalComponent } from './shared/idle-modal/idle-modal.component';
5858
import { UUIDService } from './core/shared/uuid.service';
5959
import { CookieService } from './core/services/cookie.service';
6060

61-
// import { AppConfig, APP_CONFIG } from '../config/app-config.interface';
61+
import { AppConfig, APP_CONFIG } from '../config/app-config.interface';
6262

63-
export function getBase() {
64-
return environment.ui.nameSpace;
63+
export function getConfig() {
64+
return environment;
6565
}
6666

67-
export function getMetaReducers(): MetaReducer<AppState>[] {
68-
return environment.debug ? [...appMetaReducers, ...debugMetaReducers] : appMetaReducers;
67+
export function getBase(appConfig: AppConfig) {
68+
return appConfig.ui.nameSpace;
69+
}
70+
71+
export function getMetaReducers(appConfig: AppConfig): MetaReducer<AppState>[] {
72+
return appConfig.debug ? [...appMetaReducers, ...debugMetaReducers] : appMetaReducers;
6973
}
7074

7175
/**
@@ -100,15 +104,19 @@ IMPORTS.push(
100104
);
101105

102106
const PROVIDERS = [
107+
{
108+
provide: APP_CONFIG,
109+
useFactory: getConfig
110+
},
103111
{
104112
provide: APP_BASE_HREF,
105113
useFactory: getBase,
106-
// deps: [APP_CONFIG]
114+
deps: [APP_CONFIG]
107115
},
108116
{
109117
provide: USER_PROVIDED_META_REDUCERS,
110118
useFactory: getMetaReducers,
111-
// deps: [APP_CONFIG]
119+
deps: [APP_CONFIG]
112120
},
113121
{
114122
provide: RouterStateSerializer,
@@ -199,7 +207,7 @@ const EXPORTS = [
199207

200208
@NgModule({
201209
imports: [
202-
BrowserModule.withServerTransition({ appId: 'serverApp' }),
210+
BrowserModule.withServerTransition({ appId: 'dspace-angular' }),
203211
...IMPORTS
204212
],
205213
providers: [

src/app/item-page/simple/item-types/shared/item.component.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ export class ItemComponent implements OnInit {
3636
*/
3737
iiifQuery$: Observable<string>;
3838

39-
mediaViewer = environment.mediaViewer;
39+
mediaViewer;
4040

4141
constructor(protected routeService: RouteService) {
42+
this.mediaViewer = environment.mediaViewer;
4243
}
4344

4445
ngOnInit(): void {

0 commit comments

Comments
 (0)