feat(logging): Added Elastic APM RUM logging. (TV-316)

Squashed commit of the following:

commit 3c4abbe69605caff2a39efafd90550d93e9e1447
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Mon Oct 4 15:56:41 2021 +0200

    Updated npm scripts and built/serve shell

commit 00525a666fb6b3146ea5f85c7c3ad741378401de
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Mon Oct 4 13:59:12 2021 +0200

    Updated nginx-conf

commit a9945c14cc93eebf8812c075fe8ca67e39ab8ae8
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Mon Oct 4 12:59:49 2021 +0200

    Added elastics serverUrl to environment files and fixed nginx-conf

commit 38872cea957ce54c5cb496890e4be88fb019be58
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Mon Oct 4 12:49:41 2021 +0200

    Added Elastic APM with error handling

commit d3db5e8703e3b0a1d0d0b24230dc52a64bee252c
Merge: a3bc70e9 d139f750
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Mon Oct 4 12:22:16 2021 +0200

    Merge branch 'develop' into feature/TV-316-RUM

commit a3bc70e9420dc5d309325cfcf1221c6760d18c38
Merge: 3f98a66b c2a02dba
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Mon Oct 4 09:07:11 2021 +0200

    Merge branch 'develop' into feature/TV-316-RUM

commit 3f98a66bfda3af315c5417e2d2902ab80877b98b
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Fri Oct 1 16:05:43 2021 +0200

    Added @elastic/apm-rum-angular to log errors and api-requests
This commit is contained in:
Erik Tiekstra
2021-10-05 07:22:10 +02:00
parent 81ea5611f2
commit 07ec3c4aeb
34 changed files with 343 additions and 240 deletions

View File

@@ -53,7 +53,8 @@
"stylePreprocessorOptions": {
"includePaths": ["apps/mina-sidor-fa/src/styles"]
},
"scripts": ["node_modules/marked/lib/marked.js"]
"scripts": ["node_modules/marked/lib/marked.js"],
"allowedCommonJsDependencies": ["opentracing/lib/span", "opentracing/lib/tracer", "error-stack-parser"]
},
"configurations": {
"production": {
@@ -110,11 +111,11 @@
}
]
},
"api": {
"mock": {
"fileReplacements": [
{
"replace": "apps/mina-sidor-fa/src/environments/environment.ts",
"with": "apps/mina-sidor-fa/src/environments/environment.api.ts"
"with": "apps/mina-sidor-fa/src/environments/environment.mock.ts"
}
]
}
@@ -132,11 +133,11 @@
},
"acc": {
"browserTarget": "mina-sidor-fa:build:acc",
"proxyConfig": "./config/proxy.conf.api.json"
"proxyConfig": "./config/proxy.conf.json"
},
"api": {
"browserTarget": "mina-sidor-fa:build:api",
"proxyConfig": "./config/proxy.conf.api.json"
"mock": {
"browserTarget": "mina-sidor-fa:build:mock",
"proxyConfig": "./config/proxy.conf.mock.json"
}
}
},

View File

@@ -1,20 +1,23 @@
import { registerLocaleData } from '@angular/common';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import localeSe from '@angular/common/locales/sv';
import { ErrorHandler, LOCALE_ID, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ApmErrorHandler } from '@elastic/apm-rum-angular';
import { AuthInterceptor } from '@msfa-interceptors/auth.interceptor';
import { CustomErrorHandler } from '@msfa-interceptors/custom-error-handler.module';
import { CustomErrorHandler } from '@msfa-interceptors/custom-error-handler';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ToastListModule } from './components/toast-list/toast-list.module';
import { LoggingModule } from './logging.module';
import { AvropModule } from './pages/avrop/avrop.module';
import localeSe from '@angular/common/locales/sv';
import { registerLocaleData } from '@angular/common';
registerLocaleData(localeSe);
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, HttpClientModule, AppRoutingModule, ToastListModule, AvropModule],
imports: [LoggingModule, BrowserModule, HttpClientModule, AppRoutingModule, ToastListModule, AvropModule],
providers: [
ApmErrorHandler,
{
provide: ErrorHandler,
useClass: CustomErrorHandler,

View File

@@ -0,0 +1,36 @@
import { NgModule } from '@angular/core';
import { ApmModule, ApmService } from '@elastic/apm-rum-angular';
import { Feature } from '@msfa-enums/feature.enum';
import { environment } from '@msfa-environment';
@NgModule({
imports: [ApmModule],
exports: [ApmModule],
})
export class LoggingModule {
private _elasticConfig = environment.elastic;
private _activeFeatures = environment.activeFeatures;
constructor(private apmService: ApmService) {
if (this._elasticConfig && this._activeFeatures.includes(Feature.LOGGING)) {
const { serviceName, serverUrl } = this._elasticConfig;
this.apmService.init({
serviceName,
serverUrl,
environment: this.currentEnvironment,
});
}
}
get currentEnvironment(): string {
const defaultEnvironment = environment.elastic.environment;
const testUrlRegEx = new RegExp(/(?:mina-sidor-fa-)(\w{1,})(?:\.tocp)/g);
const testEnvironment = testUrlRegEx.exec(window.location.origin);
if (testEnvironment?.length) {
return testEnvironment[1].toUpperCase();
}
return defaultEnvironment;
}
}

View File

@@ -6,18 +6,18 @@ import { Observable } from 'rxjs';
import { filter, map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class PeriodiskRedovisningService {
private _apiBaseUrl = `${environment.api.url}`;
public getActivities$(): Observable<Activity[]> { // endpoint ska uppdateras
public getActivities$(): Observable<Activity[]> {
// endpoint ska uppdateras
return this.httpClient.get<{ data: ActivityResponse[] }>(`${this._apiBaseUrl}/activities`).pipe(
filter(response => !!response?.data),
map(({ data }) => data.map(aktivitet => mapResponseToActivity(aktivitet)))
)
);
}
constructor(private httpClient: HttpClient) {}
}

View File

@@ -9,7 +9,7 @@ import { AuthenticationService } from '@msfa-services/api/authentication.service
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class LogoutComponent implements OnInit {
loginUrl = environment.loginUrl;
loginUrl = environment.ciam.loginUrl;
constructor(private authenticationService: AuthenticationService) {}

View File

@@ -10,4 +10,5 @@ export enum Feature {
ACCESSIBILITY_REPORT,
REPORTING,
SENSITIVE_INFORMATION,
LOGGING,
}

View File

@@ -22,10 +22,10 @@ export class AuthGuard implements CanActivate {
void this.authenticationService.removeLocalStorageData();
if (environment.environment === 'local') {
void this.router.navigateByUrl(environment.loginUrl);
if (environment.ciam.clientId) {
document.location.href = `${environment.ciam.loginUrl}&client_id=${environment.ciam.clientId}&redirect_uri=${window.location.origin}`;
} else {
document.location.href = `${environment.loginUrl}&client_id=${environment.clientId}&redirect_uri=${window.location.origin}`;
void this.router.navigateByUrl(environment.ciam.loginUrl);
}
return of(false);
})

View File

@@ -1,14 +0,0 @@
import { ErrorHandler, Injectable } from '@angular/core';
import { CustomError, errorToCustomError } from '@msfa-models/error/custom-error';
import { ErrorService } from '@msfa-services/error.service';
@Injectable()
export class CustomErrorHandler implements ErrorHandler {
constructor(private errorService: ErrorService) {}
handleError(error: Error & { ngDebugContext: unknown }): void {
const customError: CustomError = errorToCustomError(error);
console.error(error);
this.errorService.add(customError);
}
}

View File

@@ -0,0 +1,22 @@
import { ErrorHandler, Injectable } from '@angular/core';
import { ApmErrorHandler } from '@elastic/apm-rum-angular';
import { Feature } from '@msfa-enums/feature.enum';
import { environment } from '@msfa-environment';
import { CustomError, errorToCustomError } from '@msfa-models/error/custom-error';
import { ErrorService } from '@msfa-services/error.service';
@Injectable()
export class CustomErrorHandler implements ErrorHandler {
private _elasticConfig = environment.elastic;
private _activeFeatures = environment.activeFeatures;
constructor(private errorService: ErrorService, public apmErrorHandler: ApmErrorHandler) {}
handleError(error: Error & { ngDebugContext: unknown }): void {
const customError: CustomError = errorToCustomError(error);
this.errorService.add(customError);
if (this._elasticConfig && this._activeFeatures.includes(Feature.LOGGING)) {
this.apmErrorHandler.handleError(customError);
}
}
}

View File

@@ -1,16 +1,22 @@
import { Feature } from '@msfa-enums/feature.enum';
export interface Environment {
environment: 'api' | 'local' | 'acc' | 'prod';
version?: string;
clientId: string;
loginUrl: string;
logoutUrl: string;
production: boolean;
api: {
url: string;
headers: { [key: string]: string };
skipHeadersOn: string[];
};
ciam: {
clientId?: string;
loginUrl: string;
logoutUrl: string;
};
activeFeatures: Feature[];
elastic?: {
serviceName: string;
serverUrl: string;
environment?: 'DEV' | 'SYS' | 'TEST' | 'ACC' | 'PROD';
};
}

View File

@@ -1,26 +1,24 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from '@msfa-environment';
import { ActivityResponse } from '@msfa-models/api/activity-response.model';
import { Activity, mapResponseToActivity } from '@msfa-models/activity.model';
import { ActivityResponse } from '@msfa-models/api/activity-response.model';
import { Observable } from 'rxjs';
import { filter, map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class ActivityApiService {
private _apiBaseUrl = `${environment.api.url}`;
public getActivities$(): Observable<Activity[]> { // endpoint ska uppdateras
public getActivities$(): Observable<Activity[]> {
// endpoint ska uppdateras
return this.httpClient.get<{ data: ActivityResponse[] }>(`${this._apiBaseUrl}/aktiviteter`).pipe(
filter(response => !!response?.data),
map(({ data }) => data.map(aktivitet => mapResponseToActivity(aktivitet)))
)
);
}
constructor(private httpClient: HttpClient) {}
}

View File

@@ -86,10 +86,10 @@ export class AuthenticationService {
logout(): void {
this.removeLocalStorageData();
if (environment.environment === 'local') {
void this.router.navigateByUrl(environment.logoutUrl);
if (environment.ciam.clientId) {
document.location.href = environment.ciam.logoutUrl;
} else {
document.location.href = environment.logoutUrl;
void this.router.navigateByUrl(environment.ciam.logoutUrl);
}
}
}

View File

@@ -13,57 +13,59 @@ import {
KandaAvvikelseKoder,
mapResponseToAndraKandaOrsaker,
mapResponseToOrsaksKoderFranvaro,
OrsaksKoderFranvaro
OrsaksKoderFranvaro,
} from '@msfa-models/orsaks-koder-franvaro.model';
import { ErrorService } from '@msfa-services/error.service';
import { Observable, throwError } from 'rxjs';
import { catchError, filter, map, take } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class AvvikelseApiService {
private _apiBaseUrl = `${environment.api.url}/report`;
public getOrsaksKoderFranvaro$(): Observable<OrsaksKoderFranvaro[]> {
return this.httpClient.get<{ data: OrsaksKoderAvvikelseResponse[] }>(`${this._apiBaseUrl}/orsakskoderfranvaro`).pipe(
return this.httpClient
.get<{ data: OrsaksKoderAvvikelseResponse[] }>(`${this._apiBaseUrl}/orsakskoderfranvaro`)
.pipe(
filter(response => !!response?.data),
map(({ data }) => data.map(orsak => mapResponseToOrsaksKoderFranvaro(orsak)))
)
);
}
public getOrsaksKoderAvvikelse$(): Observable<OrsaksKoderAvvikelse[]> {
return this.httpClient.get<{ data: OrsaksKoderAvvikelseResponse[] }>(`${this._apiBaseUrl}/orsakskoderavvikelse`).pipe(
return this.httpClient
.get<{ data: OrsaksKoderAvvikelseResponse[] }>(`${this._apiBaseUrl}/orsakskoderavvikelse`)
.pipe(
filter(response => !!response?.data),
map(({ data }) => data.map(avvikelse => mapResponseToOrsaksKoderAvvikelse(avvikelse)))
)
);
}
public getAndraKandaOrsaker$(): Observable<KandaAvvikelseKoder[]> {
return this.httpClient.get<{ data: KandaAvvikelseKoderResponse[] }>(`${this._apiBaseUrl}/kandaavvikelsekoder`).pipe(
filter(response => !!response?.data),
map(({ data }) => data.map(annanKandOrsak => mapResponseToAndraKandaOrsaker(annanKandOrsak)))
)
);
}
public getFragorForAvvikelser$(): Observable<FragorForAvvikelser[]> {
return this.httpClient.get<{ data: FragorForAvvikelserResponse[] }>(`${this._apiBaseUrl}/fragorforavvikelser`).pipe(
filter(response => !!response?.data),
map(({ data }) => data.map(fraga => mapResponseToFragorForAvvikelser(fraga)))
)
);
}
public createAvvikelse$(avvikelse: Avvikelse, alternative: string): Observable<Avvikelse> {
return this.httpClient
.post<{ data: AvvikelseRequestData }>(`${this._apiBaseUrl}/${this.setEndPoint(alternative)}`, avvikelse).pipe(
.post<{ data: AvvikelseRequestData }>(`${this._apiBaseUrl}/${this.setEndPoint(alternative)}`, avvikelse)
.pipe(
filter(response => !!response?.data),
take(1),
map(({ data }) => mapAvvikelseRequestDataToAvvikelse(data)),
catchError(error => throwError({ message: error as string, type: ErrorType.API }))
)
);
}
private setEndPoint(alternative: string): string {
@@ -75,7 +77,7 @@ export class AvvikelseApiService {
break;
case Alternative.FRANVARO:
endpoint = 'franvaro';
break
break;
default:
break;
}

View File

@@ -17,7 +17,9 @@ export class ErrorService {
constructor(private injector: Injector) {
// Workaround to fix change-detection when using Error interceptor
// See https://stackoverflow.com/a/37793791
setTimeout(() => (this.appRef = this.injector.get(ApplicationRef)));
setTimeout(() => {
this.appRef = this.injector.get(ApplicationRef);
});
}
public add(error: CustomError): void {

View File

@@ -20,4 +20,5 @@ export const ACTIVE_FEATURES_TEST: Feature[] = [
Feature.ACCESSIBILITY_REPORT,
Feature.REPORTING,
Feature.SENSITIVE_INFORMATION,
Feature.LOGGING,
];

View File

@@ -3,7 +3,6 @@ import { ACTIVE_FEATURES_PROD } from './active-features';
import { CIAM_TEST } from './ciam';
export const environment: Environment = {
environment: 'acc',
version: 'acc',
production: true,
api: {
@@ -12,5 +11,10 @@ export const environment: Environment = {
skipHeadersOn: ['assets/'],
},
activeFeatures: [...ACTIVE_FEATURES_PROD],
...CIAM_TEST,
elastic: {
serverUrl: '/logging',
serviceName: 'mina-sidor-fa',
environment: 'ACC',
},
ciam: CIAM_TEST,
};

View File

@@ -1,16 +1,16 @@
import { Feature } from '@msfa-enums/feature.enum';
import { Environment } from '@msfa-models/environment.model';
import { ACTIVE_FEATURES_TEST } from './active-features';
import { CIAM_TEST } from './ciam';
import { CIAM_MOCK } from './ciam';
export const environment: Environment = {
environment: 'api',
version: 'api',
version: 'mock',
production: false,
api: {
url: '/api',
headers: {},
skipHeadersOn: ['assets/'],
skipHeadersOn: [],
},
activeFeatures: [...ACTIVE_FEATURES_TEST],
...CIAM_TEST,
activeFeatures: [...ACTIVE_FEATURES_TEST, Feature.MOCK_LOGIN],
ciam: CIAM_MOCK,
};

View File

@@ -3,7 +3,6 @@ import { ACTIVE_FEATURES_PROD } from './active-features';
import { CIAM_PROD } from './ciam';
export const environment: Environment = {
environment: 'prod',
version: 'prod',
production: true,
api: {
@@ -12,5 +11,10 @@ export const environment: Environment = {
skipHeadersOn: ['assets/'],
},
activeFeatures: [...ACTIVE_FEATURES_PROD],
...CIAM_PROD,
elastic: {
serverUrl: '/logging',
serviceName: 'mina-sidor-fa',
environment: 'PROD',
},
ciam: CIAM_PROD,
};

View File

@@ -1,17 +1,20 @@
import { Feature } from '@msfa-enums/feature.enum';
import { Environment } from '@msfa-models/environment.model';
import { ACTIVE_FEATURES_TEST } from './active-features';
import { CIAM_MOCK } from './ciam';
import { CIAM_TEST } from './ciam';
export const environment: Environment = {
environment: 'local',
version: 'local',
version: 'api',
production: false,
api: {
url: '/api',
headers: {},
skipHeadersOn: [],
skipHeadersOn: ['assets/'],
},
activeFeatures: [...ACTIVE_FEATURES_TEST, Feature.MOCK_LOGIN],
...CIAM_MOCK,
activeFeatures: [...ACTIVE_FEATURES_TEST],
elastic: {
serverUrl: '/logging',
serviceName: 'mina-sidor-fa',
environment: 'DEV',
},
ciam: CIAM_TEST,
};

View File

@@ -2,7 +2,7 @@ import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { defineCustomElements } from '@digi/core/loader';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import { environment } from './environments/environment.mock';
if (environment.production) {
enableProdMode();

View File

@@ -1,7 +0,0 @@
{
"/api": {
"target": "https://mina-sidor-fa-test.tocp.arbetsformedlingen.se",
"secure": false,
"changeOrigin": true
}
}

View File

@@ -1,9 +1,13 @@
{
"/api": {
"target": "http://localhost:8000",
"target": "https://mina-sidor-fa-test.tocp.arbetsformedlingen.se",
"secure": false,
"pathRewrite": {
"^/api": "/"
}
"changeOrigin": true
},
"/logging": {
"target": "https://298b3305d4834aa4869f8250a0d0b314.ece-test.arbetsformedlingen.se:9243",
"secure": false,
"changeOrigin": true,
"pathRewrite": { "^/logging": "" }
}
}

View File

@@ -0,0 +1,9 @@
{
"/api": {
"target": "http://localhost:8000",
"secure": false,
"pathRewrite": {
"^/api": "/"
}
}
}

View File

@@ -67,13 +67,10 @@ http {
add_header Cache-Control "no-cache, public, must-revalidate, proxy-revalidate";
}
# underscores_in_headers on;
# $RESOLVER
# # JWT TOKEN
# location /token/jwt/rest/idp/v0/msfa {
# proxy_pass $JWT_URL;
# }
# Elastic Logging
location /logging/ {
proxy_pass $ELASTIC_SERVER_URL;
}
error_page 404 /404.html;

View File

@@ -1,6 +1,5 @@
#!/bin/bash
export JWT_URL
export RESOLVER
export ELASTIC_SERVER_URL
envsubst '${JWT_URL} ${RESOLVER} ' < /usr/share/container-scripts/nginx/nginx-start/nginx.template > /etc/nginx/nginx.conf
envsubst '${ELASTIC_SERVER_URL} ' < /usr/share/container-scripts/nginx/nginx-start/nginx.template > /etc/nginx/nginx.conf

View File

@@ -1,85 +0,0 @@
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
worker_processes auto;
error_log /var/opt/rh/rh-nginx116/log/nginx/error.log;
pid /var/opt/rh/rh-nginx116/run/nginx/nginx.pid;
# Load dynamic modules. See /opt/rh/rh-nginx116/root/usr/share/doc/README.dynamic.
include /opt/rh/rh-nginx116/root/usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/opt/rh/rh-nginx116/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
gzip on;
gzip_types application/xml application/json text/css text/javascript application/javascript;
gzip_vary on;
gzip_comp_level 6;
gzip_min_length 500;
include /etc/opt/rh/rh-nginx116/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /opt/app-root/etc/nginx.d/*.conf;
server {
listen 8080 default_server;
listen [::]:8080 default_server;
server_name _;
root /opt/app-root/src;
# Load configuration files for the default server block.
include /opt/app-root/etc/nginx.default.d/*.conf;
location / {
try_files $uri $uri/ /index.html;
expires -1;
}
location ~* \.(?:jpg|jpeg|gif|png|ico|woff2)$ {
expires 1M;
add_header Cache-Control "public";
}
location ~* \.(?:js|json|css)$ {
add_header Cache-Control "no-cache, public, must-revalidate, proxy-revalidate";
}
# underscores_in_headers on;
# $RESOLVER
# # JWT TOKEN
# location /token/jwt/rest/idp/v0/msfa {
# proxy_pass $JWT_URL;
# }
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}

View File

@@ -99,7 +99,7 @@ pipeline {
steps {
echo '### Building application... ###'
sh '''
npm run build-os -- --config acc --version ${BUILD_TAG}
npm run build:acc -- --version ${BUILD_TAG}
cp -r nginx/* ${NGINX_PATH}
'''
echo '### Application built! ###'

View File

@@ -96,7 +96,7 @@ pipeline {
echo '### Building application... ###'
sh '''
npm run build-os -- --config api --version ${BUILD_TAG}
npm run build -- --version ${BUILD_TAG}
cp -r nginx/* ${NGINX_PATH}
'''

View File

@@ -95,7 +95,7 @@ pipeline {
echo '### Building application... ###'
sh '''
npm run build-os -- --config api --version ${BUILD_TAG}
npm run build -- --version ${BUILD_TAG}
cp -r nginx/* ${NGINX_PATH}
'''

View File

@@ -108,7 +108,7 @@ pipeline {
steps {
echo '### Building application... ###'
sh '''
npm run build-os -- --config prod --version ${BUILD_TAG}
npm run build:prod -- --version ${BUILD_TAG}
cp -r nginx/* ${NGINX_PATH}
'''
echo '### Application built! ###'

130
package-lock.json generated
View File

@@ -1,11 +1,11 @@
{
"name": "mina-sidor-fa-web",
"version": "2.0.0",
"version": "2.0.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"version": "2.0.0",
"version": "2.0.1",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
@@ -23,6 +23,7 @@
"@angular/router": "^11.2.0",
"@digi/core": "^9.4.0",
"@digi/styles": "^6.0.2",
"@elastic/apm-rum-angular": "^2.1.1",
"@nrwl/angular": "11.5.1",
"date-fns": "^2.22.1",
"ngx-markdown": "^11.1.3",
@@ -2708,6 +2709,50 @@
"node": ">=10.0.0"
}
},
"node_modules/@elastic/apm-rum": {
"version": "5.9.1",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/@elastic/apm-rum/-/apm-rum-5.9.1.tgz",
"integrity": "sha512-NJAdzxXxf+LeCI0Dz3P+RMVY66C8sAztIg4tvnrhvBqxf8d7se+FpYw3oYjw3BZ8UDycmXEaIqEGcynUUndgqA==",
"license": "MIT",
"dependencies": {
"@elastic/apm-rum-core": "^5.12.1"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/@elastic/apm-rum-angular": {
"version": "2.1.1",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/@elastic/apm-rum-angular/-/apm-rum-angular-2.1.1.tgz",
"integrity": "sha512-xFaIIQD9SE3QHB1jeCPbB1tcDwDXhUoZ7iA4tKDm/kgXhOL5DJtsJ1CGdRM+tx9pcUH2UKC59l9321caoIdeXg==",
"license": "MIT",
"dependencies": {
"@elastic/apm-rum": "^5.9.1",
"@elastic/apm-rum-core": "^5.12.1",
"tslib": "^2.1.0"
},
"engines": {
"node": ">=12.0.0"
},
"peerDependencies": {
"@angular/core": ">=9.0.0",
"@angular/router": ">=9.0.0"
}
},
"node_modules/@elastic/apm-rum-core": {
"version": "5.12.1",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/@elastic/apm-rum-core/-/apm-rum-core-5.12.1.tgz",
"integrity": "sha512-b9CyqLdu2rSdjqi5Pc2bNfQCRQT26GjQzCTpJq1WoewDaoivsPoUDrY7tCJV+j3rmRSxG7vX91pM5SygjFr7aA==",
"license": "MIT",
"dependencies": {
"error-stack-parser": "^1.3.5",
"opentracing": "^0.14.3",
"promise-polyfill": "^8.1.3"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/@eslint/eslintrc": {
"version": "0.1.3",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/@eslint/eslintrc/-/eslintrc-0.1.3.tgz",
@@ -9309,6 +9354,15 @@
"is-arrayish": "^0.2.1"
}
},
"node_modules/error-stack-parser": {
"version": "1.3.6",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/error-stack-parser/-/error-stack-parser-1.3.6.tgz",
"integrity": "sha1-4Oc7k+QXE40c18C3RrGkoUhUwpI=",
"license": "Unlicense",
"dependencies": {
"stackframe": "^0.3.1"
}
},
"node_modules/es-abstract": {
"version": "1.18.0",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/es-abstract/-/es-abstract-1.18.0.tgz",
@@ -19671,6 +19725,15 @@
"node": ">=8"
}
},
"node_modules/opentracing": {
"version": "0.14.5",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/opentracing/-/opentracing-0.14.5.tgz",
"integrity": "sha512-XLKtEfHxqrWyF1fzxznsv78w3csW41ucHnjiKnfzZLD5FN8UBDZZL1i4q0FR29zjxXhm+2Hop+5Vr/b8tKIvEg==",
"license": "Apache-2.0",
"engines": {
"node": ">=0.10"
}
},
"node_modules/opn": {
"version": "5.5.0",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/opn/-/opn-5.5.0.tgz",
@@ -23987,6 +24050,12 @@
"integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
"dev": true
},
"node_modules/promise-polyfill": {
"version": "8.2.0",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/promise-polyfill/-/promise-polyfill-8.2.0.tgz",
"integrity": "sha512-k/TC0mIcPVF6yHhUvwAp7cvL6I2fFV7TzF1DuGPI8mBh4QQazf36xCKEHKTZKRysEoTQoQdKyP25J8MPJp7j5g==",
"license": "MIT"
},
"node_modules/promise-retry": {
"version": "1.1.1",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/promise-retry/-/promise-retry-1.1.1.tgz",
@@ -26581,6 +26650,12 @@
"node": ">=8"
}
},
"node_modules/stackframe": {
"version": "0.3.1",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/stackframe/-/stackframe-0.3.1.tgz",
"integrity": "sha1-M6qE8Rd6VUjIk1Uzy/6zQgl19aQ=",
"license": "SEE LICENSE IN LICENSE"
},
"node_modules/static-extend": {
"version": "0.1.2",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/static-extend/-/static-extend-0.1.2.tgz",
@@ -34789,6 +34864,34 @@
"integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==",
"dev": true
},
"@elastic/apm-rum": {
"version": "5.9.1",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/@elastic/apm-rum/-/apm-rum-5.9.1.tgz",
"integrity": "sha512-NJAdzxXxf+LeCI0Dz3P+RMVY66C8sAztIg4tvnrhvBqxf8d7se+FpYw3oYjw3BZ8UDycmXEaIqEGcynUUndgqA==",
"requires": {
"@elastic/apm-rum-core": "^5.12.1"
}
},
"@elastic/apm-rum-angular": {
"version": "2.1.1",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/@elastic/apm-rum-angular/-/apm-rum-angular-2.1.1.tgz",
"integrity": "sha512-xFaIIQD9SE3QHB1jeCPbB1tcDwDXhUoZ7iA4tKDm/kgXhOL5DJtsJ1CGdRM+tx9pcUH2UKC59l9321caoIdeXg==",
"requires": {
"@elastic/apm-rum": "^5.9.1",
"@elastic/apm-rum-core": "^5.12.1",
"tslib": "^2.1.0"
}
},
"@elastic/apm-rum-core": {
"version": "5.12.1",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/@elastic/apm-rum-core/-/apm-rum-core-5.12.1.tgz",
"integrity": "sha512-b9CyqLdu2rSdjqi5Pc2bNfQCRQT26GjQzCTpJq1WoewDaoivsPoUDrY7tCJV+j3rmRSxG7vX91pM5SygjFr7aA==",
"requires": {
"error-stack-parser": "^1.3.5",
"opentracing": "^0.14.3",
"promise-polyfill": "^8.1.3"
}
},
"@eslint/eslintrc": {
"version": "0.1.3",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/@eslint/eslintrc/-/eslintrc-0.1.3.tgz",
@@ -40393,6 +40496,14 @@
"is-arrayish": "^0.2.1"
}
},
"error-stack-parser": {
"version": "1.3.6",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/error-stack-parser/-/error-stack-parser-1.3.6.tgz",
"integrity": "sha1-4Oc7k+QXE40c18C3RrGkoUhUwpI=",
"requires": {
"stackframe": "^0.3.1"
}
},
"es-abstract": {
"version": "1.18.0",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/es-abstract/-/es-abstract-1.18.0.tgz",
@@ -48466,6 +48577,11 @@
}
}
},
"opentracing": {
"version": "0.14.5",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/opentracing/-/opentracing-0.14.5.tgz",
"integrity": "sha512-XLKtEfHxqrWyF1fzxznsv78w3csW41ucHnjiKnfzZLD5FN8UBDZZL1i4q0FR29zjxXhm+2Hop+5Vr/b8tKIvEg=="
},
"opn": {
"version": "5.5.0",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/opn/-/opn-5.5.0.tgz",
@@ -52029,6 +52145,11 @@
"integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
"dev": true
},
"promise-polyfill": {
"version": "8.2.0",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/promise-polyfill/-/promise-polyfill-8.2.0.tgz",
"integrity": "sha512-k/TC0mIcPVF6yHhUvwAp7cvL6I2fFV7TzF1DuGPI8mBh4QQazf36xCKEHKTZKRysEoTQoQdKyP25J8MPJp7j5g=="
},
"promise-retry": {
"version": "1.1.1",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/promise-retry/-/promise-retry-1.1.1.tgz",
@@ -54200,6 +54321,11 @@
}
}
},
"stackframe": {
"version": "0.3.1",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/stackframe/-/stackframe-0.3.1.tgz",
"integrity": "sha1-M6qE8Rd6VUjIk1Uzy/6zQgl19aQ="
},
"static-extend": {
"version": "0.1.2",
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/static-extend/-/static-extend-0.1.2.tgz",

View File

@@ -10,14 +10,16 @@
"ng": "nx",
"postinstall": "node ./decorate-angular-cli.js && ngcc --properties es2015 browser module main",
"nx": "nx",
"start": "ng serve mina-sidor-fa",
"start:api": "ng serve mina-sidor-fa --configuration api",
"start-os": "bash ./tools/serve-os.sh",
"start-os:api": "bash ./tools/serve-os.sh -- --config api",
"build": "ng build mina-sidor-fa",
"build:api": "ng build mina-sidor-fa --configuration api",
"build:acc": "ng build mina-sidor-fa --configuration acc",
"build-os": "bash ./tools/build-os.sh",
"start": "bash ./tools/serve.sh --config api",
"start:api": "bash ./tools/serve.sh --config api",
"start:mock": "bash ./tools/serve.sh --config mock",
"start:acc": "bash ./tools/serve.sh --config acc",
"start:prod": "bash ./tools/serve.sh --config prod",
"build": "bash ./tools/build.sh --config api",
"build:api": "bash ./tools/build.sh --config api",
"build:mock": "bash ./tools/build.sh --config mock",
"build:acc": "bash ./tools/build.sh --config acc",
"build:prod": "bash ./tools/build.sh --config prod",
"test": "ng test mina-sidor-fa",
"release": "bash ./tools/release.sh",
"release:dry": "bash ./tools/release.sh dry",
@@ -58,6 +60,7 @@
"@angular/router": "^11.2.0",
"@digi/core": "^9.4.0",
"@digi/styles": "^6.0.2",
"@elastic/apm-rum-angular": "^2.1.1",
"@nrwl/angular": "11.5.1",
"date-fns": "^2.22.1",
"ngx-markdown": "^11.1.3",

View File

@@ -33,21 +33,22 @@ version=${version:-$config}
# ----------------------------------
# UPDATING VERSION
# ----------------------------------
echo -e "${CYAN}Setting version to ${version} inside environments.${config}.ts${NOCOLOR}"
echo -e "${CYAN}Setting version to ${version} inside the environments file${NOCOLOR}"
if [ $config = "api" ]; then
sed "s/version:.*',/version: '${version}',/" apps/mina-sidor-fa/src/environments/environment.ts > temp.txt && mv temp.txt apps/mina-sidor-fa/src/environments/environment.ts
else
sed "s/version:.*',/version: '${version}',/" apps/mina-sidor-fa/src/environments/environment.$config.ts > temp.txt && mv temp.txt apps/mina-sidor-fa/src/environments/environment.$config.ts
fi
echo -e "${GREEN}Version set to ${version}${NOCOLOR}"
# ----------------------------------
# BUILD APPLICATION
# ----------------------------------
if [ $config = "prod" ]; then
echo -e "${CYAN}Running npm run build -- --prod${NOCOLOR}"
npm run build -- --prod
echo -e "${GREEN}Application built ${VERSION}${NOCOLOR}"
exit
echo -e "${CYAN}Running npm run ng build mina-sidor-fa -- --configuration ${config}${NOCOLOR}"
if [ $config = "api" ]; then
npm run ng build mina-sidor-fa
else
echo -e "${CYAN}Running npm run build:${CONFIG}${NOCOLOR}"
npm run build:$config
echo -e "${GREEN}Application built ${VERSION}${NOCOLOR}"
exit
npm run ng build mina-sidor-fa -- --configuration $config
fi
echo -e "${GREEN}Application built: ${version}${NOCOLOR}"
exit

View File

@@ -27,15 +27,15 @@ while [ $# -gt 0 ]; do
shift
done
config=${config:-prod}
config=${config:-api}
version=${version:-$config}
# ----------------------------------
# UPDATING VERSION
# ----------------------------------
echo -e "${CYAN}Setting version to ${version} inside environments.${config}.ts${NOCOLOR}"
if [ $config = "local" ]; then
echo -e "${CYAN}Setting version to ${version} inside the environments file${NOCOLOR}"
if [ $config = "api" ]; then
sed "s/version:.*',/version: '${version}',/" apps/mina-sidor-fa/src/environments/environment.ts > temp.txt && mv temp.txt apps/mina-sidor-fa/src/environments/environment.ts
else
sed "s/version:.*',/version: '${version}',/" apps/mina-sidor-fa/src/environments/environment.$config.ts > temp.txt && mv temp.txt apps/mina-sidor-fa/src/environments/environment.$config.ts
@@ -47,24 +47,11 @@ echo -e "${GREEN}Version set to ${version}${NOCOLOR}"
# ----------------------------------
if [ $config = "prod" ]; then
echo -e "${CYAN}Running npm run start -- --configuration production${NOCOLOR}"
npm run start -- --configuration production
echo -e "${GREEN}Application started${NOCOLOR}"
exit
elif [ $config = 'local' ]; then
echo -e "${CYAN}Running npm run start${NOCOLOR}"
npm run start
echo -e "${GREEN}Application started${NOCOLOR}"
exit
elif [ $config = 'acc' ]; then
echo -e "${CYAN}Running npm run start -- --configuration acc${NOCOLOR}"
npm run start -- --configuration acc
echo -e "${GREEN}Application started${NOCOLOR}"
exit
echo -e "${CYAN}Running npm run ng serve -- --configuration $config${NOCOLOR}"
if [ $config = "api" ]; then
npm run ng serve mina-sidor-fa
else
echo -e "${CYAN}Running npm run start:${CONFIG}${NOCOLOR}"
npm run start:$config
npm run ng serve mina-sidor-fa -- --configuration $config
fi
echo -e "${GREEN}Application started${NOCOLOR}"
exit
fi