🔧 Import Eldarya Enhancement's ESLint
parent
4497bf7ce7
commit
7980719b9a
|
@ -1,5 +1,8 @@
|
|||
{
|
||||
"root": true,
|
||||
"env": {
|
||||
"browser": true
|
||||
},
|
||||
"ignorePatterns": [
|
||||
"projects/**/*"
|
||||
],
|
||||
|
@ -17,6 +20,7 @@
|
|||
},
|
||||
"extends": [
|
||||
"plugin:@angular-eslint/all",
|
||||
"plugin:@angular-eslint/recommended--extra",
|
||||
"plugin:@angular-eslint/template/process-inline-templates"
|
||||
],
|
||||
"rules": {
|
||||
|
@ -35,8 +39,94 @@
|
|||
"prefix": "app",
|
||||
"style": "kebab-case"
|
||||
}
|
||||
]
|
||||
],
|
||||
// Custom rules
|
||||
// @typescript-eslint
|
||||
"@typescript-eslint/array-type": "error",
|
||||
"@typescript-eslint/class-literal-property-style": "error",
|
||||
"@typescript-eslint/consistent-indexed-object-style": "error",
|
||||
"@typescript-eslint/consistent-type-assertions": [
|
||||
"error",
|
||||
{
|
||||
"assertionStyle": "as",
|
||||
"objectLiteralTypeAssertions": "never"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/consistent-type-definitions": "error",
|
||||
"@typescript-eslint/consistent-type-imports": "error",
|
||||
"@typescript-eslint/dot-notation": "error",
|
||||
"@typescript-eslint/explicit-function-return-type": "error",
|
||||
"@typescript-eslint/explicit-member-accessibility": [
|
||||
"error",
|
||||
{
|
||||
"accessibility": "no-public"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/member-delimiter-style": [
|
||||
"error",
|
||||
{
|
||||
"multiline": {
|
||||
"delimiter": "none",
|
||||
"requireLast": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/method-signature-style": "error",
|
||||
"@typescript-eslint/no-base-to-string": "error",
|
||||
"@typescript-eslint/no-confusing-non-null-assertion": "error",
|
||||
"@typescript-eslint/no-confusing-void-expression": [
|
||||
"error",
|
||||
{
|
||||
"ignoreArrowShorthand": true,
|
||||
"ignoreVoidOperator": true
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-dynamic-delete": "error",
|
||||
"@typescript-eslint/no-empty-function": [
|
||||
"error",
|
||||
{
|
||||
"allow": [
|
||||
"private-constructors",
|
||||
"protected-constructors"
|
||||
]
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-extra-parens": [
|
||||
"error",
|
||||
"functions"
|
||||
],
|
||||
"@typescript-eslint/no-implicit-any-catch": "error",
|
||||
"@typescript-eslint/no-invalid-void-type": "error",
|
||||
"@typescript-eslint/no-non-null-assertion": "error",
|
||||
"@typescript-eslint/no-unnecessary-boolean-literal-compare": "error",
|
||||
"@typescript-eslint/no-unnecessary-condition": "error",
|
||||
"@typescript-eslint/no-unnecessary-qualifier": "error",
|
||||
"@typescript-eslint/no-unnecessary-type-arguments": "error",
|
||||
"@typescript-eslint/no-unnecessary-type-constraint": "error",
|
||||
"@typescript-eslint/no-unsafe-argument": "error",
|
||||
"@typescript-eslint/no-unsafe-assignment": "error",
|
||||
"@typescript-eslint/no-var-requires": "error",
|
||||
"@typescript-eslint/non-nullable-type-assertion-style": "error",
|
||||
"@typescript-eslint/prefer-for-of": "error",
|
||||
"@typescript-eslint/prefer-function-type": "error",
|
||||
"@typescript-eslint/prefer-includes": "error",
|
||||
"@typescript-eslint/prefer-nullish-coalescing": "error",
|
||||
"@typescript-eslint/prefer-optional-chain": "error",
|
||||
"@typescript-eslint/prefer-readonly": "error",
|
||||
"@typescript-eslint/prefer-reduce-type-parameter": "error",
|
||||
"@typescript-eslint/prefer-return-this-type": "error",
|
||||
"@typescript-eslint/prefer-string-starts-ends-with": "error",
|
||||
"@typescript-eslint/prefer-ts-expect-error": "error",
|
||||
"@typescript-eslint/promise-function-async": "error",
|
||||
"@typescript-eslint/require-array-sort-compare": "error",
|
||||
"@typescript-eslint/semi": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"@typescript-eslint/sort-type-union-intersection-members": "error",
|
||||
"@typescript-eslint/switch-exhaustiveness-check": "error",
|
||||
"@typescript-eslint/type-annotation-spacing": "error",
|
||||
"@typescript-eslint/unified-signatures": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -24,11 +24,16 @@ build:
|
|||
paths:
|
||||
- dist/angular
|
||||
|
||||
test:
|
||||
lint:
|
||||
stage: test
|
||||
script:
|
||||
- pnpm run lint
|
||||
|
||||
test:
|
||||
stage: test
|
||||
script:
|
||||
- pnpm run test
|
||||
|
||||
pages:
|
||||
stage: deploy
|
||||
script:
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { environment } from '../environments/environment';
|
||||
import { NgModule } from '@angular/core'
|
||||
import type { Routes } from '@angular/router'
|
||||
import { RouterModule } from '@angular/router'
|
||||
import { environment } from '../environments/environment'
|
||||
|
||||
const routes: Routes = [{
|
||||
path: '',
|
||||
loadChildren: () => import('./pages/pages.module').then(m => m.PagesModule),
|
||||
}];
|
||||
loadChildren: async () => import('./pages/pages.module').then(m => m.PagesModule),
|
||||
}]
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes, { useHash: environment.useHash, relativeLinkResolution: 'legacy' })],
|
||||
|
|
|
@ -1,35 +1,45 @@
|
|||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { AppComponent } from './app.component';
|
||||
import { TestBed, waitForAsync } from '@angular/core/testing'
|
||||
import { RouterTestingModule } from '@angular/router/testing'
|
||||
import { AppComponent } from './app.component'
|
||||
|
||||
describe('AppComponent', (): void => {
|
||||
beforeEach(waitForAsync((): void => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
RouterTestingModule
|
||||
RouterTestingModule,
|
||||
],
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
}).compileComponents();
|
||||
}));
|
||||
}).compileComponents()
|
||||
}))
|
||||
|
||||
it('should create the app', (): void => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
});
|
||||
const fixture = TestBed.createComponent(AppComponent)
|
||||
if (!(fixture.debugElement.componentInstance instanceof AppComponent)) throw new Error("Expected AppComponent")
|
||||
|
||||
it(`should have as title 'public-gateway-cacher'`, (): void => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app.title).toEqual('public-gateway-cacher');
|
||||
});
|
||||
const app: AppComponent = fixture.debugElement.componentInstance
|
||||
expect(app).toBeTruthy()
|
||||
})
|
||||
|
||||
it(`should have a themeService`, (): void => {
|
||||
const fixture = TestBed.createComponent(AppComponent)
|
||||
if (!(fixture.debugElement.componentInstance instanceof AppComponent)) throw new Error("Expected AppComponent")
|
||||
|
||||
const app: AppComponent = fixture.debugElement.componentInstance
|
||||
expect(app.themeService).toBeTruthy()
|
||||
})
|
||||
|
||||
it('should render title', (): void => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
expect(compiled.querySelector('.content span').textContent).toContain('public-gateway-cacher app is running!');
|
||||
});
|
||||
});
|
||||
const fixture = TestBed.createComponent(AppComponent)
|
||||
fixture.detectChanges()
|
||||
if (!isHTMLElement(fixture.debugElement.nativeElement)) throw new Error("Expected HTMLElement")
|
||||
|
||||
const compiled: HTMLElement = fixture.debugElement.nativeElement
|
||||
expect(compiled.querySelector('h1')?.textContent).toContain('Public Gateway Cacher')
|
||||
})
|
||||
})
|
||||
|
||||
function isHTMLElement(element: any): element is HTMLElement {
|
||||
return element.__proto__ instanceof HTMLElement
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { ThemeService } from './services/theme.service';
|
||||
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'
|
||||
import { ThemeService } from './services/theme.service'
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
|
@ -9,6 +9,6 @@ import { ThemeService } from './services/theme.service';
|
|||
})
|
||||
export class AppComponent {
|
||||
constructor(
|
||||
public readonly themeService: ThemeService
|
||||
@Inject(ThemeService) readonly themeService: ThemeService
|
||||
) { }
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import { CommonModule } from '@angular/common';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { CommonModule } from '@angular/common'
|
||||
import { HttpClientModule } from '@angular/common/http'
|
||||
import { NgModule } from '@angular/core'
|
||||
import { FlexLayoutModule } from '@angular/flex-layout'
|
||||
import { MatButtonModule } from '@angular/material/button'
|
||||
import { MatIconModule } from '@angular/material/icon'
|
||||
import { MatToolbarModule } from '@angular/material/toolbar'
|
||||
import { BrowserModule } from '@angular/platform-browser'
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
|
||||
import { AppRoutingModule } from './app-routing.module'
|
||||
import { AppComponent } from './app.component'
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export interface Environment {
|
||||
production: boolean;
|
||||
base_href?: string;
|
||||
useHash: boolean;
|
||||
production: boolean
|
||||
base_href?: string
|
||||
useHash: boolean
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { PagesComponent } from './pages.component';
|
||||
import { NgModule } from '@angular/core'
|
||||
import type { Routes } from '@angular/router'
|
||||
import { RouterModule } from '@angular/router'
|
||||
import { PagesComponent } from './pages.component'
|
||||
|
||||
const routes: Routes = [{
|
||||
path: '',
|
||||
component: PagesComponent,
|
||||
}];
|
||||
}]
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
|
|
|
@ -1,24 +1,27 @@
|
|||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { PagesComponent } from './pages.component';
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing'
|
||||
import type { ComponentFixture } from '@angular/core/testing'
|
||||
import { TestBed, waitForAsync } from '@angular/core/testing'
|
||||
import { PagesComponent } from './pages.component'
|
||||
|
||||
describe('PagesComponent', (): void => {
|
||||
let component: PagesComponent;
|
||||
let fixture: ComponentFixture<PagesComponent>;
|
||||
let component: PagesComponent
|
||||
let fixture: ComponentFixture<PagesComponent>
|
||||
|
||||
beforeEach(waitForAsync((): void => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [HttpClientTestingModule],
|
||||
declarations: [PagesComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
.compileComponents()
|
||||
}))
|
||||
|
||||
beforeEach((): void => {
|
||||
fixture = TestBed.createComponent(PagesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
fixture = TestBed.createComponent(PagesComponent)
|
||||
component = fixture.componentInstance
|
||||
fixture.detectChanges()
|
||||
})
|
||||
|
||||
it('should create', (): void => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
expect(component).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { ChangeDetectionStrategy, Component, EventEmitter, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||
import { ThemePalette } from '@angular/material/core';
|
||||
import { MatTable, MatTableDataSource } from '@angular/material/table';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { environment } from '../../environments/environment';
|
||||
import { Protocol } from '../enums/protocol.enum';
|
||||
import { Theme } from '../enums/theme.enum';
|
||||
import { GatewayService } from '../services/gateway.service';
|
||||
import { ThemeService } from '../services/theme.service';
|
||||
import type { HttpErrorResponse } from '@angular/common/http'
|
||||
import type { OnDestroy, OnInit } from '@angular/core'
|
||||
import { ChangeDetectionStrategy, Component, EventEmitter, Inject, ViewChild } from '@angular/core'
|
||||
import type { ThemePalette } from '@angular/material/core'
|
||||
import { MatTable, MatTableDataSource } from '@angular/material/table'
|
||||
import type { Subscription } from 'rxjs'
|
||||
import { takeUntil } from 'rxjs/operators'
|
||||
import { environment } from '../../environments/environment'
|
||||
import { Protocol } from '../enums/protocol.enum'
|
||||
import { Theme } from '../enums/theme.enum'
|
||||
import { GatewayService } from '../services/gateway.service'
|
||||
import { ThemeService } from '../services/theme.service'
|
||||
|
||||
@Component({
|
||||
selector: 'app-pages',
|
||||
|
@ -18,64 +19,64 @@ import { ThemeService } from '../services/theme.service';
|
|||
})
|
||||
export class PagesComponent implements OnInit, OnDestroy {
|
||||
|
||||
@ViewChild(MatTable) matTable!: MatTable<Result>;
|
||||
@ViewChild(MatTable) matTable!: MatTable<Result>
|
||||
|
||||
gateways!: string[];
|
||||
inputColour: ThemePalette = 'primary';
|
||||
ipfs = '';
|
||||
ipns = '';
|
||||
gateways!: string[]
|
||||
inputColour: ThemePalette = 'primary'
|
||||
ipfs = ''
|
||||
ipns = ''
|
||||
|
||||
readonly dataSource = new MatTableDataSource<Result>([]);
|
||||
readonly displayedColumns: ['icon', 'gateway'] = ['icon', 'gateway'];
|
||||
readonly subscriptions: Subscription[] = [];
|
||||
readonly dataSource = new MatTableDataSource<Result>([])
|
||||
readonly displayedColumns: ['icon', 'gateway'] = ['icon', 'gateway']
|
||||
readonly subscriptions: Subscription[] = []
|
||||
|
||||
private readonly destroy$ = new EventEmitter<void>();
|
||||
private readonly destroy$ = new EventEmitter<void>()
|
||||
|
||||
constructor(
|
||||
private readonly gatewayService: GatewayService,
|
||||
private readonly themeService: ThemeService
|
||||
@Inject(GatewayService) private readonly gatewayService: GatewayService,
|
||||
@Inject(ThemeService) private readonly themeService: ThemeService
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.gatewayService.list().subscribe((gateways): void => { this.gateways = gateways; });
|
||||
this.gatewayService.list().subscribe((gateways): void => { this.gateways = gateways })
|
||||
|
||||
// Theme
|
||||
this.setColours(this.themeService.current);
|
||||
this.setColours(this.themeService.current)
|
||||
this.themeService.valueChanges.pipe(
|
||||
takeUntil(this.destroy$)
|
||||
).subscribe((theme): void => {
|
||||
this.setColours(theme);
|
||||
});
|
||||
this.setColours(theme)
|
||||
})
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.destroy$.complete();
|
||||
this.destroy$.complete()
|
||||
}
|
||||
|
||||
cacheIPFS(): void {
|
||||
this.ipfs = this.ipfs.trim();
|
||||
this.cache(Protocol.IPFS, this.ipfs);
|
||||
this.ipfs = this.ipfs.trim()
|
||||
this.cache(Protocol.IPFS, this.ipfs)
|
||||
}
|
||||
|
||||
cacheIPNS(): void {
|
||||
this.ipns = this.ipns.trim();
|
||||
this.cache(Protocol.IPNS, this.ipns);
|
||||
this.ipns = this.ipns.trim()
|
||||
this.cache(Protocol.IPNS, this.ipns)
|
||||
}
|
||||
|
||||
cache(protocol: Protocol, hashpath: string): void {
|
||||
|
||||
// Clear subscriptions
|
||||
while (this.subscriptions.length) {
|
||||
const sub = this.subscriptions.pop();
|
||||
const sub = this.subscriptions.pop()
|
||||
if (sub && !sub.closed) {
|
||||
sub.unsubscribe();
|
||||
sub.unsubscribe()
|
||||
}
|
||||
}
|
||||
|
||||
// Clear table
|
||||
this.dataSource.data = [];
|
||||
this.matTable.renderRows();
|
||||
console.clear();
|
||||
this.dataSource.data = []
|
||||
this.matTable.renderRows()
|
||||
console.clear()
|
||||
|
||||
this.gateways.forEach((gateway): void => {
|
||||
this.subscriptions.push(
|
||||
|
@ -85,50 +86,50 @@ export class PagesComponent implements OnInit, OnDestroy {
|
|||
message: resp.statusText,
|
||||
icon: this.getIcon(resp.status),
|
||||
ok: resp.ok,
|
||||
});
|
||||
this.matTable.renderRows();
|
||||
})
|
||||
this.matTable.renderRows()
|
||||
}, (error: HttpErrorResponse): void => {
|
||||
this.dataSource.data.push({
|
||||
gateway: this.gatewayService.url(gateway, protocol, hashpath),
|
||||
message: error.statusText,
|
||||
icon: this.getIcon(error.status),
|
||||
ok: error.ok,
|
||||
});
|
||||
this.matTable.renderRows();
|
||||
})
|
||||
);
|
||||
});
|
||||
this.matTable.renderRows()
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
private setColours(theme: Theme): void {
|
||||
switch (theme) {
|
||||
case Theme.Light:
|
||||
this.inputColour = 'primary';
|
||||
break;
|
||||
this.inputColour = 'primary'
|
||||
break
|
||||
case Theme.Dark:
|
||||
this.inputColour = 'accent';
|
||||
break;
|
||||
this.inputColour = 'accent'
|
||||
break
|
||||
default:
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
private getIcon(status: number): string {
|
||||
if (status >= 200 && status < 300) { return '✅'; }
|
||||
if (status >= 200 && status < 300) { return '✅' }
|
||||
switch (status) {
|
||||
case 0: return '❌';
|
||||
case 403: return '⛔';
|
||||
case 404: return '❓';
|
||||
case 500: return '❗';
|
||||
default: return environment.production ? '❌' : '❔';
|
||||
case 0: return '❌'
|
||||
case 403: return '⛔'
|
||||
case 404: return '❓'
|
||||
case 500: return '❗'
|
||||
default: return environment.production ? '❌' : '❔'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface Result {
|
||||
gateway: string;
|
||||
message: string;
|
||||
icon: string;
|
||||
ok: boolean;
|
||||
gateway: string
|
||||
message: string
|
||||
icon: string
|
||||
ok: boolean
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
import { MatSortModule } from '@angular/material/sort';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { PagesRoutingModule } from './pages-routing.module';
|
||||
import { PagesComponent } from './pages.component';
|
||||
import { CommonModule } from '@angular/common'
|
||||
import { NgModule } from '@angular/core'
|
||||
import { FlexLayoutModule } from '@angular/flex-layout'
|
||||
import { FormsModule } from '@angular/forms'
|
||||
import { MatButtonModule } from '@angular/material/button'
|
||||
import { MatInputModule } from '@angular/material/input'
|
||||
import { MatProgressBarModule } from '@angular/material/progress-bar'
|
||||
import { MatSortModule } from '@angular/material/sort'
|
||||
import { MatTableModule } from '@angular/material/table'
|
||||
import { MatTooltipModule } from '@angular/material/tooltip'
|
||||
import { PagesRoutingModule } from './pages-routing.module'
|
||||
import { PagesComponent } from './pages.component'
|
||||
|
||||
@NgModule({
|
||||
declarations: [PagesComponent],
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
import { TestBed, TestBedStatic } from '@angular/core/testing';
|
||||
import { GatewayService } from './gateway.service';
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing'
|
||||
import type { TestBedStatic } from '@angular/core/testing'
|
||||
import { TestBed } from '@angular/core/testing'
|
||||
import { GatewayService } from './gateway.service'
|
||||
|
||||
describe('GatewayService', (): void => {
|
||||
beforeEach((): TestBedStatic => TestBed.configureTestingModule({}));
|
||||
beforeEach((): TestBedStatic => TestBed.configureTestingModule({
|
||||
imports: [HttpClientTestingModule]
|
||||
}))
|
||||
|
||||
it('should be created', (): void => {
|
||||
const service: GatewayService = TestBed.inject(GatewayService);
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
const service: GatewayService = TestBed.inject(GatewayService)
|
||||
expect(service).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { HttpClient, HttpResponse } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { environment } from '../../environments/environment';
|
||||
import { Protocol } from '../enums/protocol.enum';
|
||||
import type { HttpResponse } from '@angular/common/http'
|
||||
import { HttpClient } from '@angular/common/http'
|
||||
import { Inject, Injectable } from '@angular/core'
|
||||
import type { Observable } from 'rxjs'
|
||||
import { environment } from '../../environments/environment'
|
||||
import type { Protocol } from '../enums/protocol.enum'
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
|
@ -10,7 +11,7 @@ import { Protocol } from '../enums/protocol.enum';
|
|||
export class GatewayService {
|
||||
|
||||
constructor(
|
||||
private readonly http: HttpClient
|
||||
@Inject(HttpClient) private readonly http: HttpClient
|
||||
) { }
|
||||
|
||||
list(): Observable<string[]> {
|
||||
|
@ -18,20 +19,20 @@ export class GatewayService {
|
|||
environment.base_href && environment.base_href !== '/'
|
||||
? `${environment.base_href}/assets/json/gateways.json`
|
||||
: `${document.querySelector('base')?.href}assets/json/gateways.json`
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
get(gateway: string, protocol: Protocol, hashpath: string): Observable<HttpResponse<string>> {
|
||||
return this.http.get(`${this.url(gateway, protocol, hashpath)}#x-ipfs-companion-no-redirect`, {
|
||||
observe: 'response',
|
||||
responseType: 'text',
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
url(gateway: string, protocol: Protocol, hashpath: string): string {
|
||||
const splits: string[] = hashpath.split('/');
|
||||
const url: string = gateway.replace(':type', protocol).replace(':hash', splits.shift() || '');
|
||||
return splits.length ? [url, splits.join('/')].join('/') : url;
|
||||
const splits: string[] = hashpath.split('/')
|
||||
const url: string = gateway.replace(':type', protocol).replace(':hash', splits.shift() ?? '')
|
||||
return splits.length ? [url, splits.join('/')].join('/') : url
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import { TestBed } from '@angular/core/testing';
|
||||
import { ThemeService } from './theme.service';
|
||||
import { TestBed } from '@angular/core/testing'
|
||||
import { ThemeService } from './theme.service'
|
||||
|
||||
describe('ThemeService', (): void => {
|
||||
let service: ThemeService;
|
||||
let service: ThemeService
|
||||
|
||||
beforeEach((): void => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(ThemeService);
|
||||
});
|
||||
TestBed.configureTestingModule({})
|
||||
service = TestBed.inject(ThemeService)
|
||||
})
|
||||
|
||||
it('should be created', (): void => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
expect(service).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { Theme } from '../enums/theme.enum';
|
||||
import { Injectable } from '@angular/core'
|
||||
import type { Observable } from 'rxjs'
|
||||
import { Subject } from 'rxjs'
|
||||
import { Theme } from '../enums/theme.enum'
|
||||
|
||||
function enumGuard<T>(enumeration: T): (token: unknown) => token is T[keyof T] {
|
||||
return (token: unknown): token is T[keyof T] => Object.values(enumeration).includes(token);
|
||||
return (token: unknown): token is T[keyof T] => Object.values(enumeration).includes(token)
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
|
@ -11,39 +12,39 @@ function enumGuard<T>(enumeration: T): (token: unknown) => token is T[keyof T] {
|
|||
})
|
||||
export class ThemeService {
|
||||
|
||||
current = Theme.Light;
|
||||
icon = 'brightness_low';
|
||||
readonly valueChanges: Observable<Theme>;
|
||||
current = Theme.Light
|
||||
icon = 'brightness_low'
|
||||
readonly valueChanges: Observable<Theme>
|
||||
|
||||
private readonly subject$ = new Subject<Theme>();
|
||||
private readonly subject$ = new Subject<Theme>()
|
||||
|
||||
constructor() {
|
||||
const stored = localStorage.getItem('theme');
|
||||
const stored = localStorage.getItem('theme')
|
||||
if (enumGuard(Theme)(stored)) {
|
||||
this.setTheme(stored);
|
||||
this.setTheme(stored)
|
||||
}
|
||||
|
||||
this.valueChanges = this.subject$.asObservable();
|
||||
this.valueChanges = this.subject$.asObservable()
|
||||
}
|
||||
|
||||
switchTheme(): void {
|
||||
this.setTheme(this.current === Theme.Light ? Theme.Dark : Theme.Light);
|
||||
this.setTheme(this.current === Theme.Light ? Theme.Dark : Theme.Light)
|
||||
}
|
||||
|
||||
setTheme(theme: Theme): void {
|
||||
document.querySelector('body')?.classList.remove(this.current);
|
||||
document.querySelector('body')?.classList.add(theme);
|
||||
this.current = theme;
|
||||
this.icon = this.getIcon(theme);
|
||||
this.subject$.next(theme);
|
||||
localStorage.setItem('theme', theme);
|
||||
document.querySelector('body')?.classList.remove(this.current)
|
||||
document.querySelector('body')?.classList.add(theme)
|
||||
this.current = theme
|
||||
this.icon = this.getIcon(theme)
|
||||
this.subject$.next(theme)
|
||||
localStorage.setItem('theme', theme)
|
||||
}
|
||||
|
||||
getIcon(theme: Theme): string {
|
||||
switch (theme) {
|
||||
case Theme.Dark: return 'brightness_high';
|
||||
case Theme.Dark: return 'brightness_high'
|
||||
case Theme.Light:
|
||||
default: return 'brightness_low';
|
||||
default: return 'brightness_low'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Environment } from '../app/interfaces/environment';
|
||||
import type { Environment } from '../app/interfaces/environment'
|
||||
|
||||
export const environment: Environment = {
|
||||
production: true,
|
||||
base_href: '/public-gateway-cacher',
|
||||
useHash: false,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Environment } from '../app/interfaces/environment';
|
||||
import type { Environment } from '../app/interfaces/environment'
|
||||
|
||||
export const environment: Environment = {
|
||||
production: true,
|
||||
useHash: true,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Environment } from '../app/interfaces/environment';
|
||||
import type { Environment } from '../app/interfaces/environment'
|
||||
|
||||
export const environment: Environment = {
|
||||
production: true,
|
||||
base_href: '/',
|
||||
useHash: false,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Environment } from '../app/interfaces/environment';
|
||||
import type { Environment } from '../app/interfaces/environment'
|
||||
|
||||
// This file can be replaced during build by using the `fileReplacements` array.
|
||||
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
|
||||
|
@ -8,7 +8,7 @@ export const environment: Environment = {
|
|||
production: false,
|
||||
base_href: '/',
|
||||
useHash: false,
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* For easier debugging in development mode, you can import the following file
|
||||
|
|
12
src/main.ts
12
src/main.ts
|
@ -1,11 +1,11 @@
|
|||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { AppModule } from './app/app.module';
|
||||
import { environment } from './environments/environment';
|
||||
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();
|
||||
enableProdMode()
|
||||
}
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||
.catch((err): void => console.error(err));
|
||||
.catch((err): void => console.error(err))
|
||||
|
|
26
src/test.ts
26
src/test.ts
|
@ -1,22 +1,20 @@
|
|||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
import { getTestBed } from '@angular/core/testing'
|
||||
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'
|
||||
import 'zone.js/testing'
|
||||
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import {
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
import 'zone.js/testing';
|
||||
|
||||
declare const require: any;
|
||||
declare const require: any
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting(), {
|
||||
teardown: { destroyAfterEach: false }
|
||||
}
|
||||
);
|
||||
platformBrowserDynamicTesting(),
|
||||
{ teardown: { destroyAfterEach: false } }
|
||||
)
|
||||
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
const context = require.context('./', true, /\.spec\.ts$/)
|
||||
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
context.keys().map(context)
|
||||
|
|
Loading…
Reference in New Issue