Compare commits

...

71 Commits

Author SHA1 Message Date
Amir Raminfar cc26b1be81 chore: release v6.4.2 2024-03-26 09:07:37 -07:00
renovate[bot] 263ad3f235 chore(deps): update all non-major dependencies (#2855)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-26 15:50:54 +00:00
Amir Raminfar 9c1b967502 feat: improves icons placement for expanding json (#2854) 2024-03-26 15:46:05 +00:00
renovate[bot] 21c775d40b fix(deps): update dependency @intlify/unplugin-vue-i18n to v4 (#2853)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-26 08:43:20 -07:00
renovate[bot] 943d0a87a1 chore(deps): update all non-major dependencies (#2852)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-26 14:35:49 +00:00
Amir Raminfar a08e85cf7b chore: cleans up tests (#2850) 2024-03-25 15:33:16 -07:00
Amir Raminfar 3a2546f919 feat: hides per page dropdown when total number of containers is less than a page (#2849) 2024-03-25 08:09:10 -07:00
renovate[bot] d55e5f1c53 fix(deps): update dependency unplugin-vue-macros to ^2.7.13 (#2848)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-25 03:50:06 +00:00
Amir Raminfar 0639320dca chore: updates total test for collector (#2847) 2024-03-25 01:45:09 +00:00
renovate[bot] 293f6a075b fix(deps): update all non-major dependencies (#2846)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-25 01:32:55 +00:00
Amir Raminfar ef0938d6b8 chore: adds tests (#2845) 2024-03-23 21:32:17 -07:00
renovate[bot] 192d3783af fix(deps): update all non-major dependencies (#2843)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-22 19:11:29 +00:00
renovate[bot] 2d7c806390 fix(deps): update module github.com/docker/docker to v26 (#2841)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-21 09:16:51 -07:00
renovate[bot] e643099f34 fix(deps): update all non-major dependencies (#2840)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-21 16:14:48 +00:00
Amir Raminfar 821c3e90f2 chore: release v6.4.1 2024-03-21 09:09:25 -07:00
Amir Raminfar b72ee29aa3 fix: this fixes a critical bug where multiple stat collectors were competing and never stopping. see #2838 (#2839) 2024-03-21 16:09:01 +00:00
Amir Raminfar 83ef59cd88 chore: release v6.4.0 2024-03-20 11:37:27 -07:00
Amir Raminfar 0ca6624238 feat: deactivates collection of stats after 6 hours of idle (#2830) 2024-03-20 10:53:52 -07:00
renovate[bot] f9aabf138c fix(deps): update all non-major dependencies (#2837)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-20 16:12:39 +00:00
renovate[bot] 7ed2c50ba7 chore(deps): update all non-major dependencies (#2836)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-19 22:14:23 +00:00
Amir Raminfar 993b3fd2f6 fix: fixes parsing of logfmt logs with a regex. fixes #2834 (#2835) 2024-03-19 14:36:39 -07:00
Amir Raminfar 9bf6cd8821 chore: code fix 2024-03-19 14:27:57 -07:00
renovate[bot] cb99bcdc09 fix(deps): update dependency date-fns to ^3.6.0 (#2832)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-18 03:52:02 +00:00
renovate[bot] a8e4267c67 chore(deps): update all non-major dependencies (#2831)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-18 00:57:39 +00:00
renovate[bot] c0a80c5591 chore(deps): update all non-major dependencies (#2827)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-15 16:42:44 +00:00
Amir Raminfar 7f38bdaf4b chore: code clean up 2024-03-14 12:22:32 -07:00
Amir Raminfar c2fce52e1c perf: adds caching and brotli (#2826) 2024-03-14 12:11:36 -07:00
Amir Raminfar 09a9886423 perf: makes messages for copy and paste lazy for minor perf improvement 2024-03-14 08:29:16 -07:00
Amir Raminfar e7cabc8857 chore: release v6.3.1 2024-03-13 08:37:55 -07:00
Amir Raminfar 7e3d501f0f fix: fixes global regex with g flag. fixes #2822 (#2825) 2024-03-13 15:36:55 +00:00
Amir Raminfar c2dbcd546c chore: release v6.3.0 2024-03-12 12:20:41 -07:00
Amir Raminfar ec2be9c0f2 feat: brings colors back and fixes #2639 (#2823) 2024-03-12 19:15:18 +00:00
Amir Raminfar 32ed13d7d7 fix: uses data attributes for auto theme and removes postcss-mixins (#2820) 2024-03-11 16:57:47 +00:00
renovate[bot] f5b4cfd55a fix(deps): update all non-major dependencies (#2819)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-11 16:44:58 +00:00
renovate[bot] 4c07a7210b fix(deps): update all non-major dependencies (#2818)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-11 01:05:59 +00:00
Fabeuss 34d8ef6913 feat: Adds french (#2815) 2024-03-10 06:32:41 -07:00
Amir Raminfar 7fbac3b118 chore: fix types 2024-03-08 11:41:46 -08:00
renovate[bot] 4e59cf3937 fix(deps): update dependency @intlify/unplugin-vue-i18n to v3 (#2813)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-07 15:01:40 -08:00
renovate[bot] e02378f93f chore(deps): update all non-major dependencies (#2812)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-07 22:04:10 +00:00
Nikolaos Pothitos 32b8b02607 docs: add missing base slash and remove non-existent nginx configuration (#2809) 2024-03-05 16:10:01 -08:00
renovate[bot] 721e8e9e36 chore(deps): update all non-major dependencies (#2808)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-05 22:11:40 +00:00
Amir Raminfar 8055512bc4 chore: release v6.2.7 2024-03-05 10:46:33 -08:00
Amir Raminfar 61f26b7bc3 fix: redirects login page to previous page after successful login. see #2806 (#2807) 2024-03-05 18:42:46 +00:00
renovate[bot] e6528a7fc1 fix(deps): update dependency postcss-mixins to v10 (#2805)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-05 10:37:46 -08:00
renovate[bot] 378de1a12b fix(deps): update all non-major dependencies (#2804)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-04 23:23:22 +00:00
renovate[bot] c803fe3119 chore(deps): update dependency vue-tsc to v2 (#2803)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-04 08:43:58 -08:00
renovate[bot] 0e1541b78d chore(deps): update all non-major dependencies (#2802)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-03 22:07:55 +00:00
Amir Raminfar 1d14c6c6e7 chore: release v6.2.6 2024-03-01 13:09:02 -08:00
Amir Raminfar b78b70b233 feat: adds hideMenu as a query parameter (#2796) 2024-02-29 08:11:02 -08:00
renovate[bot] f9465a2d66 chore(deps): update all non-major dependencies (#2797)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-28 18:30:49 +00:00
renovate[bot] a5da85d603 chore(deps): update all non-major dependencies to ^3.4.20 (#2795)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-26 03:40:30 +00:00
renovate[bot] 2140fe3d37 fix(deps): update module github.com/puzpuzpuz/xsync/v3 to v3.1.0 (#2794)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-25 21:24:11 +00:00
renovate[bot] ff2e766324 chore(deps): update all non-major dependencies (#2791)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-24 16:21:17 +00:00
Amir Raminfar 336e8acd0b fix: improves fuzzy by using key down instead of up (#2790) 2024-02-23 21:09:14 +00:00
renovate[bot] a6c2c7dbbc fix(deps): update all non-major dependencies (#2789)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-21 17:38:43 +00:00
Amir Raminfar 8d844b4302 chore: release v6.2.5 2024-02-20 09:15:38 -08:00
Amir Raminfar ac66969126 chore: fixes types 2024-02-20 09:15:17 -08:00
renovate[bot] b896e16941 fix(deps): update all non-major dependencies (#2788)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-20 16:57:21 +00:00
Amir Raminfar 5b1b2463b0 fix: fixes missing nano seconds for parsing between logs. see #2783 (#2785) 2024-02-20 08:50:00 -08:00
Amir Raminfar 07d0c7fac5 fix: fixes changing items per page. fixes #2784 (#2786) 2024-02-19 23:12:16 +00:00
renovate[bot] d2d573c399 fix(deps): update all non-major dependencies (#2782)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-19 01:57:52 +00:00
renovate[bot] 54ad9d094b chore(deps): update all non-major dependencies (#2781)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-16 21:51:56 +00:00
renovate[bot] afb9bc971c fix(deps): update all non-major dependencies (#2778)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-14 16:42:38 +00:00
renovate[bot] 3e0d010390 chore(deps): update all non-major dependencies (#2777)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-13 16:39:46 +00:00
renovate[bot] 76e5b960aa fix(deps): update all non-major dependencies (#2776)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-12 20:16:36 +00:00
Amir Raminfar 152bdb8c8f feat: adds italian locale (#2775) 2024-02-12 15:53:06 +00:00
Amir Raminfar 77e49d132f chore: removes unused packages (#2772) 2024-02-11 13:43:55 -08:00
Amir Raminfar 3fe087935c chore: release v6.2.4 2024-02-10 09:46:49 -08:00
renovate[bot] b47cf7940a chore(deps): update all non-major dependencies (#2771)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-10 17:16:41 +00:00
Amir Raminfar 420b398e50 chore: uses 1.22 for testing (#2770) 2024-02-10 17:13:19 +00:00
Ivan 91d79c99ea feat: add Content-Encoding for downloading logs (#2769) 2024-02-10 06:02:10 -08:00
42 changed files with 1840 additions and 1397 deletions
+4 -4
View File
@@ -31,7 +31,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v5
with:
go-version: 1.21.x
go-version: 1.22.x
check-latest: true
- name: Checkout code
uses: actions/checkout@v4
@@ -84,14 +84,14 @@ jobs:
with:
images: amir20/dozzle
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0
- name: Login to DockerHub
uses: docker/login-action@v3.0.0
uses: docker/login-action@v3.1.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push
uses: docker/build-push-action@v5.1.0
uses: docker/build-push-action@v5.3.0
with:
push: true
platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8
+3 -3
View File
@@ -18,14 +18,14 @@ jobs:
with:
images: amir20/dozzle
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0
- name: Login to DockerHub
uses: docker/login-action@v3.0.0
uses: docker/login-action@v3.1.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push
uses: docker/build-push-action@v5.1.0
uses: docker/build-push-action@v5.3.0
with:
push: true
platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8
+1 -1
View File
@@ -54,7 +54,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v5
with:
go-version: 1.21.x
go-version: 1.22.x
check-latest: true
- name: Checkout code
uses: actions/checkout@v4
+1 -1
View File
@@ -22,7 +22,7 @@ COPY public ./public
# Build assets
RUN pnpm build
FROM --platform=$BUILDPLATFORM golang:1.22.0-alpine AS builder
FROM --platform=$BUILDPLATFORM golang:1.22.1-alpine AS builder
RUN apk add --no-cache ca-certificates && mkdir /dozzle
+5 -9
View File
@@ -3,6 +3,7 @@
</template>
<script lang="ts" setup>
const mode = useColorMode();
watchEffect(() => {
if (smallerScrollbars.value) {
document.documentElement.classList.add("has-custom-scrollbars");
@@ -10,16 +11,11 @@ watchEffect(() => {
document.documentElement.classList.remove("has-custom-scrollbars");
}
switch (lightTheme.value) {
case "dark":
document.documentElement.setAttribute("data-theme", "dark");
break;
case "light":
document.documentElement.setAttribute("data-theme", "light");
break;
default:
document.documentElement.removeAttribute("data-theme");
let theme = lightTheme.value;
if (theme === "auto") {
theme = mode.value;
}
document.documentElement.setAttribute("data-theme", theme);
});
</script>
<style lang="postcss">
+2
View File
@@ -52,6 +52,8 @@ declare module 'vue' {
LogStd: typeof import('./components/LogViewer/LogStd.vue')['default']
LogViewer: typeof import('./components/LogViewer/LogViewer.vue')['default']
LogViewerWithSource: typeof import('./components/LogViewer/LogViewerWithSource.vue')['default']
'MaterialSymbols:collapseAllRounded': typeof import('~icons/material-symbols/collapse-all-rounded')['default']
'MaterialSymbols:expandAllRounded': typeof import('~icons/material-symbols/expand-all-rounded')['default']
'Mdi:announcement': typeof import('~icons/mdi/announcement')['default']
'Mdi:arrowUp': typeof import('~icons/mdi/arrow-up')['default']
'Mdi:check': typeof import('~icons/mdi/check')['default']
+2 -2
View File
@@ -1,12 +1,11 @@
!
<template>
<div class="text-right">
<div class="text-right" v-if="containers.length > pageSizes[0]">
Show per page
<dropdown-menu
class="dropdown-left btn-xs md:btn-sm"
v-model="perPage"
:options="pageSizes.map((i) => ({ label: i.toLocaleString(), value: i }))"
v-if="containers.length > 0"
/>
</div>
<table class="table table-lg bg-base">
@@ -129,6 +128,7 @@ const sortedContainers = computedWithControl(
const totalPages = computed(() => Math.ceil(sortedContainers.value.length / perPage.value));
const isPaginated = computed(() => totalPages.value > 1);
const currentPage = ref(1);
watch(perPage, () => (currentPage.value = 1));
const paginated = computed(() => {
const start = (currentPage.value - 1) * perPage.value;
const end = start + perPage.value;
+1 -1
View File
@@ -73,7 +73,7 @@ describe("<FuzzySearchModal />", () => {
test("choose baz", async () => {
const wrapper = createFuzzySearchModal();
await wrapper.find("input").setValue("baz");
await wrapper.find("input").trigger("keyup.enter");
await wrapper.find("input").trigger("keydown.enter");
expect(useRouter().push).toHaveBeenCalledWith({ name: "container-id", params: { id: "567" } });
});
});
+9 -5
View File
@@ -4,12 +4,12 @@
<mdi:magnify class="flex size-8" />
<input
tabindex="0"
class="input input-ghost input-lg flex-1 px-1"
class="input input-lg input-ghost flex-1 px-1"
ref="input"
@keyup.down="selectedIndex = Math.min(selectedIndex + 1, data.length - 1)"
@keyup.up="selectedIndex = Math.max(selectedIndex - 1, 0)"
@keyup.enter.exact="selected(data[selectedIndex].item)"
@keyup.alt.enter="addColumn(data[selectedIndex])"
@keydown.down="selectedIndex = Math.min(selectedIndex + 1, data.length - 1)"
@keydown.up="selectedIndex = Math.max(selectedIndex - 1, 0)"
@keydown.enter.exact="selected(data[selectedIndex].item)"
@keydown.alt.enter="addColumn(data[selectedIndex])"
v-model="query"
:placeholder="$t('placeholder.search-containers')"
/>
@@ -148,4 +148,8 @@ function matchedName({ item, matches = [] }: { item: { name: string }; matches?:
:deep(mark) {
@apply bg-transparent text-inherit underline underline-offset-2;
}
.menu a {
@apply transition-none duration-0;
}
</style>
+11 -16
View File
@@ -1,5 +1,10 @@
<template>
<div class="relative flex w-full gap-x-2">
<div class="group/item relative flex w-full gap-x-2" @click="expandToggle()">
<label class="swap swap-rotate invisible absolute -left-4 top-0.5 size-4 group-hover/item:visible">
<input type="checkbox" v-model="expanded" @click="expandToggle()" />
<material-symbols:expand-all-rounded class="swap-off text-secondary" />
<material-symbols:collapse-all-rounded class="swap-on text-secondary" />
</label>
<div v-if="showStd">
<log-std :std="logEntry.std"></log-std>
</div>
@@ -10,8 +15,8 @@
<log-level :level="logEntry.level"></log-level>
</div>
<div>
<ul class="fields cursor-pointer space-x-4" :class="{ expanded }" @click="expandToggle()">
<li v-for="(value, name) in validValues" class="inline-block">
<ul class="fields cursor-pointer space-x-4" :class="{ expanded }">
<li v-for="(value, name) in validValues">
<span class="text-light">{{ name }}=</span><span class="font-bold" v-if="value === null">&lt;null&gt;</span>
<template v-else-if="Array.isArray(value)">
<span class="font-bold" v-html="markSearch(JSON.stringify(value))"> </span>
@@ -24,7 +29,7 @@
</div>
<log-message-actions
class="duration-250 absolute -right-1 opacity-0 transition-opacity delay-150 group-hover/entry:opacity-100"
:message="JSON.stringify(logEntry.message)"
:message="() => JSON.stringify(logEntry.message)"
:log-entry="logEntry"
/>
</div>
@@ -52,18 +57,8 @@ const validValues = computed(() => {
}
.fields {
&:hover {
&::after {
content: "expand json";
@apply ml-2 inline-block text-secondary;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
}
}
&.expanded:hover {
&::after {
content: "collapse json";
}
li {
@apply inline-flex;
}
}
</style>
+6 -6
View File
@@ -11,9 +11,9 @@
></field-list>
</template>
<template v-else-if="Array.isArray(value)">
<a @click="toggleField(name)" class="link-primary cursor-pointer">
{{ hasField(name) ? "remove" : "add" }}&nbsp;</a
>
<a @click.stop="toggleField(name)" class="link-primary mr-2 cursor-pointer">
{{ hasField(name) ? "remove" : "add" }}
</a>
<span class="text-light">{{ name }}=</span>[
<span class="font-bold" v-for="(item, index) in value">
<span v-html="JSON.stringify(item)"></span><span v-if="index !== value.length - 1">,</span>
@@ -21,9 +21,9 @@
]
</template>
<template v-else>
<a @click="toggleField(name)" class="link-primary cursor-pointer">
{{ hasField(name) ? "remove" : "add" }}&nbsp;</a
>
<a @click.stop="toggleField(name)" class="link-primary mr-2 cursor-pointer">
{{ hasField(name) ? "remove" : "add" }}
</a>
<span class="text-light">{{ name }}=</span><span class="font-bold" v-html="value"></span>
</template>
</li>
@@ -2,7 +2,7 @@
<div class="flex gap-2">
<div
class="flex min-w-[0.98rem] items-start justify-end align-bottom hover:cursor-pointer"
v-if="isSupported && message.trim() != ''"
v-if="isSupported"
:title="t('log_actions.copy_log')"
>
<span
@@ -32,7 +32,7 @@
import { LogEntry, JSONObject } from "@/models/LogEntry";
const { message, logEntry } = defineProps<{
message: string;
message: () => string;
logEntry: LogEntry<string | JSONObject>;
}>();
@@ -44,7 +44,7 @@ const { isSearching } = useSearchFilter();
const { handleJumpLineSelected } = useLogSearchContext();
async function copyLogMessageToClipBoard() {
await copy(message);
await copy(message());
if (copied.value) {
showToast(
@@ -5,11 +5,11 @@
<log-level class="flex" :level="logEntry.level" :position="logEntry.position" />
<div
class="whitespace-pre-wrap [word-break:break-word] group-[.disable-wrap]:whitespace-nowrap"
v-html="markSearch(logEntry.message)"
v-html="colorize(logEntry.message)"
></div>
<log-message-actions
class="duration-250 absolute -right-1 opacity-0 transition-opacity delay-150 group-hover/entry:opacity-100"
:message="decodeXML(logEntry.message)"
:message="() => decodeXML(stripAnsi(logEntry.message))"
:log-entry="logEntry"
/>
</div>
@@ -17,10 +17,15 @@
<script lang="ts" setup>
import { SimpleLogEntry } from "@/models/LogEntry";
import { decodeXML } from "entities";
import AnsiConvertor from "ansi-to-html";
import stripAnsi from "strip-ansi";
const ansiConvertor = new AnsiConvertor({ escapeXML: false, fg: "var(--base-content-color)" });
defineProps<{
logEntry: SimpleLogEntry;
}>();
const { markSearch } = useSearchFilter();
const colorize = (value: string) => markSearch(ansiConvertor.toHtml(value));
</script>
+6 -5
View File
@@ -20,18 +20,19 @@ let glopbalShow = globalShowPopup();
let show = ref(glopbalShow.value);
let delayedShow = refDebounced(show, 1000);
let content: HTMLElement | null = $ref(null);
let content = ref<HTMLElement>();
const onMouseEnter = (e: Event) => {
show.value = true;
glopbalShow.value = true;
if (e.target && content && e.target instanceof Element) {
if (content.value && e.target instanceof HTMLElement) {
const { left, top, width } = e.target.getBoundingClientRect();
const x = left + width + 10;
const y = top;
content.style.left = `${x}px`;
content.style.top = `${y}px`;
content.value.style.left = `${x}px`;
content.value.style.top = `${y}px`;
}
};
@@ -40,7 +41,7 @@ const onMouseLeave = () => {
glopbalShow.value = false;
};
const el = useCurrentElement();
const el: Ref<HTMLElement> = useCurrentElement();
useEventListener(() => el.value?.nextElementSibling, "mouseenter", onMouseEnter);
useEventListener(() => el.value?.nextElementSibling, "mouseleave", onMouseLeave);
</script>
+1 -1
View File
@@ -25,7 +25,7 @@ function matchRecord(record: Record<string, any>, regex: RegExp): boolean {
export function useSearchFilter() {
const regex = $computed(() => {
const isSmartCase = debouncedSearchFilter.value === debouncedSearchFilter.value.toLowerCase();
return new RegExp(encodeXML(debouncedSearchFilter.value), isSmartCase ? "i" : undefined);
return new RegExp(encodeXML(debouncedSearchFilter.value), isSmartCase ? "ig" : "g");
});
function filteredMessages(messages: Ref<LogEntry<string | JSONObject>[]>) {
+5 -3
View File
@@ -1,8 +1,8 @@
<template>
<div>
<mobile-menu v-if="isMobile" @search="showFuzzySearch"></mobile-menu>
<mobile-menu v-if="isMobile && !forceMenuHidden" @search="showFuzzySearch"></mobile-menu>
<splitpanes @resized="onResized($event)">
<pane min-size="10" :size="menuWidth" v-if="!isMobile && !collapseNav">
<pane min-size="10" :size="menuWidth" v-if="!isMobile && !collapseNav && !forceMenuHidden">
<side-panel @search="showFuzzySearch"></side-panel>
</pane>
<pane min-size="10">
@@ -27,7 +27,7 @@
<label
class="btn btn-circle swap btn-neutral swap-rotate fixed -left-12 bottom-4 w-16 transition-all hover:-left-4"
:class="{ '!-left-6': collapseNav }"
v-if="!isMobile"
v-if="!isMobile && !forceMenuHidden"
>
<input type="checkbox" v-model="collapseNav" />
<mdi:chevron-right class="swap-on" />
@@ -79,6 +79,8 @@ const { toasts, removeToast } = useToast();
const modal = ref<HTMLDialogElement>();
const open = ref(false);
const searchParams = new URLSearchParams(window.location.search);
const forceMenuHidden = ref(searchParams.has("hideMenu"));
watch(open, () => {
if (open.value) {
+14 -30
View File
@@ -1,23 +1,5 @@
@import "splitpanes/dist/splitpanes.css";
@define-mixin light {
--base-lighter-color: 100% 0 0;
--base-color: 97% 0 0;
--base-darker-color: 90% 0 0;
--base-content-color: 33% 0 0;
--primary-color: 79.96% 0.143 176.65;
--secondary-color: 82.67% 0.15380739746702807 77.82;
}
@define-mixin dark {
--base-lighter-color: 25% 0 0;
--base-color: 18% 0 0;
--base-darker-color: 11% 0 0;
--base-content-color: 89.23% 0 0;
--primary-color: 70.96% 0.143 176.65;
--secondary-color: 91.36% 0.11098 90.1243;
}
@tailwind base;
@tailwind components;
@tailwind utilities;
@@ -41,21 +23,23 @@
--n: var(--base-lighter-color);
}
html[data-theme="dark"] {
@mixin dark;
}
@media (prefers-color-scheme: dark) {
html {
@mixin dark;
}
--base-lighter-color: 25% 0 0;
--base-color: 18% 0 0;
--base-darker-color: 11% 0 0;
--base-content-color: 89.23% 0 0;
--primary-color: 70.96% 0.143 176.65;
--secondary-color: 91.36% 0.11098 90.1243;
}
html[data-theme="light"] {
@mixin light;
}
@media (prefers-color-scheme: light) {
html {
@mixin light;
}
--base-lighter-color: 100% 0 0;
--base-color: 97% 0 0;
--base-darker-color: 90% 0 0;
--base-content-color: 33% 0 0;
--primary-color: 79.96% 0.143 176.65;
--secondary-color: 82.67% 0.15380739746702807 77.82;
}
@media screen and (max-device-width: 480px) {
body {
-webkit-text-size-adjust: 100%;
+6 -1
View File
@@ -47,6 +47,7 @@ let error = $ref(false);
let username = $ref("");
let password = $ref("");
let form: HTMLFormElement | undefined = $ref();
const params = new URLSearchParams(window.location.search);
async function onLogin() {
const url = config.authProvider === "simple" ? "/api/token" : "/api/validateCredentials";
@@ -57,7 +58,11 @@ async function onLogin() {
if (response.status == 200) {
error = false;
window.location.href = withBase("/");
if (params.has("redirectUrl")) {
window.location.href = withBase(params.get("redirectUrl")!);
} else {
window.location.href = withBase("/");
}
} else {
error = true;
}
+1 -1
View File
@@ -58,7 +58,7 @@ services:
playwright:
container_name: playwright
image: mcr.microsoft.com/playwright:v1.41.2-jammy
image: mcr.microsoft.com/playwright:v1.42.1-jammy
working_dir: /app
volumes:
- .:/app
+3 -5
View File
@@ -4,12 +4,12 @@ title: Changing Application Base
# Changing Dozzle Base
Dozzle by default mounts to "/". This can be changed with the `--base` flag. For example, if you want to mount to "/foobar" then you can use `--base foobar` or the env variable `DOZZLE_BASE`.
Dozzle by default mounts to "/". This can be changed with the `--base` flag. For example, if you want to mount to "/foobar" then you can use `--base /foobar` or the env variable `DOZZLE_BASE`.
::: code-group
```sh
docker run --volume=/var/run/docker.sock:/var/run/docker.sock -p 8080:8080 amir20/dozzle --base foobar
docker run --volume=/var/run/docker.sock:/var/run/docker.sock -p 8080:8080 amir20/dozzle --base /foobar
```
```yaml [docker-compose.yml]
@@ -22,7 +22,7 @@ services:
ports:
- 8080:8080
environment:
DOZZLE_BASE: foobar
DOZZLE_BASE: /foobar
```
:::
@@ -35,8 +35,6 @@ Here is an example with Nginx and proxy Dozzle with a different base:
```conf
location ^~ /foobar/ {
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;
set $upstream_app dozzle;
set $upstream_port 8080;
set $upstream_proto http;
+4 -4
View File
@@ -3,11 +3,11 @@
"type": "module",
"name": "docs",
"devDependencies": {
"@unocss/preset-typography": "^0.58.5",
"@unocss/reset": "^0.58.5",
"@unocss/transformer-directives": "^0.58.5",
"@unocss/preset-typography": "^0.58.7",
"@unocss/reset": "^0.58.7",
"@unocss/transformer-directives": "^0.58.7",
"dozzle": "workspace:*",
"sitemap": "^7.1.1",
"unocss": "^0.58.5"
"unocss": "^0.58.7"
}
}
+254 -267
View File
@@ -6,14 +6,14 @@ settings:
devDependencies:
'@unocss/preset-typography':
specifier: ^0.58.5
version: 0.58.5
specifier: ^0.58.7
version: 0.58.7
'@unocss/reset':
specifier: ^0.58.5
version: 0.58.5
specifier: ^0.58.7
version: 0.58.7
'@unocss/transformer-directives':
specifier: ^0.58.5
version: 0.58.5
specifier: ^0.58.7
version: 0.58.7
dozzle:
specifier: workspace:*
version: link:..
@@ -21,17 +21,17 @@ devDependencies:
specifier: ^7.1.1
version: 7.1.1
unocss:
specifier: ^0.58.5
version: 0.58.5(postcss@8.4.32)(vite@5.0.10)
specifier: ^0.58.7
version: 0.58.7(postcss@8.4.32)(vite@5.0.10)
packages:
/@ampproject/remapping@2.2.1:
resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==}
/@ampproject/remapping@2.3.0:
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
engines: {node: '>=6.0.0'}
dependencies:
'@jridgewell/gen-mapping': 0.3.3
'@jridgewell/trace-mapping': 0.3.20
'@jridgewell/gen-mapping': 0.3.5
'@jridgewell/trace-mapping': 0.3.25
dev: true
/@antfu/install-pkg@0.1.1:
@@ -45,12 +45,12 @@ packages:
resolution: {integrity: sha512-gFPqTG7otEJ8uP6wrhDv6mqwGWYZKNvAcCq6u9hOj0c+IKCEsY4L1oC9trPq2SaWIzAfHvqfBDxF591JkMf+kg==}
dev: true
/@babel/code-frame@7.23.5:
resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==}
/@babel/code-frame@7.24.2:
resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/highlight': 7.23.4
chalk: 2.4.2
'@babel/highlight': 7.24.2
picocolors: 1.0.0
dev: true
/@babel/compat-data@7.23.5:
@@ -58,20 +58,20 @@ packages:
engines: {node: '>=6.9.0'}
dev: true
/@babel/core@7.23.9:
resolution: {integrity: sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==}
/@babel/core@7.24.3:
resolution: {integrity: sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==}
engines: {node: '>=6.9.0'}
dependencies:
'@ampproject/remapping': 2.2.1
'@babel/code-frame': 7.23.5
'@babel/generator': 7.23.6
'@ampproject/remapping': 2.3.0
'@babel/code-frame': 7.24.2
'@babel/generator': 7.24.1
'@babel/helper-compilation-targets': 7.23.6
'@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.9)
'@babel/helpers': 7.23.9
'@babel/parser': 7.23.9
'@babel/template': 7.23.9
'@babel/traverse': 7.23.9
'@babel/types': 7.23.9
'@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3)
'@babel/helpers': 7.24.1
'@babel/parser': 7.24.1
'@babel/template': 7.24.0
'@babel/traverse': 7.24.1
'@babel/types': 7.24.0
convert-source-map: 2.0.0
debug: 4.3.4
gensync: 1.0.0-beta.2
@@ -81,13 +81,13 @@ packages:
- supports-color
dev: true
/@babel/generator@7.23.6:
resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==}
/@babel/generator@7.24.1:
resolution: {integrity: sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.23.9
'@jridgewell/gen-mapping': 0.3.3
'@jridgewell/trace-mapping': 0.3.20
'@babel/types': 7.24.0
'@jridgewell/gen-mapping': 0.3.5
'@jridgewell/trace-mapping': 0.3.25
jsesc: 2.5.2
dev: true
@@ -95,7 +95,7 @@ packages:
resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.23.6
'@babel/types': 7.24.0
dev: true
/@babel/helper-compilation-targets@7.23.6:
@@ -109,19 +109,19 @@ packages:
semver: 6.3.1
dev: true
/@babel/helper-create-class-features-plugin@7.23.7(@babel/core@7.23.9):
resolution: {integrity: sha512-xCoqR/8+BoNnXOY7RVSgv6X+o7pmT5q1d+gGcRlXYkI+9B31glE4jeejhKVpA04O1AtzOt7OSQ6VYKP5FcRl9g==}
/@babel/helper-create-class-features-plugin@7.24.1(@babel/core@7.24.3):
resolution: {integrity: sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
'@babel/core': 7.23.9
'@babel/core': 7.24.3
'@babel/helper-annotate-as-pure': 7.22.5
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-function-name': 7.23.0
'@babel/helper-member-expression-to-functions': 7.23.0
'@babel/helper-optimise-call-expression': 7.22.5
'@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.9)
'@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.3)
'@babel/helper-skip-transparent-expression-wrappers': 7.22.5
'@babel/helper-split-export-declaration': 7.22.6
semver: 6.3.1
@@ -136,38 +136,38 @@ packages:
resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/template': 7.23.9
'@babel/types': 7.23.9
'@babel/template': 7.24.0
'@babel/types': 7.24.0
dev: true
/@babel/helper-hoist-variables@7.22.5:
resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.23.9
'@babel/types': 7.24.0
dev: true
/@babel/helper-member-expression-to-functions@7.23.0:
resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.23.6
'@babel/types': 7.24.0
dev: true
/@babel/helper-module-imports@7.22.15:
resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.23.9
'@babel/types': 7.24.0
dev: true
/@babel/helper-module-transforms@7.23.3(@babel/core@7.23.9):
/@babel/helper-module-transforms@7.23.3(@babel/core@7.24.3):
resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
'@babel/core': 7.23.9
'@babel/core': 7.24.3
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-module-imports': 7.22.15
'@babel/helper-simple-access': 7.22.5
@@ -179,21 +179,21 @@ packages:
resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.23.6
'@babel/types': 7.24.0
dev: true
/@babel/helper-plugin-utils@7.22.5:
resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==}
/@babel/helper-plugin-utils@7.24.0:
resolution: {integrity: sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==}
engines: {node: '>=6.9.0'}
dev: true
/@babel/helper-replace-supers@7.22.20(@babel/core@7.23.9):
resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==}
/@babel/helper-replace-supers@7.24.1(@babel/core@7.24.3):
resolution: {integrity: sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
'@babel/core': 7.23.9
'@babel/core': 7.24.3
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-member-expression-to-functions': 7.23.0
'@babel/helper-optimise-call-expression': 7.22.5
@@ -203,21 +203,21 @@ packages:
resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.23.9
'@babel/types': 7.24.0
dev: true
/@babel/helper-skip-transparent-expression-wrappers@7.22.5:
resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.23.6
'@babel/types': 7.24.0
dev: true
/@babel/helper-split-export-declaration@7.22.6:
resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.23.9
'@babel/types': 7.24.0
dev: true
/@babel/helper-string-parser@7.23.4:
@@ -235,131 +235,123 @@ packages:
engines: {node: '>=6.9.0'}
dev: true
/@babel/helpers@7.23.9:
resolution: {integrity: sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==}
/@babel/helpers@7.24.1:
resolution: {integrity: sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/template': 7.23.9
'@babel/traverse': 7.23.9
'@babel/types': 7.23.9
'@babel/template': 7.24.0
'@babel/traverse': 7.24.1
'@babel/types': 7.24.0
transitivePeerDependencies:
- supports-color
dev: true
/@babel/highlight@7.23.4:
resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==}
/@babel/highlight@7.24.2:
resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/helper-validator-identifier': 7.22.20
chalk: 2.4.2
js-tokens: 4.0.0
picocolors: 1.0.0
dev: true
/@babel/parser@7.23.9:
resolution: {integrity: sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==}
/@babel/parser@7.24.1:
resolution: {integrity: sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==}
engines: {node: '>=6.0.0'}
hasBin: true
dependencies:
'@babel/types': 7.23.9
'@babel/types': 7.24.0
dev: true
/@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.23.9):
resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==}
/@babel/plugin-syntax-jsx@7.24.1(@babel/core@7.24.3):
resolution: {integrity: sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.23.9
'@babel/helper-plugin-utils': 7.22.5
'@babel/core': 7.24.3
'@babel/helper-plugin-utils': 7.24.0
dev: true
/@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.23.9):
resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==}
/@babel/plugin-syntax-typescript@7.24.1(@babel/core@7.24.3):
resolution: {integrity: sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.23.9
'@babel/helper-plugin-utils': 7.22.5
'@babel/core': 7.24.3
'@babel/helper-plugin-utils': 7.24.0
dev: true
/@babel/plugin-transform-modules-commonjs@7.23.3(@babel/core@7.23.9):
resolution: {integrity: sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==}
/@babel/plugin-transform-modules-commonjs@7.24.1(@babel/core@7.24.3):
resolution: {integrity: sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.23.9
'@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.9)
'@babel/helper-plugin-utils': 7.22.5
'@babel/core': 7.24.3
'@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3)
'@babel/helper-plugin-utils': 7.24.0
'@babel/helper-simple-access': 7.22.5
dev: true
/@babel/plugin-transform-typescript@7.23.6(@babel/core@7.23.9):
resolution: {integrity: sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==}
/@babel/plugin-transform-typescript@7.24.1(@babel/core@7.24.3):
resolution: {integrity: sha512-liYSESjX2fZ7JyBFkYG78nfvHlMKE6IpNdTVnxmlYUR+j5ZLsitFbaAE+eJSK2zPPkNWNw4mXL51rQ8WrvdK0w==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.23.9
'@babel/core': 7.24.3
'@babel/helper-annotate-as-pure': 7.22.5
'@babel/helper-create-class-features-plugin': 7.23.7(@babel/core@7.23.9)
'@babel/helper-plugin-utils': 7.22.5
'@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.9)
'@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.3)
'@babel/helper-plugin-utils': 7.24.0
'@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.3)
dev: true
/@babel/preset-typescript@7.23.3(@babel/core@7.23.9):
resolution: {integrity: sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==}
/@babel/preset-typescript@7.24.1(@babel/core@7.24.3):
resolution: {integrity: sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.23.9
'@babel/helper-plugin-utils': 7.22.5
'@babel/core': 7.24.3
'@babel/helper-plugin-utils': 7.24.0
'@babel/helper-validator-option': 7.23.5
'@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.9)
'@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.23.9)
'@babel/plugin-transform-typescript': 7.23.6(@babel/core@7.23.9)
'@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.3)
'@babel/plugin-transform-modules-commonjs': 7.24.1(@babel/core@7.24.3)
'@babel/plugin-transform-typescript': 7.24.1(@babel/core@7.24.3)
dev: true
/@babel/template@7.23.9:
resolution: {integrity: sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==}
/@babel/template@7.24.0:
resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/code-frame': 7.23.5
'@babel/parser': 7.23.9
'@babel/types': 7.23.9
'@babel/code-frame': 7.24.2
'@babel/parser': 7.24.1
'@babel/types': 7.24.0
dev: true
/@babel/traverse@7.23.9:
resolution: {integrity: sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==}
/@babel/traverse@7.24.1:
resolution: {integrity: sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/code-frame': 7.23.5
'@babel/generator': 7.23.6
'@babel/code-frame': 7.24.2
'@babel/generator': 7.24.1
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-function-name': 7.23.0
'@babel/helper-hoist-variables': 7.22.5
'@babel/helper-split-export-declaration': 7.22.6
'@babel/parser': 7.23.9
'@babel/types': 7.23.9
'@babel/parser': 7.24.1
'@babel/types': 7.24.0
debug: 4.3.4
globals: 11.12.0
transitivePeerDependencies:
- supports-color
dev: true
/@babel/types@7.23.6:
resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/helper-string-parser': 7.23.4
'@babel/helper-validator-identifier': 7.22.20
to-fast-properties: 2.0.0
dev: true
/@babel/types@7.23.9:
resolution: {integrity: sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==}
/@babel/types@7.24.0:
resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/helper-string-parser': 7.23.4
@@ -592,13 +584,13 @@ packages:
- supports-color
dev: true
/@jridgewell/gen-mapping@0.3.3:
resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
/@jridgewell/gen-mapping@0.3.5:
resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
engines: {node: '>=6.0.0'}
dependencies:
'@jridgewell/set-array': 1.1.2
'@jridgewell/set-array': 1.2.1
'@jridgewell/sourcemap-codec': 1.4.15
'@jridgewell/trace-mapping': 0.3.20
'@jridgewell/trace-mapping': 0.3.25
dev: true
/@jridgewell/resolve-uri@3.1.1:
@@ -606,8 +598,8 @@ packages:
engines: {node: '>=6.0.0'}
dev: true
/@jridgewell/set-array@1.1.2:
resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
/@jridgewell/set-array@1.2.1:
resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
engines: {node: '>=6.0.0'}
dev: true
@@ -615,8 +607,8 @@ packages:
resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
dev: true
/@jridgewell/trace-mapping@0.3.20:
resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==}
/@jridgewell/trace-mapping@0.3.25:
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
dependencies:
'@jridgewell/resolve-uri': 3.1.1
'@jridgewell/sourcemap-codec': 1.4.15
@@ -779,215 +771,215 @@ packages:
'@types/node': 17.0.45
dev: true
/@unocss/astro@0.58.5(vite@5.0.10):
resolution: {integrity: sha512-LtuVnj8oFAK9663OVhQO8KpdJFiOyyPsYfnOZlDCOFK3gHb/2WMrzdBwr1w8LoQF3bDedkFMKirVF7gWjyZiaw==}
/@unocss/astro@0.58.7(vite@5.0.10):
resolution: {integrity: sha512-htqhe+Qn9UUnND214LlwS8a9Ib0hzO+IxY79cz1GDYoDV+Z4ONXCkUxLLlnnBM/HupWKOu+bdBWWVGIOHAniig==}
peerDependencies:
vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0
peerDependenciesMeta:
vite:
optional: true
dependencies:
'@unocss/core': 0.58.5
'@unocss/reset': 0.58.5
'@unocss/vite': 0.58.5(vite@5.0.10)
'@unocss/core': 0.58.7
'@unocss/reset': 0.58.7
'@unocss/vite': 0.58.7(vite@5.0.10)
vite: 5.0.10
transitivePeerDependencies:
- rollup
dev: true
/@unocss/cli@0.58.5:
resolution: {integrity: sha512-FzVVXO9ghsGtJpu9uR4o7JeM9gUfWNbVZZ/IfH+0WbDJuyx4rO/jwN55z0yA5QDkhvOz9DvzwPCBzLpTJ5q+Lw==}
/@unocss/cli@0.58.7:
resolution: {integrity: sha512-Vr5LABxFvZa8K71qVOnP7FkSA14/xEqhVOO+KZzcZafdW3TCvWa/dr3Lr5mDUufY82s5/5KGFosVQWQymA8HMg==}
engines: {node: '>=14'}
hasBin: true
dependencies:
'@ampproject/remapping': 2.2.1
'@ampproject/remapping': 2.3.0
'@rollup/pluginutils': 5.1.0
'@unocss/config': 0.58.5
'@unocss/core': 0.58.5
'@unocss/preset-uno': 0.58.5
'@unocss/config': 0.58.7
'@unocss/core': 0.58.7
'@unocss/preset-uno': 0.58.7
cac: 6.7.14
chokidar: 3.5.3
chokidar: 3.6.0
colorette: 2.0.20
consola: 3.2.3
fast-glob: 3.3.2
magic-string: 0.30.6
magic-string: 0.30.8
pathe: 1.1.2
perfect-debounce: 1.0.0
transitivePeerDependencies:
- rollup
dev: true
/@unocss/config@0.58.5:
resolution: {integrity: sha512-O1pLSeNXfG11QHaLSVwS9rJKvE4b9304IQ3UvOdbYN+7SAT4YTZ7JDU4ngO1KWyOFBO6RD0WspCR95pgqOqJiQ==}
/@unocss/config@0.58.7:
resolution: {integrity: sha512-ZMSFWJI8DfE/4HiIU+hkTSKUtEkennRn+raej5HCGTfy5xpdYCm9Zdrw/cYqkN2LPHM8o076Z2sD6H4MV5HrvA==}
engines: {node: '>=14'}
dependencies:
'@unocss/core': 0.58.5
'@unocss/core': 0.58.7
unconfig: 0.3.11
dev: true
/@unocss/core@0.58.5:
resolution: {integrity: sha512-qbPqL+46hf1/UelQOwUwpAuvm6buoss43DPYHOPdfNJ+NTWkSpATQMF0JKT04QE0QRQbHNSHdMe9ariG+IIlCw==}
/@unocss/core@0.58.7:
resolution: {integrity: sha512-Df5ytibV0MB7kWLggzLHsJUj08Of2oqXmPg7QjRUghMvCT3dl2LUIZXiztYPMH0F4x0cPebNoa/pavNt8xz9eQ==}
dev: true
/@unocss/extractor-arbitrary-variants@0.58.5:
resolution: {integrity: sha512-KJQX0OJKzy4YjJo09h2la2Q+cn5IJ1JdyPVJJkzovHnv7jSBWzsfct+bj/6a+SJ4p4JBIqEJz3M/qxHv4EPJyA==}
/@unocss/extractor-arbitrary-variants@0.58.7:
resolution: {integrity: sha512-wEuilON0u/e1milNp1UBWGps3Hdtm9qBfmc2YmsHN8KhpTSSCluzbrLSYfF++tU5iWmVWR2514Lc2waVDhuiwg==}
dependencies:
'@unocss/core': 0.58.5
'@unocss/core': 0.58.7
dev: true
/@unocss/inspector@0.58.5:
resolution: {integrity: sha512-cbJlIHEZ14puTtttf7sl+VZFDscV1DJiSseh9sSe0xJ/1NVBT9Bvkm09/1tnpLYAgF5gfa1CaCcjKmURgYzKrA==}
/@unocss/inspector@0.58.7:
resolution: {integrity: sha512-5vYsAuOj4ODgCm2Hmfhgcih+MdjsOxAHpUUDcZKAuVkr5j4dmrQnjWmS0fafR5vcjQch6T1JTsPE9x/Ws51UIw==}
dependencies:
'@unocss/core': 0.58.5
'@unocss/rule-utils': 0.58.5
'@unocss/core': 0.58.7
'@unocss/rule-utils': 0.58.7
gzip-size: 6.0.0
sirv: 2.0.4
dev: true
/@unocss/postcss@0.58.5(postcss@8.4.32):
resolution: {integrity: sha512-m4L2YRdYfT6CV306Kl2VwEwbqa/92EpW4GE2Kqak1RuJyFJXBnWEEMJV4Uy6B1jWKLlCEWkuVUW33JUg7X6BxQ==}
/@unocss/postcss@0.58.7(postcss@8.4.32):
resolution: {integrity: sha512-4UhYTj7AaCDJKPEa9GX9L9dnH+6ci04i9ZYdNdu+Pvbki2Q2wAa2FwqLwH7+6WgWm10b9AXVacExw+4hC2reOg==}
engines: {node: '>=14'}
peerDependencies:
postcss: ^8.4.21
dependencies:
'@unocss/config': 0.58.5
'@unocss/core': 0.58.5
'@unocss/rule-utils': 0.58.5
'@unocss/config': 0.58.7
'@unocss/core': 0.58.7
'@unocss/rule-utils': 0.58.7
css-tree: 2.3.1
fast-glob: 3.3.2
magic-string: 0.30.6
magic-string: 0.30.8
postcss: 8.4.32
dev: true
/@unocss/preset-attributify@0.58.5:
resolution: {integrity: sha512-OR4gUHamHCb4/LB/zZHlibaraTyILfFvRIzgmJnEb6lITGApQUl86qaJcTbTyfTfLVRufLG/JVeuz2HLUBPRXw==}
/@unocss/preset-attributify@0.58.7:
resolution: {integrity: sha512-WmhrRSOAhbKn+q7A65Kg/49YDZOqfKxj+VZvngwjzDmSfZcr9BHhc67eg9IOF4OPHdKw/3rhSvA+FTMGre2Lpw==}
dependencies:
'@unocss/core': 0.58.5
'@unocss/core': 0.58.7
dev: true
/@unocss/preset-icons@0.58.5:
resolution: {integrity: sha512-LDNXavHtWaIvMvBezT9O8yiqHJChVCEfTRO6YFVY0yy+wo5jHiuMh6iKeHVcwbYdn3NqHYmpi7b/hrXPMtODzA==}
/@unocss/preset-icons@0.58.7:
resolution: {integrity: sha512-GeFaWiWGDktRs9TKqT4gb78Cjo7qlatOTijfJ1Zoyd3QMfbg7mRJPZGgHnLtpwYju+QKxG618fwlGvzARKhNfg==}
dependencies:
'@iconify/utils': 2.1.22
'@unocss/core': 0.58.5
ofetch: 1.3.3
'@unocss/core': 0.58.7
ofetch: 1.3.4
transitivePeerDependencies:
- supports-color
dev: true
/@unocss/preset-mini@0.58.5:
resolution: {integrity: sha512-WqD31fKUAN28OCUOyi1uremmLk0eTMqtCizjbbXsY/DP6RKYUT7trFAtppTcHWFhSQcknb4FURfAZppACsTVQQ==}
/@unocss/preset-mini@0.58.7:
resolution: {integrity: sha512-ktfrMlOtnks9j1r1ZJFzPcmCbWRjOfXh7UwoGYhH7c3Fi9Zbn1HI9+wblroEBstvbGUZGyaH5Ht+0rCmRrg5HQ==}
dependencies:
'@unocss/core': 0.58.5
'@unocss/extractor-arbitrary-variants': 0.58.5
'@unocss/rule-utils': 0.58.5
'@unocss/core': 0.58.7
'@unocss/extractor-arbitrary-variants': 0.58.7
'@unocss/rule-utils': 0.58.7
dev: true
/@unocss/preset-tagify@0.58.5:
resolution: {integrity: sha512-UB9IXi8vA/SzmmRLMWR7bzeBpxpiRo7y9xk3ruvDddYlsyiwIeDIMwG23YtcA6q41FDQvkrmvTxUEH9LFlv6aA==}
/@unocss/preset-tagify@0.58.7:
resolution: {integrity: sha512-IDR9+QDgPjcANRIWzlmubPPtgYTXGxWFqrEfRyz7ZQ4YLiA2sSLpVyOwOBW5mP7Bl2hF5oGlTKYyprk4pRzyUA==}
dependencies:
'@unocss/core': 0.58.5
'@unocss/core': 0.58.7
dev: true
/@unocss/preset-typography@0.58.5:
resolution: {integrity: sha512-rFny4a9yxgY34XOom5euCqQaOLV8PpbTg0Pn+5FelUMG4OfMevTwBCe9JttFJcUc3cNTL2enkzIdMa3l66114g==}
/@unocss/preset-typography@0.58.7:
resolution: {integrity: sha512-GCZGrFGBJO/k9widlpRvCKoouRaprgvNtt8mKpv38ToDSWexMZcaOTZHpKUPgljmjJ5As7ASwmDvjv6uiM5uYg==}
dependencies:
'@unocss/core': 0.58.5
'@unocss/preset-mini': 0.58.5
'@unocss/core': 0.58.7
'@unocss/preset-mini': 0.58.7
dev: true
/@unocss/preset-uno@0.58.5:
resolution: {integrity: sha512-vgq/R4f7RDmdROy+pX+PeE38I3SgYKd4LL7Wb1HJUaVwz7PkF0XHCynOTbwrPXnK1kp1cnZYYEww7/RiYp+IQQ==}
/@unocss/preset-uno@0.58.7:
resolution: {integrity: sha512-oirPRtIailoewLvim/VjcxHZrBotRzBNaFZFMD1GLwScAYrzS8DWJ3pozNn7+s2E80ZUBfgekRTgvUKAFMPSCw==}
dependencies:
'@unocss/core': 0.58.5
'@unocss/preset-mini': 0.58.5
'@unocss/preset-wind': 0.58.5
'@unocss/rule-utils': 0.58.5
'@unocss/core': 0.58.7
'@unocss/preset-mini': 0.58.7
'@unocss/preset-wind': 0.58.7
'@unocss/rule-utils': 0.58.7
dev: true
/@unocss/preset-web-fonts@0.58.5:
resolution: {integrity: sha512-WKZ5raSClFXhqzfAhApef3+fuMq6cjKBxvhJ1FBIxFKcSOvN8e2czty2iGQVl02yMsxBWMv0Bpfm7np+cCoI1w==}
/@unocss/preset-web-fonts@0.58.7:
resolution: {integrity: sha512-97BhHYFudIVmMmLIZl3nA6puFLr2EEgG3xxR8Sa2Ox2sFL46D6oZrsxg9qr73QdJNOU3qk7HtnCn0+rozDrixg==}
dependencies:
'@unocss/core': 0.58.5
ofetch: 1.3.3
'@unocss/core': 0.58.7
ofetch: 1.3.4
dev: true
/@unocss/preset-wind@0.58.5:
resolution: {integrity: sha512-54RkjLmlqMUlC8o8nDCVzB25D1zzK4eth+/3uQzt739qU0U92NxuZKY21ADj9Rp/mVhKBV5FKuXPjmYc6yTQRQ==}
/@unocss/preset-wind@0.58.7:
resolution: {integrity: sha512-rELMKcd/cwMnw6fPf/dmg63u41fRXJoXDO5rlO/+Fa8DF4/r8KJTUbjJbZfcOnh3n8jHz3NUz+QigdRBuDTEuw==}
dependencies:
'@unocss/core': 0.58.5
'@unocss/preset-mini': 0.58.5
'@unocss/rule-utils': 0.58.5
'@unocss/core': 0.58.7
'@unocss/preset-mini': 0.58.7
'@unocss/rule-utils': 0.58.7
dev: true
/@unocss/reset@0.58.5:
resolution: {integrity: sha512-2wMrkCj3SSb5hrx9TKs5jZa34QIRkHv9FotbJutAPo7o8hx+XXn56ogzdoUrcFPJZJUx2R2nyOVbSlGMIjtFtw==}
/@unocss/reset@0.58.7:
resolution: {integrity: sha512-KiN5u5D4zJcU0Tg+wjgTWYIm8VEfHpi7t2a3YfNCLo9s/75Ty4tlYB9StEShYmVMCXBOu0mK1CwqQTNaFpfM1w==}
dev: true
/@unocss/rule-utils@0.58.5:
resolution: {integrity: sha512-w0sGJoeUGwMWLVFLEE9PDiv/fQcQqZnTIIQLYNCjTdqXDRlwTp9ACW0h47x/hAAIXdOtEOOBuTfjGD79GznUmA==}
/@unocss/rule-utils@0.58.7:
resolution: {integrity: sha512-SbMwAUSgx5v4TXy+MXiWbqzoMjVHSeMaJpJOruU9PmtrOuZmqeajffMtI6pLtGlgrEL76frLRyMmSErxhyNelw==}
engines: {node: '>=14'}
dependencies:
'@unocss/core': 0.58.5
magic-string: 0.30.6
'@unocss/core': 0.58.7
magic-string: 0.30.8
dev: true
/@unocss/scope@0.58.5:
resolution: {integrity: sha512-vSentagAwYTnThGRCjzZ6eNSSRuzdWBl21L1BbvVNM91Ss/FugQnZ1hd0m3TrVvvStYXnFVHMQ/MjCAEJ4cMYg==}
/@unocss/scope@0.58.7:
resolution: {integrity: sha512-DaAHFT3azxq5eFiTRrDAqk8TSDlo6x5ImBowzdNO4B2QMt+o1X9uhbe8Qt+WlG3MOwhti87JT8ooNA1pzi3Iig==}
dev: true
/@unocss/transformer-attributify-jsx-babel@0.58.5:
resolution: {integrity: sha512-IAWSSKN3V0D87DE8bqaaPrZBWOdWQ06QNfi9vRuQJfRWOui87ezi9+NffjcnQw/ap9xMk1O6z74/WOW3zo6uYA==}
/@unocss/transformer-attributify-jsx-babel@0.58.7:
resolution: {integrity: sha512-IxEPQG7Kn+NgYEogOSKfqfGMQR7WU8X2DctaGBoQlizMiDr+q9DXM1dgGU0bXMxnSpRF8DYFHvgHefRnNUUVPg==}
dependencies:
'@babel/core': 7.23.9
'@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.9)
'@babel/preset-typescript': 7.23.3(@babel/core@7.23.9)
'@unocss/core': 0.58.5
'@babel/core': 7.24.3
'@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.3)
'@babel/preset-typescript': 7.24.1(@babel/core@7.24.3)
'@unocss/core': 0.58.7
transitivePeerDependencies:
- supports-color
dev: true
/@unocss/transformer-attributify-jsx@0.58.5:
resolution: {integrity: sha512-sItEALyvAt3PZLd9Q1tlIATjaj3kWbS/qI3otUVsYBdZjP4UudzJ3D1fcWNL2WPlgz8KtlVzRUuxob8TQ4ibZg==}
/@unocss/transformer-attributify-jsx@0.58.7:
resolution: {integrity: sha512-6kVTHvcTdlKpvXuXRgUPKFTTWFxJH0OL6N77x2WZgbDQc40mv95JIUCVBA8EnpRyGGTQi3yasiXIS7Ur2UmsbA==}
dependencies:
'@unocss/core': 0.58.5
'@unocss/core': 0.58.7
dev: true
/@unocss/transformer-compile-class@0.58.5:
resolution: {integrity: sha512-4MaxjaZo1rf5uHvDGa2mbnXxAYVYoj1+oRNpL4fE3FoExS1Ka2CiNGQn/S4bHMF51vmXMSWtOzurJpPD4BaJUQ==}
/@unocss/transformer-compile-class@0.58.7:
resolution: {integrity: sha512-+IWWA9/hmaZIjxB4JY3fuWuK4fAMV/uoi0T3kANDOnK/HUmX5pUF9oTzC3LBa+1SwzZiMoTJgiQEGKv1qa2QjQ==}
dependencies:
'@unocss/core': 0.58.5
'@unocss/core': 0.58.7
dev: true
/@unocss/transformer-directives@0.58.5:
resolution: {integrity: sha512-allspF5TlT1B2bJSZ1houHScXOTaTPlatLiEmgQKzr/m93rCvktokaO5J6qeN2VXQdpTIsxdA5B8//7UkfTuIA==}
/@unocss/transformer-directives@0.58.7:
resolution: {integrity: sha512-vMn86ARgrhCd+bZf1qvwBWhvQnOkAwOXbFGHM2cuuC0VVGJQcRE+dwTnUEJ5iqKGUNFWPJ/7NaV47kh58YITcg==}
dependencies:
'@unocss/core': 0.58.5
'@unocss/rule-utils': 0.58.5
'@unocss/core': 0.58.7
'@unocss/rule-utils': 0.58.7
css-tree: 2.3.1
dev: true
/@unocss/transformer-variant-group@0.58.5:
resolution: {integrity: sha512-SjUwGzKK5CVqn7Gg+3v3hV47ZUll7GcGu0vR3RCLO4gqEfFlZWMTHml1Sl2sY1WAca2iVcDRu+dp0RLxRG/dUA==}
/@unocss/transformer-variant-group@0.58.7:
resolution: {integrity: sha512-9yGvrecxvY6wEc1tV4AsUDMNbj8xWk6aJ3LyZNzxOzmxmNUNAIK+y81/Hp7djn+w0ck6ss/uo6Ug7tGX+0bKUw==}
dependencies:
'@unocss/core': 0.58.5
'@unocss/core': 0.58.7
dev: true
/@unocss/vite@0.58.5(vite@5.0.10):
resolution: {integrity: sha512-p4o1XNX1rvjmoUqSSdua8XyWNg/d+YUChDd2L/xEty+6j2qv0wUaohs3UQ87vWlv632/UmgdX+2MbrgtqthCtw==}
/@unocss/vite@0.58.7(vite@5.0.10):
resolution: {integrity: sha512-S8TJojR1/7O9Sfykj2k4yOq6gZOnjMNZq5ug/6edA11Q/gz2WrT/sx6aPcfIm3xVBnmLxaHfy3r06W+SiIbZcg==}
peerDependencies:
vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0
dependencies:
'@ampproject/remapping': 2.2.1
'@ampproject/remapping': 2.3.0
'@rollup/pluginutils': 5.1.0
'@unocss/config': 0.58.5
'@unocss/core': 0.58.5
'@unocss/inspector': 0.58.5
'@unocss/scope': 0.58.5
'@unocss/transformer-directives': 0.58.5
chokidar: 3.5.3
'@unocss/config': 0.58.7
'@unocss/core': 0.58.7
'@unocss/inspector': 0.58.7
'@unocss/scope': 0.58.7
'@unocss/transformer-directives': 0.58.7
chokidar: 3.6.0
fast-glob: 3.3.2
magic-string: 0.30.6
magic-string: 0.30.8
vite: 5.0.10
transitivePeerDependencies:
- rollup
@@ -1059,8 +1051,8 @@ packages:
supports-color: 5.5.0
dev: true
/chokidar@3.5.3:
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
/chokidar@3.6.0:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
dependencies:
anymatch: 3.1.3
@@ -1130,8 +1122,8 @@ packages:
resolution: {integrity: sha512-Vy2wmG3NTkmHNg/kzpuvHhkqeIx3ODWqasgCRbKtbXEN0G+HpEEv9BtJLp7ZG1CZloFaC41Ah3ZFbq7aqCqMeQ==}
dev: true
/destr@2.0.2:
resolution: {integrity: sha512-65AlobnZMiCET00KaFFjUefxDX0khFA/E4myqZ7a6Sq1yZtR8+FVIvilVX66vF2uobSumxooYZChiRPCKNqhmg==}
/destr@2.0.3:
resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==}
dev: true
/duplexer@0.1.2:
@@ -1364,8 +1356,8 @@ packages:
yallist: 3.1.1
dev: true
/magic-string@0.30.6:
resolution: {integrity: sha512-n62qCLbPjNjyo+owKtveQxZFZTBm+Ms6YoGD23Wew6Vw337PElFNifQpknPruVRQV57kVShPnLGo9vWxVhpPvA==}
/magic-string@0.30.8:
resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==}
engines: {node: '>=12'}
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
@@ -1397,15 +1389,6 @@ packages:
engines: {node: '>=6'}
dev: true
/mlly@1.4.2:
resolution: {integrity: sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==}
dependencies:
acorn: 8.11.3
pathe: 1.1.2
pkg-types: 1.0.3
ufo: 1.3.2
dev: true
/mlly@1.5.0:
resolution: {integrity: sha512-NPVQvAY1xr1QoVeG0cy8yUYC7FQcOx6evl/RjT1wL5FvzPnzOysoqB/jmx/DhssT2dYa8nxECLAaFI/+gVLhDQ==}
dependencies:
@@ -1430,8 +1413,8 @@ packages:
hasBin: true
dev: true
/node-fetch-native@1.6.1:
resolution: {integrity: sha512-bW9T/uJDPAJB2YNYEpWzE54U5O3MQidXsOyTfnbKYtTtFexRvGzb1waphBN4ZwP6EcIvYYEOwW0b72BpAqydTw==}
/node-fetch-native@1.6.4:
resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==}
dev: true
/node-releases@2.0.14:
@@ -1450,12 +1433,12 @@ packages:
path-key: 3.1.1
dev: true
/ofetch@1.3.3:
resolution: {integrity: sha512-s1ZCMmQWXy4b5K/TW9i/DtiN8Ku+xCiHcjQ6/J/nDdssirrQNOoB165Zu8EqLMA2lln1JUth9a0aW9Ap2ctrUg==}
/ofetch@1.3.4:
resolution: {integrity: sha512-KLIET85ik3vhEfS+3fDlc/BAZiAp+43QEC/yCo5zkNoY2YaKvNkOaFr/6wCFgFH1kuYQM5pMNi0Tg8koiIemtw==}
dependencies:
destr: 2.0.2
node-fetch-native: 1.6.1
ufo: 1.3.2
destr: 2.0.3
node-fetch-native: 1.6.4
ufo: 1.5.3
dev: true
/onetime@5.1.2:
@@ -1649,20 +1632,24 @@ packages:
resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==}
dev: true
/ufo@1.5.3:
resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==}
dev: true
/unconfig@0.3.11:
resolution: {integrity: sha512-bV/nqePAKv71v3HdVUn6UefbsDKQWRX+bJIkiSm0+twIds6WiD2bJLWWT3i214+J/B4edufZpG2w7Y63Vbwxow==}
dependencies:
'@antfu/utils': 0.7.7
defu: 6.1.3
jiti: 1.21.0
mlly: 1.4.2
mlly: 1.5.0
dev: true
/unocss@0.58.5(postcss@8.4.32)(vite@5.0.10):
resolution: {integrity: sha512-0g4P6jLgRRNnhscxw7nQ9RHGrKJ1UPPiHPet+YT3TXUcmy4mTiYgo9+kGQf5bjyrzsELJ10cT6Qz2y6g9Tls4g==}
/unocss@0.58.7(postcss@8.4.32)(vite@5.0.10):
resolution: {integrity: sha512-WZEG5+RWlMvuMX8qOpZI9PAwBlFpRMnGlOtQV3M6BHsUbEPvC7IPx1fr4I22XizctRfNftUG3MWe5l74CcoD7Q==}
engines: {node: '>=14'}
peerDependencies:
'@unocss/webpack': 0.58.5
'@unocss/webpack': 0.58.7
vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0
peerDependenciesMeta:
'@unocss/webpack':
@@ -1670,26 +1657,26 @@ packages:
vite:
optional: true
dependencies:
'@unocss/astro': 0.58.5(vite@5.0.10)
'@unocss/cli': 0.58.5
'@unocss/core': 0.58.5
'@unocss/extractor-arbitrary-variants': 0.58.5
'@unocss/postcss': 0.58.5(postcss@8.4.32)
'@unocss/preset-attributify': 0.58.5
'@unocss/preset-icons': 0.58.5
'@unocss/preset-mini': 0.58.5
'@unocss/preset-tagify': 0.58.5
'@unocss/preset-typography': 0.58.5
'@unocss/preset-uno': 0.58.5
'@unocss/preset-web-fonts': 0.58.5
'@unocss/preset-wind': 0.58.5
'@unocss/reset': 0.58.5
'@unocss/transformer-attributify-jsx': 0.58.5
'@unocss/transformer-attributify-jsx-babel': 0.58.5
'@unocss/transformer-compile-class': 0.58.5
'@unocss/transformer-directives': 0.58.5
'@unocss/transformer-variant-group': 0.58.5
'@unocss/vite': 0.58.5(vite@5.0.10)
'@unocss/astro': 0.58.7(vite@5.0.10)
'@unocss/cli': 0.58.7
'@unocss/core': 0.58.7
'@unocss/extractor-arbitrary-variants': 0.58.7
'@unocss/postcss': 0.58.7(postcss@8.4.32)
'@unocss/preset-attributify': 0.58.7
'@unocss/preset-icons': 0.58.7
'@unocss/preset-mini': 0.58.7
'@unocss/preset-tagify': 0.58.7
'@unocss/preset-typography': 0.58.7
'@unocss/preset-uno': 0.58.7
'@unocss/preset-web-fonts': 0.58.7
'@unocss/preset-wind': 0.58.7
'@unocss/reset': 0.58.7
'@unocss/transformer-attributify-jsx': 0.58.7
'@unocss/transformer-attributify-jsx-babel': 0.58.7
'@unocss/transformer-compile-class': 0.58.7
'@unocss/transformer-directives': 0.58.7
'@unocss/transformer-variant-group': 0.58.7
'@unocss/vite': 0.58.7(vite@5.0.10)
vite: 5.0.10
transitivePeerDependencies:
- postcss
+14 -13
View File
@@ -4,7 +4,7 @@ require (
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/alexflint/go-arg v1.4.3
github.com/beme/abide v0.0.0-20190723115211-635a09831760
github.com/docker/docker v25.0.3+incompatible
github.com/docker/docker v26.0.0+incompatible
github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dustin/go-humanize v1.0.1
@@ -17,19 +17,20 @@ require (
github.com/sergi/go-diff v1.1.0 // indirect
github.com/sirupsen/logrus v1.9.3
github.com/spf13/afero v1.11.0
github.com/stretchr/objx v0.5.0 // indirect
github.com/stretchr/testify v1.8.4
golang.org/x/net v0.20.0 // indirect
golang.org/x/sys v0.16.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/stretchr/testify v1.9.0
golang.org/x/net v0.21.0 // indirect
golang.org/x/sys v0.18.0 // indirect
gopkg.in/yaml.v3 v3.0.1
)
require (
github.com/PuerkitoBio/goquery v1.8.1
github.com/go-chi/chi/v5 v5.0.11
github.com/go-chi/jwtauth/v5 v5.3.0
github.com/PuerkitoBio/goquery v1.9.1
github.com/go-chi/chi/v5 v5.0.12
github.com/go-chi/jwtauth/v5 v5.3.1
github.com/go-logfmt/logfmt v0.6.0
github.com/puzpuzpuz/xsync/v3 v3.0.2
github.com/goccy/go-json v0.10.2
github.com/puzpuzpuz/xsync/v3 v3.1.0
github.com/yuin/goldmark v1.7.0
)
@@ -43,14 +44,14 @@ require (
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/kr/pretty v0.2.1 // indirect
github.com/lestrrat-go/blackmagic v1.0.2 // indirect
github.com/lestrrat-go/httpcc v1.0.1 // indirect
github.com/lestrrat-go/httprc v1.0.4 // indirect
github.com/lestrrat-go/iter v1.0.2 // indirect
github.com/lestrrat-go/jwx/v2 v2.0.19 // indirect
github.com/lestrrat-go/jwx/v2 v2.0.20 // indirect
github.com/lestrrat-go/option v1.0.1 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/segmentio/asm v1.2.0 // indirect
@@ -60,11 +61,11 @@ require (
go.opentelemetry.io/otel/metric v1.22.0 // indirect
go.opentelemetry.io/otel/sdk v1.22.0 // indirect
go.opentelemetry.io/otel/trace v1.22.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.17.0 // indirect
gotest.tools/v3 v3.0.3 // indirect
)
go 1.22.0
go 1.22.1
+28 -35
View File
@@ -2,14 +2,13 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7O
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=
github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
github.com/PuerkitoBio/goquery v1.9.1 h1:mTL6XjbJTZdpfL+Gwl5U2h1l9yEkJjhmlTeV9VPW7UI=
github.com/PuerkitoBio/goquery v1.9.1/go.mod h1:cW1n6TmIMDoORQU5IU/P1T3tGFunOeXEpGP2WHRwkbY=
github.com/alexflint/go-arg v1.4.3 h1:9rwwEBpMXfKQKceuZfYcwuc/7YY7tWJbFsgG5cAU/uo=
github.com/alexflint/go-arg v1.4.3/go.mod h1:3PZ/wp/8HuqRZMUUgu7I+e1qcpUbvmS258mRXkFH4IA=
github.com/alexflint/go-scalar v1.1.0/go.mod h1:LoFvNMqS1CPrMVltza4LvnGKhaSpc3oyLEBUZVhhS2o=
github.com/alexflint/go-scalar v1.2.0 h1:WR7JPKkeNpnYIOfHRa7ivM21aWAdHD0gEWHCx+WQBRw=
github.com/alexflint/go-scalar v1.2.0/go.mod h1:LoFvNMqS1CPrMVltza4LvnGKhaSpc3oyLEBUZVhhS2o=
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
github.com/beme/abide v0.0.0-20190723115211-635a09831760 h1:FvTM5NSN5HYvfKpgL+8x73U5v063vHsd7AX05eV1DnM=
@@ -26,12 +25,12 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etly
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/docker v25.0.1+incompatible h1:k5TYd5rIVQRSqcTwCID+cyVA0yRg86+Pcrz1ls0/frA=
github.com/docker/docker v25.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v25.0.2+incompatible h1:/OaKeauroa10K4Nqavw4zlhcDq/WBcPMc5DbjOGgozY=
github.com/docker/docker v25.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v25.0.3+incompatible h1:D5fy/lYmY7bvZa0XTZ5/UJPljor41F+vdyJG5luQLfQ=
github.com/docker/docker v25.0.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v25.0.4+incompatible h1:XITZTrq+52tZyZxUOtFIahUf3aH367FLxJzt9vZeAF8=
github.com/docker/docker v25.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v25.0.5+incompatible h1:UmQydMduGkrD5nQde1mecF/YnSbTOaPeFIeP5C4W+DE=
github.com/docker/docker v25.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v26.0.0+incompatible h1:Ng2qi+gdKADUa/VM+6b6YaY2nlZhk/lVJiKR/2bMudU=
github.com/docker/docker v26.0.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
@@ -40,10 +39,10 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/go-chi/chi/v5 v5.0.11 h1:BnpYbFZ3T3S1WMpD79r7R5ThWX40TaFB7L31Y8xqSwA=
github.com/go-chi/chi/v5 v5.0.11/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/jwtauth/v5 v5.3.0 h1:X7RKGks1lrVeIe2omGyz47pNaNjG2YmwlRN5UKhN8qg=
github.com/go-chi/jwtauth/v5 v5.3.0/go.mod h1:2PoGm/KbnzRN9ILY6HFZAI6fTnb1gEZAKogAyqkd6fY=
github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/jwtauth/v5 v5.3.1 h1:1ePWrjVctvp1tyBq5b/2ER8Th/+RbYc7x4qNsc5rh5A=
github.com/go-chi/jwtauth/v5 v5.3.1/go.mod h1:6Fl2RRmWXs3tJYE1IQGX81FsPoGqDwq9c15j52R5q80=
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
@@ -80,12 +79,14 @@ github.com/lestrrat-go/httprc v1.0.4 h1:bAZymwoZQb+Oq8MEbyipag7iSq6YIga8Wj6GOiJG
github.com/lestrrat-go/httprc v1.0.4/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo=
github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4=
github.com/lestrrat-go/jwx/v2 v2.0.19 h1:ekv1qEZE6BVct89QA+pRF6+4pCpfVrOnEJnTnT4RXoY=
github.com/lestrrat-go/jwx/v2 v2.0.19/go.mod h1:l3im3coce1lL2cDeAjqmaR+Awx+X8Ih+2k8BuHNJ4CU=
github.com/lestrrat-go/jwx/v2 v2.0.20 h1:sAgXuWS/t8ykxS9Bi2Qtn5Qhpakw1wrcjxChudjolCc=
github.com/lestrrat-go/jwx/v2 v2.0.20/go.mod h1:UlCSmKqw+agm5BsOBfEAbTvKsEApaGNqHAEUTv5PJC4=
github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU=
github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk=
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
@@ -99,8 +100,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/puzpuzpuz/xsync/v3 v3.0.2 h1:3yESHrRFYr6xzkz61LLkvNiPFXxJEAABanTQpKbAaew=
github.com/puzpuzpuz/xsync/v3 v3.0.2/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
github.com/puzpuzpuz/xsync/v3 v3.1.0 h1:EewKT7/LNac5SLiEblJeUu8z5eERHrmRLnMQL2d7qX4=
github.com/puzpuzpuz/xsync/v3 v3.1.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
@@ -111,22 +112,18 @@ github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68=
github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.7.0 h1:EfOIvIMZIzHdB/R/zVrikYLPPwJlfMcNczJFMs1m6sA=
github.com/yuin/goldmark v1.7.0/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 h1:sv9kVfal0MK0wBMCOGr+HeJm9v803BkJxGrk2au7j08=
@@ -149,8 +146,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
@@ -163,13 +160,11 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -182,22 +177,20 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+2 -3
View File
@@ -224,7 +224,6 @@ func (d *_client) ContainerStats(ctx context.Context, id string, stats chan<- Co
return err
}
log.Debugf("starting to stream stats for: %s", id)
defer response.Body.Close()
decoder := json.NewDecoder(response.Body)
var v *types.StatsJSON
@@ -334,8 +333,8 @@ func (d *_client) ContainerLogsBetweenDates(ctx context.Context, id string, from
ShowStdout: stdType&STDOUT != 0,
ShowStderr: stdType&STDERR != 0,
Timestamps: true,
Since: from.Format(time.RFC3339),
Until: to.Format(time.RFC3339),
Since: from.Format(time.RFC3339Nano),
Until: to.Format(time.RFC3339Nano),
}
log.Debugf("fetching logs from Docker with option: %+v", options)
+15 -2
View File
@@ -28,7 +28,6 @@ func NewContainerStore(ctx context.Context, client Client) *ContainerStore {
s.wg.Add(1)
go s.init(ctx)
go s.statsCollector.StartCollecting(ctx)
return s
}
@@ -49,9 +48,23 @@ func (s *ContainerStore) Client() Client {
}
func (s *ContainerStore) Subscribe(ctx context.Context, events chan ContainerEvent) {
go func() {
if s.statsCollector.Start(context.Background()) {
log.Debug("clearing container stats as stats collector has been stopped")
s.containers.Range(func(_ string, c *Container) bool {
c.Stats.Clear()
return true
})
}
}()
s.subscribers.Store(ctx, events)
}
func (s *ContainerStore) Unsubscribe(ctx context.Context) {
s.subscribers.Delete(ctx)
s.statsCollector.Stop()
}
func (s *ContainerStore) SubscribeStats(ctx context.Context, stats chan ContainerStat) {
s.statsCollector.Subscribe(ctx, stats)
}
@@ -76,7 +89,7 @@ func (s *ContainerStore) init(ctx context.Context) {
for {
select {
case event := <-events:
log.Debugf("received event: %+v", event)
log.Tracef("received event: %+v", event)
switch event.Name {
case "start":
if container, err := s.client.FindContainer(event.ActorID); err == nil {
+4 -5
View File
@@ -82,9 +82,7 @@ func (g *EventGenerator) consumeReader() {
message, streamType, readerError := readEvent(g.reader, g.tty)
if message != "" {
logEvent := createEvent(message, streamType)
if _, ok := logEvent.Message.(string); ok {
logEvent.Message = stripANSI(logEvent.Message.(string))
}
logEvent.Level = guessLogLevel(logEvent)
g.buffer <- logEvent
}
@@ -158,7 +156,8 @@ func readEvent(reader *bufio.Reader, tty bool) (string, StdType, error) {
}
}
var validLogFmtKey = regexp.MustCompile(`^[a-zA-Z0-9_]+$`)
var validLogFmtMessage = regexp.MustCompile(`([a-zA-Z0-9_.-]+)=(?:(?:"(.*)")|(?:(?:([^\s]+)[\s])))`)
var validLogFmtKey = regexp.MustCompile(`^[a-zA-Z0-9_.-]+$`)
func createEvent(message string, streamType StdType) *LogEvent {
h := fnv.New32a()
@@ -182,7 +181,7 @@ func createEvent(message string, streamType StdType) *LogEvent {
} else {
logEvent.Message = data
}
} else if strings.Contains(message, "=") {
} else if validLogFmtMessage.MatchString(message) {
buffer := bufPool.Get().(*bytes.Buffer)
buffer.Reset()
defer bufPool.Put(buffer)
+13 -12
View File
@@ -5,30 +5,31 @@ import (
"strings"
)
var KEY_VALUE_REGEX = regexp.MustCompile(`level=(\w+)`)
var LOG_LEVELS = []string{"error", "warn", "warning", "info", "debug", "trace", "fatal"}
var LOG_LEVELS_PLAIN = map[string]*regexp.Regexp{}
var LOG_LEVEL_BRACKET = map[string]*regexp.Regexp{}
var keyValueRegex = regexp.MustCompile(`level=(\w+)`)
var logLevels = []string{"error", "warn", "warning", "info", "debug", "trace", "fatal"}
var plainLevels = map[string]*regexp.Regexp{}
var bracketLevels = map[string]*regexp.Regexp{}
func init() {
for _, level := range LOG_LEVELS {
LOG_LEVELS_PLAIN[level] = regexp.MustCompile("(?i)^" + level + "[^a-z]")
for _, level := range logLevels {
plainLevels[level] = regexp.MustCompile("(?i)^" + level + "[^a-z]")
}
for _, level := range LOG_LEVELS {
LOG_LEVEL_BRACKET[level] = regexp.MustCompile("(?i)\\[ ?" + level + " ?\\]")
for _, level := range logLevels {
bracketLevels[level] = regexp.MustCompile("(?i)\\[ ?" + level + " ?\\]")
}
}
func guessLogLevel(logEvent *LogEvent) string {
switch value := logEvent.Message.(type) {
case string:
for _, level := range LOG_LEVELS {
if LOG_LEVELS_PLAIN[level].MatchString(value) {
value = stripANSI(value)
for _, level := range logLevels {
if plainLevels[level].MatchString(value) {
return level
}
if LOG_LEVEL_BRACKET[level].MatchString(value) {
if bracketLevels[level].MatchString(value) {
return level
}
@@ -37,7 +38,7 @@ func guessLogLevel(logEvent *LogEvent) string {
}
}
if matches := KEY_VALUE_REGEX.FindStringSubmatch(value); matches != nil {
if matches := keyValueRegex.FindStringSubmatch(value); matches != nil {
return matches[1]
}
+75 -24
View File
@@ -4,18 +4,27 @@ import (
"context"
"errors"
"io"
"sync"
"sync/atomic"
"time"
"github.com/puzpuzpuz/xsync/v3"
log "github.com/sirupsen/logrus"
)
type StatsCollector struct {
stream chan ContainerStat
subscribers *xsync.MapOf[context.Context, chan ContainerStat]
client Client
cancelers *xsync.MapOf[string, context.CancelFunc]
stream chan ContainerStat
subscribers *xsync.MapOf[context.Context, chan ContainerStat]
client Client
cancelers *xsync.MapOf[string, context.CancelFunc]
stopper context.CancelFunc
timer *time.Timer
mu sync.Mutex
totalStarted atomic.Int32
}
var timeToStop = 6 * time.Hour
func NewStatsCollector(client Client) *StatsCollector {
return &StatsCollector{
stream: make(chan ContainerStat),
@@ -29,19 +38,68 @@ func (c *StatsCollector) Subscribe(ctx context.Context, stats chan ContainerStat
c.subscribers.Store(ctx, stats)
}
func (sc *StatsCollector) StartCollecting(ctx context.Context) {
func (c *StatsCollector) forceStop() {
c.mu.Lock()
defer c.mu.Unlock()
if c.stopper != nil {
c.stopper()
c.stopper = nil
log.Debug("stopping container stats collector due to inactivity")
}
}
func (c *StatsCollector) Stop() {
c.mu.Lock()
defer c.mu.Unlock()
if c.totalStarted.Add(-1) == 0 {
log.Debug("scheduled to stop container stats collector")
c.timer = time.AfterFunc(timeToStop, func() {
c.forceStop()
})
}
}
func (c *StatsCollector) reset() {
c.mu.Lock()
defer c.mu.Unlock()
log.Debug("resetting timer for container stats collector")
if c.timer != nil {
c.timer.Stop()
}
c.timer = nil
}
func streamStats(parent context.Context, sc *StatsCollector, id string) {
ctx, cancel := context.WithCancel(parent)
sc.cancelers.Store(id, cancel)
log.Debugf("starting to stream stats for: %s", id)
if err := sc.client.ContainerStats(ctx, id, sc.stream); err != nil {
log.Debugf("stopping to stream stats for: %s", id)
if !errors.Is(err, context.Canceled) && !errors.Is(err, io.EOF) {
log.Errorf("unexpected error when streaming container stats: %v", err)
}
}
}
// Start starts the stats collector and blocks until it's stopped. It returns true if the collector was stopped, false if it was already running
func (sc *StatsCollector) Start(parentCtx context.Context) bool {
sc.reset()
sc.totalStarted.Add(1)
var ctx context.Context
sc.mu.Lock()
if sc.stopper != nil {
sc.mu.Unlock()
return false
}
ctx, sc.stopper = context.WithCancel(parentCtx)
sc.mu.Unlock()
if containers, err := sc.client.ListContainers(); err == nil {
for _, c := range containers {
if c.State == "running" {
go func(client Client, id string) {
ctx, cancel := context.WithCancel(ctx)
sc.cancelers.Store(id, cancel)
if err := client.ContainerStats(ctx, id, sc.stream); err != nil {
if !errors.Is(err, context.Canceled) && !errors.Is(err, io.EOF) {
log.Errorf("unexpected error when streaming container stats: %v", err)
}
}
}(sc.client, c.ID)
go streamStats(ctx, sc, c.ID)
}
}
} else {
@@ -54,15 +112,7 @@ func (sc *StatsCollector) StartCollecting(ctx context.Context) {
for event := range events {
switch event.Name {
case "start":
go func(client Client, id string) {
ctx, cancel := context.WithCancel(ctx)
sc.cancelers.Store(id, cancel)
if err := client.ContainerStats(ctx, id, sc.stream); err != nil {
if !errors.Is(err, context.Canceled) && !errors.Is(err, io.EOF) {
log.Errorf("unexpected error when streaming container stats: %v", err)
}
}
}(sc.client, event.ActorID)
go streamStats(ctx, sc, event.ActorID)
case "die":
if cancel, ok := sc.cancelers.LoadAndDelete(event.ActorID); ok {
@@ -75,7 +125,8 @@ func (sc *StatsCollector) StartCollecting(ctx context.Context) {
for {
select {
case <-ctx.Done():
return
log.Info("stopped collecting container stats")
return true
case stat := <-sc.stream:
sc.subscribers.Range(func(c context.Context, stats chan ContainerStat) bool {
select {
+75
View File
@@ -0,0 +1,75 @@
package docker
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
func startedCollector(ctx context.Context) *StatsCollector {
client := new(mockedClient)
client.On("ListContainers").Return([]Container{
{
ID: "1234",
Name: "test",
State: "running",
},
}, nil)
client.On("Events", mock.Anything, mock.AnythingOfType("chan<- docker.ContainerEvent")).Return(make(chan error))
client.On("ContainerStats", mock.Anything, mock.Anything, mock.AnythingOfType("chan<- docker.ContainerStat")).
Return(nil).
Run(func(args mock.Arguments) {
stats := args.Get(2).(chan<- ContainerStat)
stats <- ContainerStat{
ID: "1234",
}
})
collector := NewStatsCollector(client)
stats := make(chan ContainerStat)
collector.Subscribe(ctx, stats)
go collector.Start(ctx)
<-stats
return collector
}
func TestCancelers(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
collector := startedCollector(ctx)
_, ok := collector.cancelers.Load("1234")
assert.True(t, ok, "canceler should be stored")
assert.False(t, collector.Start(ctx), "second start should return false")
assert.Equal(t, int32(2), collector.totalStarted.Load(), "total started should be 2")
collector.Stop()
assert.Equal(t, int32(1), collector.totalStarted.Load(), "total started should be 1")
}
func TestSecondStart(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
collector := startedCollector(ctx)
assert.False(t, collector.Start(ctx), "second start should return false")
assert.Equal(t, int32(2), collector.totalStarted.Load(), "total started should be 2")
collector.Stop()
assert.Equal(t, int32(1), collector.totalStarted.Load(), "total started should be 1")
}
func TestStop(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
collector := startedCollector(ctx)
collector.Stop()
assert.Equal(t, int32(0), collector.totalStarted.Load(), "total started should be 1")
}
+7
View File
@@ -31,6 +31,13 @@ func (r *RingBuffer[T]) Push(data T) {
}
}
func (r *RingBuffer[T]) Clear() {
r.mutex.Lock()
defer r.mutex.Unlock()
r.data = r.data[:0]
r.start = 0
}
func (r *RingBuffer[T]) Data() []T {
r.mutex.RLock()
defer r.mutex.RUnlock()
+33
View File
@@ -25,3 +25,36 @@ func TestRingBuffer(t *testing.T) {
t.Errorf("Expected data to be %v, got %v", expectedData, data)
}
}
func TestRingBuffer_MarshalJSON(t *testing.T) {
rb := NewRingBuffer[int](3)
rb.Push(1)
rb.Push(2)
rb.Push(3)
data, err := rb.MarshalJSON()
if err != nil {
t.Errorf("Expected error to be nil, got %v", err)
}
expectedData := []byte("[1,2,3]")
if !reflect.DeepEqual(data, expectedData) {
t.Errorf("Expected data to be %v, got %v", expectedData, data)
}
}
func TestRingBuffer_Clear(t *testing.T) {
rb := NewRingBuffer[int](3)
rb.Push(1)
rb.Push(2)
rb.Push(3)
rb.Clear()
data := rb.Data()
expectedData := []int{}
if !reflect.DeepEqual(data, expectedData) {
t.Errorf("Expected data to be %v, got %v", expectedData, data)
}
}
+2 -2
View File
@@ -37,9 +37,9 @@ HTTP/1.1 307 Temporary Redirect
Connection: close
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Type: text/html; charset=utf-8
Location: /login
Location: /login?redirectUrl=/
<a href="/login">Temporary Redirect</a>.
<a href="/login?redirectUrl=/">Temporary Redirect</a>.
/* snapshot: Test_createRoutes_username_password */
HTTP/1.1 307 Temporary Redirect
+6
View File
@@ -49,6 +49,12 @@ func (h *handler) streamEvents(w http.ResponseWriter, r *http.Request) {
store.Subscribe(ctx, events)
}
defer func() {
for _, store := range h.stores {
store.Unsubscribe(ctx)
}
}()
if err := sendContainersJSON(allContainers, w); err != nil {
log.Errorf("error writing containers to event stream: %v", err)
}
+15 -3
View File
@@ -3,7 +3,10 @@ package web
import (
"html/template"
"io"
"mime"
"path/filepath"
"sort"
"strings"
"github.com/goccy/go-json"
@@ -18,9 +21,18 @@ import (
)
func (h *handler) index(w http.ResponseWriter, req *http.Request) {
_, err := h.content.Open(req.URL.Path)
path := req.URL.Path
_, err := h.content.Open(path)
if err == nil && req.URL.Path != "" && req.URL.Path != "/" {
fileServer.ServeHTTP(w, req)
w.Header().Set("Cache-Control", "max-age=31536000, immutable")
// if brotli is enabled, then just send over the compressed file
if file, err := h.content.Open(path + ".br"); strings.Contains(req.Header.Get("Accept-Encoding"), "br") && err == nil {
w.Header().Set("Content-Encoding", "br")
w.Header().Set("Content-Type", mime.TypeByExtension(filepath.Ext(path)))
io.Copy(w, file)
} else {
fileServer.ServeHTTP(w, req)
}
} else {
h.executeTemplate(w, req)
}
@@ -66,7 +78,7 @@ func (h *handler) executeTemplate(w http.ResponseWriter, req *http.Request) {
return
} else if h.config.Authorization.Provider == SIMPLE && req.URL.Path != "login" {
log.Debugf("Redirecting to login page for url /%s", req.URL.String())
http.Redirect(w, req, path.Clean(h.config.Base+"/login"), http.StatusTemporaryRedirect)
http.Redirect(w, req, path.Clean(h.config.Base+"/login")+"?redirectUrl=/"+req.URL.String(), http.StatusTemporaryRedirect)
return
}
+16 -5
View File
@@ -3,6 +3,7 @@ package web
import (
"compress/gzip"
"context"
"strings"
"github.com/goccy/go-json"
@@ -30,12 +31,22 @@ func (h *handler) downloadLogs(w http.ResponseWriter, r *http.Request) {
}
now := time.Now()
nowFmt := now.Format("2006-01-02T15-04-05")
contentDisposition := fmt.Sprintf("attachment; filename=%s-%s.log", container.Name, nowFmt)
if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
w.Header().Set("Content-Disposition", contentDisposition)
w.Header().Set("Content-Encoding", "gzip")
w.Header().Set("Content-Type", "application/text")
} else {
w.Header().Set("Content-Disposition", contentDisposition+".gz")
w.Header().Set("Content-Type", "application/gzip")
}
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s-%s.log.gz", container.Name, now.Format("2006-01-02T15-04-05")))
w.Header().Set("Content-Type", "application/gzip")
zw := gzip.NewWriter(w)
defer zw.Close()
zw.Name = fmt.Sprintf("%s-%s.log", container.Name, now.Format("2006-01-02T15-04-05"))
zw.Name = fmt.Sprintf("%s-%s.log", container.Name, nowFmt)
zw.Comment = "Logs generated by Dozzle"
zw.ModTime = now
@@ -54,8 +65,8 @@ func (h *handler) downloadLogs(w http.ResponseWriter, r *http.Request) {
func (h *handler) fetchLogsBetweenDates(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/x-jsonl; charset=UTF-8")
from, _ := time.Parse(time.RFC3339, r.URL.Query().Get("from"))
to, _ := time.Parse(time.RFC3339, r.URL.Query().Get("to"))
from, _ := time.Parse(time.RFC3339Nano, r.URL.Query().Get("from"))
to, _ := time.Parse(time.RFC3339Nano, r.URL.Query().Get("to"))
id := chi.URLParam(r, "id")
var stdTypes docker.StdType
+101
View File
@@ -0,0 +1,101 @@
toolbar:
clear: Effacer
download: Téléchargement
search: Chercher
show: Montrer seulement {std}
show-all: Afficher tous les flux
stop: Stop
start: Démarrer
restart: Redémarrer
label:
containers: Conteneurs
running-containers: Conteneurs en execution
all-containers: Tous les conteneurs
total-containers: Total des conteneurs
running: En execution
total-cpu-usage: Util. totale CPU
total-mem-usage: Util. totale Mem
dozzle-version: Version de Dozzle
all: Tout
host: Hôte
password: Mot de passe
username: Nom d'utilisateur
container-name: Nom du conteneur
status: Status
created: Créé
avg-cpu: Moyenne CPU (%)
avg-mem: Moyenne MEM (%)
pinned: Epinglé
tooltip:
search: Recherche de conteneurs (⌘ + k, ⌃k)
pin-column: Epinglé en colonne
error:
page-not-found: Cette page n'existe pas
invalid-auth: Nom d'utilisateur ou mot de passe non valides
logs-skipped: Entrées {total} ignorées
container-not-found: Conteneur non trouvé
events-stream:
title: Erreur inattendue
message: >-
L'interface utilisateur de Dozzle n'a pas pu se connecter à l'API. Veuillez vérifier les paramètres de votre réseau.
Si vous utilisez un proxy inversé, assurez-vous qu'il est configuré correctement.
events-timeout:
title: Quelque chose ne va pas
message: >-
La connexion de l'interface utilisateur de Dozzle à l'API a mis trop de temps. Veuillez vérifier la connexion
et réessayez.
alert:
redirected:
title: Redirigé vers le nouveau conteneur
message: Dozzle vous a automatiquement redirigé vers le nouveau conteneur {containerId}.
similar-container-found:
title: Conteneur similaire trouvé
message: >-
Dozzle a trouvé un conteneur similaire {containerId} qui s'exécute sur le même hôte
et basculera automatiquement vers lui à moins que vous ne cliquiez sur "Annuler".
title:
page-not-found: Page non trouvée
login: Authentification requise
dashboard: 1 conteneur | {count} conteneurs
settings: Paramètres
button:
logout: Déconnexion
login: Connexion
settings: Paramètres
placeholder:
search-containers: Recherche de conteneurs (⌘ + k, ⌃k)
settings:
display: Afficher
locale: Langue de remplacement
small-scrollbars: Utiliser des barres de défilement plus petites
show-timesamps: Afficher les horodatages
soft-wrap: Lignes d'enroulement souples
datetime-format: Remplacer le format de la date et de l'heure
font-size: Taille de police à utiliser pour les journaux
color-scheme: Schéma de couleurs
options: Options
show-stopped-containers: Afficher les conteneurs arrêtés
about: A propos de
search: Activer la recherche avec Dozzle en utilisant
using-version: Vous utilisez Dozzle {version}.
update-available: >-
Nouvelle version disponible! Mise à jour de <a href="{href}" target="_blank"
rel="noreferrer noopener">{nextVersion}</a>.
show-std: Afficher les étiquettes stdout et stderr
automatic-redirect: Redirection automatique vers de nouveaux conteneurs portant le même nom
compact: Activer le mode compact pour les journaux
releases:
features: une nouvelle fonctionnalité | {count} fonctionnalités
bugFixes: correction d'un bug | {count} bugs
breaking: un changement radical | {count} changements radicaux
three_parts: "{first}, {second} et {third}"
two_parts: "{first} avec {second}"
latest: Plus récent
no_releases: Vous avez la dernière version
log_actions:
copy_log: Copier le journal
jump_to_context: Aller au contexte
toasts:
copied:
title: Copié
message: Journal copié dans le presse-papiers
+99
View File
@@ -0,0 +1,99 @@
toolbar:
clear: Pulisci
download: Scarica
search: Cerca
show: Mostra solo {std}
show-all: Mostra tutto
stop: Stop
start: Start
restart: Restart
label:
containers: Container
running-containers: Container in esecuzione
all-containers: Tutti i Container
total-containers: Container Totali
running: In esecuzione
total-cpu-usage: Utilizzo Totale della CPU
total-mem-usage: Utilizzo Totale della Memoria
dozzle-version: Versione Dozzle
all: Tutto
host: Host
password: Password
username: Username
container-name: Nome Container
status: Stato
created: Creato
avg-cpu: CPU (%)
avg-mem: MEM (%)
pinned: Spuntato
tooltip:
search: Ricerca container (⌘ + k, ⌃k)
pin-column: Blocca come colonna
error:
page-not-found: Questa pagina non esiste
invalid-auth: Username o password non valide
logs-skipped: Saltato {total} registrazioni
container-not-found: Container non trovato
events-stream:
title: Errore inaspettato
message: >-
Dozzle UI non è stato in grado di connettersi alle API. Controlla la tua configurazione di rete.
Se stai utilizzando un reverse proxy, assicurati di averlo configurato correttamente.
events-timeout:
title: Qualcosa non è corretto
message: >-
Dozzle UI timed out durante la connessione alle API. Controlla la configurazione di rete e riprova.
alert:
redirected:
title: Reindirizzamento ad un nuovo container
message: Dozzle automaticamente si è reindirizzato ad un nuovo container {containerId}.
similar-container-found:
title: Trovato un Container simile
message: >-
Dozzle ha trovato un Container soimile {containerId} in esecuzione sullo stesso Host and verrà automaticamente agganciato ad esso se non premi 'Cancel'.
title:
page-not-found: Pagina non trovata
login: Autenticazione richiesta
dashboard: 1 container | {count} container
settings: Configurazione
button:
logout: Logout
login: Login
settings: Configurazione
placeholder:
search-containers: Ricerca container (⌘ + k, ⌃k)
settings:
display: Visualizza
locale: Sovrascrivi Linguaggio
small-scrollbars: Usa una scrollbars più piccola
show-timesamps: Visualizza timestamp
soft-wrap: Linee morbide
datetime-format: Sovrascrivi data e formato dell'ora
font-size: Grandezza del Font da usare nei log
color-scheme: Schema colori
options: Opzioni
show-stopped-containers: Visualizza i container fermi
about: Circa
search: Abilita la ricerca attraverso Dozzle
using-version: Stai utilizzando Dozzle {version}.
update-available: >-
Nuova versione disponibile! Aggiorna a <a href="{href}" target="_blank"
rel="noreferrer noopener">{nextVersion}</a>.
show-std: Visualizza stdout e stderr
automatic-redirect: Automaticamente reindirizza al nuovo container con lo stesso nome
compact: Abilita il compact mode per i log
releases:
features: nuova funzione | {count} funzioni
bugFixes: nuovo bug fix | {count} fix
breaking: nuovo breaking change | {count} breaking change
three_parts: "{first}, {second} e {third}"
two_parts: "{first} e {second}"
latest: Ultimo
no_releases: Stai utilizzando l'ultima versione
log_actions:
copy_log: Copia log
jump_to_context: Vai a
toasts:
copied:
title: Copiato
message: Log copiato nella clipboard
+34 -34
View File
@@ -1,12 +1,12 @@
{
"name": "dozzle",
"version": "6.2.3",
"version": "6.4.2",
"description": "Realtime log viewer for docker containers.",
"homepage": "https://github.com/amir20/dozzle#readme",
"bugs": {
"url": "https://github.com/amir20/dozzle/issues"
},
"packageManager": "pnpm@8.15.1",
"packageManager": "pnpm@8.15.5",
"type": "module",
"repository": {
"type": "git",
@@ -28,52 +28,54 @@
"docs:preview": "vitepress preview docs"
},
"dependencies": {
"@iconify-json/carbon": "^1.1.29",
"@iconify-json/carbon": "^1.1.31",
"@iconify-json/cil": "^1.1.8",
"@iconify-json/ic": "^1.1.17",
"@iconify-json/mdi": "^1.1.64",
"@iconify-json/mdi-light": "^1.1.10",
"@iconify-json/octicon": "^1.1.52",
"@iconify-json/ph": "^1.1.11",
"@intlify/unplugin-vue-i18n": "^2.0.0",
"@intlify/unplugin-vue-i18n": "^4.0.0",
"@tailwindcss/container-queries": "^0.1.1",
"@tailwindcss/typography": "^0.5.10",
"@vueuse/components": "^10.7.2",
"@vueuse/core": "^10.7.2",
"@vueuse/integrations": "^10.7.2",
"@vueuse/math": "^10.7.2",
"@vueuse/router": "^10.7.2",
"autoprefixer": "^10.4.17",
"@vueuse/components": "^10.9.0",
"@vueuse/core": "^10.9.0",
"@vueuse/integrations": "^10.9.0",
"@vueuse/router": "^10.9.0",
"ansi-to-html": "^0.7.2",
"autoprefixer": "^10.4.19",
"d3-array": "^3.2.4",
"d3-ease": "^3.0.1",
"d3-scale": "^4.0.2",
"d3-selection": "^3.0.0",
"d3-shape": "^3.2.0",
"d3-transition": "^3.0.1",
"daisyui": "^4.6.2",
"date-fns": "^3.3.1",
"daisyui": "^4.9.0",
"date-fns": "^3.6.0",
"entities": "^4.5.0",
"fuse.js": "^7.0.0",
"lodash.debounce": "^4.0.8",
"pinia": "^2.1.7",
"postcss": "^8.4.35",
"postcss-mixins": "^9.0.4",
"postcss": "^8.4.38",
"splitpanes": "^3.1.5",
"strip-ansi": "^7.1.0",
"tailwindcss": "^3.4.1",
"unplugin-auto-import": "^0.17.5",
"unplugin-icons": "^0.18.5",
"unplugin-vue-components": "^0.26.0",
"unplugin-vue-macros": "^2.7.10",
"vite": "5.1.0",
"vite-plugin-pages": "^0.32.0",
"unplugin-vue-macros": "^2.7.13",
"vite": "5.2.6",
"vite-plugin-compression2": "^1.0.0",
"vite-plugin-pages": "^0.32.1",
"vite-plugin-vue-layouts": "^0.11.0",
"vue": "^3.4.16",
"vue-i18n": "^9.9.1",
"vue-router": "^4.2.5"
"vue": "^3.4.21",
"vue-i18n": "^9.10.2",
"vue-router": "^4.3.0"
},
"devDependencies": {
"@iconify-json/material-symbols": "^1.1.76",
"@pinia/testing": "^0.1.3",
"@playwright/test": "^1.41.2",
"@playwright/test": "^1.42.1",
"@types/d3-array": "^3.2.1",
"@types/d3-ease": "^3.0.2",
"@types/d3-scale": "^4.0.8",
@@ -81,26 +83,24 @@
"@types/d3-shape": "^3.1.6",
"@types/d3-transition": "^3.0.8",
"@types/lodash.debounce": "^4.0.9",
"@types/node": "^20.11.16",
"@types/semver": "^7.5.6",
"@vitejs/plugin-vue": "5.0.3",
"@vue/compiler-sfc": "^3.4.16",
"@vue/test-utils": "^2.4.4",
"bumpp": "^9.3.0",
"@types/node": "^20.11.30",
"@vitejs/plugin-vue": "5.0.4",
"@vue/compiler-sfc": "^3.4.21",
"@vue/test-utils": "^2.4.5",
"bumpp": "^9.4.0",
"c8": "^9.1.0",
"concurrently": "^8.2.2",
"eventsourcemock": "^2.0.0",
"jest-serializer-vue": "^3.1.0",
"jsdom": "^24.0.0",
"lint-staged": "^15.2.2",
"prettier": "^3.2.5",
"prettier-plugin-tailwindcss": "^0.5.11",
"simple-git-hooks": "^2.9.0",
"prettier-plugin-tailwindcss": "^0.5.12",
"simple-git-hooks": "^2.11.1",
"ts-node": "^10.9.2",
"typescript": "^5.3.3",
"vitepress": "1.0.0-rc.42",
"vitest": "^1.2.2",
"vue-tsc": "^1.8.27"
"typescript": "^5.4.3",
"vitepress": "1.0.1",
"vitest": "^1.4.0",
"vue-tsc": "^2.0.7"
},
"lint-staged": {
"*.{js,vue,css,ts,html,md}": [
+950 -888
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -1,6 +1,5 @@
module.exports = {
plugins: {
"postcss-mixins": {},
"tailwindcss/nesting": {},
tailwindcss: {},
autoprefixer: {},
+2
View File
@@ -9,6 +9,7 @@ import IconsResolver from "unplugin-icons/resolver";
import Pages from "vite-plugin-pages";
import Layouts from "vite-plugin-vue-layouts";
import VueI18nPlugin from "@intlify/unplugin-vue-i18n/vite";
import { compression } from "vite-plugin-compression2";
export default defineConfig(() => ({
resolve: {
@@ -63,6 +64,7 @@ export default defineConfig(() => ({
strictMessage: false,
include: [path.resolve(__dirname, "locales/**")],
}),
compression({ algorithm: "brotliCompress", exclude: [/\.(html)$/] }),
],
server: {
watch: {