diff --git a/.editorconfig b/.editorconfig index 9ce0756..c201399 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,4 +1,3 @@ -# Editor configuration, see https://editorconfig.org root = true [*] @@ -9,8 +8,6 @@ insert_final_newline = true max_line_length = 140 trim_trailing_whitespace = true -[*.ts] -quote_type = single - [*.md] +max_line_length = false trim_trailing_whitespace = false diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..0252897 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,8 @@ +.angular +.pnpm-store +dist +e2e/protractor.conf.js +node_modules +pnpm-lock.yaml +public +src/test.ts diff --git a/.eslintrc.json b/.eslintrc.json index 57299d8..44b6d27 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,22 +1,25 @@ { "root": true, - "ignorePatterns": [ - "projects/**/*" - ], + "env": { + "browser": true + }, + "ignorePatterns": ["projects/**/*"], "overrides": [ { - "files": [ - "*.ts" - ], + "files": ["*.ts"], "parserOptions": { - "project": [ - "tsconfig.json", - "e2e/tsconfig.json" - ], + "project": ["tsconfig.json", "e2e/tsconfig.json"], "createDefaultProgram": true }, + "plugins": ["rxjs-angular"], "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", + "prettier", + "plugin:rxjs/recommended", "plugin:@angular-eslint/all", + "plugin:@angular-eslint/recommended--extra", "plugin:@angular-eslint/template/process-inline-templates" ], "rules": { @@ -35,17 +38,93 @@ "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", + // eslint-plugin-rxjs-angular + //"rxjs-angular/prefer-async-pipe": "error", + "rxjs-angular/prefer-takeuntil": "error" } }, { - "files": [ - "*.html" - ], - "extends": [ - "plugin:@angular-eslint/template/all" - ], + "files": ["*.html"], + "extends": ["plugin:@angular-eslint/template/all"], "rules": { // Custom rules "@angular-eslint/template/i18n": "off" diff --git a/.gitignore b/.gitignore index 53a8849..2312f79 100644 --- a/.gitignore +++ b/.gitignore @@ -1,47 +1,126 @@ -# See http://help.github.com/ignore-files/ for more about ignoring files. +# Created by https://www.toptal.com/developers/gitignore/api/angular,linux,windows,macos,visualstudiocode +# Edit at https://www.toptal.com/developers/gitignore?templates=angular,linux,windows,macos,visualstudiocode +### Angular ### +## Angular ## # compiled output -/dist -/tmp -/out-tsc -# Only exists if Bazel was run -/bazel-out +dist/ +tmp/ +app/**/*.js +app/**/*.js.map # dependencies -/node_modules - -# profiling files -chrome-profiler-events*.json -speed-measure-plugin*.json +node_modules/ +bower_components/ # IDEs and editors -/.idea -.project -.classpath -.c9/ -*.launch -.settings/ -*.sublime-workspace +.idea/ -# IDE - VSCode +# misc +.sass-cache/ +connect.lock/ +coverage/ +libpeerconnection.log/ +npm-debug.log +testem.log +typings/ +.angular/ + +# e2e +e2e/*.js +e2e/*.map + +# System Files +.DS_Store/ + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### VisualStudioCode ### .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json -.history/* +!.vscode/*.code-snippets -# misc -/.angular/cache -/.sass-cache -/connect.lock -/coverage -/libpeerconnection.log -npm-debug.log -yarn-error.log -testem.log -/typings +# Local History for Visual Studio Code +.history/ -# System Files -.DS_Store +# Built Visual Studio Code Extensions +*.vsix + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +# Support for Project snippet scope + +### Windows ### +# Windows thumbnail cache files Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.toptal.com/developers/gitignore/api/angular,linux,windows,macos,visualstudiocode diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index da14ba8..efb8d79 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -27,7 +27,8 @@ build: test: stage: test script: - - pnpm run lint + - pnpx ng lint + - pnpx prettier --check . pages: stage: deploy diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..79e372d --- /dev/null +++ b/.prettierignore @@ -0,0 +1,6 @@ +.angular +.pnpm-store +dist +node_modules +pnpm-lock.yaml +public diff --git a/.prettierrc.yaml b/.prettierrc.yaml new file mode 100644 index 0000000..7fa8a87 --- /dev/null +++ b/.prettierrc.yaml @@ -0,0 +1,3 @@ +arrowParens: avoid +printWidth: 140 +semi: false diff --git a/.vscode/extensions.json b/.vscode/extensions.json index a34a5a6..d4749c1 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -7,10 +7,11 @@ "davidanson.vscode-markdownlint", "dbaeumer.vscode-eslint", "editorconfig.editorconfig", + "esbenp.prettier-vscode", "gitlab.gitlab-workflow", "johnpapa.angular2", "ms-vscode.vscode-typescript-next", - "visualstudioexptteam.vscodeintellicode", + "visualstudioexptteam.vscodeintellicode" ], // List of extensions recommended by VS Code that should not be recommended for users of this workspace. "unwantedRecommendations": [ diff --git a/.vscode/launch.json b/.vscode/launch.json index 0563e4e..b49c58f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -37,9 +37,7 @@ "request": "launch", "program": "${workspaceFolder}/node_modules/protractor/bin/protractor", "protocol": "inspector", - "args": [ - "${workspaceFolder}/e2e/protractor.conf.js" - ] + "args": ["${workspaceFolder}/e2e/protractor.conf.js"] } ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index a83f4e1..a74a144 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,27 +1,20 @@ { + "[css][scss][html][javascript][typescript][json][jsonc][markdown][yaml]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, "editor.codeActionsOnSave": { "source.fixAll": true, "source.fixAll.eslint": true, "source.organizeImports": true }, + "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, - "editor.rulers": [ - 140 - ], + "editor.rulers": [140], "eslint.options": { - "extensions": [ - ".ts", - ".html" - ] + "extensions": [".ts", ".html"] }, "eslint.packageManager": "pnpm", - "eslint.validate": [ - "javascript", - "javascriptreact", - "typescript", - "typescriptreact", - "html" - ], + "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact", "html"], "files.associations": { ".ipfs-npmrc": "json" }, diff --git a/.vscode/tasks.json b/.vscode/tasks.json index d7f9cf6..69f2517 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -17,10 +17,7 @@ "owner": "typescript", "source": "ts", "applyTo": "closedDocuments", - "fileLocation": [ - "relative", - "${cwd}" - ], + "fileLocation": ["relative", "${cwd}"], "pattern": "$tsc", "background": { "activeOnStart": true, @@ -32,6 +29,6 @@ } } } - }, + } ] } diff --git a/CHANGELOG.md b/CHANGELOG.md index f49251c..7221259 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,20 +8,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/), and this ### Added -* More information in the `package.json`. -* Added ESLint +- More information in the `package.json`. +- Added ESLint ### Changed -* Updated `gateways.json` -* Upgraded to Angular 13 -* Targets ESNext +- Updated `gateways.json` +- Upgraded to Angular 13 +- Targets ESNext ### Deprecated ### Removed -* Removed TSLint +- Removed TSLint ### Fixed @@ -31,33 +31,33 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/), and this ### Added -* Added some accessibility tags -* Added some VSCode settings +- Added some accessibility tags +- Added some VSCode settings ### Changed -* Updated to Angular 11 -* Updated gateways +- Updated to Angular 11 +- Updated gateways ### Fixed -* Corrected the title from "Public IPFS Cacher" to "Public Gateway Cacher". +- Corrected the title from "Public IPFS Cacher" to "Public Gateway Cacher". ## [2.1.0] - 2020-07-10 ### Added -* Support for subdomain gateways -* Strict mode -* More icons -* IPFS colours +- Support for subdomain gateways +- Strict mode +- More icons +- IPFS colours ### Changed -* Better screenshot -* Upgraded to Angular 10 -* Now uses `--chunker=buzhash` -* Updated `bootstrap` and `ipfs-css` +- Better screenshot +- Upgraded to Angular 10 +- Now uses `--chunker=buzhash` +- Updated `bootstrap` and `ipfs-css` ## [2.0.0] - 2019-12-03 @@ -67,7 +67,7 @@ Tests were done with `ipfs-npm` : They weren't successful. `ipfs-css` is only mi ### Added -* GitLab Pages - +- GitLab Pages - ## [1.0.0] - 2019-11-28 @@ -75,9 +75,9 @@ This version is a fork of [github.com/ipfs/public-gateway-checker](https://githu ## Types of changes -* `Added` for new features. -* `Changed` for changes in existing functionality. -* `Deprecated` for soon-to-be removed features. -* `Removed` for now removed features. -* `Fixed` for any bug fixes. -* `Security` in case of vulnerabilities. +- `Added` for new features. +- `Changed` for changes in existing functionality. +- `Deprecated` for soon-to-be removed features. +- `Removed` for now removed features. +- `Fixed` for any bug fixes. +- `Security` in case of vulnerabilities. diff --git a/LICENSE.md b/LICENSE.md index 2fb2e74..f5a0171 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -217,23 +217,23 @@ produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: -- a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. -- b) The work must carry prominent notices stating that it is - released under this License and any conditions added under - section 7. This requirement modifies the requirement in section 4 - to "keep intact all notices". -- c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. -- d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. +- a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. +- b) The work must carry prominent notices stating that it is + released under this License and any conditions added under + section 7. This requirement modifies the requirement in section 4 + to "keep intact all notices". +- c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. +- d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, @@ -252,42 +252,42 @@ sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: -- a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. -- b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the Corresponding - Source from a network server at no charge. -- c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. -- d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. -- e) Convey the object code using peer-to-peer transmission, - provided you inform other peers where the object code and - Corresponding Source of the work are being offered to the general - public at no charge under subsection 6d. +- a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. +- b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the Corresponding + Source from a network server at no charge. +- c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. +- d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. +- e) Convey the object code using peer-to-peer transmission, + provided you inform other peers where the object code and + Corresponding Source of the work are being offered to the general + public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be @@ -363,23 +363,23 @@ Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: -- a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or -- b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or -- c) Prohibiting misrepresentation of the origin of that material, - or requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or -- d) Limiting the use for publicity purposes of names of licensors - or authors of the material; or -- e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or -- f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions - of it) with contractual assumptions of liability to the recipient, - for any liability that these contractual assumptions directly - impose on those licensors and authors. +- a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or +- b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or +- c) Prohibiting misrepresentation of the origin of that material, + or requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or +- d) Limiting the use for publicity purposes of names of licensors + or authors of the material; or +- e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or +- f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions + of it) with contractual assumptions of liability to the recipient, + for any liability that these contractual assumptions directly + impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you diff --git a/angular.json b/angular.json index 41fb14c..81cd97a 100644 --- a/angular.json +++ b/angular.json @@ -30,17 +30,10 @@ "main": "src/main.ts", "polyfills": "src/polyfills.ts", "tsConfig": "tsconfig.app.json", - "assets": [ - "src/favicon.png", - "src/assets" - ], - "styles": [ - "src/styles.scss" - ], + "assets": ["src/favicon.png", "src/assets"], + "styles": ["src/styles.scss"], "stylePreprocessorOptions": { - "includePaths": [ - "node_modules" - ] + "includePaths": ["node_modules"] }, "scripts": [], "vendorChunk": true, @@ -150,17 +143,10 @@ "polyfills": "src/polyfills.ts", "tsConfig": "tsconfig.spec.json", "karmaConfig": "karma.conf.js", - "assets": [ - "src/favicon.png", - "src/assets" - ], - "styles": [ - "src/styles.scss" - ], + "assets": ["src/favicon.png", "src/assets"], + "styles": ["src/styles.scss"], "stylePreprocessorOptions": { - "includePaths": [ - "node_modules" - ] + "includePaths": ["node_modules"] }, "scripts": [] } @@ -180,10 +166,7 @@ "lint": { "builder": "@angular-eslint/builder:lint", "options": { - "lintFilePatterns": [ - "src/**/*.ts", - "src/**/*.html" - ] + "lintFilePatterns": ["src/**/*.ts", "src/**/*.html"] } } } diff --git a/e2e/protractor.conf.js b/e2e/protractor.conf.js index 26f45cc..fc01477 100644 --- a/e2e/protractor.conf.js +++ b/e2e/protractor.conf.js @@ -2,35 +2,35 @@ // Protractor configuration file, see link for more information // https://github.com/angular/protractor/blob/master/lib/config.ts -const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter'); +const { SpecReporter, StacktraceOption } = require("jasmine-spec-reporter") /** * @type { import("protractor").Config } */ exports.config = { allScriptsTimeout: 11000, - specs: [ - './src/**/*.e2e-spec.ts' - ], + specs: ["./src/**/*.e2e-spec.ts"], capabilities: { - browserName: 'chrome' + browserName: "chrome", }, directConnect: true, - baseUrl: 'http://localhost:4200/', - framework: 'jasmine', + baseUrl: "http://localhost:4200/", + framework: "jasmine", jasmineNodeOpts: { showColors: true, defaultTimeoutInterval: 30000, - print: function () { } + print: function () {}, }, onPrepare() { - require('ts-node').register({ - project: require('path').join(__dirname, './tsconfig.json') - }); - jasmine.getEnv().addReporter(new SpecReporter({ - spec: { - displayStacktrace: StacktraceOption.PRETTY - } - })); - } -}; + require("ts-node").register({ + project: require("path").join(__dirname, "./tsconfig.json"), + }) + jasmine.getEnv().addReporter( + new SpecReporter({ + spec: { + displayStacktrace: StacktraceOption.PRETTY, + }, + }) + ) + }, +} diff --git a/e2e/src/app.e2e-spec.ts b/e2e/src/app.e2e-spec.ts index 954281e..e601c8c 100644 --- a/e2e/src/app.e2e-spec.ts +++ b/e2e/src/app.e2e-spec.ts @@ -1,23 +1,25 @@ -import { browser, logging } from 'protractor'; -import { AppPage } from './app.po'; +import { browser, logging } from "protractor" +import { AppPage } from "./app.po" -describe('workspace-project App', (): void => { - let page: AppPage; +describe("workspace-project App", (): void => { + let page: AppPage beforeEach((): void => { - page = new AppPage(); - }); + page = new AppPage() + }) - it('should display welcome message', (): void => { - page.navigateTo(); - expect(page.getTitleText()).toEqual('public-gateway-cacher app is running!'); - }); + it("should display welcome message", (): void => { + void page.navigateTo() + void expect(page.getTitleText()).toEqual("public-gateway-cacher app is running!") + }) afterEach(async (): Promise => { // 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({ + const logs = await browser.manage().logs().get(logging.Type.BROWSER) + const expected: Partial = { level: logging.Level.SEVERE, - } as logging.Entry)); - }); -}); + } + + void expect(logs).not.toContain(jasmine.objectContaining(expected)) + }) +}) diff --git a/e2e/src/app.po.ts b/e2e/src/app.po.ts index d1409e1..4fd9903 100644 --- a/e2e/src/app.po.ts +++ b/e2e/src/app.po.ts @@ -1,11 +1,11 @@ -import { browser, by, element } from 'protractor'; +import { browser, by, element } from "protractor" export class AppPage { - navigateTo(): Promise { - return browser.get(browser.baseUrl) as Promise; + async navigateTo(): Promise { + return browser.get(browser.baseUrl) as Promise } - getTitleText(): Promise { - return element(by.css('pgc-root .content span')).getText() as Promise; + async getTitleText(): Promise { + return element(by.css("pgc-root .content span")).getText() as Promise } } diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json index 8c57967..aa99b10 100644 --- a/e2e/tsconfig.json +++ b/e2e/tsconfig.json @@ -5,10 +5,6 @@ "outDir": "../out-tsc/e2e", "module": "commonjs", "target": "ESNext", - "types": [ - "jasmine", - "jasminewd2", - "node" - ] + "types": ["jasmine", "jasminewd2", "node"] } } diff --git a/karma.conf.js b/karma.conf.js index fc849ec..ec35717 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -3,30 +3,30 @@ module.exports = function (config) { config.set({ - basePath: '', - frameworks: ['jasmine', '@angular-devkit/build-angular'], + 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') + 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 + clearContext: false, // leave Jasmine Spec Runner output visible in browser }, coverageIstanbulReporter: { - dir: require('path').join(__dirname, './coverage/public-gateway-cacher'), - reports: ['html', 'lcovonly', 'text-summary'], - fixWebpackSourcePaths: true + dir: require("path").join(__dirname, "./coverage/public-gateway-cacher"), + reports: ["html", "lcovonly", "text-summary"], + fixWebpackSourcePaths: true, }, - reporters: ['progress', 'kjhtml'], + reporters: ["progress", "kjhtml"], port: 9876, colors: true, logLevel: config.LOG_INFO, autoWatch: true, - browsers: ['Chrome'], + browsers: ["Chrome"], singleRun: false, - restartOnFileChange: true - }); -}; + restartOnFileChange: true, + }) +} diff --git a/package.json b/package.json index 2302ec6..50b54c8 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,9 @@ "build:gitlab": "ng build --configuration=gitlab --base-href /public-gateway-cacher/", "build:ipfs": "ng build --configuration=ipfs", "test": "ng test", - "lint": "ng lint", + "lint": "ng lint --fix", + "eslint": "eslint --fix .", + "prettier": "prettier --write .", "e2e": "ng e2e", "publish:ipfs": "pnpm run build:ipfs && ipfs add --recursive --chunker=buzhash --cid-version=1 dist/angular", "postinstall": "ngcc" @@ -70,6 +72,9 @@ "@typescript-eslint/eslint-plugin": "5.14.0", "@typescript-eslint/parser": "5.14.0", "eslint": "^8.2.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-rxjs": "^5.0.2", + "eslint-plugin-rxjs-angular": "^2.0.0", "jasmine-core": "~4.0.1", "jasmine-spec-reporter": "~7.0.0", "karma": "~6.3.17", @@ -77,9 +82,10 @@ "karma-coverage-istanbul-reporter": "~3.0.2", "karma-jasmine": "~4.0.0", "karma-jasmine-html-reporter": "^1.5.0", + "prettier": "^2.5.1", "protractor": "~7.0.0", "ts-node": "~10.7.0", "typescript": "~4.5.5" }, "private": true -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2bc4fbe..0dedb1a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -28,6 +28,9 @@ specifiers: '@typescript-eslint/parser': 5.14.0 bootstrap: ^5.1.3 eslint: ^8.2.0 + eslint-config-prettier: ^8.5.0 + eslint-plugin-rxjs: ^5.0.2 + eslint-plugin-rxjs-angular: ^2.0.0 ipfs-css: ^1.3.0 jasmine-core: ~4.0.1 jasmine-spec-reporter: ~7.0.0 @@ -36,6 +39,7 @@ specifiers: karma-coverage-istanbul-reporter: ~3.0.2 karma-jasmine: ~4.0.0 karma-jasmine-html-reporter: ^1.5.0 + prettier: ^2.5.1 protractor: ~7.0.0 rxjs: ~7.5.5 ts-node: ~10.7.0 @@ -77,6 +81,9 @@ devDependencies: '@typescript-eslint/eslint-plugin': 5.14.0_e74fb90c35f99587899145b1078aa5b4 '@typescript-eslint/parser': 5.14.0_eslint@8.10.0+typescript@4.5.5 eslint: 8.10.0 + eslint-config-prettier: 8.5.0_eslint@8.10.0 + eslint-plugin-rxjs: 5.0.2_eslint@8.10.0+typescript@4.5.5 + eslint-plugin-rxjs-angular: 2.0.0_eslint@8.10.0+typescript@4.5.5 jasmine-core: 4.0.1 jasmine-spec-reporter: 7.0.0 karma: 6.3.17 @@ -84,6 +91,7 @@ devDependencies: karma-coverage-istanbul-reporter: 3.0.3 karma-jasmine: 4.0.1_karma@6.3.17 karma-jasmine-html-reporter: 1.7.0_d63185f8de84f984ad7c6427ff04984c + prettier: 2.5.1 protractor: 7.0.0 ts-node: 10.7.0_99a448058f874aec2a353d0e974167cc typescript: 4.5.5 @@ -600,7 +608,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.16.7 - '@babel/generator': 7.16.8 + '@babel/generator': 7.17.3 '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.16.12 '@babel/helper-module-transforms': 7.17.6 '@babel/helpers': 7.17.2 @@ -2074,7 +2082,7 @@ packages: dependencies: '@swc-node/core': 1.8.2 '@swc-node/sourcemap-support': 0.1.11 - chalk: 4.1.0 + chalk: 4.1.2 debug: 4.3.3 pirates: 4.0.5 tslib: 2.3.1 @@ -2406,6 +2414,16 @@ packages: '@types/node': 17.0.21 dev: true + /@types/yargs-parser/21.0.0: + resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} + dev: true + + /@types/yargs/17.0.9: + resolution: {integrity: sha512-Ci8+4/DOtkHRylcisKmVMtmVO5g7weUVCKcsu1sJvF1bn0wExTmbHmhFKj7AnEm0de800iovGhdSKzYnzbaHpg==} + dependencies: + '@types/yargs-parser': 21.0.0 + dev: true + /@typescript-eslint/eslint-plugin/5.14.0_e74fb90c35f99587899145b1078aa5b4: resolution: {integrity: sha512-ir0wYI4FfFUDfLcuwKzIH7sMVA+db7WYen47iRSaCGl+HMAZI9fpBwfDo45ZALD3A45ZGyHWDNLhbg8tZrMX4w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3153,6 +3171,14 @@ packages: tweetnacl: 0.14.5 dev: true + /bent/7.3.12: + resolution: {integrity: sha512-T3yrKnVGB63zRuoco/7Ybl7BwwGZR0lceoVG5XmQyMIH9s19SV5m+a8qam4if0zQuAmOQTyPTPmsQBdAorGK3w==} + dependencies: + bytesish: 0.4.4 + caseless: 0.12.0 + is-stream: 2.0.1 + dev: true + /big.js/5.2.2: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} dev: true @@ -3276,6 +3302,10 @@ packages: engines: {node: '>= 0.8'} dev: true + /bytesish/0.4.4: + resolution: {integrity: sha512-i4uu6M4zuMUiyfZN4RU2+i9+peJh//pXhd9x1oSe1LBkZ3LEbCoygu8W0bXTukU1Jme2txKuotpCZRaC3FLxcQ==} + dev: true + /cacache/15.3.0: resolution: {integrity: sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==} engines: {node: '>= 10'} @@ -3497,6 +3527,11 @@ packages: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} dev: true + /common-tags/1.8.2: + resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} + engines: {node: '>=4.0.0'} + dev: true + /commondir/1.0.1: resolution: {integrity: sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=} dev: true @@ -3791,6 +3826,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /decamelize/5.0.1: + resolution: {integrity: sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==} + engines: {node: '>=10'} + dev: true + /decode-uri-component/0.2.0: resolution: {integrity: sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=} engines: {node: '>=0.10'} @@ -4323,6 +4363,68 @@ packages: engines: {node: '>=10'} dev: true + /eslint-config-prettier/8.5.0_eslint@8.10.0: + resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + dependencies: + eslint: 8.10.0 + dev: true + + /eslint-etc/5.1.0_eslint@8.10.0+typescript@4.5.5: + resolution: {integrity: sha512-Rmjl01h5smi5cbsFne2xpTuch2xNnwXiX2lbS4HttXUN5FwXKAwG1UEFBVGO1nC091YO/QyVahyfNPJSX2ae+g==} + peerDependencies: + eslint: ^8.0.0 + typescript: ^4.0.0 + dependencies: + '@typescript-eslint/experimental-utils': 5.11.0_eslint@8.10.0+typescript@4.5.5 + eslint: 8.10.0 + tsutils: 3.21.0_typescript@4.5.5 + tsutils-etc: 1.4.1_tsutils@3.21.0+typescript@4.5.5 + typescript: 4.5.5 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-rxjs-angular/2.0.0_eslint@8.10.0+typescript@4.5.5: + resolution: {integrity: sha512-MalcYcEHOK2NT+avWSI1PsUilwGx6cprMQdw9jJRlCTkIvsUvCGFD1eTqQKVImwkK8+te732v9VsP/XcXlKZqA==} + peerDependencies: + eslint: ^8.0.0 + typescript: ^4.0.0 + dependencies: + '@typescript-eslint/experimental-utils': 5.11.0_eslint@8.10.0+typescript@4.5.5 + common-tags: 1.8.2 + eslint: 8.10.0 + eslint-etc: 5.1.0_eslint@8.10.0+typescript@4.5.5 + requireindex: 1.2.0 + tslib: 2.3.1 + typescript: 4.5.5 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-rxjs/5.0.2_eslint@8.10.0+typescript@4.5.5: + resolution: {integrity: sha512-Q2wsEHWInhZ3uz5df+YbD4g/NPQqAeYHjJuEsxqgVS+XAsYCuVE2pj9kADdMFy4GsQy2jt7KP+TOrnq1i6bI5Q==} + peerDependencies: + eslint: ^8.0.0 + typescript: ^4.0.0 + dependencies: + '@typescript-eslint/experimental-utils': 5.11.0_eslint@8.10.0+typescript@4.5.5 + common-tags: 1.8.2 + decamelize: 5.0.1 + eslint: 8.10.0 + eslint-etc: 5.1.0_eslint@8.10.0+typescript@4.5.5 + requireindex: 1.2.0 + rxjs-report-usage: 1.0.6 + tslib: 2.3.1 + tsutils: 3.21.0_typescript@4.5.5 + tsutils-etc: 1.4.1_tsutils@3.21.0+typescript@4.5.5 + typescript: 4.5.5 + transitivePeerDependencies: + - supports-color + dev: true + /eslint-scope/5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} @@ -5700,6 +5802,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /kleur/3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + dev: true + /klona/2.0.5: resolution: {integrity: sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==} engines: {node: '>= 8'} @@ -7045,6 +7152,12 @@ packages: engines: {node: '>= 0.8.0'} dev: true + /prettier/2.5.1: + resolution: {integrity: sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + /pretty-bytes/5.6.0: resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} engines: {node: '>=6'} @@ -7066,6 +7179,14 @@ packages: retry: 0.12.0 dev: true + /prompts/2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + dev: true + /protractor/7.0.0: resolution: {integrity: sha512-UqkFjivi4GcvUQYzqGYNe0mLzfn5jiLmO8w9nMhQoJRLhy2grJonpga2IWhI6yJO30LibWXJJtA4MOIZD2GgZw==} engines: {node: '>=10.13.x'} @@ -7303,6 +7424,11 @@ packages: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} dev: true + /requireindex/1.2.0: + resolution: {integrity: sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==} + engines: {node: '>=0.10.5'} + dev: true + /requires-port/1.0.0: resolution: {integrity: sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=} dev: true @@ -7397,6 +7523,21 @@ packages: rxjs: 6.6.7 dev: true + /rxjs-report-usage/1.0.6: + resolution: {integrity: sha512-omv1DIv5z1kV+zDAEjaDjWSkx8w5TbFp5NZoPwUipwzYVcor/4So9ZU3bUyQ1c8lxY5Q0Es/ztWW7PGjY7to0Q==} + hasBin: true + dependencies: + '@babel/parser': 7.17.3 + '@babel/traverse': 7.17.3 + '@babel/types': 7.17.0 + bent: 7.3.12 + chalk: 4.1.2 + glob: 7.2.0 + prompts: 2.4.2 + transitivePeerDependencies: + - supports-color + dev: true + /rxjs/6.6.7: resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} engines: {npm: '>=2.0.0'} @@ -7631,6 +7772,10 @@ packages: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: true + /sisteransi/1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: true + /slash/3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -8123,6 +8268,19 @@ packages: /tslib/2.3.1: resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==} + /tsutils-etc/1.4.1_tsutils@3.21.0+typescript@4.5.5: + resolution: {integrity: sha512-6UPYgc7OXcIW5tFxlsZF3OVSBvDInl/BkS3Xsu64YITXk7WrnWTVByKWPCThFDBp5gl5IGHOzGMdQuDCE7OL4g==} + hasBin: true + peerDependencies: + tsutils: ^3.0.0 + typescript: ^4.0.0 + dependencies: + '@types/yargs': 17.0.9 + tsutils: 3.21.0_typescript@4.5.5 + typescript: 4.5.5 + yargs: 17.3.1 + dev: true + /tsutils/3.21.0_typescript@4.5.5: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 4178bd0..420f9bb 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,14 +1,17 @@ -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), -}]; +const routes: Routes = [ + { + path: "", + loadChildren: async () => import("./pages/pages.module").then(m => m.PagesModule), + }, +] @NgModule({ - imports: [RouterModule.forRoot(routes, { useHash: environment.useHash, relativeLinkResolution: 'legacy' })], - exports: [RouterModule] + imports: [RouterModule.forRoot(routes, { useHash: environment.useHash, relativeLinkResolution: "legacy" })], + exports: [RouterModule], }) -export class AppRoutingModule { } +export class AppRoutingModule {} diff --git a/src/app/app.component.html b/src/app/app.component.html index dae53fe..9008f9a 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -3,8 +3,7 @@ - diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 8242c4c..4d6d997 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -1,35 +1,43 @@ -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 - ], - declarations: [ - AppComponent - ], - }).compileComponents(); - })); +describe("AppComponent", (): void => { + beforeEach( + waitForAsync((): void => { + void TestBed.configureTestingModule({ + imports: [RouterTestingModule], + declarations: [AppComponent], + }).compileComponents() + }) + ) - it('should create the app', (): void => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app).toBeTruthy(); - }); + it("should create the app", (): void => { + 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 + void expect(app).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!'); - }); -}); + 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 + void expect(app.themeService).toBeTruthy() + }) + + it("should render title", (): void => { + const fixture = TestBed.createComponent(AppComponent) + fixture.detectChanges() + if (!isHTMLElement(fixture.debugElement.nativeElement)) throw new Error("Expected HTMLElement") + + const compiled: HTMLElement = fixture.debugElement.nativeElement + void expect(compiled.querySelector("h1")?.textContent).toContain("Public Gateway Cacher") + }) +}) + +function isHTMLElement(element: unknown): element is HTMLElement { + return Object.getPrototypeOf(element) instanceof HTMLElement +} diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 3e25a2e..15b3f73 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,14 +1,12 @@ -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', - templateUrl: './app.component.html', - styleUrls: ['./app.component.scss'], + selector: "app-root", + templateUrl: "./app.component.html", + styleUrls: ["./app.component.scss"], changeDetection: ChangeDetectionStrategy.OnPush, }) export class AppComponent { - constructor( - public readonly themeService: ThemeService - ) { } + constructor(@Inject(ThemeService) readonly themeService: ThemeService) {} } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index a566949..a59eecc 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,19 +1,17 @@ -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: [ - AppComponent - ], + declarations: [AppComponent], imports: [ AppRoutingModule, BrowserAnimationsModule, @@ -26,6 +24,6 @@ import { AppComponent } from './app.component'; MatToolbarModule, ], providers: [], - bootstrap: [AppComponent] + bootstrap: [AppComponent], }) -export class AppModule { } +export class AppModule {} diff --git a/src/app/enums/protocol.enum.ts b/src/app/enums/protocol.enum.ts index d8b27e4..8736e27 100644 --- a/src/app/enums/protocol.enum.ts +++ b/src/app/enums/protocol.enum.ts @@ -1,4 +1,4 @@ export enum Protocol { - IPFS = 'ipfs', - IPNS = 'ipns', + IPFS = "ipfs", + IPNS = "ipns", } diff --git a/src/app/enums/theme.enum.ts b/src/app/enums/theme.enum.ts index 037550b..7566fa0 100644 --- a/src/app/enums/theme.enum.ts +++ b/src/app/enums/theme.enum.ts @@ -1,4 +1,4 @@ export enum Theme { - Light = 'theme-light', - Dark = 'theme-dark', + Light = "theme-light", + Dark = "theme-dark", } diff --git a/src/app/interfaces/environment.ts b/src/app/interfaces/environment.ts index f5b42a2..fc5ab5a 100644 --- a/src/app/interfaces/environment.ts +++ b/src/app/interfaces/environment.ts @@ -1,5 +1,5 @@ export interface Environment { - production: boolean; - base_href?: string; - useHash: boolean; + production: boolean + base_href?: string + useHash: boolean } diff --git a/src/app/pages/pages-routing.module.ts b/src/app/pages/pages-routing.module.ts index af55caf..2f7f8ee 100644 --- a/src/app/pages/pages-routing.module.ts +++ b/src/app/pages/pages-routing.module.ts @@ -1,14 +1,17 @@ -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, -}]; +const routes: Routes = [ + { + path: "", + component: PagesComponent, + }, +] @NgModule({ imports: [RouterModule.forChild(routes)], - exports: [RouterModule] + exports: [RouterModule], }) -export class PagesRoutingModule { } +export class PagesRoutingModule {} diff --git a/src/app/pages/pages.component.html b/src/app/pages/pages.component.html index 16b19e1..220be31 100644 --- a/src/app/pages/pages.component.html +++ b/src/app/pages/pages.component.html @@ -1,42 +1,40 @@
-
- IPFS - + -
- IPNS - + -
- + - - + @@ -44,7 +42,7 @@ - + - +
Status Status {{ element.icon }} Gateway Gateway
@@ -64,24 +62,21 @@

About

- This allows you to cache a specific IPFS hash to a bunch of public gateways. - It's inspired from github.com/ipfs/public-gateway-checker. - The source code is available at gitlab.com/NatoBoram/public-gateway-cacher. + This allows you to cache a specific IPFS hash to a bunch of public gateways. It's inspired from + github.com/ipfs/public-gateway-checker. The source code is + available at gitlab.com/NatoBoram/public-gateway-cacher.

- If you'd like to add a new public gateway, - please go to github.com/ipfs/public-gateway-checker, - submit a pull request then open an issue here. + If you'd like to add a new public gateway, please go to + github.com/ipfs/public-gateway-checker, submit a pull + request then open an issue here.

-
diff --git a/src/app/pages/pages.component.spec.ts b/src/app/pages/pages.component.spec.ts index ff76c01..c71282f 100644 --- a/src/app/pages/pages.component.spec.ts +++ b/src/app/pages/pages.component.spec.ts @@ -1,24 +1,28 @@ -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; +describe("PagesComponent", (): void => { + let component: PagesComponent + let fixture: ComponentFixture - beforeEach(waitForAsync((): void => { - TestBed.configureTestingModule({ - declarations: [PagesComponent] + beforeEach( + waitForAsync((): void => { + 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(); - }); -}); + it("should create", (): void => { + void expect(component).toBeTruthy() + }) +}) diff --git a/src/app/pages/pages.component.ts b/src/app/pages/pages.component.ts index 4e0ac00..25dd10c 100644 --- a/src/app/pages/pages.component.ts +++ b/src/app/pages/pages.component.ts @@ -1,134 +1,151 @@ -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 { 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', - templateUrl: './pages.component.html', - styleUrls: ['./pages.component.scss'], + selector: "app-pages", + templateUrl: "./pages.component.html", + styleUrls: ["./pages.component.scss"], changeDetection: ChangeDetectionStrategy.OnPush, }) export class PagesComponent implements OnInit, OnDestroy { + @ViewChild(MatTable) matTable!: MatTable - @ViewChild(MatTable) matTable!: MatTable; + gateways!: string[] + inputColour: ThemePalette = "primary" + ipfs = "" + ipns = "" - gateways!: string[]; - inputColour: ThemePalette = 'primary'; - ipfs = ''; - ipns = ''; + readonly dataSource = new MatTableDataSource([]) + readonly displayedColumns = ["icon", "gateway"] + readonly subscriptions: Subscription[] = [] - readonly dataSource = new MatTableDataSource([]); - readonly displayedColumns: ['icon', 'gateway'] = ['icon', 'gateway']; - readonly subscriptions: Subscription[] = []; - - private readonly destroy$ = new EventEmitter(); + private readonly destroy$ = new EventEmitter() 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() + .pipe(takeUntil(this.destroy$)) + .subscribe((gateways): void => { + this.gateways = gateways + }) // Theme - this.setColours(this.themeService.current); - this.themeService.valueChanges.pipe( - takeUntil(this.destroy$) - ).subscribe((theme): void => { - this.setColours(theme); - }); + this.setColours(this.themeService.current) + this.themeService.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((theme): void => { + this.setColours(theme) + }) } ngOnDestroy(): void { - this.destroy$.complete(); + this.destroy$.next() + 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( - this.gatewayService.get(gateway, protocol, hashpath).subscribe((resp): void => { - this.dataSource.data.push({ - gateway: this.gatewayService.url(gateway, protocol, hashpath), - message: resp.statusText, - icon: this.getIcon(resp.status), - ok: resp.ok, - }); - 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.gatewayService + .get(gateway, protocol, hashpath) + .pipe(takeUntil(this.destroy$)) + .subscribe( + (resp): void => { + this.dataSource.data.push({ + gateway: this.gatewayService.url(gateway, protocol, hashpath), + message: resp.statusText, + icon: this.getIcon(resp.status), + ok: resp.ok, + }) + this.matTable.renderRows() + }, + (error: unknown): void => { + if (!(error instanceof HttpErrorResponse)) return + + 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() + } + ) + ) + }) } 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 } diff --git a/src/app/pages/pages.module.ts b/src/app/pages/pages.module.ts index 2966605..96cbaea 100644 --- a/src/app/pages/pages.module.ts +++ b/src/app/pages/pages.module.ts @@ -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], @@ -24,6 +24,6 @@ import { PagesComponent } from './pages.component'; MatTableModule, MatTooltipModule, PagesRoutingModule, - ] + ], }) -export class PagesModule { } +export class PagesModule {} diff --git a/src/app/services/gateway.service.spec.ts b/src/app/services/gateway.service.spec.ts index 0e99d0e..d3e271d 100644 --- a/src/app/services/gateway.service.spec.ts +++ b/src/app/services/gateway.service.spec.ts @@ -1,11 +1,18 @@ -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({})); +describe("GatewayService", (): void => { + beforeEach( + (): TestBedStatic => + TestBed.configureTestingModule({ + imports: [HttpClientTestingModule], + }) + ) - it('should be created', (): void => { - const service: GatewayService = TestBed.inject(GatewayService); - expect(service).toBeTruthy(); - }); -}); + it("should be created", (): void => { + const service: GatewayService = TestBed.inject(GatewayService) + void expect(service).toBeTruthy() + }) +}) diff --git a/src/app/services/gateway.service.ts b/src/app/services/gateway.service.ts index e5a1cc5..310a2c1 100644 --- a/src/app/services/gateway.service.ts +++ b/src/app/services/gateway.service.ts @@ -1,37 +1,34 @@ -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' + providedIn: "root", }) export class GatewayService { - - constructor( - private readonly http: HttpClient - ) { } + constructor(@Inject(HttpClient) private readonly http: HttpClient) {} list(): Observable { return this.http.get( - environment.base_href && environment.base_href !== '/' + environment.base_href && environment.base_href !== "/" ? `${environment.base_href}/assets/json/gateways.json` - : `${document.querySelector('base')?.href}assets/json/gateways.json` - ); + : `${document.querySelector("base")?.href ?? ""}assets/json/gateways.json` + ) } get(gateway: string, protocol: Protocol, hashpath: string): Observable> { return this.http.get(`${this.url(gateway, protocol, hashpath)}#x-ipfs-companion-no-redirect`, { - observe: 'response', - responseType: 'text', - }); + 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 } - } diff --git a/src/app/services/theme.service.spec.ts b/src/app/services/theme.service.spec.ts index 092f96f..a8d0615 100644 --- a/src/app/services/theme.service.spec.ts +++ b/src/app/services/theme.service.spec.ts @@ -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; +describe("ThemeService", (): void => { + 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(); - }); -}); + it("should be created", (): void => { + void expect(service).toBeTruthy() + }) +}) diff --git a/src/app/services/theme.service.ts b/src/app/services/theme.service.ts index 8504bb0..eda3e91 100644 --- a/src/app/services/theme.service.ts +++ b/src/app/services/theme.service.ts @@ -1,49 +1,51 @@ -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(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({ - providedIn: 'root' + providedIn: "root", }) export class ThemeService { + current = Theme.Light + icon = "brightness_low" + readonly valueChanges: Observable - current = Theme.Light; - icon = 'brightness_low'; - readonly valueChanges: Observable; - - private readonly subject$ = new Subject(); + private readonly subject$ = new Subject() 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" } } } diff --git a/src/environments/environment.gitlab.ts b/src/environments/environment.gitlab.ts index d43ab83..b003693 100644 --- a/src/environments/environment.gitlab.ts +++ b/src/environments/environment.gitlab.ts @@ -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', + base_href: "/public-gateway-cacher", useHash: false, -}; +} diff --git a/src/environments/environment.ipfs.ts b/src/environments/environment.ipfs.ts index aa5bbea..bf345c1 100644 --- a/src/environments/environment.ipfs.ts +++ b/src/environments/environment.ipfs.ts @@ -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, -}; +} diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index 237438d..8313431 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -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: '/', + base_href: "/", useHash: false, -}; +} diff --git a/src/environments/environment.ts b/src/environments/environment.ts index aca3a85..4d4a77e 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -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`. @@ -6,9 +6,9 @@ import { Environment } from '../app/interfaces/environment'; export const environment: Environment = { production: false, - base_href: '/', + base_href: "/", useHash: false, -}; +} /* * For easier debugging in development mode, you can import the following file diff --git a/src/index.html b/src/index.html index d324920..ba35ee2 100644 --- a/src/index.html +++ b/src/index.html @@ -1,26 +1,23 @@ - + + + + Public Gateway Cacher - - - Public Gateway Cacher + + - - + + - - - - - - - - - - - - + + + + + + + diff --git a/src/main.ts b/src/main.ts index 50b0ec7..081a9e9 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,11 +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'; +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)); +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err): void => console.error(err)) diff --git a/src/polyfills.ts b/src/polyfills.ts index 13e0ea4..339425e 100644 --- a/src/polyfills.ts +++ b/src/polyfills.ts @@ -45,8 +45,7 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ -import 'zone.js'; // Included with Angular CLI. - +import "zone.js" // Included with Angular CLI. /*************************************************************************************************** * APPLICATION IMPORTS diff --git a/src/styles.scss b/src/styles.scss index f7be942..9bb28a5 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -1,5 +1,5 @@ // Custom Theming for Angular Material -@use '@angular/material'as mat; +@use "@angular/material" as mat; // For more information: https://material.angular.io/guide/theming // Plus imports for other components in your app. @@ -25,7 +25,7 @@ // // that you are using. // @include angular-material-theme($public-gateway-cacher-theme); -@import 'styles/ipfs-themes.scss'; +@import "styles/ipfs-themes.scss"; .theme-light { @include mat.all-component-themes($ipfs-light-theme); @@ -47,5 +47,5 @@ body { font-family: Roboto, "Helvetica Neue", sans-serif; } -@import '~bootstrap/scss/bootstrap-grid.scss'; -@import '~ipfs-css/theme.scss'; +@import "~bootstrap/scss/bootstrap-grid.scss"; +@import "~ipfs-css/theme.scss"; diff --git a/src/styles/ipfs-colours.scss b/src/styles/ipfs-colours.scss index bf903b1..59fece5 100644 --- a/src/styles/ipfs-colours.scss +++ b/src/styles/ipfs-colours.scss @@ -1,25 +1,34 @@ @import "@angular/material/core/theming/palette"; -$ipfs-colour-navy: (default: #0B3A53, +$ipfs-colour-navy: ( + default: #0b3a53, lighter: #3e6480, darker: #00142a, - contrast: (default: $light-primary-text, + contrast: ( + default: $light-primary-text, lighter: $light-primary-text, darker: $light-primary-text, - )); + ), +); -$ipfs-colour-aqua: (default: #69c5cd, +$ipfs-colour-aqua: ( + default: #69c5cd, lighter: #9df8ff, darker: #32949c, - contrast: (default: $dark-primary-text, + contrast: ( + default: $dark-primary-text, lighter: $dark-primary-text, darker: $dark-primary-text, - )); + ), +); -$ipfs-colour-yellow: (default: #f39021, +$ipfs-colour-yellow: ( + default: #f39021, lighter: #ffc155, darker: #bb6200, - contrast: (default: $dark-primary-text, + contrast: ( + default: $dark-primary-text, lighter: $dark-primary-text, darker: $dark-primary-text, - )); + ), +); diff --git a/src/styles/ipfs-palettes.scss b/src/styles/ipfs-palettes.scss index 211e1ec..639a210 100644 --- a/src/styles/ipfs-palettes.scss +++ b/src/styles/ipfs-palettes.scss @@ -1,6 +1,6 @@ -@use '@angular/material'as mat; -@import 'ipfs-colours.scss'; +@use "@angular/material" as mat; +@import "ipfs-colours.scss"; -$ipfs-primary: mat.define-palette($ipfs-colour-navy, 'default', 'lighter', 'darker'); -$ipfs-accent: mat.define-palette($ipfs-colour-aqua, 'default', 'lighter', 'darker'); -$ipfs-warn: mat.define-palette($ipfs-colour-yellow, 'default', 'lighter', 'darker'); +$ipfs-primary: mat.define-palette($ipfs-colour-navy, "default", "lighter", "darker"); +$ipfs-accent: mat.define-palette($ipfs-colour-aqua, "default", "lighter", "darker"); +$ipfs-warn: mat.define-palette($ipfs-colour-yellow, "default", "lighter", "darker"); diff --git a/src/styles/ipfs-themes.scss b/src/styles/ipfs-themes.scss index ea64470..dc96d85 100644 --- a/src/styles/ipfs-themes.scss +++ b/src/styles/ipfs-themes.scss @@ -1,5 +1,5 @@ -@use '@angular/material'as mat; -@import 'ipfs-palettes.scss'; +@use "@angular/material" as mat; +@import "ipfs-palettes.scss"; $ipfs-light-theme: mat.define-light-theme($ipfs-primary, $ipfs-accent, $ipfs-warn); $ipfs-dark-theme: mat.define-dark-theme($ipfs-primary, $ipfs-accent, $ipfs-warn); diff --git a/src/test.ts b/src/test.ts index dcf80e7..23eb9b5 100644 --- a/src/test.ts +++ b/src/test.ts @@ -1,22 +1,16 @@ // 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'; -import 'zone.js/testing'; +import { getTestBed } from "@angular/core/testing" +import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from "@angular/platform-browser-dynamic/testing" -declare const require: any; +declare const require: any // First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting(), { - teardown: { destroyAfterEach: false } -} -); +getTestBed().initTestEnvironment(BrowserDynamicTestingModule, 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) diff --git a/tsconfig.app.json b/tsconfig.app.json index 82d91dc..ff396d4 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -5,11 +5,6 @@ "outDir": "./out-tsc/app", "types": [] }, - "files": [ - "src/main.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.d.ts" - ] + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"] } diff --git a/tsconfig.json b/tsconfig.json index 10841b9..33fbdbb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -30,10 +30,7 @@ "importHelpers": true, "target": "ESNext", "module": "ESNext", - "lib": [ - "ESNext", - "DOM" - ] + "lib": ["ESNext", "DOM"] }, "angularCompilerOptions": { "fullTemplateTypeCheck": true, diff --git a/tsconfig.spec.json b/tsconfig.spec.json index 092345b..669344f 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -3,16 +3,8 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/spec", - "types": [ - "jasmine" - ] + "types": ["jasmine"] }, - "files": [ - "src/test.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] + "files": ["src/test.ts", "src/polyfills.ts"], + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] }