├── .gitignore ├── .travis.yml ├── .vscode └── settings.json ├── CHANGELOG.md ├── README.md ├── dist └── .npmignore ├── docs └── FolderStructure.png ├── karma.conf.js ├── package-lock.json ├── package.json ├── src ├── .npmignore ├── base.spec.ts ├── configuration.service.spec.ts ├── configuration.service.ts └── index.ts ├── tsconfig.aot.json ├── tsconfig.json └── tslint.json /.gitignore: -------------------------------------------------------------------------------- 1 | coverage/ 2 | dist/**/*.d.ts 3 | dist/**/*.js 4 | dist/**/*.map 5 | dist/**/*.json 6 | node_modules/ 7 | package/ 8 | 9 | *.tgz 10 | npm-debug.log 11 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | cache: 3 | directories: 4 | - node_modules 5 | node_js: 6 | - '8' 7 | before_script: 8 | - npm prune 9 | after_success: 10 | - npm run report-coverage 11 | - npm run semantic-release 12 | branches: 13 | except: 14 | - /^v\d+\.\d+\.\d+$/ 15 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "./node_modules/typescript/lib", 3 | "markdownlint.config": { 4 | "MD009": { 5 | "br_spaces": 2 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | see [GitHub Releases](https://github.com/Ritzlgrmft/ionic-configuration-service/releases) 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ionic-configuration-service 2 | 3 | **Please be aware that this component is deprecated since Angular 6 provides a very similar mechanism for environizing, see [Application Environments](https://github.com/angular/angular-cli/wiki/stories-application-environments).** 4 | 5 | For older versions use: 6 | 7 | | ionic-configuration-service | Ionic | Angular 8 | | ----- | -------- | ------ 9 | | - | >= 4.0.0 | ^6.0.0 10 | | 6.0.0 | >= 3.9.0 | ^5.0.0 11 | | 5.0.0 | >= 3.0.0 | ^4.0.0 12 | | 4.0.0 | >= 2.2.0 | ^2.4.8 13 | | 3.1.1 | >= 2.0.0 | ^2.2.1 14 | 15 | [![Build](https://travis-ci.org/Ritzlgrmft/ionic-configuration-service.svg?branch=master)](https://travis-ci.org/Ritzlgrmft/ionic-configuration-service) 16 | [![Codecov](https://codecov.io/gh/Ritzlgrmft/ionic-configuration-service/branch/master/graph/badge.svg)](https://codecov.io/gh/Ritzlgrmft/ionic-configuration-service) 17 | [![Version](https://badge.fury.io/js/ionic-configuration-service.svg)](https://www.npmjs.com/package/ionic-configuration-service) 18 | [![Downloads](https://img.shields.io/npm/dt/ionic-configuration-service.svg)](https://www.npmjs.com/package/ionic-configuration-service) 19 | [![Dependencies](https://david-dm.org/ritzlgrmft/ionic-configuration-service/master/status.svg)](https://david-dm.org/ritzlgrmft/ionic-configuration-service/master) 20 | [![Peer-Dependencies](https://david-dm.org/ritzlgrmft/ionic-configuration-service/master/peer-status.svg)](https://david-dm.org/ritzlgrmft/ionic-configuration-service/master?type=peer) 21 | [![Dev-Dependencies](https://david-dm.org/ritzlgrmft/ionic-configuration-service/master/dev-status.svg)](https://david-dm.org/ritzlgrmft/ionic-configuration-service/master?type=dev) 22 | [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/) 23 | [![Known Vulnerabilities](https://snyk.io/test/github/ritzlgrmft/ionic-configuration-service/badge.svg)](https://snyk.io/test/github/ritzlgrmft/ionic-configuration-service) 24 | [![License](https://img.shields.io/npm/l/ionic-configuration-service.svg)](https://www.npmjs.com/package/ionic-configuration-service) 25 | 26 | This service encapsulates configuration functionalities for apps built with [Ionic framework](http://ionicframework.com). 27 | 28 | Most apps need some kind of configuration. And often, the configuration data is different 29 | between the environments: 30 | 31 | - maybe you want to use different web services in test and production 32 | - in test, you want to log everything, but in production only errors 33 | - you want to have all configuration data in one place, so you are able to change something easily 34 | - ... 35 | 36 | The idea is: 37 | 38 | - add *one* json file containing all the configuration data 39 | - at *build* this file can be modified (par example you will use a different file in your release build) 40 | - before the app really starts, the configuration gets loaded 41 | - whereever you need the configuration data, you can get it via the injected configuration service 42 | 43 | ## Settings file containing the configuration data 44 | 45 | The settings file is just a JSON file. It contains some keys, whose values can be of any type (either scalar or complex): 46 | 47 | ```json 48 | { 49 | "helloWorld": "Hello World", 50 | "secretNumber": 42, 51 | "somethingComplex": { 52 | "backendUrl": "http://server.com/api" 53 | } 54 | } 55 | ``` 56 | 57 | ## Replace settings file at build time 58 | 59 | Now it gets a little bit tricky: you have a json file in a source directory (e.g. `environments`), 60 | which should be copied to the `www/assets` directory. A good place to do this is using the copy step of Ionic's build. 61 | You just need to add a copy statement to `copy.config.js`. 62 | 63 | Unfortunately, the copied file should have always the same name. Otherwise you could not load it in your code. 64 | On the other side, you want to have several files (with different names) for the different environments. 65 | The solution is to have separate directories for every environment. 66 | 67 | ### Folder structure 68 | 69 | So, in the source, you have the following folder structure: 70 | 71 | ![folder structure](docs/FolderStructure.png) 72 | 73 | Just create a new folder below `environments` for every environment you want to support. Be aware that the filename itself 74 | (`settings.json`) has to be always the same. 75 | 76 | ### Copy correct environment 77 | 78 | If you do not have an own `copy.config.js`, just create one. For details have a look at 79 | [Custom configuration of Ionic's app scripts](https://github.com/ionic-team/ionic-app-scripts#custom-configuration). 80 | 81 | There you can add your own copy step to `module.exports`: 82 | 83 | ```JavaScript 84 | module.exports = { 85 | copySettings: { 86 | src: ['{{ROOT}}/environments/' + envDirectory + "/settings.json"], 87 | dest: '{{WWW}}/assets' 88 | }, 89 | ... 90 | } 91 | ``` 92 | 93 | As you can see, it simply copies the `settings.json` from `envDirectory` to `www/assets`. 94 | What is missing so far, is the right value of `envDirectory`, which has to be dynamic. 95 | Fortunately, `copy.config.js` is just JavaScript. So we can add some logic at the beginning: 96 | 97 | ```JavaScript 98 | var envDirectory = process.env.env || "default"; 99 | process.stdout.write("using environment '" + envDirectory + "'\n"); 100 | ``` 101 | 102 | As you see, `envDirectory` has a default value of `default`. 103 | But if you specify a value for the environment variable `env`, you can set there another environment. 104 | If you want to test the release environment in the emulator, you can use: 105 | 106 | ```bash 107 | export env=release 108 | ionic emulate --prod 109 | ``` 110 | 111 | Or even shorter: 112 | 113 | ```bash 114 | env=release ionic emulate --prod 115 | ``` 116 | 117 | Side note: my former solution with `--env` argument does no longer work, since the Ionic 118 | commands spawn internally new node processes which do not get the additional argument. 119 | 120 | ## Load the configuration data 121 | 122 | The loading of the configuration data is done in the `AppModule`, before the bootstrapping 123 | of the `IonicApp`. This is done using [Angular's APP_INITIALIZER](https://github.com/angular/angular/issues/9047): 124 | 125 | ```TypeScript 126 | import { HttpClientModule } from "@angular/common/http"; 127 | import { APP_INITIALIZER } from "@angular/core"; 128 | import { ConfigurationService } from "ionic-configuration-service"; 129 | 130 | export function loadConfiguration(configurationService: ConfigurationService): () => Promise { 131 | return () => configurationService.load("assets/settings.json"); 132 | } 133 | 134 | @NgModule({ 135 | ... 136 | imports: [ 137 | ... 138 | HttpClientModule, 139 | ], 140 | providers: [ 141 | ConfigurationService, 142 | { 143 | provide: APP_INITIALIZER, 144 | useFactory: loadConfiguration, 145 | deps: [ConfigurationService], 146 | multi: true 147 | }, 148 | .... 149 | ] 150 | }) 151 | ``` 152 | 153 | For `APP_INITIALIZER`, the factory function just loads the configuration data. 154 | The `multi` parameter is important, because there can be more `APP_INITIALIZER`s. 155 | 156 | The factory function `loadConfiguration()` is needed, since otherwise the angular compiler `ngc` 157 | could not compile the module. 158 | 159 | ## Access the configuration data 160 | 161 | The access to the configuration data is quite easy. Just inject the `ConfigurationService` into your component. 162 | And call `configurationService.getValue()` later on: 163 | 164 | ```TypeScript 165 | constructor( 166 | private configurationService: ConfigurationService) { 167 | } 168 | 169 | let secretNumber = this.configurationService.getValue("secretNumber"); 170 | ``` 171 | 172 | For more complex configuration, it's a good practise to define an interface 173 | describing your part of the configuration: 174 | 175 | ```TypeScript 176 | export interface LoggingConfiguration { 177 | logLevels?: { 178 | loggerName: string; 179 | logLevel: string; 180 | }[]; 181 | } 182 | 183 | let configuration = this.configurationService.getValue("logging"); 184 | ``` 185 | 186 | ## API 187 | 188 | ### getKeys(): string[] 189 | 190 | Get all available keys. 191 | 192 | Returns 193 | 194 | - all available keys 195 | 196 | ### getValue<T>(key: string): T 197 | 198 | Get the configuration data for the given key. 199 | 200 | Parameters 201 | 202 | - *T*: type of the returned value (default: object) 203 | - *key*: key of the configuration data 204 | 205 | Returns 206 | 207 | - configuration data for the given key 208 | 209 | ### load(configurationUrl: string): Promise<void> 210 | 211 | Loads the configuration from the given url. 212 | 213 | Parameters 214 | 215 | - *configurationUrl* url from which the configuration should be loaded 216 | 217 | Returns 218 | 219 | - promise which gets resolved as soon as the data is loaded; 220 | in case of an error, the promise gets rejected 221 | -------------------------------------------------------------------------------- /dist/.npmignore: -------------------------------------------------------------------------------- 1 | .npmignore 2 | base.spec.* 3 | *.spec.* 4 | -------------------------------------------------------------------------------- /docs/FolderStructure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ritzlgrmft/ionic-configuration-service/db00634f9d010834ff8b9700365fc41ec3478a13/docs/FolderStructure.png -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = function (config) { 2 | var configuration = { 3 | 4 | frameworks: ["jasmine", "karma-typescript"], 5 | 6 | files: [ 7 | { pattern: "src/**/*.+(ts|html)" }, 8 | "node_modules/reflect-metadata/Reflect.js", 9 | "node_modules/babel-polyfill/dist/polyfill.js" 10 | ], 11 | 12 | exclude: [ 13 | "dist/**/*" 14 | ], 15 | 16 | proxies: { 17 | "/app/": "/base/src/app/" 18 | }, 19 | 20 | preprocessors: { 21 | "**/*.ts": ["karma-typescript"] 22 | }, 23 | 24 | reporters: ["progress", "karma-typescript"], 25 | 26 | browsers: ["Chrome", "PhantomJS"], 27 | 28 | karmaTypescriptConfig: { 29 | exclude: ["dist"], 30 | reports: 31 | { 32 | "html": "coverage", 33 | "lcovonly": { 34 | "directory": "coverage", 35 | "filename": "lcovonly/lcov.info" 36 | }, 37 | "text-summary": "" 38 | }, 39 | compilerOptions: { 40 | "target": "es5", 41 | "lib": [ 42 | "dom", 43 | "es2015" 44 | ], 45 | "module": "commonjs", 46 | "moduleResolution": "node", 47 | "emitDecoratorMetadata": true, 48 | "experimentalDecorators": true, 49 | "noFallthroughCasesInSwitch": true, 50 | "noImplicitAny": true, 51 | "noImplicitReturns": true, 52 | "noUnusedLocals": true, 53 | "noUnusedParameters": true, 54 | "declaration": true, 55 | "sourceMap": true, 56 | "outDir": "dist" 57 | } 58 | }, 59 | 60 | // base path that will be used to resolve all patterns (eg. files, exclude) 61 | basePath: '', 62 | 63 | // web server port 64 | port: 9876, 65 | 66 | // enable / disable colors in the output (reporters and logs) 67 | colors: true, 68 | 69 | // level of logging 70 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 71 | logLevel: config.LOG_INFO, 72 | 73 | // enable / disable watching file and executing tests whenever any file changes 74 | autoWatch: true, 75 | 76 | // Continuous Integration mode 77 | // if true, Karma captures browsers, runs the tests and exits 78 | singleRun: false, 79 | 80 | // Concurrency level 81 | // how many browser should be started simultaneous 82 | concurrency: Infinity, 83 | }; 84 | 85 | config.set(configuration); 86 | } 87 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ionic-configuration-service", 3 | "version": "0.0.0-development", 4 | "description": "Configuration functionalities for apps built with Ionic framework", 5 | "author": { 6 | "name": "Markus Wagner", 7 | "email": "markus.wagner02@web.de" 8 | }, 9 | "repository": "https://github.com/Ritzlgrmft/ionic-configuration-service.git", 10 | "license": "MIT", 11 | "private": false, 12 | "keywords": [ 13 | "ionic", 14 | "mobile", 15 | "configuration", 16 | "environizing" 17 | ], 18 | "scripts": { 19 | "build": "npm run clean && npm run compile", 20 | "clean": "cd dist && ls | grep -v .npmignore | xargs rm && cd ..", 21 | "commit": "git-cz", 22 | "compile": "ngc -p tsconfig.aot.json", 23 | "karma": "karma start karma.conf.js --browsers Chrome", 24 | "karma-once": "karma start karma.conf.js --browsers PhantomJS --single-run", 25 | "lint": "tslint --project tsconfig.json --format verbose --exclude \"**/*.spec.ts\"", 26 | "report-coverage": "codecov", 27 | "semantic-release": "semantic-release pre && npm publish && semantic-release post", 28 | "test": "npm run compile && npm run lint && npm run karma-once" 29 | }, 30 | "files": [ 31 | "dist", 32 | "src" 33 | ], 34 | "main": "dist/index.js", 35 | "typings": "dist/index.d.ts", 36 | "peerDependencies": { 37 | "@angular/core": "^5.0.0", 38 | "@angular/http": "^5.0.0", 39 | "rxjs": "^5.5.2", 40 | "zone.js": "^0.8.18" 41 | }, 42 | "devDependencies": { 43 | "@angular/common": "5.0.0", 44 | "@angular/compiler": "5.0.0", 45 | "@angular/compiler-cli": "5.0.0", 46 | "@angular/core": "5.0.0", 47 | "@angular/forms": "5.0.0", 48 | "@angular/http": "5.0.0", 49 | "@angular/platform-browser": "5.0.0", 50 | "@angular/platform-browser-dynamic": "5.0.0", 51 | "rxjs": "5.5.2", 52 | "zone.js": "0.8.18", 53 | "@types/jasmine": "2.8.2", 54 | "babel-polyfill": "6.26.0", 55 | "codecov": "3.0.0", 56 | "codelyzer": "4.0.1", 57 | "commitizen": "2.9.6", 58 | "cz-conventional-changelog": "2.1.0", 59 | "jasmine-core": "2.8.0", 60 | "karma": "1.7.1", 61 | "karma-chrome-launcher": "2.2.0", 62 | "karma-jasmine": "1.1.0", 63 | "karma-phantomjs-launcher": "1.0.4", 64 | "karma-typescript": "3.0.8", 65 | "reflect-metadata": "0.1.10", 66 | "requirejs": "2.3.5", 67 | "tslint": "5.8.0", 68 | "typescript": "2.4.2", 69 | "semantic-release": "8.2.0" 70 | }, 71 | "config": { 72 | "commitizen": { 73 | "path": "cz-conventional-changelog" 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /src/.npmignore: -------------------------------------------------------------------------------- 1 | .npmignore 2 | *.spec.ts 3 | -------------------------------------------------------------------------------- /src/base.spec.ts: -------------------------------------------------------------------------------- 1 | import "reflect-metadata"; 2 | // tslint:disable:ordered-imports 3 | import "zone.js/dist/zone"; 4 | import "zone.js/dist/long-stack-trace-zone"; 5 | import "zone.js/dist/proxy"; 6 | import "zone.js/dist/sync-test"; 7 | import "zone.js/dist/jasmine-patch"; 8 | import "zone.js/dist/async-test"; 9 | import "zone.js/dist/fake-async-test"; 10 | // tslint:enable:ordered-imports 11 | 12 | import { TestBed } from "@angular/core/testing"; 13 | import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from "@angular/platform-browser-dynamic/testing"; 14 | 15 | TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); 16 | -------------------------------------------------------------------------------- /src/configuration.service.spec.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-magic-numbers 2 | import { HttpClientTestingModule, HttpTestingController } from "@angular/common/http/testing"; 3 | import { getTestBed, TestBed } from "@angular/core/testing"; 4 | 5 | import { ConfigurationService } from "./configuration.service"; 6 | 7 | describe("ConfigurationService", () => { 8 | 9 | interface ComplexObject { 10 | prop1: number; 11 | prop2: string; 12 | } 13 | 14 | let injector: TestBed; 15 | let configurationService: ConfigurationService; 16 | let httpMock: HttpTestingController; 17 | 18 | beforeEach(() => { 19 | TestBed.configureTestingModule({ 20 | imports: [HttpClientTestingModule], 21 | providers: [ 22 | ConfigurationService, 23 | ], 24 | }); 25 | injector = getTestBed(); 26 | configurationService = injector.get(ConfigurationService); 27 | httpMock = injector.get(HttpTestingController); 28 | }); 29 | 30 | afterEach(() => { 31 | httpMock.verify(); 32 | }); 33 | 34 | describe("load(settingsUrl: string): Promise", () => { 35 | 36 | it("returned promise gets resolved when settings is loaded", async (done) => { 37 | configurationService.load("settings.json").then(() => { 38 | done(); 39 | }); 40 | 41 | const req = httpMock.expectOne("settings.json"); 42 | expect(req.request.method).toBe("GET"); 43 | req.flush(""); 44 | }); 45 | 46 | it("returned promise gets rejected when settings do not exist", async (done) => { 47 | configurationService.load("unknown.json").catch((reason) => { 48 | expect(reason).toEqual(jasmine.any(Error)); 49 | expect(reason.message).toBe("unknown.json could not be loaded: 404"); 50 | done(); 51 | }); 52 | 53 | const req = httpMock.expectOne("unknown.json"); 54 | expect(req.request.method).toBe("GET"); 55 | req.flush("", { status: 404, statusText: "Not Found" }); 56 | }); 57 | }); 58 | 59 | describe("getValue(key: string): any", () => { 60 | 61 | it("returns undefined if configuration is not loaded", () => { 62 | const value = configurationService.getValue("xxx"); 63 | expect(value).toBeUndefined(); 64 | }); 65 | 66 | it("returns value of existing simple string", async (done) => { 67 | configurationService.load("settings.json").then(() => { 68 | const value = configurationService.getValue("simpleString"); 69 | expect(value).toBe("abc"); 70 | done(); 71 | }); 72 | 73 | const req = httpMock.expectOne("settings.json"); 74 | expect(req.request.method).toBe("GET"); 75 | req.flush({ 76 | simpleString: "abc", 77 | }); 78 | }); 79 | 80 | it("returns value of existing simple number", async (done) => { 81 | configurationService.load("settings.json").then(() => { 82 | const value = configurationService.getValue("simpleNumber"); 83 | expect(value).toBe(42); 84 | done(); 85 | }); 86 | 87 | const req = httpMock.expectOne("settings.json"); 88 | expect(req.request.method).toBe("GET"); 89 | req.flush({ 90 | simpleNumber: 42, 91 | }); 92 | }); 93 | 94 | it("returns value of existing complex object", async (done) => { 95 | configurationService.load("settings.json").then(() => { 96 | const value = configurationService.getValue("complexObject"); 97 | expect(value.prop1).toBe(1); 98 | expect(value.prop2).toBe("x"); 99 | done(); 100 | }); 101 | 102 | const req = httpMock.expectOne("settings.json"); 103 | expect(req.request.method).toBe("GET"); 104 | req.flush({ 105 | complexObject: { 106 | prop1: 1, 107 | prop2: "x", 108 | }, 109 | }); 110 | }); 111 | 112 | it("returns undefined if key does not exist", async (done) => { 113 | configurationService.load("settings.json").then(() => { 114 | const value = configurationService.getValue("unknown"); 115 | expect(value).toBeUndefined(); 116 | done(); 117 | }); 118 | 119 | const req = httpMock.expectOne("settings.json"); 120 | expect(req.request.method).toBe("GET"); 121 | req.flush(""); 122 | }); 123 | }); 124 | 125 | describe("getKeys(): string[]", () => { 126 | 127 | it("returns all keys from settings", async (done) => { 128 | configurationService.load("settings.json").then(() => { 129 | const keys = configurationService.getKeys(); 130 | expect(keys.length).toBe(3); 131 | expect(keys).toEqual(["complexObject", "simpleNumber", "simpleString"]); 132 | done(); 133 | }); 134 | 135 | const req = httpMock.expectOne("settings.json"); 136 | expect(req.request.method).toBe("GET"); 137 | req.flush({ 138 | complexObject: { 139 | prop1: 1, 140 | prop2: "x", 141 | }, 142 | simpleNumber: 42, 143 | simpleString: "abc", 144 | }); 145 | }); 146 | }); 147 | }); 148 | -------------------------------------------------------------------------------- /src/configuration.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | 3 | import { HttpClient, HttpErrorResponse } from "@angular/common/http"; 4 | 5 | /** 6 | * Service which encapsulates configuration functionalities for apps built with Ionic framework. 7 | */ 8 | @Injectable() 9 | export class ConfigurationService { 10 | 11 | /** 12 | * Internal storage of the configuration data. 13 | */ 14 | private configValues: { [key: string]: any }; 15 | 16 | constructor(private httpClient: HttpClient) { 17 | } 18 | 19 | /** 20 | * Get all available keys. 21 | * @returns all available keys 22 | */ 23 | public getKeys(): string[] { 24 | const keys: string[] = []; 25 | // tslint:disable-next-line:forin 26 | for (const key in this.configValues) { 27 | keys.push(key); 28 | } 29 | return keys; 30 | } 31 | 32 | /** 33 | * Get the configuration data for the given key. 34 | * @param T type of the returned value (default: object) 35 | * @param key key of the configuration data 36 | * @returns configuration data for the given key 37 | */ 38 | public getValue(key: string): T { 39 | if (this.configValues) { 40 | return this.configValues[key]; 41 | } else { 42 | return undefined; 43 | } 44 | } 45 | 46 | /** 47 | * Loads the configuration from the given url. 48 | * @param configurationUrl url from which the configuration should be loaded 49 | * @returns promise which gets resolved as soon as the data is loaded; in case of an error, the promise gets rejected 50 | */ 51 | public async load(configurationUrl: string): Promise { 52 | try { 53 | this.configValues = await this.httpClient.get<{ [key: string]: any }>(configurationUrl).toPromise(); 54 | } catch (e) { 55 | throw new Error(`${configurationUrl} could not be loaded: ${(e as HttpErrorResponse).status}`); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./configuration.service"; 2 | -------------------------------------------------------------------------------- /tsconfig.aot.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "es2015" 7 | ], 8 | "types": [ 9 | "jasmine" 10 | ], 11 | "module": "es2015", 12 | "moduleResolution": "node", 13 | "emitDecoratorMetadata": true, 14 | "experimentalDecorators": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "noImplicitAny": true, 17 | "noImplicitReturns": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "declaration": true, 21 | "sourceMap": true, 22 | "rootDir": "src", 23 | "outDir": "dist" 24 | }, 25 | "compileOnSave": false, 26 | "atom": { 27 | "rewriteTsconfig": false 28 | }, 29 | "files": [ 30 | "src/index.ts" 31 | ] 32 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "es2015" 7 | ], 8 | "types": [ 9 | "jasmine" 10 | ], 11 | "module": "commonjs", 12 | "moduleResolution": "node", 13 | "emitDecoratorMetadata": true, 14 | "experimentalDecorators": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "noImplicitAny": true, 17 | "noImplicitReturns": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "declaration": true, 21 | "sourceMap": true, 22 | "outDir": "dist" 23 | }, 24 | "compileOnSave": false, 25 | "atom": { 26 | "rewriteTsconfig": false 27 | } 28 | } -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "extends": "tslint:recommended", 6 | "rules": { 7 | "indent": [ 8 | true, 9 | "tabs" 10 | ], 11 | "interface-name": [ 12 | false 13 | ], 14 | "directive-selector": [ 15 | true, 16 | "attribute", 17 | "sg", 18 | "camelCase" 19 | ], 20 | "component-selector": [ 21 | true, 22 | "element", 23 | "sg", 24 | "kebab-case" 25 | ], 26 | "use-input-property-decorator": true, 27 | "use-output-property-decorator": true, 28 | "use-host-property-decorator": true, 29 | "no-attribute-parameter-decorator": true, 30 | "no-input-rename": true, 31 | "no-output-on-prefix": true, 32 | "no-output-rename": true, 33 | "no-forward-ref": true, 34 | "use-life-cycle-interface": true, 35 | "use-pipe-transform-interface": true, 36 | "component-class-suffix": true, 37 | "directive-class-suffix": true 38 | } 39 | } --------------------------------------------------------------------------------