.browserslistrc000066400000000000000000000015251516101643700141550ustar00rootroot00000000000000# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. # For additional information regarding the format and rule options, please see: # https://github.com/browserslist/browserslist#queries # For the full list of supported browsers by the Angular framework, please see: # https://angular.io/guide/browser-support # You can see what browsers were selected by your queries by running: # npx browserslist last 1 Chrome version last 1 Firefox version last 2 Edge major versions last 2 Safari major versions last 2 iOS major versions Firefox ESR not IE 9-10 # Angular support for IE 9-10 has been deprecated and will be removed as of Angular v11. To opt-in, remove the 'not' prefix on this line. not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. .editorconfig000066400000000000000000000004231516101643700135360ustar00rootroot00000000000000# Editor configuration, see https://editorconfig.org root = true [*] charset = utf-8 indent_style = space indent_size = 2 insert_final_newline = true trim_trailing_whitespace = false [*.ts] quote_type = single [*.md] max_line_length = off trim_trailing_whitespace = false .eslintrc.json000066400000000000000000000020741516101643700136610ustar00rootroot00000000000000{ "root": true, "ignorePatterns": [ "projects/**/*" ], "overrides": [ { "files": [ "*.ts" ], "parserOptions": { "project": [ "tsconfig.json", "e2e/tsconfig.json" ], "createDefaultProgram": true }, "extends": [ "plugin:@angular-eslint/ng-cli-compat", "plugin:@angular-eslint/ng-cli-compat--formatting-add-on", "plugin:@angular-eslint/template/process-inline-templates" ], "rules": { "@angular-eslint/component-selector": [ "error", { "type": "element", "prefix": "p3x", "style": "kebab-case" } ], "@angular-eslint/directive-selector": [ "error", { "type": "attribute", "prefix": "p3x", "style": "camelCase" } ] } }, { "files": [ "*.html" ], "extends": [ "plugin:@angular-eslint/template/recommended" ], "rules": {} } ] } .github/000077500000000000000000000000001516101643700124225ustar00rootroot00000000000000.github/workflows/000077500000000000000000000000001516101643700144575ustar00rootroot00000000000000.github/workflows/build.yml000066400000000000000000000016761516101643700163130ustar00rootroot00000000000000# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions name: build on: schedule: - cron: '0 0 1 * *' push: branches: [ master ] pull_request: branches: [ master ] jobs: build: runs-on: ubuntu-latest strategy: matrix: node-version: ['lts/*'] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v2 with: node-version: ${{ matrix.node-version }} - run: npm i -g grunt-cli - run: npm install - run: grunt .gitignore000066400000000000000000000015571516101643700130620ustar00rootroot00000000000000/build /node_modules /*.log /*.iws .idea/workspace.xml .idea/tasks.xml .idea/profiles_settings.xml .idea/inspectionProfiles/Project_Default.xml .idea/inspectionProfiles/profiles_settings.xml node_modules/.yarn-integrity # See http://help.github.com/ignore-files/ for more about ignoring files. # compiled output /dist /release /tmp /out-tsc # Only exists if Bazel was run /bazel-out # dependencies /node_modules # profiling files chrome-profiler-events*.json speed-measure-plugin*.json # IDEs and editors /.idea .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # IDE - VSCode .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json .history/* # misc /.angular/cache /.sass-cache /connect.lock /coverage /libpeerconnection.log npm-debug.log yarn-error.log testem.log /typings # System Files .DS_Store Thumbs.db .ncurc.json000066400000000000000000000002711516101643700131450ustar00rootroot00000000000000{ "reject": [ "core-js", "reflect-metadata", "rxjs", "tslib", "zone.js", "typescript", "karma", "ng-packagr" ] } .npmignore000066400000000000000000000002611516101643700130600ustar00rootroot00000000000000/.idea /artifacts /build /Gemfile /_layouts /_site /_includes /test /node_modules /*.iml /*.ipr /*.iws /.travis.yml /.scrutinizer.yml /Gruntfile.js /corifeus-boot.json /.github .travis.yml000066400000000000000000000015141516101643700131740ustar00rootroot00000000000000language: node_js cache: npm: false node_js: - lts/* before_script: - npm install -g grunt-cli npm after_success: - grunt publish env: global: secure: hv/FQcpG82bcau68yDbZYMY3ifdtqP2Rx5ZWibvjAYysR1YQe4m7hKs6IDxx9YvFHGMQc5V8JnLEVAkjg6FynL+cTpM5UM4983vv7eneTRIb3XK39dbcvZgZhH/T9dfY+Hodkij3GcLGcUyxm0LS2vOM9JozDGroHhN4VjAUib3rkLLaX88zBSdCPWLFQV3wJU3Wk9u5ddosC4iV5I56Jk7+X0to+aflS0oS3xiOybYdzVKYwWHxGOBpJhQs43vMOwbxY+5ao/EcTMGy/fb/VJNaH2KSkr/v0kB3SsmW2q/W7CFIp6F5AZt5me2bLZlFwo17z9RS6oB5jR9PbdOysOo+V+8RStqRTwUlBhiDPIffpZdQZajwHVea/1R2k3fW+JOgPmsqfb39/OGM9bEI7A4iv6WwGxShEF1ZJCwJSEWNMemSKfWBAul1M9SIUzUhrUo7r0DwJR/P5/jrqR82or1LnheS2RSlQRNOME1dItisjStPuH0ojPSztcrnmElE1fAGOZBCKRDJuWdbd1aAPaKIbSL4cR0UP2eJzTCy2Y0L/uYu/BQgwTDbJA+7cCrxKbYv46r2gZR3Hljw5WnCMnaxUHUutEDLR0O1rn+nU5oJxiVjr5fQvJfTqnR0be43TtcOL5Q+ELOIhMceuJ0aYc3MRVCohcDJL/m+dNyQ0C8= Gruntfile.js000066400000000000000000000027771516101643700133740ustar00rootroot00000000000000const utils = require('corifeus-utils'); const path = require('path') const fs = require('fs').promises module.exports = (grunt) => { const builder = require(`corifeus-builder`); const loader = new builder.loader(grunt); loader.js({ replacer: { type: 'p3x', npmio: true, }, config: { htmlmin: { dist: { options: { // Target options removeComments: true, collapseWhitespace: true, minifyCSS: true, }, files: { './dist/workspace/index.html': './dist/workspace/index.html' } } }, } }); grunt.registerTask('publish', async function () { const done = this.async(); try { await builder.utils.spawn({ grunt: grunt, gruntThis: this, }, { cmd: 'npm', args: [ 'run', 'build-lib', ] }); done() } catch (e) { done(e) } }); grunt.registerTask('build', async function () { const done = this.async(); try { await builder.utils.spawn({ grunt: grunt, gruntThis: this, }, { cmd: 'npm', args: [ 'run', 'build-app', ] }); done() } catch (e) { done(e) } }); const defaultTask = builder.config.task.build.js.concat(['cory-angular-hook-lib', 'cory-raw-npm-angular', 'build', 'htmlmin:dist']) grunt.registerTask('default', defaultTask); } LICENSE000066400000000000000000000027061516101643700120740ustar00rootroot00000000000000 @license p3x-angular-http-cache-interceptor v2021.10.161 🔥 Cache every request in Angular, not only the GET, but all methods of this interceptor, and allows you to interact with the interceptor via specific headers and modify the request, and these specific headers will be not included in the final request https://corifeus.com/angular-http-cache-interceptor Copyright (c) 2021 Patrik Laszlo / P3X / Corifeus and contributors. MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. README.md000066400000000000000000000154641516101643700123530ustar00rootroot00000000000000[//]: #@corifeus-header [![NPM](https://nodei.co/npm/p3x-angular-http-cache-interceptor.png?downloads=true&downloadRank=true)](https://www.npmjs.com/package/p3x-angular-http-cache-interceptor/) [![Donate for Corifeus / P3X](https://img.shields.io/badge/Donate-Corifeus-003087.svg)](https://paypal.me/patrikx3) [![Contact Corifeus / P3X](https://img.shields.io/badge/Contact-P3X-ff9900.svg)](https://www.patrikx3.com/en/front/contact) [![Corifeus @ Facebook](https://img.shields.io/badge/Facebook-Corifeus-3b5998.svg)](https://www.facebook.com/corifeus.software) [![Build Status](https://github.com/patrikx3/angular-http-cache-interceptor/workflows/build/badge.svg)](https://github.com/patrikx3/angular-http-cache-interceptor/actions?query=workflow%3Abuild) [![Uptime Robot ratio (30 days)](https://img.shields.io/uptimerobot/ratio/m780749701-41bcade28c1ea8154eda7cca.svg)](https://stats.uptimerobot.com/9ggnzcWrw) # 🔥 Cache every request in Angular, not only the GET, but all methods of this interceptor, and allows you to interact with the interceptor via specific headers and modify the request, and these specific headers will be not included in the final request v2021.10.161 **Bugs are evident™ - MATRIX️** ### NodeJS LTS is supported ### Built on NodeJs version ```txt v16.13.1 ``` # Built on Angular ```text 13.1.0 ``` # Description [//]: #@corifeus-header:end Usually, when you want to cache all requests, you do not cache all requests, but only the `GET` method. But, for some frontend applications, it is required to cache everything, otherwise the subsequent requests, without cache, would slow down the application flow. So, this micro-service caches all method/path/query variables/parameters/request body. The way, we can find out what we are caching it is not simple. Usually, you would cache by a key of the `httpRequest.urlWithParams` and only the `GET` HTTP method. To create this cache key, this package is using the `object-hash` package, with the following algorithm: ```ts import * as hash from 'object-hash' const hashOptions = { algorithm: 'md5', encoding: 'hex' } httpToKey(httpRequest: HttpRequest) { const key = httpRequest.method + '@' + httpRequest.urlWithParams + '@' + hash(httpRequest.params, hashOptions) + '@' + hash(httpRequest.body, hashOptions) return key } ``` There is room in the future, to restrict to specific methods and add more configurations and functions. If there is a need for this micro-service, it could be enhanced, but for now, it is caching everything, with the exception, when you include the `CachingHeaders.NoCache` header into your request, then this request will always hit the server. # Example web page that uses this package https://angular-http-cache-interceptor.corifeus.com # How to use it ```bash npm i p3x-angular-http-cache-interceptor object-hash ``` ## Include the caching interceptor into your Angular module ```ts import { NgModule } from '@angular/core'; import { P3XHttpCacheInterceptorModule } from 'p3x-angular-http-cache-interceptor'; @NgModule({ declarations: [ ], imports: [ P3XHttpCacheInterceptorModule, ], providers: [ ], bootstrap: [] }) export class SomeModule { } ``` ### Options ```ts import { P3XHttpCacheInterceptorModule, CachingHeaders, CachingStore } from 'p3x-angular-http-cache-interceptor'; P3XHttpCacheInterceptorModule.forRoot({ // default request is no cache behavior: CachingHeaders.NoCache, // if a request has CachingHeaders.Cache header it will cache globally store: CachingStore.Global, }) P3XHttpCacheInterceptorModule.forRoot({ // default request is cache behavior: CachingHeaders.Cache, // in this config, it will cache not globally, but per module store: CachingStore.PerModule, }) ``` ## Example invocation in a component With and without cache: ```ts import { Component } from '@angular/core'; import { HttpClient } from "@angular/common/http"; import {MatSnackBar} from "@angular/material/snack-bar"; import { CachingHeaders } from 'p3x-angular-http-cache-interceptor' @Component({ selector: 'p3x-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { constructor( private http: HttpClient, private snack: MatSnackBar, ) { } async loadCached() { try { const response : any = await this.http.get('https://server.patrikx3.com/api/core/util/random/32').toPromise() this.snack.open(`Will be always the same: ${response.random}`, 'OK') } catch(e) { this.snack.open(`Sorry, error happened, check the console for the error`, 'OK') console.error(e) } } async loadNonCached() { try { const response : any = await this.http.get('https://server.patrikx3.com/api/core/util/random/32', { headers: { [CachingHeaders.NoCache]: '1' } }).toPromise() this.snack.open(`Truly random data: ${response.random}`, 'OK') } catch(e) { this.snack.open(`Sorry, error happened, check the console for the error`, 'OK') console.error(e) } } } ``` [//]: #@corifeus-footer --- 🙏 This is an open-source project. Star this repository, if you like it, or even donate to maintain the servers and the development. Thank you so much! Possible, this server, rarely, is down, please, hang on for 15-30 minutes and the server will be back up. All my domains ([patrikx3.com](https://patrikx3.com) and [corifeus.com](https://corifeus.com)) could have minor errors, since I am developing in my free time. However, it is usually stable. **Note about versioning:** Versions are cut in Major.Minor.Patch schema. Major is always the current year. Minor is either 4 (January - June) or 10 (July - December). Patch is incremental by every build. If there is a breaking change, it should be noted in the readme. --- [**P3X-ANGULAR-HTTP-CACHE-INTERCEPTOR**](https://corifeus.com/angular-http-cache-interceptor) Build v2021.10.161 [![Donate for Corifeus / P3X](https://img.shields.io/badge/Donate-Corifeus-003087.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QZVM4V6HVZJW6) [![Contact Corifeus / P3X](https://img.shields.io/badge/Contact-P3X-ff9900.svg)](https://www.patrikx3.com/en/front/contact) [![Like Corifeus @ Facebook](https://img.shields.io/badge/LIKE-Corifeus-3b5998.svg)](https://www.facebook.com/corifeus.software) ## P3X Sponsor [IntelliJ - The most intelligent Java IDE](https://www.jetbrains.com/?from=patrikx3) [![JetBrains](https://cdn.corifeus.com/assets/svg/jetbrains-logo.svg)](https://www.jetbrains.com/?from=patrikx3) [//]: #@corifeus-footer:end README_Angular.md000066400000000000000000000055361516101643700140230ustar00rootroot00000000000000[//]: #@corifeus-header # 🔥 Cache every request in Angular, not only the GET, but all methods of this interceptor, and allows you to interact with the interceptor via specific headers and modify the request, and these specific headers will be not included in the final request [//]: #@corifeus-header:end # Workspace This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.1. ## Development server Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. ## Code scaffolding Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. ## Build Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. ## Running unit tests Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). ## Running end-to-end tests Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). ## Further help To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). [//]: #@corifeus-footer --- 🙏 This is an open-source project. Star this repository, if you like it, or even donate to maintain the servers and the development. Thank you so much! Possible, this server, rarely, is down, please, hang on for 15-30 minutes and the server will be back up. All my domains ([patrikx3.com](https://patrikx3.com) and [corifeus.com](https://corifeus.com)) could have minor errors, since I am developing in my free time. However, it is usually stable. **Note about versioning:** Versions are cut in Major.Minor.Patch schema. Major is always the current year. Minor is either 4 (January - June) or 10 (July - December). Patch is incremental by every build. If there is a breaking change, it should be noted in the readme. --- [**P3X-ANGULAR-HTTP-CACHE-INTERCEPTOR**](https://corifeus.com/angular-http-cache-interceptor) Build v2021.10.161 [![Donate for Corifeus / P3X](https://img.shields.io/badge/Donate-Corifeus-003087.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QZVM4V6HVZJW6) [![Contact Corifeus / P3X](https://img.shields.io/badge/Contact-P3X-ff9900.svg)](https://www.patrikx3.com/en/front/contact) [![Like Corifeus @ Facebook](https://img.shields.io/badge/LIKE-Corifeus-3b5998.svg)](https://www.facebook.com/corifeus.software) ## P3X Sponsor [IntelliJ - The most intelligent Java IDE](https://www.jetbrains.com/?from=patrikx3) [![JetBrains](https://cdn.corifeus.com/assets/svg/jetbrains-logo.svg)](https://www.jetbrains.com/?from=patrikx3) [//]: #@corifeus-footer:end angular-http-cache-interceptor.iml000066400000000000000000000007111516101643700175670ustar00rootroot00000000000000 angular.json000066400000000000000000000117521516101643700134140ustar00rootroot00000000000000{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { "workspace": { "projectType": "application", "schematics": { "@schematics/angular:component": { "style": "scss" } }, "root": "", "sourceRoot": "src", "prefix": "p3x", "architect": { "build": { "builder": "@angular-devkit/build-angular:browser", "options": { "outputPath": "dist/workspace", "index": "src/index.html", "main": "src/main.ts", "polyfills": "src/polyfills.ts", "tsConfig": "tsconfig.app.json", "assets": [ "src/favicon.ico", "src/assets" ], "styles": [ "src/styles.scss" ], "scripts": [], "vendorChunk": true, "extractLicenses": false, "buildOptimizer": false, "sourceMap": true, "optimization": false, "namedChunks": true }, "configurations": { "production": { "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.prod.ts" } ], "optimization": true, "outputHashing": "all", "sourceMap": false, "namedChunks": false, "extractLicenses": true, "vendorChunk": false, "buildOptimizer": true, "budgets": [ { "type": "initial", "maximumWarning": "2mb", "maximumError": "5mb" }, { "type": "anyComponentStyle", "maximumWarning": "6kb", "maximumError": "10kb" } ] } } }, "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { "browserTarget": "workspace:build" }, "configurations": { "production": { "browserTarget": "workspace:build:production" } } }, "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", "options": { "browserTarget": "workspace:build" } }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { "main": "src/test.ts", "polyfills": "src/polyfills.ts", "tsConfig": "tsconfig.spec.json", "karmaConfig": "karma.conf.js", "assets": [ "src/favicon.ico", "src/assets" ], "styles": [ "src/styles.scss" ], "scripts": [] } }, "lint": { "builder": "@angular-eslint/builder:lint", "options": { "lintFilePatterns": [ "src/**/*.ts", "src/**/*.html" ] } }, "e2e": { "builder": "@angular-devkit/build-angular:protractor", "options": { "protractorConfig": "e2e/protractor.conf.js", "devServerTarget": "workspace:serve" }, "configurations": { "production": { "devServerTarget": "workspace:serve:production" } } } } }, "angular-http-cache-interceptor": { "projectType": "library", "root": "projects/angular-http-cache-interceptor", "sourceRoot": "projects/angular-http-cache-interceptor/src", "prefix": "p3x", "architect": { "build": { "builder": "@angular-devkit/build-angular:ng-packagr", "options": { "tsConfig": "projects/angular-http-cache-interceptor/tsconfig.lib.json", "project": "projects/angular-http-cache-interceptor/ng-package.json" }, "configurations": { "production": { "tsConfig": "projects/angular-http-cache-interceptor/tsconfig.lib.prod.json" } } }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { "main": "projects/angular-http-cache-interceptor/src/test.ts", "tsConfig": "projects/angular-http-cache-interceptor/tsconfig.spec.json", "karmaConfig": "projects/angular-http-cache-interceptor/karma.conf.js" } }, "lint": { "builder": "@angular-eslint/builder:lint", "options": { "lintFilePatterns": [ "projects/angular-http-cache-interceptor/**/*.ts", "projects/angular-http-cache-interceptor/**/*.html" ] } } } } }, "defaultProject": "workspace" } e2e/000077500000000000000000000000001516101643700115355ustar00rootroot00000000000000e2e/protractor.conf.js000066400000000000000000000014501516101643700152160ustar00rootroot00000000000000// @ts-check // Protractor configuration file, see link for more information // https://github.com/angular/protractor/blob/master/lib/config.ts const { SpecReporter } = require('jasmine-spec-reporter'); /** * @type { import("protractor").Config } */ exports.config = { allScriptsTimeout: 11000, specs: [ './src/**/*.e2e-spec.ts' ], capabilities: { browserName: 'chrome' }, directConnect: true, baseUrl: 'http://localhost:4200/', framework: 'jasmine', jasmineNodeOpts: { showColors: true, defaultTimeoutInterval: 30000, print: function() {} }, onPrepare() { require('ts-node').register({ project: require('path').join(__dirname, './tsconfig.json') }); jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); } };e2e/src/000077500000000000000000000000001516101643700123245ustar00rootroot00000000000000e2e/src/app.e2e-spec.ts000066400000000000000000000012021516101643700150510ustar00rootroot00000000000000import { AppPage } from './app.po'; import { browser, logging } from 'protractor'; describe('workspace-project App', () => { let page: AppPage; beforeEach(() => { page = new AppPage(); }); it('should display welcome message', () => { page.navigateTo(); expect(page.getTitleText()).toEqual('workspace app is running!'); }); afterEach(async () => { // Assert that there are no errors emitted from the browser const logs = await browser.manage().logs().get(logging.Type.BROWSER); expect(logs).not.toContain(jasmine.objectContaining({ level: logging.Level.SEVERE, } as logging.Entry)); }); }); e2e/src/app.po.ts000066400000000000000000000004551516101643700140750ustar00rootroot00000000000000import { browser, by, element } from 'protractor'; export class AppPage { navigateTo(): Promise { return browser.get(browser.baseUrl) as Promise; } getTitleText(): Promise { return element(by.css('p3x-root .content span')).getText() as Promise; } } e2e/tsconfig.json000066400000000000000000000003311516101643700142410ustar00rootroot00000000000000{ "extends": "../tsconfig.json", "compilerOptions": { "outDir": "../out-tsc/e2e", "module": "commonjs", "target": "es2018", "types": [ "jasmine", "jasminewd2", "node" ] } } karma.conf.js000066400000000000000000000017751516101643700134510ustar00rootroot00000000000000// Karma configuration file, see link for more information // https://karma-runner.github.io/1.0/config/configuration-file.html module.exports = function (config) { config.set({ basePath: '', frameworks: ['jasmine', '@angular-devkit/build-angular'], plugins: [ require('karma-jasmine'), require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), require('karma-coverage-istanbul-reporter'), require('@angular-devkit/build-angular/plugins/karma') ], client: { clearContext: false // leave Jasmine Spec Runner output visible in browser }, coverageIstanbulReporter: { dir: require('path').join(__dirname, './coverage/workspace'), reports: ['html', 'lcovonly', 'text-summary'], fixWebpackSourcePaths: true }, reporters: ['progress', 'kjhtml'], port: 9876, colors: true, logLevel: config.LOG_INFO, autoWatch: true, browsers: ['Chrome'], singleRun: false, restartOnFileChange: true }); }; package.json000066400000000000000000000101061516101643700133460ustar00rootroot00000000000000{ "name": "p3x-angular-http-cache-interceptor", "version": "2021.10.161", "corifeus": { "icon": "fas fa-fire", "prefix": "p3x-", "publish": true, "type": "p3x", "code": "Breeze", "nodejs": "v16.13.1", "opencollective": false, "reponame": "angular-http-cache-interceptor", "build": true, "cdn": true, "publish-location": "./dist/angular-http-cache-interceptor", "angular": "13.1.0" }, "description": "🔥 Cache every request in Angular, not only the GET, but all methods of this interceptor, and allows you to interact with the interceptor via specific headers and modify the request, and these specific headers will be not included in the final request", "scripts": { "test": "grunt", "ng": "ng", "start": "ng serve --hmr", "build": "ng build", "test2": "ng test", "lint": "ng lint", "e2e": "ng e2e", "build-lib": "ng build --configuration=production --project angular-http-cache-interceptor && cp README.md ./dist/angular-http-cache-interceptor && cp LICENSE ./dist/angular-http-cache-interceptor && node node_modules/corifeus-builder/src/utils/angular/post-lib-build.js", "build-app": "ng build --source-map=false --output-hashing=all --configuration=production --base-href=/ --aot=true --build-optimizer=true --optimization=true && grunt htmlmin:dist", "stats": "ng build --stats-json && webpack-bundle-analyzer dist/workspace/stats.json" }, "repository": { "type": "git", "url": "git+https://github.com/patrikx3/angular-http-cache-interceptor.git" }, "keywords": [ "angular", "cache", "interceptor", "network", "http", "client", "http-client", "header", "headers", "interact", "configuration" ], "author": "Patrik Laszlo ", "license": "MIT", "bugs": { "url": "https://github.com/patrikx3/angular-http-cache-interceptor/issues" }, "homepage": "https://corifeus.com/angular-http-cache-interceptor", "dependencies": { "@angular/animations": "~13.1.0", "@angular/cdk": "^13.1.0", "@angular/common": "~13.1.0", "@angular/compiler": "~13.1.0", "@angular/core": "~13.1.0", "@angular/forms": "~13.1.0", "@angular/material": "^13.1.0", "@angular/platform-browser": "~13.1.0", "@angular/platform-browser-dynamic": "~13.1.0", "@angular/router": "~13.1.0", "@types/node": "^16.11.12", "hash": "^0.2.1", "highlight.js": "^11.3.1", "object": "^0.1.1", "object-hash": "^2.2.0", "postcss": "^8.4.4", "rxjs": "~6.6.3", "tslib": "^2.2.0", "zone.js": "~0.11.4" }, "dependencies-save": { "p3x-interceptor": "npm:p3x-angular-http-cache-interceptor@^2020.4.304" }, "devDependencies": { "@angular-devkit/build-angular": "~13.1.1", "@angular/cli": "~13.1.1", "@angular/compiler-cli": "~13.1.0", "@angular/language-service": "~13.1.0", "@types/highlight.js": "^9.12.4", "@types/jasmine": "~3.10.2", "@types/jasminewd2": "~2.0.10", "@typescript-eslint/eslint-plugin": "5.6.0", "@typescript-eslint/parser": "5.6.0", "codelyzer": "^6.0.2", "corifeus-builder": "^2021.10.206", "eslint": "^8.4.1", "eslint-plugin-import": "2.25.3", "eslint-plugin-jsdoc": "37.2.0", "eslint-plugin-prefer-arrow": "1.2.3", "jasmine-core": "~3.10.1", "jasmine-spec-reporter": "~7.0.0", "karma": "~6.3.2", "karma-chrome-launcher": "~3.1.0", "karma-coverage-istanbul-reporter": "~3.0.3", "karma-jasmine": "~4.0.1", "karma-jasmine-html-reporter": "^1.7.0", "ng-packagr": "^13.0.3", "protractor": "~7.0.0", "ts-node": "~10.4.0", "typescript": "~4.4.4", "webpack-bundle-analyzer": "^4.5.0" }, "engines": { "node": ">=12.13.0" } }projects/000077500000000000000000000000001516101643700127135ustar00rootroot00000000000000projects/angular-http-cache-interceptor/000077500000000000000000000000001516101643700207165ustar00rootroot00000000000000projects/angular-http-cache-interceptor/.eslintrc.json000066400000000000000000000015721516101643700235170ustar00rootroot00000000000000{ "extends": "../../.eslintrc.json", "ignorePatterns": [ "!**/*" ], "overrides": [ { "files": [ "*.ts" ], "parserOptions": { "project": [ "projects/angular-http-cache-interceptor/tsconfig.lib.json", "projects/angular-http-cache-interceptor/tsconfig.spec.json" ], "createDefaultProgram": true }, "rules": { "@angular-eslint/component-selector": [ "error", { "type": "element", "prefix": "p3x", "style": "kebab-case" } ], "@angular-eslint/directive-selector": [ "error", { "type": "attribute", "prefix": "p3x", "style": "camelCase" } ] } }, { "files": [ "*.html" ], "rules": {} } ] } projects/angular-http-cache-interceptor/.gitignore000066400000000000000000000015631516101643700227130ustar00rootroot00000000000000/build /node_modules /*.log /*.iws .idea/workspace.xml .idea/tasks.xml .idea/profiles_settings.xml .idea/inspectionProfiles/Project_Default.xml .idea/inspectionProfiles/profiles_settings.xml node_modules/.yarn-integrity # See http://help.github.com/ignore-files/ for more about ignoring files. # compiled output /dist /release /tmp /out-tsc # Only exists if Bazel was run /bazel-out # dependencies /node_modules # profiling files chrome-profiler-events*.json speed-measure-plugin*.json # IDEs and editors /.idea .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # IDE - VSCode .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json .history/* # misc /.sass-cache /connect.lock /coverage /libpeerconnection.log npm-debug.log yarn-error.log testem.log /typings # System Files .DS_Store Thumbs.db /package-lock.json projects/angular-http-cache-interceptor/README.md000066400000000000000000000022301516101643700221720ustar00rootroot00000000000000# AngularHttpCacheInterceptor This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.3. ## Code scaffolding Run `ng generate component component-name --project angular-http-cache-interceptor` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project angular-http-cache-interceptor`. > Note: Don't forget to add `--project angular-http-cache-interceptor` or else it will be added to the default project in your `angular.json` file. ## Build Run `ng build angular-http-cache-interceptor` to build the project. The build artifacts will be stored in the `dist/` directory. ## Publishing After building your library with `ng build angular-http-cache-interceptor`, go to the dist folder `cd dist/angular-http-cache-interceptor` and run `npm publish`. ## Running unit tests Run `ng test angular-http-cache-interceptor` to execute the unit tests via [Karma](https://karma-runner.github.io). ## Further help To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). projects/angular-http-cache-interceptor/karma.conf.js000066400000000000000000000020261516101643700232730ustar00rootroot00000000000000// Karma configuration file, see link for more information // https://karma-runner.github.io/1.0/config/configuration-file.html module.exports = function (config) { config.set({ basePath: '', frameworks: ['jasmine', '@angular-devkit/build-angular'], plugins: [ require('karma-jasmine'), require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), require('karma-coverage-istanbul-reporter'), require('@angular-devkit/build-angular/plugins/karma') ], client: { clearContext: false // leave Jasmine Spec Runner output visible in browser }, coverageIstanbulReporter: { dir: require('path').join(__dirname, '../../coverage/angular-http-cache-interceptor'), reports: ['html', 'lcovonly', 'text-summary'], fixWebpackSourcePaths: true }, reporters: ['progress', 'kjhtml'], port: 9876, colors: true, logLevel: config.LOG_INFO, autoWatch: true, browsers: ['Chrome'], singleRun: false, restartOnFileChange: true }); }; projects/angular-http-cache-interceptor/ng-package.json000066400000000000000000000002641516101643700236100ustar00rootroot00000000000000{ "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", "dest": "../../dist/angular-http-cache-interceptor", "lib": { "entryFile": "src/public-api.ts" } } projects/angular-http-cache-interceptor/package.json000066400000000000000000000005621516101643700232070ustar00rootroot00000000000000{ "name": "p3x-angular-http-cache-interceptor", "peerDependencies": { "object-hash": "^2.1.1", "@angular/common": "^12.0.0", "@angular/core": "^12.0.0" }, "corifeus": { "install": false }, "devDependencies": { "corifeus-builder": "^2021.4.132" }, "dependencies": { "tslib": "^2.0.3" } }projects/angular-http-cache-interceptor/src/000077500000000000000000000000001516101643700215055ustar00rootroot00000000000000projects/angular-http-cache-interceptor/src/lib/000077500000000000000000000000001516101643700222535ustar00rootroot00000000000000projects/angular-http-cache-interceptor/src/lib/caching-headers.enum.ts000066400000000000000000000001771516101643700266000ustar00rootroot00000000000000// cache headers has to have a x- prefix export enum CachingHeaders { NoCache = "x-p3x-no-cache", Cache = "x-p3x-cache", } projects/angular-http-cache-interceptor/src/lib/caching-store.enum.ts000066400000000000000000000001341516101643700263120ustar00rootroot00000000000000// cache headers has to have a x- prefix export enum CachingStore { Global, PerModule } projects/angular-http-cache-interceptor/src/lib/http-cache-config.token.ts000066400000000000000000000002751516101643700272310ustar00rootroot00000000000000import { InjectionToken } from "@angular/core"; import { HttpCacheConfig } from "./http-cache-config"; export const P3X_HTTP_CACHE_CONFIG = new InjectionToken( 'P3X_HTTP_CACHE_CONFIG' ) projects/angular-http-cache-interceptor/src/lib/http-cache-config.ts000066400000000000000000000003061516101643700261050ustar00rootroot00000000000000import { CachingHeaders} from "./caching-headers.enum"; import { CachingStore } from "./caching-store.enum"; export interface HttpCacheConfig { behavior: CachingHeaders, store: CachingStore, } projects/angular-http-cache-interceptor/src/lib/http-cache-interceptor.interceptor.ts000066400000000000000000000102651516101643700315400ustar00rootroot00000000000000import {Inject, Injectable, Optional} from '@angular/core'; import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http'; import {Observable, of} from 'rxjs'; import * as hash from 'object-hash' import {tap} from "rxjs/operators"; import {CachingHeaders} from "./caching-headers.enum"; import {CachingStore} from "./caching-store.enum"; import {P3X_HTTP_CACHE_CONFIG} from "./http-cache-config.token"; import {HttpCacheConfig} from "./http-cache-config"; const hashOptions = { algorithm: 'md5', encoding: 'hex' } const globalCache = new Map() @Injectable() export class HttpCacheInterceptorInterceptor implements HttpInterceptor { private cachedData = new Map() httpCacheConfig : HttpCacheConfig = { behavior: CachingHeaders.Cache, store: CachingStore.Global, } getCache(key: string) { if (this.httpCacheConfig.store === CachingStore.Global) { return globalCache.get(key) } else { return this.cachedData.get(key) } } setCache(key: string, value: any) { if (this.httpCacheConfig.store === CachingStore.Global) { globalCache.set(key, value) } else { this.cachedData.set(key, value) } } constructor(@Inject(P3X_HTTP_CACHE_CONFIG) @Optional() httpCacheConfigToken: HttpCacheConfig) { if (httpCacheConfigToken) { this.httpCacheConfig = httpCacheConfigToken } } httpToKey(httpRequest: HttpRequest) { const body = JSON.parse(JSON.stringify(httpRequest.body)) const key = httpRequest.method + '@' + httpRequest.urlWithParams + '@' + hash(httpRequest.params, hashOptions) + '@' + hash(body, hashOptions) return key } intercept(httpRequest: HttpRequest, next: HttpHandler): Observable> { //console.log(httpRequest) //console.log('has', httpRequest.headers.has(CachingHeaders.NoCache)) //console.log('value', httpRequest.headers.get(CachingHeaders.NoCache)) const forcedCache = httpRequest.headers.get(CachingHeaders.Cache) !== null const forcedNoneCache = httpRequest.headers.get(CachingHeaders.NoCache) !== null //console.log('forcedCache', forcedCache, 'forcedNoneCache', forcedNoneCache) let headers = httpRequest.headers.delete(CachingHeaders.NoCache) headers = headers.delete(CachingHeaders.Cache) httpRequest = httpRequest.clone({ headers: headers }) if (forcedCache && forcedNoneCache) { throw new Error('You cannot use cache and non-cache header at once!') } else if (forcedNoneCache || (this.httpCacheConfig.behavior === CachingHeaders.NoCache && !forcedCache)) { return next.handle(httpRequest); } else if (forcedCache || (this.httpCacheConfig.behavior === CachingHeaders.Cache && !forcedNoneCache)) { // Checked if there is cached data for this URI const key = this.httpToKey(httpRequest) const lastResponse = this.getCache(key); if (lastResponse) { // In case of parallel requests to same URI, // return the request already in progress // otherwise return the last cached data //console.info('http cache interceptor hit cache', key) return (lastResponse instanceof Observable) ? lastResponse : of(lastResponse.clone()); } //console.info('http cache interceptor', key) // If the request of going through for first time // then let the request proceed and cache the response const requestHandle = next.handle(httpRequest).pipe( tap((stateEvent: any) => { if (stateEvent instanceof HttpResponse) { this.setCache( key, stateEvent.clone() ); } }) ) // Meanwhile cache the request Observable to handle parallel request //this.cachedData.set(key, requestHandle); return requestHandle; } else { console.error(this.httpCacheConfig) console.error(httpRequest.headers) throw new Error('There is a configuration in your setup') } /* // Also leave scope of resetting already cached data for a URI if (httpRequest.headers.get("reset-cache")) { this.cachedData.delete(httpRequest.urlWithParams); } */ } } projects/angular-http-cache-interceptor/src/lib/http-cache-interceptor.module.ts000066400000000000000000000015561516101643700304720ustar00rootroot00000000000000import {ModuleWithProviders, NgModule} from '@angular/core'; import {HTTP_INTERCEPTORS} from "@angular/common/http"; import { HttpCacheInterceptorInterceptor } from './http-cache-interceptor.interceptor' import { P3X_HTTP_CACHE_CONFIG } from "./http-cache-config.token"; import { HttpCacheConfig } from "./http-cache-config"; @NgModule({ declarations: [], imports: [ ], providers: [ { provide: HTTP_INTERCEPTORS, useClass: HttpCacheInterceptorInterceptor, multi: true } ], exports: [] }) export class P3XHttpCacheInterceptorModule { static forRoot(httpCacheConfig: HttpCacheConfig): ModuleWithProviders { return { ngModule: P3XHttpCacheInterceptorModule, providers: [ { provide: P3X_HTTP_CACHE_CONFIG, useValue: httpCacheConfig } ] }; } } projects/angular-http-cache-interceptor/src/public-api.ts000066400000000000000000000004371516101643700241060ustar00rootroot00000000000000/* * Public API Surface of angular-http-cache-interceptor */ export * from './lib/http-cache-interceptor.module'; export * from './lib/caching-headers.enum' export * from './lib/http-cache-config' export * from './lib/http-cache-config.token' export * from './lib/caching-store.enum' projects/angular-http-cache-interceptor/src/test.ts000066400000000000000000000014501516101643700230340ustar00rootroot00000000000000// This file is required by karma.conf.js and loads recursively all the .spec and framework files import 'zone.js'; import 'zone.js/testing'; import { getTestBed } from '@angular/core/testing'; import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; declare const require: { context(path: string, deep?: boolean, filter?: RegExp): { keys(): string[]; (id: string): T; }; }; // First, initialize the Angular testing environment. getTestBed().initTestEnvironment( BrowserDynamicTestingModule, platformBrowserDynamicTesting(), { teardown: { destroyAfterEach: false } } ); // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. context.keys().map(context); projects/angular-http-cache-interceptor/tsconfig.lib.json000066400000000000000000000007171516101643700241770ustar00rootroot00000000000000{ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "../../out-tsc/lib", "declarationMap": true, "target": "es2015", "declaration": true, "inlineSources": true, "types": [], "lib": [ "dom", "es2018" ] }, "angularCompilerOptions": { "skipTemplateCodegen": true, "strictMetadataEmit": true, "enableResourceInlining": true }, "exclude": [ "src/test.ts", "**/*.spec.ts" ] } projects/angular-http-cache-interceptor/tsconfig.lib.prod.json000066400000000000000000000002431516101643700251340ustar00rootroot00000000000000{ "extends": "./tsconfig.lib.json", "compilerOptions": { "declarationMap": false }, "angularCompilerOptions": { "compilationMode": "partial" } } projects/angular-http-cache-interceptor/tsconfig.spec.json000066400000000000000000000003661516101643700243630ustar00rootroot00000000000000{ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "../../out-tsc/spec", "types": [ "jasmine", "node" ] }, "files": [ "src/test.ts" ], "include": [ "**/*.spec.ts", "**/*.d.ts" ] } src/000077500000000000000000000000001516101643700116515ustar00rootroot00000000000000src/app/000077500000000000000000000000001516101643700124315ustar00rootroot00000000000000src/app/app-routing.module.ts000066400000000000000000000015301516101643700165310ustar00rootroot00000000000000import {NgModule} from '@angular/core' import {PreloadAllModules, RouterModule, Routes} from '@angular/router' const routes: Routes = [ { path: 'default', loadChildren: () => import('./default/default.module').then(m => m.DefaultModule) }, { path: 'cache', loadChildren: () => import('./cache/cache.module').then(m => m.CacheModule) }, { path: 'non-cache', loadChildren: () => import('./non-cache/non-cache.module').then(m => m.NonCacheModule) }, { path: '', redirectTo: `/default`, pathMatch: 'full' }, { path: '**', loadChildren: () => import('./not-found/not-found.module').then(m => m.NotFoundModule) } ] @NgModule({ imports: [ RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules, }) ], exports: [RouterModule] }) export class AppRoutingModule { } src/app/app.component.html000066400000000000000000000024121516101643700160770ustar00rootroot00000000000000 P3X Angular HTTP Cache Interceptor v{{ version }} src/app/app.component.scss000066400000000000000000000005671516101643700161170ustar00rootroot00000000000000.list-item-fix { padding-left: 15px; } .ellipsis { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .mat-button-wrapping.mat-button { white-space: normal !important; text-align: left; } .link-fix { $pos: 15px; position: relative; left: -15px; width: calc(100% + 30px); padding-top: $pos; padding-bottom: $pos; text-align: left; } src/app/app.component.spec.ts000066400000000000000000000007461516101643700165220ustar00rootroot00000000000000import { TestBed, waitForAsync } from '@angular/core/testing'; import { AppComponent } from './app.component'; describe('AppComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ AppComponent ], }).compileComponents(); })); it('should create the app', () => { const fixture = TestBed.createComponent(AppComponent); const app = fixture.componentInstance; expect(app).toBeTruthy(); }); }); src/app/app.component.ts000066400000000000000000000016551516101643700155710ustar00rootroot00000000000000import {Component, OnInit} from '@angular/core'; import packageInfo from '../../package.json'; import {Router} from "@angular/router"; @Component({ selector: 'p3x-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent implements OnInit { public version: string = packageInfo.version; navLinks: any[]; activeLinkIndex = -1; constructor(private router: Router) { this.navLinks = [ { label: 'Default', link: './default', index: 0 }, { label: 'Configured caching', link: './cache', index: 1 }, { label: 'Configured non-caching', link: './non-cache', index: 2 }, ]; } ngOnInit(): void { this.router.events.subscribe((res) => { this.activeLinkIndex = this.navLinks.indexOf(this.navLinks.find(tab => tab.link === '.' + this.router.url)); }); } } src/app/app.module.ts000066400000000000000000000016341516101643700150510ustar00rootroot00000000000000import {BrowserModule} from '@angular/platform-browser'; import {NgModule} from '@angular/core'; import {AppComponent} from './app.component'; import {BrowserAnimationsModule} from '@angular/platform-browser/animations' import {MatToolbarModule} from '@angular/material/toolbar'; import { MatTabsModule} from "@angular/material/tabs"; import { AppRoutingModule } from "./app-routing.module"; import {MatCardModule} from "@angular/material/card"; import {MatDividerModule} from "@angular/material/divider"; import {MatButtonModule} from "@angular/material/button"; @NgModule({ declarations: [ AppComponent, ], imports: [ AppRoutingModule, BrowserModule, BrowserAnimationsModule, //MatProgressSpinnerModule, MatButtonModule, MatDividerModule, MatToolbarModule, MatTabsModule, MatCardModule, ], providers: [ ], bootstrap: [AppComponent] }) export class AppModule { } src/app/cache/000077500000000000000000000000001516101643700134745ustar00rootroot00000000000000src/app/cache/bootstrap/000077500000000000000000000000001516101643700155115ustar00rootroot00000000000000src/app/cache/bootstrap/bootstrap.component.html000066400000000000000000000007641516101643700224240ustar00rootroot00000000000000
This is configured to cache, so, it caches everything, unless you use the CachingHeaders.NoCache header in your request. Should you wish to use a per-module cache, in the interceptor configuration, you would use the CachingStore.PerModule store configuration.




src/app/cache/bootstrap/bootstrap.component.scss000066400000000000000000000000001516101643700224120ustar00rootroot00000000000000src/app/cache/bootstrap/bootstrap.component.spec.ts000066400000000000000000000012271516101643700230320ustar00rootroot00000000000000import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { BootstrapComponent } from './bootstrap.component'; describe('BootstrapComponent', () => { let component: BootstrapComponent; let fixture: ComponentFixture; beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ BootstrapComponent ] }) .compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(BootstrapComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); }); src/app/cache/bootstrap/bootstrap.component.ts000066400000000000000000000015051516101643700221000ustar00rootroot00000000000000import { Component, OnInit } from '@angular/core'; import {HighlightService} from "../../common/highlight.service"; @Component({ selector: 'p3x-bootstrap', templateUrl: './bootstrap.component.html', styleUrls: ['./bootstrap.component.scss'] }) export class BootstrapComponent implements OnInit { defaultSettings: string constructor(private service: HighlightService) { } ngOnInit(): void { this.defaultSettings = this.service.hljs.highlight('typescript', `import { P3XHttpCacheInterceptorModule, CachingHeaders, CachingStore } from 'p3x-angular-http-cache-interceptor'; @NgModule({ declarations: [], imports: [ P3XHttpCacheInterceptorModule.forRoot({ behavior: CachingHeaders.Cache, store: CachingStore.Global, }), CommonModule ] }) export class NonCacheModule { }`).value } } src/app/cache/cache-routing.module.ts000066400000000000000000000005611516101643700200620ustar00rootroot00000000000000import {NgModule} from '@angular/core' import {RouterModule, Routes} from '@angular/router' import {BootstrapComponent} from "./bootstrap/bootstrap.component"; const routes: Routes = [ { path: '**', component: BootstrapComponent }, ] @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class CacheRoutingModule { } src/app/cache/cache.module.ts000066400000000000000000000020031516101643700163660ustar00rootroot00000000000000import {NgModule} from '@angular/core'; import {CommonModule as AngularCommonModule} from '@angular/common'; import {BootstrapComponent} from './bootstrap/bootstrap.component'; import {CacheRoutingModule} from "./cache-routing.module"; import {CommonModule} from "../common/common.module"; import {P3XHttpCacheInterceptorModule} from '../../../projects/angular-http-cache-interceptor/src/lib/http-cache-interceptor.module'; import {CachingHeaders} from "../../../projects/angular-http-cache-interceptor/src/lib/caching-headers.enum"; import {CachingStore} from "../../../projects/angular-http-cache-interceptor/src/lib/caching-store.enum"; import { MatDividerModule } from "@angular/material/divider"; @NgModule({ declarations: [ BootstrapComponent, ], imports: [ P3XHttpCacheInterceptorModule.forRoot({ behavior: CachingHeaders.Cache, store: CachingStore.Global, }), AngularCommonModule, CacheRoutingModule, CommonModule, MatDividerModule, ], }) export class CacheModule { } src/app/common/000077500000000000000000000000001516101643700137215ustar00rootroot00000000000000src/app/common/common.module.ts000066400000000000000000000014521516101643700170470ustar00rootroot00000000000000import { NgModule } from '@angular/core'; import { CommonModule as AngularCommonModule } from '@angular/common'; import { DefaultComponentComponent } from './default-component/default-component.component'; import {MatSnackBarModule} from "@angular/material/snack-bar"; import {MatButtonModule} from "@angular/material/button"; import {MatDividerModule} from "@angular/material/divider"; import {HttpClientModule} from "@angular/common/http"; import { HighlightService } from "./highlight.service"; @NgModule({ declarations: [DefaultComponentComponent], imports: [ AngularCommonModule, MatSnackBarModule, MatButtonModule, MatDividerModule, HttpClientModule, ], providers: [ HighlightService ], exports: [ DefaultComponentComponent, ] }) export class CommonModule { } src/app/common/default-component/000077500000000000000000000000001516101643700173455ustar00rootroot00000000000000src/app/common/default-component/default-component.component.html000066400000000000000000000022111516101643700256540ustar00rootroot00000000000000


Itt will try to load some random data, based on the default interceptor behavior without using headers.




Itt will try to load some random data with cached data. You can see in the browser inspector network tab, that there will be only one request. Here, we use the CachingHeaders.Cache header.




It will try to load some random data without cache. You can see in the browser inspector network tab, that every click will talk to a server and retrieve the new data. Here, we use the CachingHeaders.NoCache header.
src/app/common/default-component/default-component.component.scss000066400000000000000000000000001516101643700256550ustar00rootroot00000000000000src/app/common/default-component/default-component.component.spec.ts000066400000000000000000000013111516101643700262670ustar00rootroot00000000000000import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { DefaultComponentComponent } from './default-component.component'; describe('DefaultComponentComponent', () => { let component: DefaultComponentComponent; let fixture: ComponentFixture; beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ DefaultComponentComponent ] }) .compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(DefaultComponentComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); }); src/app/common/default-component/default-component.component.ts000066400000000000000000000043451516101643700253500ustar00rootroot00000000000000import {Component, ViewEncapsulation} from '@angular/core'; import { HttpClient } from "@angular/common/http"; import {MatSnackBar, MatSnackBarConfig} from "@angular/material/snack-bar"; import { CachingHeaders} from "../../../../projects/angular-http-cache-interceptor/src/lib/caching-headers.enum"; @Component({ selector: 'p3x-default-component', templateUrl: './default-component.component.html', styleUrls: ['./default-component.component.scss'], //FIXME why do we have to use ViewEncapsulation.None? //encapsulation: ViewEncapsulation.None }) export class DefaultComponentComponent { defaultSnackbarSettings : MatSnackBarConfig = { horizontalPosition: "center", verticalPosition: "bottom" } constructor( private http: HttpClient, private snack: MatSnackBar, ) { } async loadDefault() { try { const response : any = await this.http.get('https://server.patrikx3.com/api/core/util/random/32').toPromise() this.snack.open(`The output is based on the default interceptor behavior: ${response.random}`, 'OK', this.defaultSnackbarSettings) } catch(e) { this.snack.open(`Sorry, error happened, check the console for the error`, 'OK', this.defaultSnackbarSettings) console.error(e) } } async loadCached() { try { const response : any = await this.http.get('https://server.patrikx3.com/api/core/util/random/32', { headers: { [CachingHeaders.Cache]: '1', } }).toPromise() this.snack.open(`Will be always the same output: ${response.random}`, 'OK', this.defaultSnackbarSettings) } catch(e) { this.snack.open(`Sorry, error happened, check the console for the error`, 'OK', this.defaultSnackbarSettings) console.error(e) } } async loadNonCached() { try { const response : any = await this.http.get('https://server.patrikx3.com/api/core/util/random/16', { headers: { [CachingHeaders.NoCache]: '1', } }).toPromise() this.snack.open(`Truly random data: ${response.random}`, 'OK', this.defaultSnackbarSettings) } catch(e) { this.snack.open(`Sorry, error happened, check the console for the error`, 'OK', this.defaultSnackbarSettings) console.error(e) } } } src/app/common/highlight.service.ts000066400000000000000000000005121516101643700176750ustar00rootroot00000000000000import { Injectable } from '@angular/core'; import hljs from 'highlight.js/lib/core'; import typescript from 'highlight.js/lib/languages/typescript'; hljs.registerLanguage('typescript', typescript); @Injectable({ providedIn: 'root' }) export class HighlightService { constructor() { } get hljs() { return hljs } } src/app/default/000077500000000000000000000000001516101643700140555ustar00rootroot00000000000000src/app/default/bootstrap/000077500000000000000000000000001516101643700160725ustar00rootroot00000000000000src/app/default/bootstrap/bootstrap.component.html000066400000000000000000000007351516101643700230030ustar00rootroot00000000000000
This is the default settings. By default, it caches everything, unless you use the CachingHeaders.NoCache header in your request. Besides, the cache is using a global store, unless you use the CachingStore.PerModule store configuration.




src/app/default/bootstrap/bootstrap.component.scss000066400000000000000000000000001516101643700227730ustar00rootroot00000000000000src/app/default/bootstrap/bootstrap.component.spec.ts000066400000000000000000000012271516101643700234130ustar00rootroot00000000000000import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { BootstrapComponent } from './bootstrap.component'; describe('BootstrapComponent', () => { let component: BootstrapComponent; let fixture: ComponentFixture; beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ BootstrapComponent ] }) .compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(BootstrapComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); }); src/app/default/bootstrap/bootstrap.component.ts000066400000000000000000000013141516101643700224570ustar00rootroot00000000000000import { Component, OnInit } from '@angular/core'; import {HighlightService} from "../../common/highlight.service"; @Component({ selector: 'p3x-bootstrap', templateUrl: './bootstrap.component.html', styleUrls: ['./bootstrap.component.scss'] }) export class BootstrapComponent implements OnInit { defaultSettings: string constructor(private service: HighlightService) { } ngOnInit(): void { this.defaultSettings = this.service.hljs.highlight('typescript', `import { P3XHttpCacheInterceptorModule } from 'p3x-angular-http-cache-interceptor'; @NgModule({ declarations: [], imports: [ P3XHttpCacheInterceptorModule, CommonModule, ] }) export class DefaultModule { }`).value } } src/app/default/default-routing.module.ts000066400000000000000000000005631516101643700210260ustar00rootroot00000000000000import {NgModule} from '@angular/core' import {RouterModule, Routes} from '@angular/router' import {BootstrapComponent} from "./bootstrap/bootstrap.component"; const routes: Routes = [ { path: '**', component: BootstrapComponent }, ] @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class DefaultRoutingModule { } src/app/default/default.module.ts000066400000000000000000000016241516101643700173400ustar00rootroot00000000000000import { NgModule } from '@angular/core'; import { CommonModule as AngularCommonModule } from '@angular/common'; import { BootstrapComponent } from './bootstrap/bootstrap.component'; import {DefaultRoutingModule} from "./default-routing.module"; import {CommonModule} from "../common/common.module"; import {P3XHttpCacheInterceptorModule} from '../../../projects/angular-http-cache-interceptor/src/lib/http-cache-interceptor.module'; //import {CachingHeaders} from "../../../projects/angular-http-cache-interceptor/src/lib/caching-headers.enum"; //import { P3XHttpCacheInterceptorModule } from 'p3x-interceptor' import { MatDividerModule } from "@angular/material/divider"; @NgModule({ declarations: [ BootstrapComponent, ], imports: [ P3XHttpCacheInterceptorModule, AngularCommonModule, DefaultRoutingModule, CommonModule, MatDividerModule, ], }) export class DefaultModule { } src/app/non-cache/000077500000000000000000000000001516101643700142645ustar00rootroot00000000000000src/app/non-cache/bootstrap/000077500000000000000000000000001516101643700163015ustar00rootroot00000000000000src/app/non-cache/bootstrap/bootstrap.component.html000066400000000000000000000007341516101643700232110ustar00rootroot00000000000000
This is configured to not cache, unless you use the CachingHeaders.Cache header in your request. Should you wish to use a per-module cache, in the interceptor configuration, you would use the CachingStore.PerModule store configuration.




src/app/non-cache/bootstrap/bootstrap.component.scss000066400000000000000000000000001516101643700232020ustar00rootroot00000000000000src/app/non-cache/bootstrap/bootstrap.component.spec.ts000066400000000000000000000012271516101643700236220ustar00rootroot00000000000000import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { BootstrapComponent } from './bootstrap.component'; describe('BootstrapComponent', () => { let component: BootstrapComponent; let fixture: ComponentFixture; beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ BootstrapComponent ] }) .compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(BootstrapComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); }); src/app/non-cache/bootstrap/bootstrap.component.ts000066400000000000000000000015101516101643700226640ustar00rootroot00000000000000import { Component, OnInit } from '@angular/core'; import {HighlightService} from "../../common/highlight.service"; @Component({ selector: 'p3x-bootstrap', templateUrl: './bootstrap.component.html', styleUrls: ['./bootstrap.component.scss'] }) export class BootstrapComponent implements OnInit { defaultSettings: string constructor(private service: HighlightService) { } ngOnInit(): void { this.defaultSettings = this.service.hljs.highlight('typescript', `import { P3XHttpCacheInterceptorModule, CachingHeaders, CachingStore } from 'p3x-angular-http-cache-interceptor'; @NgModule({ declarations: [], imports: [ P3XHttpCacheInterceptorModule.forRoot({ behavior: CachingHeaders.NoCache, store: CachingStore.Global, }), CommonModule ] }) export class NonCacheModule { }`).value } } src/app/non-cache/non-cache-routing.module.ts000066400000000000000000000005641516101643700214450ustar00rootroot00000000000000import {NgModule} from '@angular/core' import {RouterModule, Routes} from '@angular/router' import {BootstrapComponent} from "./bootstrap/bootstrap.component"; const routes: Routes = [ { path: '**', component: BootstrapComponent }, ] @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class NonCacheRoutingModule { } src/app/non-cache/non-cache.module.ts000066400000000000000000000020221516101643700177470ustar00rootroot00000000000000import { NgModule } from '@angular/core'; import { CommonModule as AngularCommonModule } from '@angular/common'; import { BootstrapComponent } from './bootstrap/bootstrap.component'; import {NonCacheRoutingModule} from "./non-cache-routing.module"; import {CommonModule} from "../common/common.module"; import {P3XHttpCacheInterceptorModule} from '../../../projects/angular-http-cache-interceptor/src/lib/http-cache-interceptor.module'; import {CachingHeaders} from "../../../projects/angular-http-cache-interceptor/src/lib/caching-headers.enum"; import {CachingStore} from "../../../projects/angular-http-cache-interceptor/src/lib/caching-store.enum"; import { MatDividerModule } from "@angular/material/divider"; @NgModule({ declarations: [BootstrapComponent], imports: [ P3XHttpCacheInterceptorModule.forRoot({ behavior: CachingHeaders.NoCache, store: CachingStore.Global, }), NonCacheRoutingModule, AngularCommonModule, CommonModule, MatDividerModule, ], }) export class NonCacheModule { } src/app/not-found/000077500000000000000000000000001516101643700143425ustar00rootroot00000000000000src/app/not-found/not-found-routing.module.ts000066400000000000000000000005571516101643700216030ustar00rootroot00000000000000import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import {NotFoundComponent} from "./not-found.component"; const routes: Routes = [ { path: '**', component: NotFoundComponent }, ]; @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class NotFoundRoutingModule { } src/app/not-found/not-found.component.html000066400000000000000000000000511516101643700211360ustar00rootroot00000000000000

404 Not found

src/app/not-found/not-found.component.scss000066400000000000000000000000001516101643700211370ustar00rootroot00000000000000src/app/not-found/not-found.component.ts000066400000000000000000000004371516101643700206300ustar00rootroot00000000000000import { Component, OnInit } from '@angular/core'; @Component({ selector: 'p3x-not-found', templateUrl: './not-found.component.html', styleUrls: ['./not-found.component.scss'] }) export class NotFoundComponent implements OnInit { constructor() { } ngOnInit(): void { } } src/app/not-found/not-found.module.ts000066400000000000000000000005551516101643700201140ustar00rootroot00000000000000import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { NotFoundRoutingModule } from './not-found-routing.module'; import { NotFoundComponent } from './not-found.component'; @NgModule({ declarations: [NotFoundComponent], imports: [ CommonModule, NotFoundRoutingModule ] }) export class NotFoundModule { } src/assets/000077500000000000000000000000001516101643700131535ustar00rootroot00000000000000src/assets/.gitkeep000066400000000000000000000000001516101643700145720ustar00rootroot00000000000000src/environments/000077500000000000000000000000001516101643700144005ustar00rootroot00000000000000src/environments/environment.prod.ts000066400000000000000000000000631516101643700202560ustar00rootroot00000000000000export const environment = { production: true }; src/environments/environment.ts000066400000000000000000000012301516101643700173100ustar00rootroot00000000000000// This file can be replaced during build by using the `fileReplacements` array. // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. // The list of file replacements can be found in `angular.json`. export const environment = { production: false }; /* * For easier debugging in development mode, you can import the following file * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. * * This import should be commented out in production mode because it will have a negative impact * on performance if an error is thrown. */ //import 'zone.js/plugins/zone-error'; // Included with Angular CLI. src/favicon.ico000066400000000000000000000764461516101643700140130ustar00rootroot00000000000000 hF 00 %V@@ (B:(  @]KI]KI;]KI\JI]KI]KIc]KI]KI]KIq]KI]KI]KI\JH]KI]KI]KI]KI7]KI]KI]KI-]KI]KI]KHM]KI]KI]KI]KI]KI]KIC]KI]KI]KI]KIi]KI]KI]KI]KI]KI]KI]KI]KI\KI]KI]KI]KH]KI]KI]KI]KI9]KI]KI]KI\KH\KHw\KI]KI]KI]KI\KI1]JI]KI]KI]KI]KH]KI]KI]KI \KI]KI]KI]KI5]KI'\KI]KI%]KI \KI]KI]KI+\KI]KI( @ ]KIC]KH]KI-]KI]KH]KI]KI]KI]KIQ]KI_]KI]KH]KI \JI]KI]KI]KI]JI]KI]KI]KI;]KI]KI]KI7]KI]KI]KI]KI]KI]KI]KI]KI ]KI ]KI]KI]KI]KI]KI{]KI]KH]KIc]KIc]KI]KI]KI]KI)]KI%]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]JI\JI]KI]KI]KI]KI]KI]KIk]KIM]KI]KI]KI]KI]KI]KI]KI9]KI7]KI]KI]KI]KI]KI]KI ]KI]KI]KI]KI]KI]KI]KI]KI]KH ]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KH]KI]KI]KI]KH]KIW]KI+]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]JH\JH]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KIW]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KH]KIE]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI ]KI]KI]KI]KI]KI]KI]KI]KI]KI\KI]]KI]KI]KI]KI]KI\KI]KI1]KI]KI]KI]KI]KI]KI]KI\KI]KI]KI]KI]KI]KI]KI]KI3]KH]KI]KI]KI]KI]KI]KI]KI\KI#]KI/]KI]KI]KI\KI]KI]KI]KI]KI]KI]KI]KI]KI\KI]JH]KI\KI\KIq]KI]KI]KI]KI]KI]KH]KI3]KI ]KI]KI]KI!]KI]KI]KI]KI]KI]JI=]KIo]KI]KI]KI]KIC\KI]KI_\JI(0` %\KHM]JI]KI]KI!\JH\JH]KI]]KI]KI]JH\JH]KIC]KIK]KI\KI]KI]KI]KI]KI\JH]KI]KH]KI]KI]KH]JH]KI-]KI)\KH]KI\KI\KI]KI]KI]KI\JH\JH\KHm]KIU]KI]KI]KI]JH]KI]KH]KI+]KI]KI\KH]JI\JH\JH]KH\JI\KI=\JH]JI]KI']KI]KI]KI\JH\JH]KI]KHU\KI ]JI]KI]KH]KI]KI]JH5\KH]KI]KI]KI]KI\KI]KIa]KI]KI]KI\JI]KIE]KH ]KI\JH]KI\JH\JH\JI]KI]KI]KI]KI]KI]KH\JH]KI]KI]KH]]JI\JH]KI]KI]KH]KIE]KI]KI]KI\KI]KI]KI\JH]KI]KHs\KI]KI]KI]KI\JH]KH]KI]KI\KH]KI;]KI]KH]KI]KI]KI]KI]KI]KI]KI%\KI]KI]KI]KI]KI]KI]KI]KI]KI]KI ]KI]KI]KH]KI]KI]KI]KI]JH]KI]KI\KI]KI1\KH]KI]KI]KI]KI]KI\KI3]KIc]JH]KH\JH\JH]KH]KI\KI\JH\JH\KH]JHE]KH ]KI\JH\JH]KH\JH\KI]KI]KI ]JI]JI]KI]KI]JI]KI]KI]KI]KI]KI]KI]KI]KI]KI \KI_]KI]JI]KI]KI]KI]KI]KIu]KI]KI]KH]KI]JH]KI]KI]KI]KI]KI]KI]KI]KI]KI\KI]KI]JH]KI]KI]KI\KI]KH%]KI?\JI\KH]KI]KI\JH]KI]KI]KI\KH]KI]KI\JH\JH\JH\JH\JH\JH]KI]KI\KH]KI]KI ]KI ]JI]KI]KI]KI]KI]KH]KI]KH]KI\JH]KI]KI]KI]KI]KI]KI]KI]KH]KI]KH]JI]KI_\KIo]KI]KI\JH]KH]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI%\KH]KI\KH\KH]KI\KH]KH\JH]KI]KI]KI]KI]KH\JH]KI\JH\KI]KI]KH\JH]KI\KI]JH]JI]KI\JI]JH]KI\JH]KI]KI]KI]KI]KH]JH]KI]JH]JH]KI]KI]KH]KI]KI]KI]KI]KH]KIQ]KIM]KI]KI]KI]KI\JH]JH]KI]KI]KI]KI]KH]KI]KI]KH\JH]KI]KH]KI]KI]KI]KI]KI]KI]KI]JI\KH\JH]KI\JH\JH]KI\JH]KI\KI]KI]KI[]KI#]KI]KI]KI]KI]KH]KI\JH]KI\KI]KI\KIw]KI]KI]KI]KH]KI]KI]KI]KI]KH]KI]KI\JI]JIg]KH\JH]KI]JI]KI]KI]KH\JH]KI?]KI+\JH\JI]KI\JH]KI]KI]JH\JH]KI\JH\JH]KIm]KH \KH\JH]KI\JH]KH]KI\JH]KH]KI ]KI]JI]KI]KI\KH\JH]KI]KI\JH]KI\JH]JH]KI\KH\KI9]KI]KH]KH]KH]JI]JH]KH}]KI\JI]KI\KH]KI]KI\JH]KI]JI]JI]KI]KI\KI\JI]KI]KI]KI]KI]JH]KI1]KIA]KH]KI]KI]KI]KI]KI]KI]KI]KI\KI]JH#]KI]KI\JH\KH]KI]KI]KI]KIC]KI]KI]KI]KI]KI\JH]KI\KI]JH]KIY]JI]KI\JI\KHi\JIE\KI\JH]KI]KI\JH]KI]JH]KH3\KI]JI]KI]KH]KI]KIE\KI]KI]KI\JH]KI]KI]KI-\KI]KH\JIE]KI]KI\JI]KI]KI?]KIC]KH]KI\JH]KI]JI=]KI]KI7(@ B\KIQ]JH]KIo]KI ]KI]KI]KI]KI]KI-]KI ]JH]KI]KI]KI]KI-]KIG]KI]KI]KI\KI]KI]KI]KI]KI]KI]KI]KIo]KH]KIm]KI]KI]KI]KI]KI']KI+\JI]KI]KI]KI]KI]KI]KI]JI]KI]KI\KI]KIY]JHC]KI]KI]KI]KI]KI]KI+]KI]KI]KI]KI]KI]KI]KI]JI]KI\KIg]KI]KI]KI]KI]KI]KIK\KI1]KI]KI]KI]KI]KI]KI]KI]KI ]KIE]KI3]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KIo]KI]KI]JII]KIC]KI]KI]KI]KI]KI]KI\KIA\KI5]KI]KI]KI\KI]KI!]KI]KI]KI]KI]KI]KI]KI]KI]KI\KI]KI]KI]KI]KI\KIu]KIy]KI]KI]KI]KI]KI]KI]KI{]KI]KIU]KH]KI]KI]KI]KI]KI\KI1\JH%]KI]KI]KI]KI]KI]KI]KI\KI%]KI]KI\JI]KI]KI]KI]KI]KI]KI]KI]KH ]KI]KI]KI]KI]KI]KI]KI\JH]KI ]KI}]KI]KI]KI]KI]KI]KI]KI]KI]KIU]JHW]KI]KI]KI]KI]KI]KI]KI]KIe]KI1]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI\KH]KI]KI]KI]KI]KI]KI]KI]KI\JH]KI)]JH ]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI\JI]KI\KH]KI]KI]KI]KI]KI]KI]KI]KI]KI\JIS]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI\KI]KI-]KI1]KI]KI]KI]KI]KI]KI]KI]KI]KIM]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI ]KI]KI]KI]KI]KI]KI]KI]KI]KH]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KH]KIa]KI]KI_]KI]KI]KI]KI]KI]KI]KI]KI\KH]KI]KI#]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KII]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]JI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]]JI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI\KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KH1]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]JI]KI]JI9]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KIk\JH ]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI_]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI%]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KH]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI[]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KH]KI}]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]JI]JI']KIG]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI ]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI\KHI]KI)]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KIE]KIa]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KIm]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI ]KI-]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI\KI]JHM]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI\KI]KI ]KII]KI]KI]KI]KI]KI]KI]KI]KI]KI]KHC]KI)]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]JI]KIg]KI ]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI ]KI-]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI#]KI]KI]KI]KI]KI]KI]KI]KHu]KIk]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]JIm]KIc]KI]KI]KI]KI]KI]KI]KI!]KI \KIk]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI]KI%]KI]KI]KI]KI]KI]KI]KI]KI ]KI]KIo\KI]KI]KI]KI]KI]KI]KI]KI]KI]KH]KI]KI]KI/]JI]KI]KI\JH]KHa]KH ]KIk]KI]KI]KI]KI]KI]KI]KI]KI]KH]KI5]KI]KI]KI]KI]KI]KI\JH]KIo]KI]KI]KI]KI]KI]KI]KI]KH]JH%]KI]KI]KI\JH]KIk\KI]KI]KI]KI]KI]KI]KI;]KI]KI]KI ]KH ]KIo]KI]KI]KI]KI]KI\KH]KI\KIk]KI]KI]KI]KIG]KI ]KIc\KI]KI\JI src/index.html000066400000000000000000000010311516101643700136410ustar00rootroot00000000000000 P3X Angular HTTP Cache Interceptor src/main.ts000066400000000000000000000007231516101643700131470ustar00rootroot00000000000000import { enableProdMode } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; window['corifeus'] = { core: { http: { status: 200, counter: 0, } } } if (environment.production) { enableProdMode(); } platformBrowserDynamic().bootstrapModule(AppModule) .catch(err => console.error(err)); src/polyfills.ts000066400000000000000000000044441516101643700142440ustar00rootroot00000000000000/** * This file includes polyfills needed by Angular and is loaded before the app. * You can add your own extra polyfills to this file. * * This file is divided into 2 sections: * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. * 2. Application imports. Files imported after ZoneJS that should be loaded before your main * file. * * The current setup is for so-called "evergreen" browsers; the last versions of browsers that * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. * * Learn more in https://angular.io/guide/browser-support */ /*************************************************************************************************** * BROWSER POLYFILLS */ /** * By default, zone.js will patch all possible macroTask and DomEvents * user can disable parts of macroTask/DomEvents patch by setting following flags * because those flags need to be set before `zone.js` being loaded, and webpack * will put import in the top of bundle, so user need to create a separate file * in this directory (for example: zone-flags.ts), and put the following flags * into that file, and then add the following code before importing zone.js. * import './zone-flags'; * * The flags allowed in zone-flags.ts are listed here. * * The following flags will work for all browsers. * * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames * * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js * with the following flag, it will bypass `zone.js` patch for IE/Edge * * (window as any).__Zone_enable_cross_context_check = true; * */ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ import 'zone.js'; // Included with Angular CLI. /*************************************************************************************************** * APPLICATION IMPORTS */ src/styles.scss000066400000000000000000000051351516101643700140750ustar00rootroot00000000000000@use '@angular/material' as mat; @import '~highlight.js/scss/idea'; // Custom Theming for Angular Material // For more information: https://material.angular.io/guide/theming // Plus imports for other components in your app. // Include the common styles for Angular Material. We include this here so that you only // have to load a single css file for Angular Material in your app. // Be sure that you only ever include this mixin once! @include mat.core(); // Define the palettes for your theme using the Material Design palettes available in palette.scss // (imported above). For each palette, you can optionally specify a default, lighter, and darker // hue. Available color palettes: https://material.io/design/color/ $workspace-primary: mat.define-palette(mat.$green-palette); $workspace-accent: mat.define-palette(mat.$purple-palette, A200, A100, A400); // The warn palette is optional (defaults to red). $workspace-warn: mat.define-palette(mat.$red-palette); // Create the theme object (a Sass map containing all of the palettes). $workspace-theme: mat.define-light-theme($workspace-primary, $workspace-accent, $workspace-warn); // Include theme styles for core and each component used in your app. // Alternatively, you can import and @include the theme mixins for each component // that you are using. //@include mat.all-component-themes($workspace-theme); @include mat.core-theme($workspace-theme); @include mat.divider-theme($workspace-theme); //@include mat.progress-spinner-theme($workspace-theme); @include mat.toolbar-theme(mat.define-light-theme( mat.define-palette(mat.$blue-gray-palette, 600), mat.define-palette(mat.$deep-orange-palette), mat.define-palette(mat.$green-palette) )); @include mat.snack-bar-theme(mat.define-light-theme( mat.define-palette(mat.$blue-grey-palette), mat.define-palette(mat.$blue-grey-palette), mat.define-palette(mat.$green-palette) )); @include mat.button-theme( mat.define-light-theme( mat.define-palette(mat.$blue-palette, 800), mat.define-palette(mat.$orange-palette, 900), mat.define-palette(mat.$green-palette) )); @include mat.card-theme($workspace-theme); @include mat.tabs-theme(mat.define-light-theme( mat.define-palette(mat.$blue-grey-palette, 100), mat.define-palette(mat.$blue-grey-palette, 900), mat.define-palette(mat.$green-palette) )); /* You can add global styles to this file, and also import other style files */ html, body { height: 100%; } body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; background-color: mat.get-color-from-palette(mat.$gray-palette, 200); } .p3x-ng-http-pre { overflow: auto; } src/test.ts000066400000000000000000000014261516101643700132030ustar00rootroot00000000000000// This file is required by karma.conf.js and loads recursively all the .spec and framework files import 'zone.js/testing'; import { getTestBed } from '@angular/core/testing'; import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; declare const require: { context(path: string, deep?: boolean, filter?: RegExp): { keys(): string[]; (id: string): T; }; }; // First, initialize the Angular testing environment. getTestBed().initTestEnvironment( BrowserDynamicTestingModule, platformBrowserDynamicTesting(), { teardown: { destroyAfterEach: false } } ); // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. context.keys().map(context); tsconfig.app.json000066400000000000000000000003221516101643700143450ustar00rootroot00000000000000{ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, "files": [ "src/main.ts", "src/polyfills.ts" ], "include": [ "src/**/*.d.ts" ] } tsconfig.json000066400000000000000000000013661516101643700135770ustar00rootroot00000000000000{ "compileOnSave": false, "compilerOptions": { "allowSyntheticDefaultImports": true, "resolveJsonModule": true, "baseUrl": "./", "outDir": "./dist/out-tsc", "sourceMap": true, "declaration": false, "downlevelIteration": true, "experimentalDecorators": true, "module": "es2020", "moduleResolution": "node", "importHelpers": true, "target": "es2015", "lib": [ "es2018", "dom" ], "paths": { "angular-http-cache-interceptor": [ "dist/angular-http-cache-interceptor/angular-http-cache-interceptor", "dist/angular-http-cache-interceptor" ] } }, "angularCompilerOptions": { "fullTemplateTypeCheck": true, "strictInjectionParameters": true } } tsconfig.spec.json000066400000000000000000000004161516101643700145230ustar00rootroot00000000000000{ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/spec", "types": [ "jasmine", "node" ] }, "files": [ "src/test.ts", "src/polyfills.ts" ], "include": [ "src/**/*.spec.ts", "src/**/*.d.ts" ] }