Update Angular (#2952)

* fix Tor logs actually fetching od logs

* chore: update to Angular 18

* chore: update to Angular 19

* bump patchDB

* chore: update Angular

* chore: fix setup-wizard success page

* chore: fix

* chore: fix

* chore: fix

* chore: fix

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
This commit is contained in:
Alex Inkin
2025-05-30 21:34:24 +07:00
committed by GitHub
parent 05b8dd9ad8
commit 02413a4fac
257 changed files with 5921 additions and 9539 deletions

View File

@@ -1,193 +0,0 @@
# Size Limit [![Cult Of Martians][cult-img]][cult]
Size Limit is a performance budget tool for JavaScript. It checks every commit
on CI, calculates the real cost of your JS for end-users and throws an error
if the cost exceeds the limit.
- **ES modules** and **tree-shaking** support.
- Add Size Limit to **Travis CI**, **Circle CI**, **GitHub Actions**
or another CI system to know if a pull request adds a massive dependency.
- **Modular** to fit different use cases: big JS applications
that use their own bundler or small npm libraries with many files.
- Can calculate **the time** it would take a browser
to download and **execute** your JS. Time is a much more accurate
and understandable metric compared to the size in bytes.
- Calculations include **all dependencies and polyfills**
used in your JS.
<p align="center">
<img src="./img/example.png" alt="Size Limit CLI" width="738">
</p>
With **[GitHub action]** Size Limit will post bundle size changes as a comment
in pull request discussion.
<p align="center">
<img src="https://raw.githubusercontent.com/andresz1/size-limit-action/master/assets/pr.png"
alt="Size Limit comment in pull request about bundle size changes"
width="686" height="289">
</p>
With `--why`, Size Limit can tell you _why_ your library is of this size
and show the real cost of all your internal dependencies.
<p align="center">
<img src="./img/why.png" alt="Bundle Analyzer example" width="650">
</p>
<p align="center">
<a href="https://evilmartians.com/?utm_source=size-limit">
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg"
alt="Sponsored by Evil Martians" width="236" height="54">
</a>
</p>
[github action]: https://github.com/andresz1/size-limit-action
[cult-img]: http://cultofmartians.com/assets/badges/badge.svg
[cult]: http://cultofmartians.com/tasks/size-limit-config.html
## Who Uses Size Limit
- [MobX](https://github.com/mobxjs/mobx)
- [Material-UI](https://github.com/callemall/material-ui)
- [Autoprefixer](https://github.com/postcss/autoprefixer)
- [PostCSS](https://github.com/postcss/postcss) reduced
[25% of the size](https://github.com/postcss/postcss/commit/150edaa42f6d7ede73d8c72be9909f0a0f87a70f).
- [Browserslist](https://github.com/ai/browserslist) reduced
[25% of the size](https://github.com/ai/browserslist/commit/640b62fa83a20897cae75298a9f2715642531623).
- [EmojiMart](https://github.com/missive/emoji-mart) reduced
[20% of the size](https://github.com/missive/emoji-mart/pull/111)
- [nanoid](https://github.com/ai/nanoid) reduced
[33% of the size](https://github.com/ai/nanoid/commit/036612e7d6cc5760313a8850a2751a5e95184eab).
- [React Focus Lock](https://github.com/theKashey/react-focus-lock) reduced
[32% of the size](https://github.com/theKashey/react-focus-lock/pull/48).
- [Logux](https://github.com/logux) reduced
[90% of the size](https://github.com/logux/logux-client/commit/62b258e20e1818b23ae39b9c4cd49e2495781e91).
## How It Works
1. Size Limit contains a CLI tool, 3 plugins (`file`, `webpack`, `time`)
and 3 plugin presets for popular use cases (`app`, `big-lib`, `small-lib`).
A CLI tool finds plugins in `package.json` and loads the config.
2. If you use the `webpack` plugin, Size Limit will bundle your JS files into
a single file. It is important to track dependencies and webpack polyfills.
It is also useful for small libraries with many small files and without
a bundler.
3. The `webpack` plugin creates an empty webpack project, adds your library
and looks for the bundle size difference.
4. The `time` plugin compares the current machine performance with that of
a low-priced Android devices to calculate the CPU throttling rate.
5. Then the `time` plugin runs headless Chrome (or desktop Chrome if its
available) to track the time a browser takes to compile and execute your JS.
Note that these measurements depend on available resources and might
be unstable. [See here](https://github.com/mbalabash/estimo/issues/5)
for more details.
## Usage
### JS Applications
Suitable for applications that have their own bundler and send the JS bundle
directly to a client (without publishing it to npm). Think of a user-facing app
or website, like an email client, a CRM, a landing page or a blog with
interactive elements, using React/Vue/Svelte lib or vanilla JS.
<details><summary><b>Show instructions</b></summary>
1. Install the preset:
```sh
$ npm install --save-dev size-limit @size-limit/preset-app
```
2. Add the `size-limit` section and the `size` script to your `package.json`:
```diff
+ "size-limit": [
+ {
+ "path": "dist/app-*.js"
+ }
+ ],
"scripts": {
"build": "webpack ./webpack.config.js",
+ "size": "npm run build && size-limit",
"test": "jest && eslint ."
}
```
3. Heres how you can get the size for your current project:
```sh
$ npm run size
Package size: 30.08 KB with all dependencies, minified and gzipped
Loading time: 602 ms on slow 3G
Running time: 214 ms on Snapdragon 410
Total time: 815 ms
```
4. Now, lets set the limit. Add 25% to the current total time and use that as
the limit in your `package.json`:
```diff
"size-limit": [
{
+ "limit": "1 s",
"path": "dist/app-*.js"
}
],
```
5. Add the `size` script to your test suite:
```diff
"scripts": {
"build": "webpack ./webpack.config.js",
"size": "npm run build && size-limit",
- "test": "jest && eslint ."
+ "test": "jest && eslint . && npm run size"
}
```
6. If you dont have a continuous integration service running, dont forget
to add one — start with [Travis CI].
</details>
## Reports
Size Limit has a [GitHub action] that comments and rejects pull requests based
on Size Limit output.
1. Install and configure Size Limit as shown above.
2. Add the following action inside `.github/workflows/size-limit.yml`
```yaml
name: 'size'
on:
pull_request:
branches:
- master
jobs:
size:
runs-on: ubuntu-latest
env:
CI_JOB_NUMBER: 1
steps:
- uses: actions/checkout@v1
- uses: andresz1/size-limit-action@v1.0.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
```
## JS API
```js
const sizeLimit = require('size-limit')
const filePlugin = require('@size-limit/file')
const webpackPlugin = require('@size-limit/webpack')
sizeLimit([filePlugin, webpackPlugin], [filePath]).then(result => {
result //=> { size: 12480 }
})
```

View File

@@ -3,7 +3,6 @@ import { Component, Input } from '@angular/core'
import { UnitConversionPipesModule } from '../pipes/unit-conversion/unit-conversion.module'
@Component({
standalone: true,
selector: 'button[drive]',
template: `
<tui-icon icon="@tui.save" />

View File

@@ -5,7 +5,6 @@ import { LogsWindowComponent } from './logs-window.component'
import { i18nPipe } from '../i18n/i18n.pipe'
@Component({
standalone: true,
selector: 'app-initializing',
template: `
<section>

View File

@@ -1,16 +1,15 @@
import { TuiScrollbar } from '@taiga-ui/core'
import { AsyncPipe } from '@angular/common'
import { Component, ElementRef, inject } from '@angular/core'
import {
WaIntersectionObserver,
INTERSECTION_ROOT,
WaIntersectionObserver,
} from '@ng-web-apis/intersection-observer'
import { WaMutationObserver } from '@ng-web-apis/mutation-observer'
import { NgDompurifyModule } from '@tinkoff/ng-dompurify'
import { TuiScrollbar } from '@taiga-ui/core'
import { NgDompurifyPipe } from '@taiga-ui/dompurify'
import { SetupLogsService } from '../services/setup-logs.service'
@Component({
standalone: true,
selector: 'logs-window',
template: `
<tui-scrollbar childList subtree (waMutationObserver)="scrollTo(bottom)">
@@ -25,11 +24,16 @@ import { SetupLogsService } from '../services/setup-logs.service'
></section>
</tui-scrollbar>
`,
styles: `
pre {
white-space: normal;
}
`,
imports: [
AsyncPipe,
WaMutationObserver,
WaIntersectionObserver,
NgDompurifyModule,
NgDompurifyPipe,
TuiScrollbar,
],
providers: [

View File

@@ -2,8 +2,8 @@ import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
import { toSignal } from '@angular/core/rxjs-interop'
import { ActivatedRoute } from '@angular/router'
import { TuiDialogContext, TuiLoader, TuiNotification } from '@taiga-ui/core'
import { NgDompurifyPipe } from '@taiga-ui/dompurify'
import { injectContext, PolymorpheusComponent } from '@taiga-ui/polymorpheus'
import { NgDompurifyModule } from '@tinkoff/ng-dompurify'
import { catchError, ignoreElements, Observable, of } from 'rxjs'
import { SafeLinksDirective } from '../directives/safe-links.directive'
import { MarkdownPipe } from '../pipes/markdown.pipe'
@@ -24,12 +24,11 @@ import { getErrorMessage } from '../services/error.service'
}
`,
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
host: { class: 'g-subpage' },
imports: [
TuiNotification,
TuiLoader,
NgDompurifyModule,
NgDompurifyPipe,
MarkdownPipe,
SafeLinksDirective,
],

View File

@@ -12,7 +12,6 @@ import { i18nPipe } from '../i18n/i18n.pipe'
import { i18nKey } from '../i18n/i18n.providers'
@Component({
standalone: true,
template: `
<p>{{ options.message }}</p>
<p *ngIf="options.warning" class="warning">{{ options.warning }}</p>
@@ -60,22 +59,20 @@ import { i18nKey } from '../i18n/i18n.providers'
></button>
</ng-template>
`,
styles: [
`
.warning {
color: var(--tui-status-warning);
}
styles: `
.warning {
color: var(--tui-status-warning);
}
.button {
pointer-events: auto;
margin-left: 0.25rem;
}
.button {
pointer-events: auto;
margin-left: 0.25rem;
}
.masked {
-webkit-text-security: disc;
}
`,
],
.masked {
-webkit-text-security: disc;
}
`,
imports: [
CommonModule,
FormsModule,

View File

@@ -5,7 +5,6 @@ import { TuiCell } from '@taiga-ui/layout'
import { StartOSDiskInfo } from '../types/api'
@Component({
standalone: true,
selector: 'button[server]',
template: `
<tui-icon icon="@tui.save" />
@@ -21,7 +20,12 @@ import { StartOSDiskInfo } from '../types/api'
</span>
</span>
`,
styles: ':host { width: stretch; border-radius: var(--tui-radius-l); }',
styles: `
:host {
border-radius: var(--tui-radius-l);
}
`,
host: { class: 'g-stretch' },
hostDirectives: [TuiCell],
imports: [DatePipe, TuiIcon, TuiTitle],
})

View File

@@ -7,7 +7,6 @@ import {
} from '@angular/core'
@Component({
standalone: true,
selector: '[ticker]',
template: '<ng-content />',
styles: `

View File

@@ -10,7 +10,6 @@ export const VERSION = new InjectionToken<string>('VERSION')
@Directive({
selector: '[docsLink]',
standalone: true,
host: {
target: '_blank',
rel: 'noreferrer',

View File

@@ -1,59 +0,0 @@
import {
Directive,
ElementRef,
HostListener,
inject,
NgZone,
} from '@angular/core'
import { ANIMATION_FRAME } from '@ng-web-apis/common'
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'
import { tuiZonefree } from '@taiga-ui/cdk'
import { filter } from 'rxjs'
const SIZE = 100
const SPEED = 15
@Directive({
selector: '[dragScroller]',
standalone: true,
})
export class DragScrollerDirective {
private readonly element: HTMLElement = inject(ElementRef).nativeElement
private dragging = false
private x = 0
private y = 0
private readonly sub = inject(ANIMATION_FRAME)
.pipe(
filter(() => this.dragging),
tuiZonefree(inject(NgZone)),
takeUntilDestroyed(),
)
.subscribe(() => {
this.element.scrollTop += this.y * SPEED
this.element.scrollLeft += this.x * SPEED
})
@HostListener('document:pointerdown.silent', ['true'])
@HostListener('document:pointerup.silent', ['false'])
onPointer(dragging: boolean) {
this.dragging = dragging
this.x = 0
this.y = 0
}
@HostListener('pointermove.silent', ['$event'])
onPointerMove(event: PointerEvent) {
if (!this.dragging) {
return
}
const { clientX, clientY } = event
const { top, left, right, bottom } = this.element.getBoundingClientRect()
const x = Math.min(clientX - left, SIZE) - Math.min(right - clientX, SIZE)
const y = Math.min(clientY - top, SIZE) - Math.min(bottom - clientY, SIZE)
this.x = x / SIZE
this.y = y / SIZE
}
}

View File

@@ -16,7 +16,6 @@ import { tuiInjectElement } from '@taiga-ui/cdk'
subtree: true,
}),
],
standalone: true,
})
export class SafeLinksDirective {
private readonly doc = inject(DOCUMENT)

View File

@@ -519,4 +519,5 @@ export default {
517: 'Möchten Sie diese Aufgabe wirklich verwerfen?',
518: 'Verwerfen',
519: 'Um Clearnet-Domains zu veröffentlichen, musst du oben auf „Öffentlich machen“ klicken.',
520: 'Update verfügbar',
} satisfies i18n

View File

@@ -518,4 +518,5 @@ export const ENGLISH = {
'Are you sure you want to dismiss this task?': 517,
'Dismiss': 518, // as in, dismiss or delete a task
'To publish clearnet domains, you must click "Make Public", above.': 519,
'Update available': 520,
} as const

View File

@@ -519,4 +519,5 @@ export default {
517: '¿Estás seguro de que deseas descartar esta tarea?',
518: 'Descartar',
519: 'Para publicar dominios en clearnet, debes hacer clic en "Hacer público" arriba.',
520: 'Actualización disponible',
} satisfies i18n

View File

@@ -519,4 +519,5 @@ export default {
517: 'Êtes-vous sûr de vouloir ignorer cette tâche ?',
518: 'Ignorer',
519: 'Pour publier des domaines clearnet, vous devez cliquer sur « Rendre public » ci-dessus.',
520: 'Mise à jour disponible',
} satisfies i18n

View File

@@ -519,4 +519,5 @@ export default {
517: 'Czy na pewno chcesz odrzucić to zadanie?',
518: 'Odrzuć',
519: 'Aby opublikować domeny w clearnet, kliknij „Upublicznij” powyżej.',
520: 'Aktualizacja dostępna',
} satisfies i18n

View File

@@ -3,7 +3,6 @@ import { ENGLISH } from './dictionaries/en'
import { I18N, i18nKey } from './i18n.providers'
@Pipe({
standalone: true,
name: 'i18n',
pure: false,
})

View File

@@ -3,6 +3,7 @@ import { Exver } from '../../services/exver.service'
@Pipe({
name: 'satisfiesExver',
standalone: false,
})
export class ExverSatisfiesPipe implements PipeTransform {
constructor(private readonly exver: Exver) {}
@@ -18,6 +19,7 @@ export class ExverSatisfiesPipe implements PipeTransform {
@Pipe({
name: 'compareExver',
standalone: false,
})
export class ExverComparesPipe implements PipeTransform {
constructor(private readonly exver: Exver) {}

View File

@@ -2,7 +2,6 @@ import { Pipe, PipeTransform } from '@angular/core'
import { marked } from 'marked'
@Pipe({
standalone: true,
name: 'markdown',
})
export class MarkdownPipe implements PipeTransform {

View File

@@ -3,6 +3,7 @@ import { isEmptyObject } from '../../util/misc.util'
@Pipe({
name: 'empty',
standalone: false,
})
export class EmptyPipe implements PipeTransform {
transform(val: object | [] = {}): boolean {

View File

@@ -2,6 +2,7 @@ import { Pipe, PipeTransform } from '@angular/core'
@Pipe({
name: 'includes',
standalone: false,
})
export class IncludesPipe implements PipeTransform {
transform<T>(list: T[], val: T): boolean {

View File

@@ -2,6 +2,7 @@ import { Pipe, PipeTransform } from '@angular/core'
@Pipe({
name: 'sort',
standalone: false,
})
export class SortPipe implements PipeTransform {
transform(

View File

@@ -3,6 +3,7 @@ import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'
@Pipe({
name: 'trustUrl',
standalone: false,
})
export class TrustUrlPipe implements PipeTransform {
constructor(private readonly sanitizer: DomSanitizer) {}

View File

@@ -3,6 +3,7 @@ import { Pipe, PipeTransform } from '@angular/core'
// converts bytes to gigabytes
@Pipe({
name: 'convertBytes',
standalone: false,
})
export class ConvertBytesPipe implements PipeTransform {
transform(bytes: number): string {
@@ -21,6 +22,7 @@ export function convertBytes(bytes: number): string {
@Pipe({
name: 'durationToSeconds',
standalone: false,
})
export class DurationToSecondsPipe implements PipeTransform {
transform(duration?: string | null): number {

View File

@@ -14,7 +14,6 @@ export * from './components/prompt.component'
export * from './components/server.component'
export * from './directives/docs-link.directive'
export * from './directives/drag-scroller.directive'
export * from './directives/safe-links.directive'
export * from './i18n/i18n.pipe'

View File

@@ -6,7 +6,6 @@ import { i18nPipe } from '../i18n/i18n.pipe'
import { i18nKey } from '../i18n/i18n.providers'
@Component({
standalone: true,
template: '<tui-loader [textContent]="content | i18n" />',
styles: `
:host {

View File

@@ -1,4 +1,4 @@
@import '@taiga-ui/core/styles/taiga-ui-local';
@use '@taiga-ui/core/styles/taiga-ui-local' as taiga;
[tuiTheme='dark'] {
--tui-background-base: rgba(23, 23, 23, 1);
@@ -89,7 +89,7 @@
}
[tuiAppearance][data-appearance^='primary'] {
@include appearance-disabled {
@include taiga.appearance-disabled {
background: var(--tui-status-neutral);
color: #333;
}
@@ -99,15 +99,15 @@
color: var(--tui-text-primary-on-accent-1);
background: var(--tui-status-positive);
@include appearance-hover {
@include taiga.appearance-hover {
filter: brightness(1.2);
}
@include appearance-active {
@include taiga.appearance-active {
filter: brightness(0.9);
}
@include appearance-disabled {
@include taiga.appearance-disabled {
background: var(--tui-status-neutral);
color: #333;
}