@alliance-droid/status-feedback-system 2.3.1 → 3.0.0
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/CHANGELOG.md +78 -61
- package/LICENSE +11 -11
- package/README.md +275 -273
- package/dist/components/DevFeedback.svelte +589 -583
- package/dist/components/DevFeedback.svelte.d.ts +7 -2
- package/dist/components/FeedbackBoard.svelte +110 -110
- package/dist/components/FeedbackButton.svelte +72 -72
- package/dist/components/FeedbackForm.svelte +155 -155
- package/dist/components/StatusBanner.svelte +105 -105
- package/dist/components/StatusPage.svelte +244 -244
- package/dist/components/board/FeedbackDetail.svelte +299 -299
- package/dist/components/board/FeedbackItem.svelte +117 -117
- package/dist/components/board/FeedbackList.svelte +58 -58
- package/dist/components/board/FeedbackSidebar.svelte +60 -60
- package/dist/components/board/FeedbackSubmitForm.svelte +123 -123
- package/dist/components/dev/DevContextMenu.svelte +178 -178
- package/dist/components/dev/DevOnboardingToast.svelte +73 -73
- package/dist/components/dev/environment.d.ts +2 -6
- package/dist/components/dev/environment.js +2 -23
- package/dist/components/shared/IncidentTimeline.svelte +55 -55
- package/dist/components/shared/PasteImageInput.svelte +169 -169
- package/dist/components/shared/StatusIndicator.svelte +50 -50
- package/dist/components/shared/SystemCard.svelte +30 -30
- package/dist/components/shared/UptimeBar.svelte +85 -85
- package/package.json +66 -66
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { SystemStatus } from '../../types.js';
|
|
3
|
-
|
|
4
|
-
interface Props {
|
|
5
|
-
status: SystemStatus;
|
|
6
|
-
size?: 'sm' | 'md' | 'lg';
|
|
7
|
-
showLabel?: boolean;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
let { status, size = 'md', showLabel = false }: Props = $props();
|
|
11
|
-
|
|
12
|
-
const config: Record<SystemStatus, { label: string; icon: string; colorClass: string }> = {
|
|
13
|
-
operational: {
|
|
14
|
-
label: 'Operational',
|
|
15
|
-
icon: 'fa-circle-check',
|
|
16
|
-
colorClass: 'text-green-500',
|
|
17
|
-
},
|
|
18
|
-
degraded: {
|
|
19
|
-
label: 'Degraded',
|
|
20
|
-
icon: 'fa-exclamation-triangle',
|
|
21
|
-
colorClass: 'text-yellow-500',
|
|
22
|
-
},
|
|
23
|
-
outage: {
|
|
24
|
-
label: 'Outage',
|
|
25
|
-
icon: 'fa-circle-xmark',
|
|
26
|
-
colorClass: 'text-red-500',
|
|
27
|
-
},
|
|
28
|
-
maintenance: {
|
|
29
|
-
label: 'Maintenance',
|
|
30
|
-
icon: 'fa-wrench',
|
|
31
|
-
colorClass: 'text-blue-500',
|
|
32
|
-
},
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const sizeClasses: Record<string, string> = {
|
|
36
|
-
sm: 'text-xs',
|
|
37
|
-
md: 'text-sm',
|
|
38
|
-
lg: 'text-base',
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
let current = $derived(config[status]);
|
|
42
|
-
let sizeClass = $derived(sizeClasses[size]);
|
|
43
|
-
</script>
|
|
44
|
-
|
|
45
|
-
<span class="inline-flex items-center gap-1.5 {sizeClass}" role="status" aria-label="{current.label}">
|
|
46
|
-
<i class="fa-solid {current.icon} {current.colorClass}" aria-hidden="true"></i>
|
|
47
|
-
{#if showLabel}
|
|
48
|
-
<span class="text-foreground-secondary">{current.label}</span>
|
|
49
|
-
{/if}
|
|
50
|
-
</span>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { SystemStatus } from '../../types.js';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
status: SystemStatus;
|
|
6
|
+
size?: 'sm' | 'md' | 'lg';
|
|
7
|
+
showLabel?: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let { status, size = 'md', showLabel = false }: Props = $props();
|
|
11
|
+
|
|
12
|
+
const config: Record<SystemStatus, { label: string; icon: string; colorClass: string }> = {
|
|
13
|
+
operational: {
|
|
14
|
+
label: 'Operational',
|
|
15
|
+
icon: 'fa-circle-check',
|
|
16
|
+
colorClass: 'text-green-500',
|
|
17
|
+
},
|
|
18
|
+
degraded: {
|
|
19
|
+
label: 'Degraded',
|
|
20
|
+
icon: 'fa-exclamation-triangle',
|
|
21
|
+
colorClass: 'text-yellow-500',
|
|
22
|
+
},
|
|
23
|
+
outage: {
|
|
24
|
+
label: 'Outage',
|
|
25
|
+
icon: 'fa-circle-xmark',
|
|
26
|
+
colorClass: 'text-red-500',
|
|
27
|
+
},
|
|
28
|
+
maintenance: {
|
|
29
|
+
label: 'Maintenance',
|
|
30
|
+
icon: 'fa-wrench',
|
|
31
|
+
colorClass: 'text-blue-500',
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const sizeClasses: Record<string, string> = {
|
|
36
|
+
sm: 'text-xs',
|
|
37
|
+
md: 'text-sm',
|
|
38
|
+
lg: 'text-base',
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
let current = $derived(config[status]);
|
|
42
|
+
let sizeClass = $derived(sizeClasses[size]);
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<span class="inline-flex items-center gap-1.5 {sizeClass}" role="status" aria-label="{current.label}">
|
|
46
|
+
<i class="fa-solid {current.icon} {current.colorClass}" aria-hidden="true"></i>
|
|
47
|
+
{#if showLabel}
|
|
48
|
+
<span class="text-foreground-secondary">{current.label}</span>
|
|
49
|
+
{/if}
|
|
50
|
+
</span>
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { System, StatusHistoryEntry } from '../../types.js';
|
|
3
|
-
import StatusIndicator from './StatusIndicator.svelte';
|
|
4
|
-
import UptimeBar from './UptimeBar.svelte';
|
|
5
|
-
|
|
6
|
-
interface Props {
|
|
7
|
-
system: System;
|
|
8
|
-
history?: StatusHistoryEntry[];
|
|
9
|
-
showUptime?: boolean;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
let { system, history = [], showUptime = true }: Props = $props();
|
|
13
|
-
</script>
|
|
14
|
-
|
|
15
|
-
<div class="rounded-lg border border-border bg-surface p-4">
|
|
16
|
-
<div class="flex items-center justify-between">
|
|
17
|
-
<div>
|
|
18
|
-
<h3 class="text-sm font-semibold text-foreground">{system.name}</h3>
|
|
19
|
-
{#if system.description}
|
|
20
|
-
<p class="mt-0.5 text-xs text-foreground-tertiary">{system.description}</p>
|
|
21
|
-
{/if}
|
|
22
|
-
</div>
|
|
23
|
-
<StatusIndicator status={system.status} showLabel size="sm" />
|
|
24
|
-
</div>
|
|
25
|
-
{#if showUptime && history.length > 0}
|
|
26
|
-
<div class="mt-3">
|
|
27
|
-
<UptimeBar {history} />
|
|
28
|
-
</div>
|
|
29
|
-
{/if}
|
|
30
|
-
</div>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { System, StatusHistoryEntry } from '../../types.js';
|
|
3
|
+
import StatusIndicator from './StatusIndicator.svelte';
|
|
4
|
+
import UptimeBar from './UptimeBar.svelte';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
system: System;
|
|
8
|
+
history?: StatusHistoryEntry[];
|
|
9
|
+
showUptime?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let { system, history = [], showUptime = true }: Props = $props();
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<div class="rounded-lg border border-border bg-surface p-4">
|
|
16
|
+
<div class="flex items-center justify-between">
|
|
17
|
+
<div>
|
|
18
|
+
<h3 class="text-sm font-semibold text-foreground">{system.name}</h3>
|
|
19
|
+
{#if system.description}
|
|
20
|
+
<p class="mt-0.5 text-xs text-foreground-tertiary">{system.description}</p>
|
|
21
|
+
{/if}
|
|
22
|
+
</div>
|
|
23
|
+
<StatusIndicator status={system.status} showLabel size="sm" />
|
|
24
|
+
</div>
|
|
25
|
+
{#if showUptime && history.length > 0}
|
|
26
|
+
<div class="mt-3">
|
|
27
|
+
<UptimeBar {history} />
|
|
28
|
+
</div>
|
|
29
|
+
{/if}
|
|
30
|
+
</div>
|
|
@@ -1,85 +1,85 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { StatusHistoryEntry, SystemStatus } from '../../types.js';
|
|
3
|
-
|
|
4
|
-
interface Props {
|
|
5
|
-
history: StatusHistoryEntry[];
|
|
6
|
-
days?: number;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
let { history, days = 90 }: Props = $props();
|
|
10
|
-
|
|
11
|
-
const statusColors: Record<SystemStatus, string> = {
|
|
12
|
-
operational: '#22c55e',
|
|
13
|
-
degraded: '#eab308',
|
|
14
|
-
outage: '#ef4444',
|
|
15
|
-
maintenance: '#3b82f6',
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Build day-by-day status bars from history entries.
|
|
20
|
-
* Each day gets the "worst" status that occurred during it.
|
|
21
|
-
*/
|
|
22
|
-
let dayBars = $derived.by(() => {
|
|
23
|
-
const now = Date.now();
|
|
24
|
-
const msPerDay = 24 * 60 * 60 * 1000;
|
|
25
|
-
const bars: { date: string; status: SystemStatus; color: string }[] = [];
|
|
26
|
-
|
|
27
|
-
const severity: Record<SystemStatus, number> = {
|
|
28
|
-
operational: 0,
|
|
29
|
-
maintenance: 1,
|
|
30
|
-
degraded: 2,
|
|
31
|
-
outage: 3,
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
for (let i = days - 1; i >= 0; i--) {
|
|
35
|
-
const dayStart = now - (i + 1) * msPerDay;
|
|
36
|
-
const dayEnd = now - i * msPerDay;
|
|
37
|
-
const dateStr = new Date(dayEnd).toLocaleDateString();
|
|
38
|
-
|
|
39
|
-
// Find worst status that overlapped with this day
|
|
40
|
-
let worstStatus: SystemStatus = 'operational';
|
|
41
|
-
let worstSeverity = 0;
|
|
42
|
-
|
|
43
|
-
for (const entry of history) {
|
|
44
|
-
if (entry.changedAt <= dayEnd && entry.changedAt >= dayStart - msPerDay) {
|
|
45
|
-
const s = severity[entry.status] ?? 0;
|
|
46
|
-
if (s > worstSeverity) {
|
|
47
|
-
worstSeverity = s;
|
|
48
|
-
worstStatus = entry.status;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
bars.push({
|
|
54
|
-
date: dateStr,
|
|
55
|
-
status: worstStatus,
|
|
56
|
-
color: statusColors[worstStatus],
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return bars;
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
let uptimePercent = $derived.by(() => {
|
|
64
|
-
if (dayBars.length === 0) return 100;
|
|
65
|
-
const operational = dayBars.filter((d) => d.status === 'operational').length;
|
|
66
|
-
return Math.round((operational / dayBars.length) * 1000) / 10;
|
|
67
|
-
});
|
|
68
|
-
</script>
|
|
69
|
-
|
|
70
|
-
<div class="space-y-1">
|
|
71
|
-
<div class="flex items-center justify-between text-xs text-foreground-tertiary">
|
|
72
|
-
<span>{days} days ago</span>
|
|
73
|
-
<span>{uptimePercent}% uptime</span>
|
|
74
|
-
<span>Today</span>
|
|
75
|
-
</div>
|
|
76
|
-
<div class="flex gap-px">
|
|
77
|
-
{#each dayBars as bar (bar.date)}
|
|
78
|
-
<div
|
|
79
|
-
class="h-8 flex-1 rounded-sm transition-opacity hover:opacity-80"
|
|
80
|
-
style="background-color: {bar.color}"
|
|
81
|
-
title="{bar.date}: {bar.status}"
|
|
82
|
-
></div>
|
|
83
|
-
{/each}
|
|
84
|
-
</div>
|
|
85
|
-
</div>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { StatusHistoryEntry, SystemStatus } from '../../types.js';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
history: StatusHistoryEntry[];
|
|
6
|
+
days?: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let { history, days = 90 }: Props = $props();
|
|
10
|
+
|
|
11
|
+
const statusColors: Record<SystemStatus, string> = {
|
|
12
|
+
operational: '#22c55e',
|
|
13
|
+
degraded: '#eab308',
|
|
14
|
+
outage: '#ef4444',
|
|
15
|
+
maintenance: '#3b82f6',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Build day-by-day status bars from history entries.
|
|
20
|
+
* Each day gets the "worst" status that occurred during it.
|
|
21
|
+
*/
|
|
22
|
+
let dayBars = $derived.by(() => {
|
|
23
|
+
const now = Date.now();
|
|
24
|
+
const msPerDay = 24 * 60 * 60 * 1000;
|
|
25
|
+
const bars: { date: string; status: SystemStatus; color: string }[] = [];
|
|
26
|
+
|
|
27
|
+
const severity: Record<SystemStatus, number> = {
|
|
28
|
+
operational: 0,
|
|
29
|
+
maintenance: 1,
|
|
30
|
+
degraded: 2,
|
|
31
|
+
outage: 3,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
for (let i = days - 1; i >= 0; i--) {
|
|
35
|
+
const dayStart = now - (i + 1) * msPerDay;
|
|
36
|
+
const dayEnd = now - i * msPerDay;
|
|
37
|
+
const dateStr = new Date(dayEnd).toLocaleDateString();
|
|
38
|
+
|
|
39
|
+
// Find worst status that overlapped with this day
|
|
40
|
+
let worstStatus: SystemStatus = 'operational';
|
|
41
|
+
let worstSeverity = 0;
|
|
42
|
+
|
|
43
|
+
for (const entry of history) {
|
|
44
|
+
if (entry.changedAt <= dayEnd && entry.changedAt >= dayStart - msPerDay) {
|
|
45
|
+
const s = severity[entry.status] ?? 0;
|
|
46
|
+
if (s > worstSeverity) {
|
|
47
|
+
worstSeverity = s;
|
|
48
|
+
worstStatus = entry.status;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
bars.push({
|
|
54
|
+
date: dateStr,
|
|
55
|
+
status: worstStatus,
|
|
56
|
+
color: statusColors[worstStatus],
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return bars;
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
let uptimePercent = $derived.by(() => {
|
|
64
|
+
if (dayBars.length === 0) return 100;
|
|
65
|
+
const operational = dayBars.filter((d) => d.status === 'operational').length;
|
|
66
|
+
return Math.round((operational / dayBars.length) * 1000) / 10;
|
|
67
|
+
});
|
|
68
|
+
</script>
|
|
69
|
+
|
|
70
|
+
<div class="space-y-1">
|
|
71
|
+
<div class="flex items-center justify-between text-xs text-foreground-tertiary">
|
|
72
|
+
<span>{days} days ago</span>
|
|
73
|
+
<span>{uptimePercent}% uptime</span>
|
|
74
|
+
<span>Today</span>
|
|
75
|
+
</div>
|
|
76
|
+
<div class="flex gap-px">
|
|
77
|
+
{#each dayBars as bar (bar.date)}
|
|
78
|
+
<div
|
|
79
|
+
class="h-8 flex-1 rounded-sm transition-opacity hover:opacity-80"
|
|
80
|
+
style="background-color: {bar.color}"
|
|
81
|
+
title="{bar.date}: {bar.status}"
|
|
82
|
+
></div>
|
|
83
|
+
{/each}
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
package/package.json
CHANGED
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@alliance-droid/status-feedback-system",
|
|
3
|
-
"version": "
|
|
4
|
-
"type": "module",
|
|
5
|
-
"description": "Drop-in system status pages and user feedback forms for SvelteKit apps",
|
|
6
|
-
"svelte": "./dist/index.js",
|
|
7
|
-
"types": "./dist/index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"types": "./dist/index.d.ts",
|
|
11
|
-
"svelte": "./dist/index.js"
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
"files": [
|
|
15
|
-
"dist",
|
|
16
|
-
"!dist/**/*.test.*",
|
|
17
|
-
"CHANGELOG.md"
|
|
18
|
-
],
|
|
19
|
-
"scripts": {
|
|
20
|
-
"build": "svelte-package -o dist && publint",
|
|
21
|
-
"lint": "eslint src",
|
|
22
|
-
"check": "svelte-check --tsconfig ./tsconfig.json",
|
|
23
|
-
"test": "vitest run",
|
|
24
|
-
"test:watch": "vitest",
|
|
25
|
-
"prepublishOnly": "npm run build"
|
|
26
|
-
},
|
|
27
|
-
"peerDependencies": {
|
|
28
|
-
"@alliance-droid/svelte-component-library": ">=1.0.0",
|
|
29
|
-
"svelte": "^5.0.0"
|
|
30
|
-
},
|
|
31
|
-
"devDependencies": {
|
|
32
|
-
"@alliance-droid/svelte-component-library": "^1.0.5",
|
|
33
|
-
"@eslint/js": "^10.0.1",
|
|
34
|
-
"@sveltejs/package": "^2.3.0",
|
|
35
|
-
"@sveltejs/vite-plugin-svelte": "^6.0.0",
|
|
36
|
-
"@testing-library/jest-dom": "^6.9.1",
|
|
37
|
-
"@testing-library/svelte": "^5.3.1",
|
|
38
|
-
"eslint": "^10.4.0",
|
|
39
|
-
"eslint-plugin-svelte": "^3.17.1",
|
|
40
|
-
"globals": "^17.6.0",
|
|
41
|
-
"jsdom": "^29.0.0",
|
|
42
|
-
"publint": "^0.3.0",
|
|
43
|
-
"svelte": "^5.48.0",
|
|
44
|
-
"svelte-check": "^4.3.0",
|
|
45
|
-
"typescript": "^5.9.0",
|
|
46
|
-
"typescript-eslint": "^8.59.4",
|
|
47
|
-
"vite": "^7.3.0",
|
|
48
|
-
"vitest": "^4.0.0"
|
|
49
|
-
},
|
|
50
|
-
"keywords": [
|
|
51
|
-
"svelte",
|
|
52
|
-
"sveltekit",
|
|
53
|
-
"status-page",
|
|
54
|
-
"feedback",
|
|
55
|
-
"uptime"
|
|
56
|
-
],
|
|
57
|
-
"author": "Alliance Technical Group",
|
|
58
|
-
"license": "UNLICENSED",
|
|
59
|
-
"publishConfig": {
|
|
60
|
-
"access": "restricted"
|
|
61
|
-
},
|
|
62
|
-
"repository": {
|
|
63
|
-
"type": "git",
|
|
64
|
-
"url": "git+https://alliance.ghe.com/alliance/status-feedback-system.git"
|
|
65
|
-
}
|
|
66
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@alliance-droid/status-feedback-system",
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Drop-in system status pages and user feedback forms for SvelteKit apps",
|
|
6
|
+
"svelte": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"svelte": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"!dist/**/*.test.*",
|
|
17
|
+
"CHANGELOG.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "svelte-package -o dist && publint",
|
|
21
|
+
"lint": "eslint src",
|
|
22
|
+
"check": "svelte-check --tsconfig ./tsconfig.json",
|
|
23
|
+
"test": "vitest run",
|
|
24
|
+
"test:watch": "vitest",
|
|
25
|
+
"prepublishOnly": "npm run build"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"@alliance-droid/svelte-component-library": ">=1.0.0",
|
|
29
|
+
"svelte": "^5.0.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@alliance-droid/svelte-component-library": "^1.0.5",
|
|
33
|
+
"@eslint/js": "^10.0.1",
|
|
34
|
+
"@sveltejs/package": "^2.3.0",
|
|
35
|
+
"@sveltejs/vite-plugin-svelte": "^6.0.0",
|
|
36
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
37
|
+
"@testing-library/svelte": "^5.3.1",
|
|
38
|
+
"eslint": "^10.4.0",
|
|
39
|
+
"eslint-plugin-svelte": "^3.17.1",
|
|
40
|
+
"globals": "^17.6.0",
|
|
41
|
+
"jsdom": "^29.0.0",
|
|
42
|
+
"publint": "^0.3.0",
|
|
43
|
+
"svelte": "^5.48.0",
|
|
44
|
+
"svelte-check": "^4.3.0",
|
|
45
|
+
"typescript": "^5.9.0",
|
|
46
|
+
"typescript-eslint": "^8.59.4",
|
|
47
|
+
"vite": "^7.3.0",
|
|
48
|
+
"vitest": "^4.0.0"
|
|
49
|
+
},
|
|
50
|
+
"keywords": [
|
|
51
|
+
"svelte",
|
|
52
|
+
"sveltekit",
|
|
53
|
+
"status-page",
|
|
54
|
+
"feedback",
|
|
55
|
+
"uptime"
|
|
56
|
+
],
|
|
57
|
+
"author": "Alliance Technical Group",
|
|
58
|
+
"license": "UNLICENSED",
|
|
59
|
+
"publishConfig": {
|
|
60
|
+
"access": "restricted"
|
|
61
|
+
},
|
|
62
|
+
"repository": {
|
|
63
|
+
"type": "git",
|
|
64
|
+
"url": "git+https://alliance.ghe.com/alliance/status-feedback-system.git"
|
|
65
|
+
}
|
|
66
|
+
}
|