@firestitch/system 18.0.38 → 18.0.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/modules/system/components/server-logs/components/server-log/server-log.component.d.ts +14 -9
- package/esm2022/app/modules/system/components/server-logs/components/server-log/server-log.component.mjs +101 -19
- package/fesm2022/firestitch-system.mjs +98 -18
- package/fesm2022/firestitch-system.mjs.map +1 -1
- package/package.json +1 -1
package/app/modules/system/components/server-logs/components/server-log/server-log.component.d.ts
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
|
-
import { OnInit } from '@angular/core';
|
|
2
1
|
import * as i0 from "@angular/core";
|
|
3
|
-
export declare class ServerLogComponent
|
|
4
|
-
|
|
2
|
+
export declare class ServerLogComponent {
|
|
3
|
+
log: import("@angular/core").WritableSignal<any>;
|
|
4
|
+
backtrace: import("@angular/core").WritableSignal<string>;
|
|
5
|
+
logData: import("@angular/core").WritableSignal<string>;
|
|
6
|
+
server: import("@angular/core").WritableSignal<string>;
|
|
7
|
+
LogTypes: Record<string, string>;
|
|
8
|
+
private _data;
|
|
9
|
+
private _api;
|
|
5
10
|
private _clipboard;
|
|
6
11
|
private _message;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
logData: string;
|
|
10
|
-
server: string;
|
|
11
|
-
LogTypes: Record<string, string>;
|
|
12
|
-
ngOnInit(): void;
|
|
12
|
+
private _destroyRef;
|
|
13
|
+
constructor();
|
|
13
14
|
copy(): void;
|
|
15
|
+
private _init;
|
|
16
|
+
private _prettifyBacktrace;
|
|
17
|
+
private _parseBacktrace;
|
|
18
|
+
private _formatArg;
|
|
14
19
|
private _prettify;
|
|
15
20
|
static ɵfac: i0.ɵɵFactoryDeclaration<ServerLogComponent, never>;
|
|
16
21
|
static ɵcmp: i0.ɵɵComponentDeclaration<ServerLogComponent, "ng-component", never, {}, {}, never, never, true, never>;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
|
1
|
+
import { ChangeDetectionStrategy, Component, DestroyRef, inject, signal } from '@angular/core';
|
|
2
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
2
3
|
import { MatButtonModule } from '@angular/material/button';
|
|
3
4
|
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
|
4
5
|
import { MatTabsModule } from '@angular/material/tabs';
|
|
6
|
+
import { FsApi } from '@firestitch/api';
|
|
5
7
|
import { FsClipboard } from '@firestitch/clipboard';
|
|
6
8
|
import { index } from '@firestitch/common';
|
|
7
9
|
import { FsDateModule } from '@firestitch/date';
|
|
@@ -9,6 +11,7 @@ import { FsDialogModule } from '@firestitch/dialog';
|
|
|
9
11
|
import { FsLabelModule } from '@firestitch/label';
|
|
10
12
|
import { FsMessage } from '@firestitch/message';
|
|
11
13
|
import { FsSkeletonModule } from '@firestitch/skeleton';
|
|
14
|
+
import { tap } from 'rxjs/operators';
|
|
12
15
|
import { LogTypes } from '../../../../../../consts';
|
|
13
16
|
import * as i0 from "@angular/core";
|
|
14
17
|
import * as i1 from "@angular/material/dialog";
|
|
@@ -19,26 +22,105 @@ import * as i5 from "@firestitch/date";
|
|
|
19
22
|
import * as i6 from "@firestitch/skeleton";
|
|
20
23
|
import * as i7 from "@firestitch/dialog";
|
|
21
24
|
export class ServerLogComponent {
|
|
22
|
-
|
|
25
|
+
log = signal(null);
|
|
26
|
+
backtrace = signal('');
|
|
27
|
+
logData = signal('');
|
|
28
|
+
server = signal('');
|
|
29
|
+
LogTypes = index(LogTypes, 'value', 'name');
|
|
30
|
+
_data = inject(MAT_DIALOG_DATA);
|
|
31
|
+
_api = inject(FsApi);
|
|
23
32
|
_clipboard = inject(FsClipboard);
|
|
24
33
|
_message = inject(FsMessage);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
server;
|
|
29
|
-
LogTypes = index(LogTypes, 'value', 'name');
|
|
30
|
-
ngOnInit() {
|
|
31
|
-
if (this.data.log) {
|
|
32
|
-
this.log = this.data.log;
|
|
33
|
-
this.backtrace = this._prettify(this.log.backtrace);
|
|
34
|
-
this.logData = this._prettify(this.log.data);
|
|
35
|
-
this.server = this._prettify(this.log.server);
|
|
36
|
-
}
|
|
34
|
+
_destroyRef = inject(DestroyRef);
|
|
35
|
+
constructor() {
|
|
36
|
+
this._init();
|
|
37
37
|
}
|
|
38
38
|
copy() {
|
|
39
|
-
this._clipboard.copy(JSON.stringify(this.log, null, 2));
|
|
39
|
+
this._clipboard.copy(JSON.stringify(this.log(), null, 2));
|
|
40
40
|
this._message.success('Copied to clipboard');
|
|
41
41
|
}
|
|
42
|
+
_init() {
|
|
43
|
+
// The listing excludes the large columns — fetch the single log with them included
|
|
44
|
+
this._api
|
|
45
|
+
.get(`system/logs/server/${this._data.log.id}`, {
|
|
46
|
+
backtraces: true,
|
|
47
|
+
data: true,
|
|
48
|
+
servers: true,
|
|
49
|
+
}, { key: 'log' })
|
|
50
|
+
.pipe(tap((log) => {
|
|
51
|
+
this.log.set(log);
|
|
52
|
+
this.backtrace.set(this._prettifyBacktrace(log.backtrace));
|
|
53
|
+
this.logData.set(this._prettify(log.data));
|
|
54
|
+
this.server.set(this._prettify(log.server));
|
|
55
|
+
}), takeUntilDestroyed(this._destroyRef))
|
|
56
|
+
.subscribe();
|
|
57
|
+
}
|
|
58
|
+
_prettifyBacktrace(value) {
|
|
59
|
+
let truncated = false;
|
|
60
|
+
if (typeof value === 'string') {
|
|
61
|
+
value = value.trim();
|
|
62
|
+
const parsed = this._parseBacktrace(value);
|
|
63
|
+
if (!parsed) {
|
|
64
|
+
return value;
|
|
65
|
+
}
|
|
66
|
+
truncated = parsed.truncated;
|
|
67
|
+
value = parsed.frames;
|
|
68
|
+
}
|
|
69
|
+
if (!Array.isArray(value)) {
|
|
70
|
+
return this._prettify(value);
|
|
71
|
+
}
|
|
72
|
+
const lines = value
|
|
73
|
+
.map((frame, idx) => {
|
|
74
|
+
const call = [frame.class, frame.type, frame.function]
|
|
75
|
+
.filter((part) => !!part)
|
|
76
|
+
.join('');
|
|
77
|
+
const args = (frame.args || [])
|
|
78
|
+
.map((arg) => this._formatArg(arg))
|
|
79
|
+
.join(', ');
|
|
80
|
+
const location = frame.file
|
|
81
|
+
? `${frame.file}(${frame.line ?? '?'})`
|
|
82
|
+
: '[internal function]';
|
|
83
|
+
return `#${idx} ${location}: ${call}(${args})`;
|
|
84
|
+
});
|
|
85
|
+
if (truncated) {
|
|
86
|
+
lines.push('… (backtrace truncated)');
|
|
87
|
+
}
|
|
88
|
+
return lines.join('\n');
|
|
89
|
+
}
|
|
90
|
+
_parseBacktrace(value) {
|
|
91
|
+
try {
|
|
92
|
+
return { frames: JSON.parse(value), truncated: false };
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
// stored backtrace may be cut off mid-frame — recover the complete frames
|
|
96
|
+
}
|
|
97
|
+
let boundary = value.lastIndexOf('},{');
|
|
98
|
+
while (boundary > 0) {
|
|
99
|
+
try {
|
|
100
|
+
const frames = JSON.parse(`${value.substring(0, boundary + 1)}]`);
|
|
101
|
+
return { frames, truncated: true };
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
// keep trying earlier frame boundaries
|
|
105
|
+
}
|
|
106
|
+
boundary = value.lastIndexOf('},{', boundary - 1);
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
_formatArg(arg) {
|
|
111
|
+
if (typeof arg === 'string') {
|
|
112
|
+
const max = 60;
|
|
113
|
+
const value = arg.replace(/\s+/g, ' ');
|
|
114
|
+
return `'${value.length > max ? `${value.substring(0, max)}…` : value}'`;
|
|
115
|
+
}
|
|
116
|
+
if (Array.isArray(arg)) {
|
|
117
|
+
return 'Array';
|
|
118
|
+
}
|
|
119
|
+
if (arg && typeof arg === 'object') {
|
|
120
|
+
return 'Object';
|
|
121
|
+
}
|
|
122
|
+
return String(arg);
|
|
123
|
+
}
|
|
42
124
|
_prettify(value) {
|
|
43
125
|
if (typeof value === 'string') {
|
|
44
126
|
value = value.trim();
|
|
@@ -55,7 +137,7 @@ export class ServerLogComponent {
|
|
|
55
137
|
return JSON.stringify(value, null, 2);
|
|
56
138
|
}
|
|
57
139
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ServerLogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
58
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: ServerLogComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"log\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log.type] || log.type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log.message }}\n </fs-label-field>\n @if (log.url) {\n <fs-label-field>\n <fs-label>\n URL\n </fs-label>\n {{ log.url }}\n </fs-label-field>\n }\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{ log.createDate|fsDateFormat: 'full-date-time' }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log.file }} @ {{ log.line }}\n </fs-label-field>\n </div>\n @if (backtrace || logData || server) {\n <mat-tab-group>\n @if (backtrace) {\n <mat-tab label=\"Backtrace\">\n <pre>{{ backtrace }}</pre>\n </mat-tab>\n }\n @if (logData) {\n <mat-tab label=\"Data\">\n <pre>{{ logData }}</pre>\n </mat-tab>\n }\n @if (server) {\n <mat-tab label=\"$_SERVER\">\n <pre>{{ server }}</pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i3.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i3.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: FsLabelModule }, { kind: "component", type: i4.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i4.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "ngmodule", type: FsDateModule }, { kind: "pipe", type: i5.FsDateFormatPipe, name: "fsDateFormat" }, { kind: "ngmodule", type: FsSkeletonModule }, { kind: "directive", type: i6.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "ngmodule", type: FsDialogModule }, { kind: "component", type: i7.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
140
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: ServerLogComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"log()\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log().type] || log().type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log().message }}\n </fs-label-field>\n @if (log().url) {\n <fs-label-field>\n <fs-label>\n URL\n </fs-label>\n {{ log().url }}\n </fs-label-field>\n }\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{ log().createDate|fsDateFormat: 'full-date-time' }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log().file }} @ {{ log().line }}\n </fs-label-field>\n </div>\n @if (backtrace() || logData() || server()) {\n <mat-tab-group>\n @if (backtrace()) {\n <mat-tab label=\"Backtrace\">\n <pre>{{ backtrace() }}</pre>\n </mat-tab>\n }\n @if (logData()) {\n <mat-tab label=\"Data\">\n <pre>{{ logData() }}</pre>\n </mat-tab>\n }\n @if (server()) {\n <mat-tab label=\"$_SERVER\">\n <pre>{{ server() }}</pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i3.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i3.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: FsLabelModule }, { kind: "component", type: i4.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i4.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "ngmodule", type: FsDateModule }, { kind: "pipe", type: i5.FsDateFormatPipe, name: "fsDateFormat" }, { kind: "ngmodule", type: FsSkeletonModule }, { kind: "directive", type: i6.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "ngmodule", type: FsDialogModule }, { kind: "component", type: i7.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
59
141
|
}
|
|
60
142
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ServerLogComponent, decorators: [{
|
|
61
143
|
type: Component,
|
|
@@ -67,6 +149,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImpor
|
|
|
67
149
|
FsDateModule,
|
|
68
150
|
FsSkeletonModule,
|
|
69
151
|
FsDialogModule,
|
|
70
|
-
], template: "<fs-dialog *fsSkeleton=\"log\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log.type] || log.type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log.message }}\n </fs-label-field>\n @if (log.url) {\n <fs-label-field>\n <fs-label>\n URL\n </fs-label>\n {{ log.url }}\n </fs-label-field>\n }\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{ log.createDate|fsDateFormat: 'full-date-time' }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log.file }} @ {{ log.line }}\n </fs-label-field>\n </div>\n @if (backtrace || logData || server) {\n <mat-tab-group>\n @if (backtrace) {\n <mat-tab label=\"Backtrace\">\n <pre>{{ backtrace }}</pre>\n </mat-tab>\n }\n @if (logData) {\n <mat-tab label=\"Data\">\n <pre>{{ logData }}</pre>\n </mat-tab>\n }\n @if (server) {\n <mat-tab label=\"$_SERVER\">\n <pre>{{ server }}</pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"] }]
|
|
71
|
-
}] });
|
|
72
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLWxvZy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL21vZHVsZXMvc3lzdGVtL2NvbXBvbmVudHMvc2VydmVyLWxvZ3MvY29tcG9uZW50cy9zZXJ2ZXItbG9nL3NlcnZlci1sb2cuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9tb2R1bGVzL3N5c3RlbS9jb21wb25lbnRzL3NlcnZlci1sb2dzL2NvbXBvbmVudHMvc2VydmVyLWxvZy9zZXJ2ZXItbG9nLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQVUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRW5GLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsZUFBZSxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzVFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUV2RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDcEQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDcEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUV4RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7Ozs7Ozs7OztBQWtCcEQsTUFBTSxPQUFPLGtCQUFrQjtJQUM3QixJQUFJLEdBQUcsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBRXZCLFVBQVUsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDakMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUU5QixHQUFHLENBQUM7SUFDSixTQUFTLENBQVM7SUFDbEIsT0FBTyxDQUFTO0lBQ2hCLE1BQU0sQ0FBUztJQUNmLFFBQVEsR0FBMkIsS0FBSyxDQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFFcEUsUUFBUTtRQUNiLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNsQixJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO1lBQ3pCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ3BELElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzdDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2hELENBQUM7SUFDSCxDQUFDO0lBRU0sSUFBSTtRQUNULElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4RCxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFFTyxTQUFTLENBQUMsS0FBSztRQUNyQixJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQzlCLEtBQUssR0FBRyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7WUFFckIsSUFBSSxDQUFDO2dCQUNILEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzVCLENBQUM7WUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUNYLE9BQU8sS0FBSyxDQUFDO1lBQ2YsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDN0UsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDeEMsQ0FBQzt1R0ExQ1Usa0JBQWtCOzJGQUFsQixrQkFBa0Isd0VDaEMvQiwwd0RBMEVBLGdLRG5ESSxlQUFlLCtuQkFDZixlQUFlLDJOQUNmLGFBQWEsNG9CQUNiLGFBQWEsK1FBQ2IsWUFBWSxpR0FDWixnQkFBZ0IsaUtBQ2hCLGNBQWM7OzJGQUdMLGtCQUFrQjtrQkFmOUIsU0FBUztzQ0FHUyx1QkFBdUIsQ0FBQyxNQUFNLGNBQ25DLElBQUksV0FDUDt3QkFDUCxlQUFlO3dCQUNmLGVBQWU7d0JBQ2YsYUFBYTt3QkFDYixhQUFhO3dCQUNiLFlBQVk7d0JBQ1osZ0JBQWdCO3dCQUNoQixjQUFjO3FCQUNmIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgT25Jbml0LCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgTWF0QnV0dG9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvYnV0dG9uJztcbmltcG9ydCB7IE1BVF9ESUFMT0dfREFUQSwgTWF0RGlhbG9nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IE1hdFRhYnNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90YWJzJztcblxuaW1wb3J0IHsgRnNDbGlwYm9hcmQgfSBmcm9tICdAZmlyZXN0aXRjaC9jbGlwYm9hcmQnO1xuaW1wb3J0IHsgaW5kZXggfSBmcm9tICdAZmlyZXN0aXRjaC9jb21tb24nO1xuaW1wb3J0IHsgRnNEYXRlTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvZGF0ZSc7XG5pbXBvcnQgeyBGc0RpYWxvZ01vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2RpYWxvZyc7XG5pbXBvcnQgeyBGc0xhYmVsTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbGFiZWwnO1xuaW1wb3J0IHsgRnNNZXNzYWdlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbWVzc2FnZSc7XG5pbXBvcnQgeyBGc1NrZWxldG9uTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvc2tlbGV0b24nO1xuXG5pbXBvcnQgeyBMb2dUeXBlcyB9IGZyb20gJy4uLy4uLy4uLy4uLy4uLy4uL2NvbnN0cyc7XG5cblxuQENvbXBvbmVudCh7XG4gIHRlbXBsYXRlVXJsOiAnLi9zZXJ2ZXItbG9nLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vc2VydmVyLWxvZy5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIE1hdERpYWxvZ01vZHVsZSxcbiAgICBNYXRCdXR0b25Nb2R1bGUsXG4gICAgTWF0VGFic01vZHVsZSxcbiAgICBGc0xhYmVsTW9kdWxlLFxuICAgIEZzRGF0ZU1vZHVsZSxcbiAgICBGc1NrZWxldG9uTW9kdWxlLFxuICAgIEZzRGlhbG9nTW9kdWxlLFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBTZXJ2ZXJMb2dDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBkYXRhID0gaW5qZWN0KE1BVF9ESUFMT0dfREFUQSk7XG5cbiAgcHJpdmF0ZSBfY2xpcGJvYXJkID0gaW5qZWN0KEZzQ2xpcGJvYXJkKTtcbiAgcHJpdmF0ZSBfbWVzc2FnZSA9IGluamVjdChGc01lc3NhZ2UpO1xuXG4gIHB1YmxpYyBsb2c7XG4gIHB1YmxpYyBiYWNrdHJhY2U6IHN0cmluZztcbiAgcHVibGljIGxvZ0RhdGE6IHN0cmluZztcbiAgcHVibGljIHNlcnZlcjogc3RyaW5nO1xuICBwdWJsaWMgTG9nVHlwZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSBpbmRleChMb2dUeXBlcywgJ3ZhbHVlJywgJ25hbWUnKTtcblxuICBwdWJsaWMgbmdPbkluaXQoKSB7XG4gICAgaWYgKHRoaXMuZGF0YS5sb2cpIHtcbiAgICAgIHRoaXMubG9nID0gdGhpcy5kYXRhLmxvZztcbiAgICAgIHRoaXMuYmFja3RyYWNlID0gdGhpcy5fcHJldHRpZnkodGhpcy5sb2cuYmFja3RyYWNlKTtcbiAgICAgIHRoaXMubG9nRGF0YSA9IHRoaXMuX3ByZXR0aWZ5KHRoaXMubG9nLmRhdGEpO1xuICAgICAgdGhpcy5zZXJ2ZXIgPSB0aGlzLl9wcmV0dGlmeSh0aGlzLmxvZy5zZXJ2ZXIpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBjb3B5KCkge1xuICAgIHRoaXMuX2NsaXBib2FyZC5jb3B5KEpTT04uc3RyaW5naWZ5KHRoaXMubG9nLCBudWxsLCAyKSk7XG4gICAgdGhpcy5fbWVzc2FnZS5zdWNjZXNzKCdDb3BpZWQgdG8gY2xpcGJvYXJkJyk7XG4gIH1cblxuICBwcml2YXRlIF9wcmV0dGlmeSh2YWx1ZSk6IHN0cmluZyB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHZhbHVlID0gdmFsdWUudHJpbSgpO1xuXG4gICAgICB0cnkge1xuICAgICAgICB2YWx1ZSA9IEpTT04ucGFyc2UodmFsdWUpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCF2YWx1ZSB8fCAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiBPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoID09PSAwKSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2YWx1ZSwgbnVsbCwgMik7XG4gIH1cbn1cbiIsIjxmcy1kaWFsb2cgKmZzU2tlbGV0b249XCJsb2dcIj5cbiAgPGRpdiBtYXQtZGlhbG9nLXRpdGxlPlxuICAgIExvZ1xuICA8L2Rpdj5cbiAgPG1hdC1kaWFsb2ctY29udGVudD5cbiAgICA8ZGl2IGNsYXNzPVwiZnMtcm93LmNvbHVtbi1nYXAtbGcucm93LWdhcC1zbS53cmFwLmFsaWduLXN0YXJ0XCI+XG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICBFcnJvciBUeXBlXG4gICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgIHt7IExvZ1R5cGVzW2xvZy50eXBlXSB8fCBsb2cudHlwZSB9fVxuICAgICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgPGZzLWxhYmVsPlxuICAgICAgICAgIE1lc3NhZ2VcbiAgICAgICAgPC9mcy1sYWJlbD5cbiAgICAgICAge3sgbG9nLm1lc3NhZ2UgfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICBAaWYgKGxvZy51cmwpIHtcbiAgICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICAgIFVSTFxuICAgICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgICAge3sgbG9nLnVybCB9fVxuICAgICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgICAgfVxuICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICA8ZnMtbGFiZWw+XG4gICAgICAgICAgRGF0ZVxuICAgICAgICA8L2ZzLWxhYmVsPlxuICAgICAgICB7eyBsb2cuY3JlYXRlRGF0ZXxmc0RhdGVGb3JtYXQ6ICdmdWxsLWRhdGUtdGltZScgfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICBGaWxlXG4gICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgIHt7IGxvZy5maWxlIH19ICYjNjQ7IHt7IGxvZy5saW5lIH19XG4gICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgIDwvZGl2PlxuICAgIEBpZiAoYmFja3RyYWNlIHx8IGxvZ0RhdGEgfHwgc2VydmVyKSB7XG4gICAgICA8bWF0LXRhYi1ncm91cD5cbiAgICAgICAgQGlmIChiYWNrdHJhY2UpIHtcbiAgICAgICAgICA8bWF0LXRhYiBsYWJlbD1cIkJhY2t0cmFjZVwiPlxuICAgICAgICAgICAgPHByZT57eyBiYWNrdHJhY2UgfX08L3ByZT5cbiAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgIH1cbiAgICAgICAgQGlmIChsb2dEYXRhKSB7XG4gICAgICAgICAgPG1hdC10YWIgbGFiZWw9XCJEYXRhXCI+XG4gICAgICAgICAgICA8cHJlPnt7IGxvZ0RhdGEgfX08L3ByZT5cbiAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgIH1cbiAgICAgICAgQGlmIChzZXJ2ZXIpIHtcbiAgICAgICAgICA8bWF0LXRhYiBsYWJlbD1cIiRfU0VSVkVSXCI+XG4gICAgICAgICAgICA8cHJlPnt7IHNlcnZlciB9fTwvcHJlPlxuICAgICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgfVxuICAgICAgPC9tYXQtdGFiLWdyb3VwPlxuICAgIH1cbiAgPC9tYXQtZGlhbG9nLWNvbnRlbnQ+XG4gIDxtYXQtZGlhbG9nLWFjdGlvbnM+XG4gICAgPGJ1dHRvblxuICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgIFttYXQtZGlhbG9nLWNsb3NlXT1cInRydWVcIlxuICAgICAgICBjb2xvcj1cInByaW1hcnlcIj5cbiAgICAgIERvbmVcbiAgICA8L2J1dHRvbj5cbiAgICA8YnV0dG9uXG4gICAgICAgIG1hdC1idXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIChjbGljayk9XCJjb3B5KClcIj5cbiAgICAgIENvcHlcbiAgICA8L2J1dHRvbj5cbiAgPC9tYXQtZGlhbG9nLWFjdGlvbnM+XG48L2ZzLWRpYWxvZz5cbiJdfQ==
|
|
152
|
+
], template: "<fs-dialog *fsSkeleton=\"log()\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log().type] || log().type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log().message }}\n </fs-label-field>\n @if (log().url) {\n <fs-label-field>\n <fs-label>\n URL\n </fs-label>\n {{ log().url }}\n </fs-label-field>\n }\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{ log().createDate|fsDateFormat: 'full-date-time' }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log().file }} @ {{ log().line }}\n </fs-label-field>\n </div>\n @if (backtrace() || logData() || server()) {\n <mat-tab-group>\n @if (backtrace()) {\n <mat-tab label=\"Backtrace\">\n <pre>{{ backtrace() }}</pre>\n </mat-tab>\n }\n @if (logData()) {\n <mat-tab label=\"Data\">\n <pre>{{ logData() }}</pre>\n </mat-tab>\n }\n @if (server()) {\n <mat-tab label=\"$_SERVER\">\n <pre>{{ server() }}</pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"] }]
|
|
153
|
+
}], ctorParameters: () => [] });
|
|
154
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLWxvZy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL21vZHVsZXMvc3lzdGVtL2NvbXBvbmVudHMvc2VydmVyLWxvZ3MvY29tcG9uZW50cy9zZXJ2ZXItbG9nL3NlcnZlci1sb2cuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9tb2R1bGVzL3N5c3RlbS9jb21wb25lbnRzL3NlcnZlci1sb2dzL2NvbXBvbmVudHMvc2VydmVyLWxvZy9zZXJ2ZXItbG9nLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0YsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFaEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDNUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRXZELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN4QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDcEQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDcEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFB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Q1A7d0JBQ1AsZUFBZTt3QkFDZixlQUFlO3dCQUNmLGFBQWE7d0JBQ2IsYUFBYTt3QkFDYixZQUFZO3dCQUNaLGdCQUFnQjt3QkFDaEIsY0FBYztxQkFDZiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIERlc3Ryb3lSZWYsIGluamVjdCwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0YWtlVW50aWxEZXN0cm95ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5cbmltcG9ydCB7IE1hdEJ1dHRvbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbic7XG5pbXBvcnQgeyBNQVRfRElBTE9HX0RBVEEsIE1hdERpYWxvZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpYWxvZyc7XG5pbXBvcnQgeyBNYXRUYWJzTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdGFicyc7XG5cbmltcG9ydCB7IEZzQXBpIH0gZnJvbSAnQGZpcmVzdGl0Y2gvYXBpJztcbmltcG9ydCB7IEZzQ2xpcGJvYXJkIH0gZnJvbSAnQGZpcmVzdGl0Y2gvY2xpcGJvYXJkJztcbmltcG9ydCB7IGluZGV4IH0gZnJvbSAnQGZpcmVzdGl0Y2gvY29tbW9uJztcbmltcG9ydCB7IEZzRGF0ZU1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2RhdGUnO1xuaW1wb3J0IHsgRnNEaWFsb2dNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9kaWFsb2cnO1xuaW1wb3J0IHsgRnNMYWJlbE1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2xhYmVsJztcbmltcG9ydCB7IEZzTWVzc2FnZSB9IGZyb20gJ0BmaXJlc3RpdGNoL21lc3NhZ2UnO1xuaW1wb3J0IHsgRnNTa2VsZXRvbk1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL3NrZWxldG9uJztcblxuaW1wb3J0IHsgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBMb2dUeXBlcyB9IGZyb20gJy4uLy4uLy4uLy4uLy4uLy4uL2NvbnN0cyc7XG5cblxuQENvbXBvbmVudCh7XG4gIHRlbXBsYXRlVXJsOiAnLi9zZXJ2ZXItbG9nLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vc2VydmVyLWxvZy5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIE1hdERpYWxvZ01vZHVsZSxcbiAgICBNYXRCdXR0b25Nb2R1bGUsXG4gICAgTWF0VGFic01vZHVsZSxcbiAgICBGc0xhYmVsTW9kdWxlLFxuICAgIEZzRGF0ZU1vZHVsZSxcbiAgICBGc1NrZWxldG9uTW9kdWxlLFxuICAgIEZzRGlhbG9nTW9kdWxlLFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBTZXJ2ZXJMb2dDb21wb25lbnQge1xuXG4gIHB1YmxpYyBsb2cgPSBzaWduYWw8YW55PihudWxsKTtcbiAgcHVibGljIGJhY2t0cmFjZSA9IHNpZ25hbDxzdHJpbmc+KCcnKTtcbiAgcHVibGljIGxvZ0RhdGEgPSBzaWduYWw8c3RyaW5nPignJyk7XG4gIHB1YmxpYyBzZXJ2ZXIgPSBzaWduYWw8c3RyaW5nPignJyk7XG4gIHB1YmxpYyBMb2dUeXBlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IGluZGV4KExvZ1R5cGVzLCAndmFsdWUnLCAnbmFtZScpO1xuXG4gIHByaXZhdGUgX2RhdGEgPSBpbmplY3QoTUFUX0RJQUxPR19EQVRBKTtcbiAgcHJpdmF0ZSBfYXBpID0gaW5qZWN0KEZzQXBpKTtcbiAgcHJpdmF0ZSBfY2xpcGJvYXJkID0gaW5qZWN0KEZzQ2xpcGJvYXJkKTtcbiAgcHJpdmF0ZSBfbWVzc2FnZSA9IGluamVjdChGc01lc3NhZ2UpO1xuICBwcml2YXRlIF9kZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuX2luaXQoKTtcbiAgfVxuXG4gIHB1YmxpYyBjb3B5KCkge1xuICAgIHRoaXMuX2NsaXBib2FyZC5jb3B5KEpTT04uc3RyaW5naWZ5KHRoaXMubG9nKCksIG51bGwsIDIpKTtcbiAgICB0aGlzLl9tZXNzYWdlLnN1Y2Nlc3MoJ0NvcGllZCB0byBjbGlwYm9hcmQnKTtcbiAgfVxuXG4gIHByaXZhdGUgX2luaXQoKTogdm9pZCB7XG4gICAgLy8gVGhlIGxpc3RpbmcgZXhjbHVkZXMgdGhlIGxhcmdlIGNvbHVtbnMg4oCUIGZldGNoIHRoZSBzaW5nbGUgbG9nIHdpdGggdGhlbSBpbmNsdWRlZFxuICAgIHRoaXMuX2FwaVxuICAgICAgLmdldChcbiAgICAgICAgYHN5c3RlbS9sb2dzL3NlcnZlci8ke3RoaXMuX2RhdGEubG9nLmlkfWAsXG4gICAgICAgIHtcbiAgICAgICAgICBiYWNrdHJhY2VzOiB0cnVlLFxuICAgICAgICAgIGRhdGE6IHRydWUsXG4gICAgICAgICAgc2VydmVyczogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAgeyBrZXk6ICdsb2cnIH0sXG4gICAgICApXG4gICAgICAucGlwZShcbiAgICAgICAgdGFwKChsb2cpID0+IHtcbiAgICAgICAgICB0aGlzLmxvZy5zZXQobG9nKTtcbiAgICAgICAgICB0aGlzLmJhY2t0cmFjZS5zZXQodGhpcy5fcHJldHRpZnlCYWNrdHJhY2UobG9nLmJhY2t0cmFjZSkpO1xuICAgICAgICAgIHRoaXMubG9nRGF0YS5zZXQodGhpcy5fcHJldHRpZnkobG9nLmRhdGEpKTtcbiAgICAgICAgICB0aGlzLnNlcnZlci5zZXQodGhpcy5fcHJldHRpZnkobG9nLnNlcnZlcikpO1xuICAgICAgICB9KSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBfcHJldHRpZnlCYWNrdHJhY2UodmFsdWUpOiBzdHJpbmcge1xuICAgIGxldCB0cnVuY2F0ZWQgPSBmYWxzZTtcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICB2YWx1ZSA9IHZhbHVlLnRyaW0oKTtcblxuICAgICAgY29uc3QgcGFyc2VkID0gdGhpcy5fcGFyc2VCYWNrdHJhY2UodmFsdWUpO1xuXG4gICAgICBpZiAoIXBhcnNlZCkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHRydW5jYXRlZCA9IHBhcnNlZC50cnVuY2F0ZWQ7XG4gICAgICB2YWx1ZSA9IHBhcnNlZC5mcmFtZXM7XG4gICAgfVxuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHRoaXMuX3ByZXR0aWZ5KHZhbHVlKTtcbiAgICB9XG5cbiAgICBjb25zdCBsaW5lcyA9IHZhbHVlXG4gICAgICAubWFwKChmcmFtZSwgaWR4KSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGwgPSBbZnJhbWUuY2xhc3MsIGZyYW1lLnR5cGUsIGZyYW1lLmZ1bmN0aW9uXVxuICAgICAgICAgIC5maWx0ZXIoKHBhcnQpID0+ICEhcGFydClcbiAgICAgICAgICAuam9pbignJyk7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSAoZnJhbWUuYXJncyB8fCBbXSlcbiAgICAgICAgICAubWFwKChhcmcpID0+IHRoaXMuX2Zvcm1hdEFyZyhhcmcpKVxuICAgICAgICAgIC5qb2luKCcsICcpO1xuICAgICAgICBjb25zdCBsb2NhdGlvbiA9IGZyYW1lLmZpbGVcbiAgICAgICAgICA/IGAke2ZyYW1lLmZpbGV9KCR7ZnJhbWUubGluZSA/PyAnPyd9KWBcbiAgICAgICAgICA6ICdbaW50ZXJuYWwgZnVuY3Rpb25dJztcblxuICAgICAgICByZXR1cm4gYCMke2lkeH0gJHtsb2NhdGlvbn06ICR7Y2FsbH0oJHthcmdzfSlgO1xuICAgICAgfSk7XG5cbiAgICBpZiAodHJ1bmNhdGVkKSB7XG4gICAgICBsaW5lcy5wdXNoKCfigKYgKGJhY2t0cmFjZSB0cnVuY2F0ZWQpJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxpbmVzLmpvaW4oJ1xcbicpO1xuICB9XG5cbiAgcHJpdmF0ZSBfcGFyc2VCYWNrdHJhY2UodmFsdWU6IHN0cmluZyk6IHsgZnJhbWVzOiBhbnk7IHRydW5jYXRlZDogYm9vbGVhbiB9IHwgbnVsbCB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB7IGZyYW1lczogSlNPTi5wYXJzZSh2YWx1ZSksIHRydW5jYXRlZDogZmFsc2UgfTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBzdG9yZWQgYmFja3RyYWNlIG1heSBiZSBjdXQgb2ZmIG1pZC1mcmFtZSDigJQgcmVjb3ZlciB0aGUgY29tcGxldGUgZnJhbWVzXG4gICAgfVxuXG4gICAgbGV0IGJvdW5kYXJ5ID0gdmFsdWUubGFzdEluZGV4T2YoJ30seycpO1xuXG4gICAgd2hpbGUgKGJvdW5kYXJ5ID4gMCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZnJhbWVzID0gSlNPTi5wYXJzZShgJHt2YWx1ZS5zdWJzdHJpbmcoMCwgYm91bmRhcnkgKyAxKX1dYCk7XG5cbiAgICAgICAgcmV0dXJuIHsgZnJhbWVzLCB0cnVuY2F0ZWQ6IHRydWUgfTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8ga2VlcCB0cnlpbmcgZWFybGllciBmcmFtZSBib3VuZGFyaWVzXG4gICAgICB9XG5cbiAgICAgIGJvdW5kYXJ5ID0gdmFsdWUubGFzdEluZGV4T2YoJ30seycsIGJvdW5kYXJ5IC0gMSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIF9mb3JtYXRBcmcoYXJnKTogc3RyaW5nIHtcbiAgICBpZiAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbnN0IG1heCA9IDYwO1xuICAgICAgY29uc3QgdmFsdWUgPSBhcmcucmVwbGFjZSgvXFxzKy9nLCAnICcpO1xuXG4gICAgICByZXR1cm4gYCcke3ZhbHVlLmxlbmd0aCA+IG1heCA/IGAke3ZhbHVlLnN1YnN0cmluZygwLCBtYXgpfeKApmAgOiB2YWx1ZX0nYDtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShhcmcpKSB7XG4gICAgICByZXR1cm4gJ0FycmF5JztcbiAgICB9XG5cbiAgICBpZiAoYXJnICYmIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm4gJ09iamVjdCc7XG4gICAgfVxuXG4gICAgcmV0dXJuIFN0cmluZyhhcmcpO1xuICB9XG5cbiAgcHJpdmF0ZSBfcHJldHRpZnkodmFsdWUpOiBzdHJpbmcge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICB2YWx1ZSA9IHZhbHVlLnRyaW0oKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgdmFsdWUgPSBKU09OLnBhcnNlKHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghdmFsdWUgfHwgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgT2JqZWN0LmtleXModmFsdWUpLmxlbmd0aCA9PT0gMCkpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodmFsdWUsIG51bGwsIDIpO1xuICB9XG59XG4iLCI8ZnMtZGlhbG9nICpmc1NrZWxldG9uPVwibG9nKClcIj5cbiAgPGRpdiBtYXQtZGlhbG9nLXRpdGxlPlxuICAgIExvZ1xuICA8L2Rpdj5cbiAgPG1hdC1kaWFsb2ctY29udGVudD5cbiAgICA8ZGl2IGNsYXNzPVwiZnMtcm93LmNvbHVtbi1nYXAtbGcucm93LWdhcC1zbS53cmFwLmFsaWduLXN0YXJ0XCI+XG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICBFcnJvciBUeXBlXG4gICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgIHt7IExvZ1R5cGVzW2xvZygpLnR5cGVdIHx8IGxvZygpLnR5cGUgfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICBNZXNzYWdlXG4gICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgIHt7IGxvZygpLm1lc3NhZ2UgfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICBAaWYgKGxvZygpLnVybCkge1xuICAgICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgICAgPGZzLWxhYmVsPlxuICAgICAgICAgICAgVVJMXG4gICAgICAgICAgPC9mcy1sYWJlbD5cbiAgICAgICAgICB7eyBsb2coKS51cmwgfX1cbiAgICAgICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICAgIH1cbiAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgPGZzLWxhYmVsPlxuICAgICAgICAgIERhdGVcbiAgICAgICAgPC9mcy1sYWJlbD5cbiAgICAgICAge3sgbG9nKCkuY3JlYXRlRGF0ZXxmc0RhdGVGb3JtYXQ6ICdmdWxsLWRhdGUtdGltZScgfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICBGaWxlXG4gICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgIHt7IGxvZygpLmZpbGUgfX0gJiM2NDsge3sgbG9nKCkubGluZSB9fVxuICAgICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICA8L2Rpdj5cbiAgICBAaWYgKGJhY2t0cmFjZSgpIHx8IGxvZ0RhdGEoKSB8fCBzZXJ2ZXIoKSkge1xuICAgICAgPG1hdC10YWItZ3JvdXA+XG4gICAgICAgIEBpZiAoYmFja3RyYWNlKCkpIHtcbiAgICAgICAgICA8bWF0LXRhYiBsYWJlbD1cIkJhY2t0cmFjZVwiPlxuICAgICAgICAgICAgPHByZT57eyBiYWNrdHJhY2UoKSB9fTwvcHJlPlxuICAgICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgfVxuICAgICAgICBAaWYgKGxvZ0RhdGEoKSkge1xuICAgICAgICAgIDxtYXQtdGFiIGxhYmVsPVwiRGF0YVwiPlxuICAgICAgICAgICAgPHByZT57eyBsb2dEYXRhKCkgfX08L3ByZT5cbiAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgIH1cbiAgICAgICAgQGlmIChzZXJ2ZXIoKSkge1xuICAgICAgICAgIDxtYXQtdGFiIGxhYmVsPVwiJF9TRVJWRVJcIj5cbiAgICAgICAgICAgIDxwcmU+e3sgc2VydmVyKCkgfX08L3ByZT5cbiAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgIH1cbiAgICAgIDwvbWF0LXRhYi1ncm91cD5cbiAgICB9XG4gIDwvbWF0LWRpYWxvZy1jb250ZW50PlxuICA8bWF0LWRpYWxvZy1hY3Rpb25zPlxuICAgIDxidXR0b25cbiAgICAgICAgbWF0LWJ1dHRvblxuICAgICAgICBbbWF0LWRpYWxvZy1jbG9zZV09XCJ0cnVlXCJcbiAgICAgICAgY29sb3I9XCJwcmltYXJ5XCI+XG4gICAgICBEb25lXG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvblxuICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAoY2xpY2spPVwiY29weSgpXCI+XG4gICAgICBDb3B5XG4gICAgPC9idXR0b24+XG4gIDwvbWF0LWRpYWxvZy1hY3Rpb25zPlxuPC9mcy1kaWFsb2c+XG4iXX0=
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i1$2 from '@angular/common';
|
|
2
2
|
import { JsonPipe, NgClass, NgStyle, CommonModule, NgTemplateOutlet } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { inject, Component, ChangeDetectionStrategy, ViewChild, Input, Injectable, ChangeDetectorRef, EventEmitter, Output, Pipe, InjectionToken, NgModule } from '@angular/core';
|
|
4
|
+
import { inject, Component, ChangeDetectionStrategy, ViewChild, Input, Injectable, ChangeDetectorRef, signal, DestroyRef, EventEmitter, Output, Pipe, InjectionToken, NgModule } from '@angular/core';
|
|
5
5
|
import * as i1$4 from '@angular/forms';
|
|
6
6
|
import { FormsModule } from '@angular/forms';
|
|
7
7
|
import * as i2$2 from '@angular/material/button';
|
|
@@ -53,6 +53,7 @@ import { SelectionActionType } from '@firestitch/selection';
|
|
|
53
53
|
import { FsBuildService } from '@firestitch/build';
|
|
54
54
|
import * as i6 from '@firestitch/common';
|
|
55
55
|
import { index, FsCommonModule } from '@firestitch/common';
|
|
56
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
56
57
|
import * as i3$4 from '@firestitch/clipboard';
|
|
57
58
|
import { FsClipboard, FsClipboardModule } from '@firestitch/clipboard';
|
|
58
59
|
import { MatOption } from '@angular/material/core';
|
|
@@ -1266,26 +1267,105 @@ const LogTypes = [
|
|
|
1266
1267
|
];
|
|
1267
1268
|
|
|
1268
1269
|
class ServerLogComponent {
|
|
1269
|
-
|
|
1270
|
+
log = signal(null);
|
|
1271
|
+
backtrace = signal('');
|
|
1272
|
+
logData = signal('');
|
|
1273
|
+
server = signal('');
|
|
1274
|
+
LogTypes = index(LogTypes, 'value', 'name');
|
|
1275
|
+
_data = inject(MAT_DIALOG_DATA);
|
|
1276
|
+
_api = inject(FsApi);
|
|
1270
1277
|
_clipboard = inject(FsClipboard);
|
|
1271
1278
|
_message = inject(FsMessage);
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
server;
|
|
1276
|
-
LogTypes = index(LogTypes, 'value', 'name');
|
|
1277
|
-
ngOnInit() {
|
|
1278
|
-
if (this.data.log) {
|
|
1279
|
-
this.log = this.data.log;
|
|
1280
|
-
this.backtrace = this._prettify(this.log.backtrace);
|
|
1281
|
-
this.logData = this._prettify(this.log.data);
|
|
1282
|
-
this.server = this._prettify(this.log.server);
|
|
1283
|
-
}
|
|
1279
|
+
_destroyRef = inject(DestroyRef);
|
|
1280
|
+
constructor() {
|
|
1281
|
+
this._init();
|
|
1284
1282
|
}
|
|
1285
1283
|
copy() {
|
|
1286
|
-
this._clipboard.copy(JSON.stringify(this.log, null, 2));
|
|
1284
|
+
this._clipboard.copy(JSON.stringify(this.log(), null, 2));
|
|
1287
1285
|
this._message.success('Copied to clipboard');
|
|
1288
1286
|
}
|
|
1287
|
+
_init() {
|
|
1288
|
+
// The listing excludes the large columns — fetch the single log with them included
|
|
1289
|
+
this._api
|
|
1290
|
+
.get(`system/logs/server/${this._data.log.id}`, {
|
|
1291
|
+
backtraces: true,
|
|
1292
|
+
data: true,
|
|
1293
|
+
servers: true,
|
|
1294
|
+
}, { key: 'log' })
|
|
1295
|
+
.pipe(tap((log) => {
|
|
1296
|
+
this.log.set(log);
|
|
1297
|
+
this.backtrace.set(this._prettifyBacktrace(log.backtrace));
|
|
1298
|
+
this.logData.set(this._prettify(log.data));
|
|
1299
|
+
this.server.set(this._prettify(log.server));
|
|
1300
|
+
}), takeUntilDestroyed(this._destroyRef))
|
|
1301
|
+
.subscribe();
|
|
1302
|
+
}
|
|
1303
|
+
_prettifyBacktrace(value) {
|
|
1304
|
+
let truncated = false;
|
|
1305
|
+
if (typeof value === 'string') {
|
|
1306
|
+
value = value.trim();
|
|
1307
|
+
const parsed = this._parseBacktrace(value);
|
|
1308
|
+
if (!parsed) {
|
|
1309
|
+
return value;
|
|
1310
|
+
}
|
|
1311
|
+
truncated = parsed.truncated;
|
|
1312
|
+
value = parsed.frames;
|
|
1313
|
+
}
|
|
1314
|
+
if (!Array.isArray(value)) {
|
|
1315
|
+
return this._prettify(value);
|
|
1316
|
+
}
|
|
1317
|
+
const lines = value
|
|
1318
|
+
.map((frame, idx) => {
|
|
1319
|
+
const call = [frame.class, frame.type, frame.function]
|
|
1320
|
+
.filter((part) => !!part)
|
|
1321
|
+
.join('');
|
|
1322
|
+
const args = (frame.args || [])
|
|
1323
|
+
.map((arg) => this._formatArg(arg))
|
|
1324
|
+
.join(', ');
|
|
1325
|
+
const location = frame.file
|
|
1326
|
+
? `${frame.file}(${frame.line ?? '?'})`
|
|
1327
|
+
: '[internal function]';
|
|
1328
|
+
return `#${idx} ${location}: ${call}(${args})`;
|
|
1329
|
+
});
|
|
1330
|
+
if (truncated) {
|
|
1331
|
+
lines.push('… (backtrace truncated)');
|
|
1332
|
+
}
|
|
1333
|
+
return lines.join('\n');
|
|
1334
|
+
}
|
|
1335
|
+
_parseBacktrace(value) {
|
|
1336
|
+
try {
|
|
1337
|
+
return { frames: JSON.parse(value), truncated: false };
|
|
1338
|
+
}
|
|
1339
|
+
catch (e) {
|
|
1340
|
+
// stored backtrace may be cut off mid-frame — recover the complete frames
|
|
1341
|
+
}
|
|
1342
|
+
let boundary = value.lastIndexOf('},{');
|
|
1343
|
+
while (boundary > 0) {
|
|
1344
|
+
try {
|
|
1345
|
+
const frames = JSON.parse(`${value.substring(0, boundary + 1)}]`);
|
|
1346
|
+
return { frames, truncated: true };
|
|
1347
|
+
}
|
|
1348
|
+
catch (e) {
|
|
1349
|
+
// keep trying earlier frame boundaries
|
|
1350
|
+
}
|
|
1351
|
+
boundary = value.lastIndexOf('},{', boundary - 1);
|
|
1352
|
+
}
|
|
1353
|
+
return null;
|
|
1354
|
+
}
|
|
1355
|
+
_formatArg(arg) {
|
|
1356
|
+
if (typeof arg === 'string') {
|
|
1357
|
+
const max = 60;
|
|
1358
|
+
const value = arg.replace(/\s+/g, ' ');
|
|
1359
|
+
return `'${value.length > max ? `${value.substring(0, max)}…` : value}'`;
|
|
1360
|
+
}
|
|
1361
|
+
if (Array.isArray(arg)) {
|
|
1362
|
+
return 'Array';
|
|
1363
|
+
}
|
|
1364
|
+
if (arg && typeof arg === 'object') {
|
|
1365
|
+
return 'Object';
|
|
1366
|
+
}
|
|
1367
|
+
return String(arg);
|
|
1368
|
+
}
|
|
1289
1369
|
_prettify(value) {
|
|
1290
1370
|
if (typeof value === 'string') {
|
|
1291
1371
|
value = value.trim();
|
|
@@ -1302,7 +1382,7 @@ class ServerLogComponent {
|
|
|
1302
1382
|
return JSON.stringify(value, null, 2);
|
|
1303
1383
|
}
|
|
1304
1384
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ServerLogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1305
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: ServerLogComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"log\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log.type] || log.type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log.message }}\n </fs-label-field>\n @if (log.url) {\n <fs-label-field>\n <fs-label>\n URL\n </fs-label>\n {{ log.url }}\n </fs-label-field>\n }\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{ log.createDate|fsDateFormat: 'full-date-time' }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log.file }} @ {{ log.line }}\n </fs-label-field>\n </div>\n @if (backtrace || logData || server) {\n <mat-tab-group>\n @if (backtrace) {\n <mat-tab label=\"Backtrace\">\n <pre>{{ backtrace }}</pre>\n </mat-tab>\n }\n @if (logData) {\n <mat-tab label=\"Data\">\n <pre>{{ logData }}</pre>\n </mat-tab>\n }\n @if (server) {\n <mat-tab label=\"$_SERVER\">\n <pre>{{ server }}</pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1$3.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1$3.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$3.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$3.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i3$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i3$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: FsLabelModule }, { kind: "component", type: i3.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i3.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "ngmodule", type: FsDateModule }, { kind: "pipe", type: i4.FsDateFormatPipe, name: "fsDateFormat" }, { kind: "ngmodule", type: FsSkeletonModule }, { kind: "directive", type: i1.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "ngmodule", type: FsDialogModule }, { kind: "component", type: i2.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1385
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: ServerLogComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"log()\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log().type] || log().type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log().message }}\n </fs-label-field>\n @if (log().url) {\n <fs-label-field>\n <fs-label>\n URL\n </fs-label>\n {{ log().url }}\n </fs-label-field>\n }\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{ log().createDate|fsDateFormat: 'full-date-time' }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log().file }} @ {{ log().line }}\n </fs-label-field>\n </div>\n @if (backtrace() || logData() || server()) {\n <mat-tab-group>\n @if (backtrace()) {\n <mat-tab label=\"Backtrace\">\n <pre>{{ backtrace() }}</pre>\n </mat-tab>\n }\n @if (logData()) {\n <mat-tab label=\"Data\">\n <pre>{{ logData() }}</pre>\n </mat-tab>\n }\n @if (server()) {\n <mat-tab label=\"$_SERVER\">\n <pre>{{ server() }}</pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1$3.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1$3.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$3.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$3.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i3$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i3$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: FsLabelModule }, { kind: "component", type: i3.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i3.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "ngmodule", type: FsDateModule }, { kind: "pipe", type: i4.FsDateFormatPipe, name: "fsDateFormat" }, { kind: "ngmodule", type: FsSkeletonModule }, { kind: "directive", type: i1.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "ngmodule", type: FsDialogModule }, { kind: "component", type: i2.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1306
1386
|
}
|
|
1307
1387
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ServerLogComponent, decorators: [{
|
|
1308
1388
|
type: Component,
|
|
@@ -1314,8 +1394,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImpor
|
|
|
1314
1394
|
FsDateModule,
|
|
1315
1395
|
FsSkeletonModule,
|
|
1316
1396
|
FsDialogModule,
|
|
1317
|
-
], template: "<fs-dialog *fsSkeleton=\"log\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log.type] || log.type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log.message }}\n </fs-label-field>\n @if (log.url) {\n <fs-label-field>\n <fs-label>\n URL\n </fs-label>\n {{ log.url }}\n </fs-label-field>\n }\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{ log.createDate|fsDateFormat: 'full-date-time' }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log.file }} @ {{ log.line }}\n </fs-label-field>\n </div>\n @if (backtrace || logData || server) {\n <mat-tab-group>\n @if (backtrace) {\n <mat-tab label=\"Backtrace\">\n <pre>{{ backtrace }}</pre>\n </mat-tab>\n }\n @if (logData) {\n <mat-tab label=\"Data\">\n <pre>{{ logData }}</pre>\n </mat-tab>\n }\n @if (server) {\n <mat-tab label=\"$_SERVER\">\n <pre>{{ server }}</pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"] }]
|
|
1318
|
-
}] });
|
|
1397
|
+
], template: "<fs-dialog *fsSkeleton=\"log()\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log().type] || log().type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log().message }}\n </fs-label-field>\n @if (log().url) {\n <fs-label-field>\n <fs-label>\n URL\n </fs-label>\n {{ log().url }}\n </fs-label-field>\n }\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{ log().createDate|fsDateFormat: 'full-date-time' }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log().file }} @ {{ log().line }}\n </fs-label-field>\n </div>\n @if (backtrace() || logData() || server()) {\n <mat-tab-group>\n @if (backtrace()) {\n <mat-tab label=\"Backtrace\">\n <pre>{{ backtrace() }}</pre>\n </mat-tab>\n }\n @if (logData()) {\n <mat-tab label=\"Data\">\n <pre>{{ logData() }}</pre>\n </mat-tab>\n }\n @if (server()) {\n <mat-tab label=\"$_SERVER\">\n <pre>{{ server() }}</pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"] }]
|
|
1398
|
+
}], ctorParameters: () => [] });
|
|
1319
1399
|
|
|
1320
1400
|
class ServerLogsComponent {
|
|
1321
1401
|
_dialog = inject(MatDialog);
|