mirror of https://github.com/waku-org/js-waku.git
Angular js example for relay best practices (#549)
Co-authored-by: Franck Royer <franck@status.im>
This commit is contained in:
parent
c60811852d
commit
da52903357
|
@ -12,7 +12,7 @@ jobs:
|
|||
examples_build_and_test:
|
||||
strategy:
|
||||
matrix:
|
||||
example: [ web-chat, eth-pm, eth-pm-wallet-encryption, relay-reactjs-chat, store-reactjs-chat ]
|
||||
example: [ web-chat, eth-pm, eth-pm-wallet-encryption, relay-reactjs-chat, store-reactjs-chat, relay-angular-chat ]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
|
@ -24,7 +24,14 @@ jobs:
|
|||
with:
|
||||
node-version: '16'
|
||||
|
||||
- name: Cache npm cache
|
||||
- name: Check if `yarn` or `npm` is used.
|
||||
id: use-yarn
|
||||
shell: bash
|
||||
run: echo "::set-output name=lockfile::$(ls yarn.lock 2> /dev/null)"
|
||||
working-directory: examples/${{ matrix.example }}
|
||||
|
||||
- name: (npm) Cache npm cache
|
||||
if: steps.use-yarn.outputs.lockfile != 'yarn.lock'
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.npm
|
||||
|
@ -36,10 +43,22 @@ jobs:
|
|||
- name: "[js-waku] build"
|
||||
run: npm run build
|
||||
|
||||
- name: ${{ matrix.example }} install using npm i
|
||||
- name: (npm) ${{ matrix.example }} install using npm i
|
||||
if: steps.use-yarn.outputs.lockfile != 'yarn.lock'
|
||||
run: npm install
|
||||
working-directory: examples/${{ matrix.example }}
|
||||
|
||||
- name: ${{ matrix.example }} test
|
||||
- name: (npm) ${{ matrix.example }} test
|
||||
if: steps.use-yarn.outputs.lockfile != 'yarn.lock'
|
||||
run: npm run test
|
||||
working-directory: examples/${{ matrix.example }}
|
||||
|
||||
- name: (yarn) ${{ matrix.example }} install using yarn
|
||||
if: steps.use-yarn.outputs.lockfile == 'yarn.lock'
|
||||
run: yarn install --frozen-lockfile
|
||||
working-directory: examples/${{ matrix.example }}
|
||||
|
||||
- name: (yarn) ${{ matrix.example }} test
|
||||
if: steps.use-yarn.outputs.lockfile == 'yarn.lock'
|
||||
run: echo "test skipped" # yarn test; tracked with https://github.com/status-im/js-waku/issues/563
|
||||
working-directory: examples/${{ matrix.example }}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.idea/*
|
||||
.nyc_output
|
||||
.angular
|
||||
build
|
||||
node_modules
|
||||
src/**.js
|
||||
coverage
|
||||
*.log
|
||||
yarn.lock
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
# Minimal Angular (v13) Waku Relay App
|
||||
|
||||
**Demonstrates**:
|
||||
|
||||
- Group messaging
|
||||
- Angular/JavaScript
|
||||
- Waku Relay
|
||||
- Protobuf using `protons`
|
||||
- No async/await syntax
|
||||
|
||||
A barebones messaging app to illustrate the [Angular Relay guide](https://docs.wakuconnect.dev/docs/guides/10_angular_relay/).
|
||||
|
||||
To run a development version locally, do:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/status-im/js-waku/ ; cd js-waku
|
||||
npm install # Install dependencies for js-waku
|
||||
npm run build # Build js-waku
|
||||
cd examples/relay-reactjs-chat
|
||||
yarn # Install dependencies for the web app
|
||||
yarn start # Start development server to serve the web app on http://localhost:4200/
|
||||
```
|
||||
|
||||
### Known issues
|
||||
|
||||
There is a problem when using `npm` to install/run the Angular app.
|
|
@ -0,0 +1,130 @@
|
|||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"relay-angular-chat": {
|
||||
"projectType": "application",
|
||||
"schematics": {
|
||||
"@schematics/angular:application": {
|
||||
"strict": true
|
||||
}
|
||||
},
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"prefix": "app",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist/relay-angular-chat",
|
||||
"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.css"
|
||||
],
|
||||
"scripts": [],
|
||||
"allowedCommonJsDependencies": [
|
||||
"libp2p-gossipsub/src/utils",
|
||||
"rlp",
|
||||
"multiaddr/src/convert",
|
||||
"varint",
|
||||
"multihashes",
|
||||
"@chainsafe/libp2p-noise/dist/src/noise",
|
||||
"debug",
|
||||
"libp2p",
|
||||
"libp2p-bootstrap",
|
||||
"libp2p-crypto",
|
||||
"libp2p-websockets",
|
||||
"libp2p-websockets/src/filters",
|
||||
"libp2p/src/ping",
|
||||
"multiaddr",
|
||||
"peer-id",
|
||||
"buffer",
|
||||
"crypto",
|
||||
"ecies-geth",
|
||||
"secp256k1",
|
||||
"libp2p-gossipsub",
|
||||
"it-concat",
|
||||
"protons"
|
||||
]
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "500kb",
|
||||
"maximumError": "1mb"
|
||||
},
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
"maximumWarning": "2kb",
|
||||
"maximumError": "4kb"
|
||||
}
|
||||
],
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"buildOptimizer": false,
|
||||
"optimization": false,
|
||||
"vendorChunk": true,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true,
|
||||
"namedChunks": true
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "relay-angular-chat:build:production"
|
||||
},
|
||||
"development": {
|
||||
"browserTarget": "relay-angular-chat:build:development"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"browserTarget": "relay-angular-chat: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.css"
|
||||
],
|
||||
"scripts": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "relay-angular-chat"
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
// 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'),
|
||||
require('@angular-devkit/build-angular/plugins/karma')
|
||||
],
|
||||
client: {
|
||||
jasmine: {
|
||||
// you can add configuration options for Jasmine here
|
||||
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
||||
// for example, you can disable the random execution with `random: false`
|
||||
// or set a specific seed with `seed: 4321`
|
||||
},
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
jasmineHtmlReporter: {
|
||||
suppressAll: true // removes the duplicated traces
|
||||
},
|
||||
coverageReporter: {
|
||||
dir: require('path').join(__dirname, './coverage/relay-angular-chat'),
|
||||
subdir: '.',
|
||||
reporters: [
|
||||
{ type: 'html' },
|
||||
{ type: 'text-summary' }
|
||||
]
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true
|
||||
});
|
||||
};
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"name": "@waku/relay-angular-chat",
|
||||
"version": "0.1.0",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"test": "ng test"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~13.2.0",
|
||||
"@angular/common": "~13.2.0",
|
||||
"@angular/compiler": "~13.2.0",
|
||||
"@angular/core": "~13.2.0",
|
||||
"@angular/forms": "~13.2.0",
|
||||
"@angular/platform-browser": "~13.2.0",
|
||||
"@angular/platform-browser-dynamic": "~13.2.0",
|
||||
"@angular/router": "~13.2.0",
|
||||
"crypto-browserify": "^3.12.0",
|
||||
"js-waku": "file:../../build/esm",
|
||||
"protons": "^2.0.3",
|
||||
"rxjs": "~7.5.0",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~13.2.2",
|
||||
"@angular/cli": "~13.2.2",
|
||||
"@angular/compiler-cli": "~13.2.0",
|
||||
"@types/bl": "^5.0.2",
|
||||
"@types/jasmine": "~3.10.0",
|
||||
"@types/node": "^12.11.1",
|
||||
"jasmine-core": "~4.0.0",
|
||||
"karma": "~6.3.0",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage": "~2.1.0",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"typescript": "~4.5.2"
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
declare module 'protons';
|
|
@ -0,0 +1,15 @@
|
|||
declare module "time-cache" {
|
||||
|
||||
interface ITimeCache {
|
||||
put(key: string, value: any, validity: number): void;
|
||||
get(key: string): any;
|
||||
has(key: string): boolean;
|
||||
}
|
||||
|
||||
type TimeCache = ITimeCache;
|
||||
|
||||
function TimeCache(options: object): TimeCache;
|
||||
|
||||
export = TimeCache;
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/* Application-wide Styles */
|
||||
h1 {
|
||||
color: #369;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 250%;
|
||||
}
|
||||
h2,
|
||||
h3 {
|
||||
color: #444;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-weight: lighter;
|
||||
}
|
||||
body {
|
||||
margin: 2em;
|
||||
}
|
||||
body,
|
||||
input[type="text"],
|
||||
button {
|
||||
color: #333;
|
||||
font-family: Cambria, Georgia, serif;
|
||||
}
|
||||
/* everywhere else */
|
||||
* {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
<h1>{{ title }}</h1>
|
||||
<p>Waku node's status: {{ wakuStatus }}</p>
|
||||
<app-messages></app-messages>
|
|
@ -0,0 +1,33 @@
|
|||
import { TestBed } from '@angular/core/testing';
|
||||
import { AppComponent } from './app.component';
|
||||
import { MessagesComponent } from './messages/messages.component';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
MessagesComponent
|
||||
],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
xit('should create the app', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
});
|
||||
|
||||
xit(`should have as title 'relay-angular-chat'`, () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app.title).toEqual('relay-angular-chat');
|
||||
});
|
||||
|
||||
xit('should render title', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.nativeElement as HTMLElement;
|
||||
expect(compiled.querySelector('.h1')?.textContent).toContain('relay-angular-chat');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,23 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { WakuService } from './waku.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
|
||||
export class AppComponent {
|
||||
|
||||
title: string = 'relay-angular-chat';
|
||||
wakuStatus!: string;
|
||||
|
||||
constructor(private wakuService: WakuService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.wakuService.init();
|
||||
this.wakuService.wakuStatus.subscribe(wakuStatus => {
|
||||
this.wakuStatus = wakuStatus;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { AppComponent } from './app.component';
|
||||
import { MessagesComponent } from './messages/messages.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
MessagesComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
|
@ -0,0 +1,7 @@
|
|||
<button (click)="sendMessage()" [disabled]="wakuStatus !== 'Connected'">Send Message</button>
|
||||
<h2>Messages</h2>
|
||||
<ul class="messages">
|
||||
<li *ngFor="let message of messages">
|
||||
<span>{{ message.timestamp }} {{ message.text }}</span>
|
||||
</li>
|
||||
</ul>
|
|
@ -0,0 +1,24 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { MessagesComponent } from './messages.component';
|
||||
|
||||
describe('MessagesComponent', () => {
|
||||
let component: MessagesComponent;
|
||||
let fixture: ComponentFixture<MessagesComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ MessagesComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(MessagesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
xit('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,78 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { WakuService } from '../waku.service';
|
||||
import { Waku, WakuMessage } from 'js-waku';
|
||||
import protons from 'protons';
|
||||
|
||||
const proto = protons(`
|
||||
message SimpleChatMessage {
|
||||
uint64 timestamp = 1;
|
||||
string text = 2;
|
||||
}
|
||||
`);
|
||||
|
||||
interface MessageInterface {
|
||||
timestamp: Date,
|
||||
text: string
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-messages',
|
||||
templateUrl: './messages.component.html',
|
||||
styleUrls: ['./messages.component.css']
|
||||
})
|
||||
export class MessagesComponent implements OnInit {
|
||||
|
||||
contentTopic: string = `/relay-angular-chat/1/chat/proto`;
|
||||
messages: MessageInterface[] = [];
|
||||
messageCount: number = 0;
|
||||
waku!: Waku;
|
||||
wakuStatus!: string;
|
||||
|
||||
constructor(private wakuService: WakuService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.wakuService.wakuStatus.subscribe(wakuStatus => {
|
||||
this.wakuStatus = wakuStatus;
|
||||
});
|
||||
|
||||
this.wakuService.waku.subscribe(waku => {
|
||||
this.waku = waku;
|
||||
this.waku.relay.addObserver(this.processIncomingMessages, [this.contentTopic]);
|
||||
});
|
||||
|
||||
window.onbeforeunload = () => this.ngOnDestroy();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.waku.relay.deleteObserver(this.processIncomingMessages, [this.contentTopic]);
|
||||
}
|
||||
|
||||
sendMessage(): void {
|
||||
const time = new Date().getTime();
|
||||
|
||||
const payload = proto.SimpleChatMessage.encode({
|
||||
timestamp: time,
|
||||
text: `Here is a message #${this.messageCount}`,
|
||||
});
|
||||
|
||||
WakuMessage.fromBytes(payload, this.contentTopic).then(wakuMessage => {
|
||||
this.waku.relay.send(wakuMessage).then(() => {
|
||||
console.log(`Message #${this.messageCount} sent`);
|
||||
this.messageCount += 1;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
processIncomingMessages = (wakuMessage: WakuMessage) => {
|
||||
if (!wakuMessage.payload) return;
|
||||
|
||||
const { timestamp, text } = proto.SimpleChatMessage.decode(
|
||||
wakuMessage.payload
|
||||
);
|
||||
const time = new Date();
|
||||
time.setTime(timestamp);
|
||||
const message = { text, timestamp: time };
|
||||
|
||||
this.messages.push(message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { WakuService } from './waku.service';
|
||||
|
||||
describe('WakuService', () => {
|
||||
let service: WakuService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(WakuService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,28 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { Waku } from 'js-waku';
|
||||
import { BehaviorSubject, Subject } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class WakuService {
|
||||
|
||||
private wakuSubject = new Subject<Waku>();
|
||||
public waku = this.wakuSubject.asObservable();
|
||||
|
||||
private wakuStatusSubject = new BehaviorSubject('');
|
||||
public wakuStatus = this.wakuStatusSubject.asObservable();
|
||||
|
||||
constructor() { }
|
||||
|
||||
init() {
|
||||
Waku.create({ bootstrap: { default: true } }).then(waku => {
|
||||
this.wakuSubject.next(waku);
|
||||
this.wakuStatusSubject.next('Connecting...');
|
||||
|
||||
waku.waitForRemotePeer().then(() => {
|
||||
this.wakuStatusSubject.next('Connected');
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export const environment = {
|
||||
production: true
|
||||
};
|
|
@ -0,0 +1,16 @@
|
|||
// This file can be replaced during build by using the `fileReplacements` array.
|
||||
// `ng build` 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.
|
Binary file not shown.
After Width: | Height: | Size: 948 B |
|
@ -0,0 +1,13 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>RelayAngularChat</title>
|
||||
<base href="/">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
import { environment } from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||
.catch(err => console.error(err));
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* 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 recent versions of Safari, Chrome (including
|
||||
* Opera), Edge on the desktop, and iOS 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;
|
||||
*
|
||||
*/
|
||||
|
||||
(window as any).process = { env: { DEBUG: undefined }, };
|
||||
(window as any)['global'] = window;
|
||||
global.Buffer = global.Buffer || require('buffer').Buffer;
|
||||
|
||||
/***************************************************************************************************
|
||||
* Zone JS is required by default for Angular itself.
|
||||
*/
|
||||
import 'zone.js'; // Included with Angular CLI.
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
* APPLICATION IMPORTS
|
||||
*/
|
|
@ -0,0 +1 @@
|
|||
/* You can add global styles to this file, and also import other style files */
|
|
@ -0,0 +1,26 @@
|
|||
// 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): {
|
||||
<T>(id: string): T;
|
||||
keys(): string[];
|
||||
};
|
||||
};
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting(),
|
||||
);
|
||||
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
|
@ -0,0 +1,15 @@
|
|||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./out-tsc/app",
|
||||
"types": []
|
||||
},
|
||||
"files": [
|
||||
"src/main.ts",
|
||||
"src/polyfills.ts"
|
||||
],
|
||||
"include": [
|
||||
"src/**/*.d.ts"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"outDir": "./dist/out-tsc",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
"downlevelIteration": true,
|
||||
"experimentalDecorators": true,
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"target": "es2020",
|
||||
"module": "es2020",
|
||||
"lib": [
|
||||
"es2020",
|
||||
"dom"
|
||||
],
|
||||
"paths": {
|
||||
"buffer": ["node_modules/buffer"],
|
||||
"crypto": ["node_modules/crypto-browserify"],
|
||||
"stream": ["node_modules/stream-browserify"]
|
||||
},
|
||||
"allowSyntheticDefaultImports": true,
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"strictTemplates": true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts",
|
||||
"src/polyfills.ts"
|
||||
],
|
||||
"include": [
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.d.ts"
|
||||
]
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -33,6 +33,7 @@
|
|||
"@istanbuljs/nyc-config-typescript": "^1.0.1",
|
||||
"@size-limit/preset-big-lib": "^7.0.8",
|
||||
"@types/app-root-path": "^1.2.4",
|
||||
"@types/bl": "^5.0.2",
|
||||
"@types/chai": "^4.2.15",
|
||||
"@types/mocha": "^9.1.0",
|
||||
"@types/node": "^17.0.6",
|
||||
|
@ -1435,6 +1436,16 @@
|
|||
"integrity": "sha1-p4twMoKzKsVN52j1US7MNWmRncc=",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/bl": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/bl/-/bl-5.0.2.tgz",
|
||||
"integrity": "sha512-V4g3uJIfBHeDd/35QTPOujJ4+viJJVtNwC2LmBUZeXGSGL60R5iTsBEZ9Nh+wP3asMOA/LEFHxmKT6JzK+Vd0A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"@types/readable-stream": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/chai": {
|
||||
"version": "4.2.19",
|
||||
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.19.tgz",
|
||||
|
@ -1552,6 +1563,16 @@
|
|||
"integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/readable-stream": {
|
||||
"version": "2.3.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.13.tgz",
|
||||
"integrity": "sha512-4JSCx8EUzaW9Idevt+9lsRAt1lcSccoQfE+AouM1gk8sFxnnytKNIO3wTl9Dy+4m6jRJ1yXhboLHHT/LXBQiEw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"safe-buffer": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/retry": {
|
||||
"version": "0.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz",
|
||||
|
@ -13442,6 +13463,16 @@
|
|||
"integrity": "sha1-p4twMoKzKsVN52j1US7MNWmRncc=",
|
||||
"dev": true
|
||||
},
|
||||
"@types/bl": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/bl/-/bl-5.0.2.tgz",
|
||||
"integrity": "sha512-V4g3uJIfBHeDd/35QTPOujJ4+viJJVtNwC2LmBUZeXGSGL60R5iTsBEZ9Nh+wP3asMOA/LEFHxmKT6JzK+Vd0A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"@types/readable-stream": "*"
|
||||
}
|
||||
},
|
||||
"@types/chai": {
|
||||
"version": "4.2.19",
|
||||
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.19.tgz",
|
||||
|
@ -13559,6 +13590,16 @@
|
|||
"integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/readable-stream": {
|
||||
"version": "2.3.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.13.tgz",
|
||||
"integrity": "sha512-4JSCx8EUzaW9Idevt+9lsRAt1lcSccoQfE+AouM1gk8sFxnnytKNIO3wTl9Dy+4m6jRJ1yXhboLHHT/LXBQiEw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"safe-buffer": "*"
|
||||
}
|
||||
},
|
||||
"@types/retry": {
|
||||
"version": "0.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz",
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
"@istanbuljs/nyc-config-typescript": "^1.0.1",
|
||||
"@size-limit/preset-big-lib": "^7.0.8",
|
||||
"@types/app-root-path": "^1.2.4",
|
||||
"@types/bl": "^5.0.2",
|
||||
"@types/chai": "^4.2.15",
|
||||
"@types/mocha": "^9.1.0",
|
||||
"@types/node": "^17.0.6",
|
||||
|
|
Loading…
Reference in New Issue