mirror of
https://github.com/gethomepage/homepage.git
synced 2026-05-18 19:40:58 +08:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9cef37aed6 | ||
|
|
9a4dea39b0 | ||
|
|
e7a147899c | ||
|
|
e81aadb071 | ||
|
|
1e6be5cc17 | ||
|
|
9b1b14116b | ||
|
|
02a9d74c95 | ||
|
|
e7a749782a | ||
|
|
f8e2e8d410 | ||
|
|
6053ddbab6 | ||
|
|
11e9f28e5e | ||
|
|
233721cc90 | ||
|
|
d294a25145 | ||
|
|
0ff9af4c3c | ||
|
|
a6c753c8aa | ||
|
|
5d71c3aa65 | ||
|
|
1cc4608d72 | ||
|
|
d65e5447e4 | ||
|
|
d3256596d8 |
44
.github/release-drafter.yml
vendored
44
.github/release-drafter.yml
vendored
@@ -47,15 +47,34 @@ categories:
|
|||||||
- 'documentation'
|
- 'documentation'
|
||||||
|
|
||||||
autolabeler:
|
autolabeler:
|
||||||
|
- label: 'bug'
|
||||||
|
title:
|
||||||
|
- '/^fix(\(.+\))?:/i'
|
||||||
|
body:
|
||||||
|
- '/- \[[xX]\] Bug fix \(non-breaking change which fixes an issue\)/'
|
||||||
|
|
||||||
|
- label: 'enhancement'
|
||||||
|
title:
|
||||||
|
- '/^(feature|enhancement)(\(.+\))?:/i'
|
||||||
|
body:
|
||||||
|
- '/- \[[xX]\] New service widget/'
|
||||||
|
- '/- \[[xX]\] New feature or enhancement \(non-breaking change which adds functionality\)/'
|
||||||
|
|
||||||
- label: 'documentation'
|
- label: 'documentation'
|
||||||
files:
|
title:
|
||||||
- 'docs/**'
|
- '/^(documentation|docs)(\(.+\))?:/i'
|
||||||
- '*.md'
|
body:
|
||||||
- '.github/**/*.md'
|
- '/- \[[xX]\] Documentation only/'
|
||||||
|
|
||||||
|
- label: 'chore'
|
||||||
|
body:
|
||||||
|
- '/- \[[xX]\] Other \(please explain\)/'
|
||||||
|
|
||||||
- label: 'ci'
|
- label: 'ci'
|
||||||
files:
|
branch:
|
||||||
- '.github/workflows/**'
|
- '/^(ci|workflow|actions)\//'
|
||||||
|
title:
|
||||||
|
- '/^(ci|workflow|actions)(\(.+\))?:/i'
|
||||||
|
|
||||||
- label: 'dependencies'
|
- label: 'dependencies'
|
||||||
files:
|
files:
|
||||||
@@ -64,19 +83,6 @@ autolabeler:
|
|||||||
- 'pyproject.toml'
|
- 'pyproject.toml'
|
||||||
- 'uv.lock'
|
- 'uv.lock'
|
||||||
|
|
||||||
- label: 'feature'
|
|
||||||
files:
|
|
||||||
- 'src/components/**'
|
|
||||||
- 'src/widgets/**'
|
|
||||||
- 'src/pages/**'
|
|
||||||
- 'src/utils/**'
|
|
||||||
|
|
||||||
- label: 'chore'
|
|
||||||
files:
|
|
||||||
- 'Dockerfile*'
|
|
||||||
- 'docker-entrypoint.sh'
|
|
||||||
- 'k3d/**'
|
|
||||||
|
|
||||||
- label: 'translation'
|
- label: 'translation'
|
||||||
files:
|
files:
|
||||||
- 'public/locales/**'
|
- 'public/locales/**'
|
||||||
|
|||||||
2
.github/workflows/docker-publish.yml
vendored
2
.github/workflows/docker-publish.yml
vendored
@@ -61,7 +61,7 @@ jobs:
|
|||||||
nextjs-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
nextjs-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
||||||
|
|
||||||
- name: Install pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@26f6d4f2c533a43e6b5da0b4a5dd983f98f7b49a # v6.0.4
|
uses: pnpm/action-setup@8912a9102ac27614460f54aedde9e1e7f9aec20d # v6.0.5
|
||||||
with:
|
with:
|
||||||
version: 10
|
version: 10
|
||||||
run_install: false
|
run_install: false
|
||||||
|
|||||||
90
.github/workflows/issue-triage.yml
vendored
Normal file
90
.github/workflows/issue-triage.yml
vendored
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
name: Issue Triage
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [labeled]
|
||||||
|
discussion:
|
||||||
|
types: [labeled]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
discussions: write
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
close-needs-discussion:
|
||||||
|
name: Issues Need Discussion
|
||||||
|
if: github.event_name == 'issues' && github.event.label.name == 'needs-discussion'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const issueNumber = context.payload.issue.number;
|
||||||
|
const owner = context.repo.owner;
|
||||||
|
const repo = context.repo.repo;
|
||||||
|
|
||||||
|
await github.rest.issues.createComment({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
issue_number: issueNumber,
|
||||||
|
body: 'This issue is being closed because it was opened before a maintainer asked for an issue to be created. Please start with a discussion and follow the issue template; only open an issue when a maintainer asks you to do so.',
|
||||||
|
});
|
||||||
|
|
||||||
|
await github.rest.issues.update({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
issue_number: issueNumber,
|
||||||
|
state: 'closed',
|
||||||
|
state_reason: 'not_planned',
|
||||||
|
});
|
||||||
|
|
||||||
|
await github.rest.issues.lock({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
issue_number: issueNumber,
|
||||||
|
lock_reason: 'off-topic',
|
||||||
|
});
|
||||||
|
|
||||||
|
comment-needs-information:
|
||||||
|
name: Discussions Need Information
|
||||||
|
if: github.event_name == 'discussion' && github.event.label.name == 'needs-information'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const owner = context.repo.owner;
|
||||||
|
const repo = context.repo.repo;
|
||||||
|
const discussionNumber = context.payload.discussion.number;
|
||||||
|
let discussionId = context.payload.discussion.node_id;
|
||||||
|
|
||||||
|
if (!discussionId) {
|
||||||
|
const result = await github.graphql(
|
||||||
|
`query($owner:String!, $repo:String!, $number:Int!) {
|
||||||
|
repository(owner:$owner, name:$repo) {
|
||||||
|
discussion(number:$number) {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`,
|
||||||
|
{
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
number: discussionNumber,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
discussionId = result.repository.discussion.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
await github.graphql(
|
||||||
|
`mutation($discussion:ID!, $body:String!) {
|
||||||
|
addDiscussionComment(input:{discussionId:$discussion, body:$body}) {
|
||||||
|
clientMutationId
|
||||||
|
}
|
||||||
|
}`,
|
||||||
|
{
|
||||||
|
discussion: discussionId,
|
||||||
|
body: 'Dear homepage user, thanks for opening this discussion! Please ensure you add the output from the troubleshooting guide steps, the support template asks for those details because they usually make it possible to understand the problem without guessing. Please update the discussion with the relevant troubleshooting output, configuration, logs, and browser console details where applicable: https://gethomepage.dev/troubleshooting/. Thank you!',
|
||||||
|
},
|
||||||
|
);
|
||||||
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
|||||||
uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
|
uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
|
||||||
|
|
||||||
- name: Install pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@26f6d4f2c533a43e6b5da0b4a5dd983f98f7b49a # v6.0.4
|
uses: pnpm/action-setup@8912a9102ac27614460f54aedde9e1e7f9aec20d # v6.0.5
|
||||||
with:
|
with:
|
||||||
version: 10
|
version: 10
|
||||||
run_install: false
|
run_install: false
|
||||||
|
|||||||
36
.github/workflows/pr-triage.yml
vendored
Normal file
36
.github/workflows/pr-triage.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
name: PR Triage
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
types: [labeled]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
close-needs-requirements:
|
||||||
|
name: PRs Need Requirements
|
||||||
|
if: github.event.label.name == 'needs-requirements'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const pullNumber = context.payload.pull_request.number;
|
||||||
|
const owner = context.repo.owner;
|
||||||
|
const repo = context.repo.repo;
|
||||||
|
|
||||||
|
await github.rest.issues.createComment({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
issue_number: pullNumber,
|
||||||
|
body: 'Dear contributor, thanks for taking the time to open this pull request! It is being closed because it does not currently meet the pull request guidelines. Please review the checklist in the pull request template and the relevant [contributing guidelines](https://gethomepage.dev/widgets/authoring/getting-started/#new-feature-guidelines) before opening a new pull request.',
|
||||||
|
});
|
||||||
|
|
||||||
|
await github.rest.pulls.update({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
pull_number: pullNumber,
|
||||||
|
state: 'closed',
|
||||||
|
});
|
||||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
|
|
||||||
- uses: pnpm/action-setup@26f6d4f2c533a43e6b5da0b4a5dd983f98f7b49a # v6.0.4
|
- uses: pnpm/action-setup@8912a9102ac27614460f54aedde9e1e7f9aec20d # v6.0.5
|
||||||
with:
|
with:
|
||||||
version: 9
|
version: 9
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "homepage",
|
"name": "homepage",
|
||||||
"version": "1.13.0",
|
"version": "1.13.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"preinstall": "npx only-allow pnpm",
|
"preinstall": "npx only-allow pnpm",
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
"luxon": "^3.6.1",
|
"luxon": "^3.6.1",
|
||||||
"memory-cache": "^0.2.0",
|
"memory-cache": "^0.2.0",
|
||||||
"minecraftstatuspinger": "^1.2.2",
|
"minecraftstatuspinger": "^1.2.2",
|
||||||
"next": "^16.2.4",
|
"next": "^16.2.6",
|
||||||
"next-i18next": "^15.4.3",
|
"next-i18next": "^15.4.3",
|
||||||
"ping": "^0.4.4",
|
"ping": "^0.4.4",
|
||||||
"pretty-bytes": "^7.1.0",
|
"pretty-bytes": "^7.1.0",
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
"react-icons": "^5.6.0",
|
"react-icons": "^5.6.0",
|
||||||
"recharts": "^3.1.2",
|
"recharts": "^3.1.2",
|
||||||
"swr": "^2.4.1",
|
"swr": "^2.4.1",
|
||||||
"systeminformation": "^5.30.8",
|
"systeminformation": "^5.31.6",
|
||||||
"tough-cookie": "^6.0.0",
|
"tough-cookie": "^6.0.0",
|
||||||
"urbackup-server-api": "^0.92.2",
|
"urbackup-server-api": "^0.92.2",
|
||||||
"winston": "^3.19.0",
|
"winston": "^3.19.0",
|
||||||
|
|||||||
166
pnpm-lock.yaml
generated
166
pnpm-lock.yaml
generated
@@ -51,11 +51,11 @@ importers:
|
|||||||
specifier: ^1.2.2
|
specifier: ^1.2.2
|
||||||
version: 1.2.2
|
version: 1.2.2
|
||||||
next:
|
next:
|
||||||
specifier: ^16.2.4
|
specifier: ^16.2.6
|
||||||
version: 16.2.4(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
|
version: 16.2.6(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
|
||||||
next-i18next:
|
next-i18next:
|
||||||
specifier: ^15.4.3
|
specifier: ^15.4.3
|
||||||
version: 15.4.3(@types/react@19.0.10)(i18next@25.10.9(typescript@5.7.3))(next@16.2.4(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react-i18next@15.5.3(i18next@25.10.9(typescript@5.7.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@5.7.3))(react@19.2.5)
|
version: 15.4.3(@types/react@19.0.10)(i18next@25.10.9(typescript@5.7.3))(next@16.2.6(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react-i18next@15.5.3(i18next@25.10.9(typescript@5.7.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@5.7.3))(react@19.2.5)
|
||||||
ping:
|
ping:
|
||||||
specifier: ^0.4.4
|
specifier: ^0.4.4
|
||||||
version: 0.4.4
|
version: 0.4.4
|
||||||
@@ -84,8 +84,8 @@ importers:
|
|||||||
specifier: ^2.4.1
|
specifier: ^2.4.1
|
||||||
version: 2.4.1(react@19.2.5)
|
version: 2.4.1(react@19.2.5)
|
||||||
systeminformation:
|
systeminformation:
|
||||||
specifier: ^5.30.8
|
specifier: ^5.31.6
|
||||||
version: 5.30.8
|
version: 5.31.6
|
||||||
tough-cookie:
|
tough-cookie:
|
||||||
specifier: ^6.0.0
|
specifier: ^6.0.0
|
||||||
version: 6.0.0
|
version: 6.0.0
|
||||||
@@ -773,56 +773,56 @@ packages:
|
|||||||
'@napi-rs/wasm-runtime@0.2.8':
|
'@napi-rs/wasm-runtime@0.2.8':
|
||||||
resolution: {integrity: sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg==}
|
resolution: {integrity: sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg==}
|
||||||
|
|
||||||
'@next/env@16.2.4':
|
'@next/env@16.2.6':
|
||||||
resolution: {integrity: sha512-dKkkOzOSwFYe5RX6y26fZgkSpVAlIOJKQHIiydQcrWH6y/97+RceSOAdjZ14Qa3zLduVUy0TXcn+EiM6t4rPgw==}
|
resolution: {integrity: sha512-gd8HoHN4ufj73WmR3JmVolrpJR47ILK6LouP5xElPglaVxir6e1a7VzvTvDWkOoPXT9rkkTzyCxBu4yeZfZwcw==}
|
||||||
|
|
||||||
'@next/eslint-plugin-next@15.5.11':
|
'@next/eslint-plugin-next@15.5.11':
|
||||||
resolution: {integrity: sha512-tS/HYQOjIoX9ZNDQitba/baS8sTvo3ekY6Vgdx5lmhN4jov082bdApIChXr94qhMZHvEciz9DZglFFnhguQp/A==}
|
resolution: {integrity: sha512-tS/HYQOjIoX9ZNDQitba/baS8sTvo3ekY6Vgdx5lmhN4jov082bdApIChXr94qhMZHvEciz9DZglFFnhguQp/A==}
|
||||||
|
|
||||||
'@next/swc-darwin-arm64@16.2.4':
|
'@next/swc-darwin-arm64@16.2.6':
|
||||||
resolution: {integrity: sha512-OXTFFox5EKN1Ym08vfrz+OXxmCcEjT4SFMbNRsWZE99dMqt2Kcusl5MqPXcW232RYkMLQTy0hqgAMEsfEd/l2A==}
|
resolution: {integrity: sha512-ZJGkkcNfYgrrMkqOdZ7zoLa1TOy0qpcMfk/z4Mh/FKUz40gVO+HNQWqmLxf67Z5WB64DRp0dhEbyHfel+6sJUg==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
|
|
||||||
'@next/swc-darwin-x64@16.2.4':
|
'@next/swc-darwin-x64@16.2.6':
|
||||||
resolution: {integrity: sha512-XhpVnUfmYWvD3YrXu55XdcAkQtOnvaI6wtQa8fuF5fGoKoxIUZ0kWPtcOfqJEWngFF/lOS9l3+O9CcownhiQxQ==}
|
resolution: {integrity: sha512-v/YLBHIY132Ced3puBJ7YJKw1lqsCrgcNo2aRJlCEyQrrCeRJlvGlnmxhPxNQI3KE3N1DN5r9TPNPvka3nq5RQ==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
|
|
||||||
'@next/swc-linux-arm64-gnu@16.2.4':
|
'@next/swc-linux-arm64-gnu@16.2.6':
|
||||||
resolution: {integrity: sha512-Mx/tjlNA3G8kg14QvuGAJ4xBwPk1tUHq56JxZ8CXnZwz1Etz714soCEzGQQzVMz4bEnGPowzkV6Xrp6wAkEWOQ==}
|
resolution: {integrity: sha512-RPOvqlYBbcQjkz9VQQDZ2T2bARIjXZV1KFlt+V2Mr6SW/e4I9fcKsaA0hdyf2FHoTlsV2xnBd5Y912rP/1Ce6w==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@next/swc-linux-arm64-musl@16.2.4':
|
'@next/swc-linux-arm64-musl@16.2.6':
|
||||||
resolution: {integrity: sha512-iVMMp14514u7Nup2umQS03nT/bN9HurK8ufylC3FZNykrwjtx7V1A7+4kvhbDSCeonTVqV3Txnv0Lu+m2oDXNg==}
|
resolution: {integrity: sha512-URUTu1+dMkxJsPFgm+OeEvq9wf5sujw0EvgYy80TDGHTSLTnIHeqb0Eu8A3sC95IRgjejQL+kC4mw+4yPxiAXA==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@next/swc-linux-x64-gnu@16.2.4':
|
'@next/swc-linux-x64-gnu@16.2.6':
|
||||||
resolution: {integrity: sha512-EZOvm1aQWgnI/N/xcWOlnS3RQBk0VtVav5Zo7n4p0A7UKyTDx047k8opDbXgBpHl4CulRqRfbw3QrX2w5UOXMQ==}
|
resolution: {integrity: sha512-DOj182mPV8G3UkrayLoREM5YEYI+Dk5wv7Ox9xl1fFibAELEsFD0lDPfHIeILlutMMfdyhlzYPELG3peuKaurw==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@next/swc-linux-x64-musl@16.2.4':
|
'@next/swc-linux-x64-musl@16.2.6':
|
||||||
resolution: {integrity: sha512-h9FxsngCm9cTBf71AR4fGznDEDx1hS7+kSEiIRjq5kO1oXWm07DxVGZjCvk0SGx7TSjlUqhI8oOyz7NfwAdPoA==}
|
resolution: {integrity: sha512-HKQ5SP/V/ub73UvF7n/zeJlxk2kLmtL7Wzrg4WfmkjmNos5onJ2tKu7yZOPdL18A6Svfn3max29ym+ry7NkK4g==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@next/swc-win32-arm64-msvc@16.2.4':
|
'@next/swc-win32-arm64-msvc@16.2.6':
|
||||||
resolution: {integrity: sha512-3NdJV5OXMSOeJYijX+bjaLge3mJBlh4ybydbT4GFoB/2hAojWHtMhl3CYlYoMrjPuodp0nzFVi4Tj2+WaMg+Ow==}
|
resolution: {integrity: sha512-LZXpTlPyS5v7HhSmnvsLGP3iIYgYOBnc8r8ArlT55sGHV89bR2HlDdBjWQ+PY6SJMmk8TuVGFuxalnP3k/0Dwg==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
'@next/swc-win32-x64-msvc@16.2.4':
|
'@next/swc-win32-x64-msvc@16.2.6':
|
||||||
resolution: {integrity: sha512-kMVGgsqhO5YTYODD9IPGGhA6iprWidQckK3LmPeW08PIFENRmgfb4MjXHO+p//d+ts2rpjvK5gXWzXSMrPl9cw==}
|
resolution: {integrity: sha512-F0+4i0h9J6C4eE3EAPWsoCk7UW/dbzOjyzxY0qnDUOYFu6FFmdZ6l97/XdV3/Nz3VYyO7UWjyEJUXkGqcoXfMA==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
@@ -857,8 +857,8 @@ packages:
|
|||||||
'@protobufjs/base64@1.1.2':
|
'@protobufjs/base64@1.1.2':
|
||||||
resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==}
|
resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==}
|
||||||
|
|
||||||
'@protobufjs/codegen@2.0.4':
|
'@protobufjs/codegen@2.0.5':
|
||||||
resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==}
|
resolution: {integrity: sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==}
|
||||||
|
|
||||||
'@protobufjs/eventemitter@1.1.0':
|
'@protobufjs/eventemitter@1.1.0':
|
||||||
resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==}
|
resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==}
|
||||||
@@ -869,8 +869,8 @@ packages:
|
|||||||
'@protobufjs/float@1.0.2':
|
'@protobufjs/float@1.0.2':
|
||||||
resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==}
|
resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==}
|
||||||
|
|
||||||
'@protobufjs/inquire@1.1.0':
|
'@protobufjs/inquire@1.1.1':
|
||||||
resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==}
|
resolution: {integrity: sha512-mnzgDV26ueAvk7rsbt9L7bE0SuAoqyuys/sMMrmVcN5x9VsxpcG3rqAUSgDyLp0UZlmNfIbQ4fHfCtreVBk8Ew==}
|
||||||
|
|
||||||
'@protobufjs/path@1.1.2':
|
'@protobufjs/path@1.1.2':
|
||||||
resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==}
|
resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==}
|
||||||
@@ -878,8 +878,8 @@ packages:
|
|||||||
'@protobufjs/pool@1.1.0':
|
'@protobufjs/pool@1.1.0':
|
||||||
resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==}
|
resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==}
|
||||||
|
|
||||||
'@protobufjs/utf8@1.1.0':
|
'@protobufjs/utf8@1.1.1':
|
||||||
resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==}
|
resolution: {integrity: sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==}
|
||||||
|
|
||||||
'@react-aria/focus@3.22.0':
|
'@react-aria/focus@3.22.0':
|
||||||
resolution: {integrity: sha512-ZfDOVuVhqDsM9mkNji3QUZ/d40JhlVgXrDkrfXylM1035QCrcTHN7m2DpbE95sU2A8EQb4wikvt5jM6K/73BPg==}
|
resolution: {integrity: sha512-ZfDOVuVhqDsM9mkNji3QUZ/d40JhlVgXrDkrfXylM1035QCrcTHN7m2DpbE95sU2A8EQb4wikvt5jM6K/73BPg==}
|
||||||
@@ -1577,8 +1577,8 @@ packages:
|
|||||||
base64-js@1.5.1:
|
base64-js@1.5.1:
|
||||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||||
|
|
||||||
baseline-browser-mapping@2.10.27:
|
baseline-browser-mapping@2.10.29:
|
||||||
resolution: {integrity: sha512-zEs/ufmZoUd7WftKpKyXaT6RFxpQ5Qm9xytKRHvJfxFV9DFJkZph9RvJ1LcOUi0Z1ZVijMte65JbILeV+8QQEA==}
|
resolution: {integrity: sha512-Asa2krT+XTPZINCS+2QcyS8WTkObE77RwkydwF7h6DmnKqbvlalz93m/dnphUyCa6SWSP51VgtEUf2FN+gelFQ==}
|
||||||
engines: {node: '>=6.0.0'}
|
engines: {node: '>=6.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
@@ -1644,8 +1644,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
|
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
caniuse-lite@1.0.30001791:
|
caniuse-lite@1.0.30001792:
|
||||||
resolution: {integrity: sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ==}
|
resolution: {integrity: sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==}
|
||||||
|
|
||||||
chai@5.3.3:
|
chai@5.3.3:
|
||||||
resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==}
|
resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==}
|
||||||
@@ -2888,8 +2888,8 @@ packages:
|
|||||||
react: '>= 17.0.2'
|
react: '>= 17.0.2'
|
||||||
react-i18next: '>= 13.5.0'
|
react-i18next: '>= 13.5.0'
|
||||||
|
|
||||||
next@16.2.4:
|
next@16.2.6:
|
||||||
resolution: {integrity: sha512-kPvz56wF5frc+FxlHI5qnklCzbq53HTwORaWBGdT0vNoKh1Aya9XC8aPauH4NJxqtzbWsS5mAbctm4cr+EkQ2Q==}
|
resolution: {integrity: sha512-qOVgKJg1+At15NpeUP+eJgCHvTCgXsogweq87Ri/Ix7PkqQHg4sdaXmSFqKlgaIXE4kW0g25LE68W87UANlHtw==}
|
||||||
engines: {node: '>=20.9.0'}
|
engines: {node: '>=20.9.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -3092,8 +3092,8 @@ packages:
|
|||||||
prop-types@15.8.1:
|
prop-types@15.8.1:
|
||||||
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
|
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
|
||||||
|
|
||||||
protobufjs@7.5.5:
|
protobufjs@7.5.8:
|
||||||
resolution: {integrity: sha512-3wY1AxV+VBNW8Yypfd1yQY9pXnqTAN+KwQxL8iYm3/BjKYMNg4i0owhEe26PWDOMaIrzeeF98Lqd5NGz4omiIg==}
|
resolution: {integrity: sha512-dvpCIeLPbXZS/Ete7yLaO7RenOdken2NHKykBXbsaGxZT0UTltcarBciw+A78SRQs9iMAAVpsYA+l8b1hTePIA==}
|
||||||
engines: {node: '>=12.0.0'}
|
engines: {node: '>=12.0.0'}
|
||||||
|
|
||||||
pump@3.0.4:
|
pump@3.0.4:
|
||||||
@@ -3309,8 +3309,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
|
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
semver@7.7.4:
|
semver@7.8.0:
|
||||||
resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==}
|
resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
@@ -3504,8 +3504,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==}
|
resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==}
|
||||||
engines: {node: ^14.18.0 || >=16.0.0}
|
engines: {node: ^14.18.0 || >=16.0.0}
|
||||||
|
|
||||||
systeminformation@5.30.8:
|
systeminformation@5.31.6:
|
||||||
resolution: {integrity: sha512-imB8LwJCc2DkufKlSRHfzbjhheGzpg1P31A4c55IKTq/ll6Agn1rhBOY+WmS/hyg5inGFp7AyZIK0gvq5rFO2Q==}
|
resolution: {integrity: sha512-Uv2b2uGGM6ns+26czgW2cYRabYdnswM0ddSOOlryHOaelzsmDSet1iM/NT7VOYxW8x/BW+HkY+b1Ve2pLTSGSA==}
|
||||||
engines: {node: '>=8.0.0'}
|
engines: {node: '>=8.0.0'}
|
||||||
os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android]
|
os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android]
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@@ -4187,14 +4187,14 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
lodash.camelcase: 4.3.0
|
lodash.camelcase: 4.3.0
|
||||||
long: 5.3.2
|
long: 5.3.2
|
||||||
protobufjs: 7.5.5
|
protobufjs: 7.5.8
|
||||||
yargs: 17.7.2
|
yargs: 17.7.2
|
||||||
|
|
||||||
'@grpc/proto-loader@0.8.0':
|
'@grpc/proto-loader@0.8.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
lodash.camelcase: 4.3.0
|
lodash.camelcase: 4.3.0
|
||||||
long: 5.3.2
|
long: 5.3.2
|
||||||
protobufjs: 7.5.5
|
protobufjs: 7.5.8
|
||||||
yargs: 17.7.2
|
yargs: 17.7.2
|
||||||
|
|
||||||
'@headlessui/react@2.2.10(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
|
'@headlessui/react@2.2.10(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
|
||||||
@@ -4405,34 +4405,34 @@ snapshots:
|
|||||||
'@tybys/wasm-util': 0.9.0
|
'@tybys/wasm-util': 0.9.0
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/env@16.2.4': {}
|
'@next/env@16.2.6': {}
|
||||||
|
|
||||||
'@next/eslint-plugin-next@15.5.11':
|
'@next/eslint-plugin-next@15.5.11':
|
||||||
dependencies:
|
dependencies:
|
||||||
fast-glob: 3.3.1
|
fast-glob: 3.3.1
|
||||||
|
|
||||||
'@next/swc-darwin-arm64@16.2.4':
|
'@next/swc-darwin-arm64@16.2.6':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-darwin-x64@16.2.4':
|
'@next/swc-darwin-x64@16.2.6':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-linux-arm64-gnu@16.2.4':
|
'@next/swc-linux-arm64-gnu@16.2.6':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-linux-arm64-musl@16.2.4':
|
'@next/swc-linux-arm64-musl@16.2.6':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-linux-x64-gnu@16.2.4':
|
'@next/swc-linux-x64-gnu@16.2.6':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-linux-x64-musl@16.2.4':
|
'@next/swc-linux-x64-musl@16.2.6':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-win32-arm64-msvc@16.2.4':
|
'@next/swc-win32-arm64-msvc@16.2.6':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-win32-x64-msvc@16.2.4':
|
'@next/swc-win32-x64-msvc@16.2.6':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@nodelib/fs.scandir@2.1.5':
|
'@nodelib/fs.scandir@2.1.5':
|
||||||
@@ -4458,24 +4458,24 @@ snapshots:
|
|||||||
|
|
||||||
'@protobufjs/base64@1.1.2': {}
|
'@protobufjs/base64@1.1.2': {}
|
||||||
|
|
||||||
'@protobufjs/codegen@2.0.4': {}
|
'@protobufjs/codegen@2.0.5': {}
|
||||||
|
|
||||||
'@protobufjs/eventemitter@1.1.0': {}
|
'@protobufjs/eventemitter@1.1.0': {}
|
||||||
|
|
||||||
'@protobufjs/fetch@1.1.0':
|
'@protobufjs/fetch@1.1.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@protobufjs/aspromise': 1.1.2
|
'@protobufjs/aspromise': 1.1.2
|
||||||
'@protobufjs/inquire': 1.1.0
|
'@protobufjs/inquire': 1.1.1
|
||||||
|
|
||||||
'@protobufjs/float@1.0.2': {}
|
'@protobufjs/float@1.0.2': {}
|
||||||
|
|
||||||
'@protobufjs/inquire@1.1.0': {}
|
'@protobufjs/inquire@1.1.1': {}
|
||||||
|
|
||||||
'@protobufjs/path@1.1.2': {}
|
'@protobufjs/path@1.1.2': {}
|
||||||
|
|
||||||
'@protobufjs/pool@1.1.0': {}
|
'@protobufjs/pool@1.1.0': {}
|
||||||
|
|
||||||
'@protobufjs/utf8@1.1.0': {}
|
'@protobufjs/utf8@1.1.1': {}
|
||||||
|
|
||||||
'@react-aria/focus@3.22.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
|
'@react-aria/focus@3.22.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -4867,7 +4867,7 @@ snapshots:
|
|||||||
fast-glob: 3.3.3
|
fast-glob: 3.3.3
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
minimatch: 9.0.5
|
minimatch: 9.0.5
|
||||||
semver: 7.7.4
|
semver: 7.8.0
|
||||||
ts-api-utils: 2.1.0(typescript@5.7.3)
|
ts-api-utils: 2.1.0(typescript@5.7.3)
|
||||||
typescript: 5.7.3
|
typescript: 5.7.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@@ -5154,7 +5154,7 @@ snapshots:
|
|||||||
|
|
||||||
base64-js@1.5.1: {}
|
base64-js@1.5.1: {}
|
||||||
|
|
||||||
baseline-browser-mapping@2.10.27: {}
|
baseline-browser-mapping@2.10.29: {}
|
||||||
|
|
||||||
bcrypt-pbkdf@1.0.2:
|
bcrypt-pbkdf@1.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -5231,7 +5231,7 @@ snapshots:
|
|||||||
|
|
||||||
callsites@3.1.0: {}
|
callsites@3.1.0: {}
|
||||||
|
|
||||||
caniuse-lite@1.0.30001791: {}
|
caniuse-lite@1.0.30001792: {}
|
||||||
|
|
||||||
chai@5.3.3:
|
chai@5.3.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -5457,7 +5457,7 @@ snapshots:
|
|||||||
'@grpc/grpc-js': 1.14.3
|
'@grpc/grpc-js': 1.14.3
|
||||||
'@grpc/proto-loader': 0.7.15
|
'@grpc/proto-loader': 0.7.15
|
||||||
docker-modem: 5.0.7
|
docker-modem: 5.0.7
|
||||||
protobufjs: 7.5.5
|
protobufjs: 7.5.8
|
||||||
tar-fs: 2.1.4
|
tar-fs: 2.1.4
|
||||||
uuid: 10.0.0
|
uuid: 10.0.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@@ -6252,7 +6252,7 @@ snapshots:
|
|||||||
|
|
||||||
is-bun-module@2.0.0:
|
is-bun-module@2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
semver: 7.7.4
|
semver: 7.8.0
|
||||||
|
|
||||||
is-callable@1.2.7: {}
|
is-callable@1.2.7: {}
|
||||||
|
|
||||||
@@ -6573,7 +6573,7 @@ snapshots:
|
|||||||
|
|
||||||
make-dir@4.0.0:
|
make-dir@4.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
semver: 7.7.4
|
semver: 7.8.0
|
||||||
|
|
||||||
math-intrinsics@1.1.0: {}
|
math-intrinsics@1.1.0: {}
|
||||||
|
|
||||||
@@ -6637,7 +6637,7 @@ snapshots:
|
|||||||
|
|
||||||
net@1.0.2: {}
|
net@1.0.2: {}
|
||||||
|
|
||||||
next-i18next@15.4.3(@types/react@19.0.10)(i18next@25.10.9(typescript@5.7.3))(next@16.2.4(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react-i18next@15.5.3(i18next@25.10.9(typescript@5.7.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@5.7.3))(react@19.2.5):
|
next-i18next@15.4.3(@types/react@19.0.10)(i18next@25.10.9(typescript@5.7.3))(next@16.2.6(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react-i18next@15.5.3(i18next@25.10.9(typescript@5.7.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@5.7.3))(react@19.2.5):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.28.6
|
'@babel/runtime': 7.28.6
|
||||||
'@types/hoist-non-react-statics': 3.3.7(@types/react@19.0.10)
|
'@types/hoist-non-react-statics': 3.3.7(@types/react@19.0.10)
|
||||||
@@ -6645,31 +6645,31 @@ snapshots:
|
|||||||
hoist-non-react-statics: 3.3.2
|
hoist-non-react-statics: 3.3.2
|
||||||
i18next: 25.10.9(typescript@5.7.3)
|
i18next: 25.10.9(typescript@5.7.3)
|
||||||
i18next-fs-backend: 2.6.4
|
i18next-fs-backend: 2.6.4
|
||||||
next: 16.2.4(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
|
next: 16.2.6(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
|
||||||
react: 19.2.5
|
react: 19.2.5
|
||||||
react-i18next: 15.5.3(i18next@25.10.9(typescript@5.7.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@5.7.3)
|
react-i18next: 15.5.3(i18next@25.10.9(typescript@5.7.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@5.7.3)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@types/react'
|
- '@types/react'
|
||||||
|
|
||||||
next@16.2.4(react-dom@19.2.5(react@19.2.5))(react@19.2.5):
|
next@16.2.6(react-dom@19.2.5(react@19.2.5))(react@19.2.5):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@next/env': 16.2.4
|
'@next/env': 16.2.6
|
||||||
'@swc/helpers': 0.5.15
|
'@swc/helpers': 0.5.15
|
||||||
baseline-browser-mapping: 2.10.27
|
baseline-browser-mapping: 2.10.29
|
||||||
caniuse-lite: 1.0.30001791
|
caniuse-lite: 1.0.30001792
|
||||||
postcss: 8.4.31
|
postcss: 8.4.31
|
||||||
react: 19.2.5
|
react: 19.2.5
|
||||||
react-dom: 19.2.5(react@19.2.5)
|
react-dom: 19.2.5(react@19.2.5)
|
||||||
styled-jsx: 5.1.6(react@19.2.5)
|
styled-jsx: 5.1.6(react@19.2.5)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@next/swc-darwin-arm64': 16.2.4
|
'@next/swc-darwin-arm64': 16.2.6
|
||||||
'@next/swc-darwin-x64': 16.2.4
|
'@next/swc-darwin-x64': 16.2.6
|
||||||
'@next/swc-linux-arm64-gnu': 16.2.4
|
'@next/swc-linux-arm64-gnu': 16.2.6
|
||||||
'@next/swc-linux-arm64-musl': 16.2.4
|
'@next/swc-linux-arm64-musl': 16.2.6
|
||||||
'@next/swc-linux-x64-gnu': 16.2.4
|
'@next/swc-linux-x64-gnu': 16.2.6
|
||||||
'@next/swc-linux-x64-musl': 16.2.4
|
'@next/swc-linux-x64-musl': 16.2.6
|
||||||
'@next/swc-win32-arm64-msvc': 16.2.4
|
'@next/swc-win32-arm64-msvc': 16.2.6
|
||||||
'@next/swc-win32-x64-msvc': 16.2.4
|
'@next/swc-win32-x64-msvc': 16.2.6
|
||||||
sharp: 0.34.5
|
sharp: 0.34.5
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@babel/core'
|
- '@babel/core'
|
||||||
@@ -6847,18 +6847,18 @@ snapshots:
|
|||||||
object-assign: 4.1.1
|
object-assign: 4.1.1
|
||||||
react-is: 16.13.1
|
react-is: 16.13.1
|
||||||
|
|
||||||
protobufjs@7.5.5:
|
protobufjs@7.5.8:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@protobufjs/aspromise': 1.1.2
|
'@protobufjs/aspromise': 1.1.2
|
||||||
'@protobufjs/base64': 1.1.2
|
'@protobufjs/base64': 1.1.2
|
||||||
'@protobufjs/codegen': 2.0.4
|
'@protobufjs/codegen': 2.0.5
|
||||||
'@protobufjs/eventemitter': 1.1.0
|
'@protobufjs/eventemitter': 1.1.0
|
||||||
'@protobufjs/fetch': 1.1.0
|
'@protobufjs/fetch': 1.1.0
|
||||||
'@protobufjs/float': 1.0.2
|
'@protobufjs/float': 1.0.2
|
||||||
'@protobufjs/inquire': 1.1.0
|
'@protobufjs/inquire': 1.1.1
|
||||||
'@protobufjs/path': 1.1.2
|
'@protobufjs/path': 1.1.2
|
||||||
'@protobufjs/pool': 1.1.0
|
'@protobufjs/pool': 1.1.0
|
||||||
'@protobufjs/utf8': 1.1.0
|
'@protobufjs/utf8': 1.1.1
|
||||||
'@types/node': 25.5.0
|
'@types/node': 25.5.0
|
||||||
long: 5.3.2
|
long: 5.3.2
|
||||||
|
|
||||||
@@ -7124,7 +7124,7 @@ snapshots:
|
|||||||
|
|
||||||
semver@6.3.1: {}
|
semver@6.3.1: {}
|
||||||
|
|
||||||
semver@7.7.4: {}
|
semver@7.8.0: {}
|
||||||
|
|
||||||
set-function-length@1.2.2:
|
set-function-length@1.2.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -7154,7 +7154,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@img/colour': 1.1.0
|
'@img/colour': 1.1.0
|
||||||
detect-libc: 2.1.2
|
detect-libc: 2.1.2
|
||||||
semver: 7.7.4
|
semver: 7.8.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@img/sharp-darwin-arm64': 0.34.5
|
'@img/sharp-darwin-arm64': 0.34.5
|
||||||
'@img/sharp-darwin-x64': 0.34.5
|
'@img/sharp-darwin-x64': 0.34.5
|
||||||
@@ -7375,7 +7375,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@pkgr/core': 0.2.9
|
'@pkgr/core': 0.2.9
|
||||||
|
|
||||||
systeminformation@5.30.8: {}
|
systeminformation@5.31.6: {}
|
||||||
|
|
||||||
tabbable@6.4.0: {}
|
tabbable@6.4.0: {}
|
||||||
|
|
||||||
|
|||||||
@@ -344,15 +344,15 @@
|
|||||||
"address": "Adresse",
|
"address": "Adresse",
|
||||||
"expires": "Expire",
|
"expires": "Expire",
|
||||||
"never": "Jamais",
|
"never": "Jamais",
|
||||||
"user": "User",
|
"user": "Utilisateur",
|
||||||
"hostname": "Hostname",
|
"hostname": "Nom d'hôte",
|
||||||
"name": "Name",
|
"name": "Nom",
|
||||||
"client_version": "Client Version",
|
"client_version": "Version client",
|
||||||
"os": "OS",
|
"os": "OS",
|
||||||
"created": "Created",
|
"created": "Créé",
|
||||||
"authorized": "Authorized",
|
"authorized": "Autorisée",
|
||||||
"is_external": "Is External",
|
"is_external": "Externe",
|
||||||
"update_available": "Update Available",
|
"update_available": "Mise à jour disponible",
|
||||||
"tags": "Tags",
|
"tags": "Tags",
|
||||||
"last_seen": "Vu pour la dernière fois",
|
"last_seen": "Vu pour la dernière fois",
|
||||||
"now": "Maintenant",
|
"now": "Maintenant",
|
||||||
@@ -363,8 +363,8 @@
|
|||||||
"minutes": "{{number}}m",
|
"minutes": "{{number}}m",
|
||||||
"seconds": "{{number}}s",
|
"seconds": "{{number}}s",
|
||||||
"ago": "Il y a {{value}}",
|
"ago": "Il y a {{value}}",
|
||||||
"true": "Yes",
|
"true": "Oui",
|
||||||
"false": "No"
|
"false": "Non"
|
||||||
},
|
},
|
||||||
"technitium": {
|
"technitium": {
|
||||||
"totalQueries": "Requêtes",
|
"totalQueries": "Requêtes",
|
||||||
@@ -937,16 +937,16 @@
|
|||||||
"criticals": "Urgent"
|
"criticals": "Urgent"
|
||||||
},
|
},
|
||||||
"ntfy": {
|
"ntfy": {
|
||||||
"title": "Title",
|
"title": "Titre",
|
||||||
"priority": "Priority",
|
"priority": "Priorité",
|
||||||
"lastReceived": "Last Received",
|
"lastReceived": "Dernière réception",
|
||||||
"message": "Message",
|
"message": "Message",
|
||||||
"tags": "Tags",
|
"tags": "Tags",
|
||||||
"none": "None",
|
"none": "Aucun",
|
||||||
"min": "Min",
|
"min": "Min",
|
||||||
"low": "Low",
|
"low": "Bas",
|
||||||
"default": "Default",
|
"default": "Défaut",
|
||||||
"high": "High",
|
"high": "Haut",
|
||||||
"urgent": "Urgent"
|
"urgent": "Urgent"
|
||||||
},
|
},
|
||||||
"plantit": {
|
"plantit": {
|
||||||
|
|||||||
@@ -67,14 +67,14 @@
|
|||||||
"empty_data": "Статус подсистемы неизвестен"
|
"empty_data": "Статус подсистемы неизвестен"
|
||||||
},
|
},
|
||||||
"unifi_drive": {
|
"unifi_drive": {
|
||||||
"healthy": "Healthy",
|
"healthy": "Здоров",
|
||||||
"degraded": "Degraded",
|
"degraded": "Деградация",
|
||||||
"no_data": "No storage data available"
|
"no_data": "Нет доступных данных о хранилище"
|
||||||
},
|
},
|
||||||
"docker": {
|
"docker": {
|
||||||
"rx": "RX",
|
"rx": "RX",
|
||||||
"tx": "TX",
|
"tx": "TX",
|
||||||
"mem": "Память",
|
"mem": "ОЗУ",
|
||||||
"cpu": "ЦП",
|
"cpu": "ЦП",
|
||||||
"running": "Запущено",
|
"running": "Запущено",
|
||||||
"offline": "Не в сети",
|
"offline": "Не в сети",
|
||||||
@@ -184,15 +184,15 @@
|
|||||||
},
|
},
|
||||||
"tautulli": {
|
"tautulli": {
|
||||||
"playing": "Играет",
|
"playing": "Играет",
|
||||||
"transcoding": "Транскодируется",
|
"transcoding": "Перекодируется",
|
||||||
"bitrate": "Битрейт",
|
"bitrate": "Битрейт",
|
||||||
"no_active": "Нет активных стримов",
|
"no_active": "Нет активных потоков",
|
||||||
"plex_connection_error": "Проверка соединения Plex"
|
"plex_connection_error": "Проверка соединения Plex"
|
||||||
},
|
},
|
||||||
"tracearr": {
|
"tracearr": {
|
||||||
"no_active": "Нет активных потоков",
|
"no_active": "Нет активных потоков",
|
||||||
"streams": "Потоки",
|
"streams": "Потоки",
|
||||||
"transcodes": "Transcodes",
|
"transcodes": "Перекодирования",
|
||||||
"directplay": "Прямое воспроизведение",
|
"directplay": "Прямое воспроизведение",
|
||||||
"bitrate": "Битрейт"
|
"bitrate": "Битрейт"
|
||||||
},
|
},
|
||||||
@@ -215,18 +215,18 @@
|
|||||||
"tv": "Сериалы"
|
"tv": "Сериалы"
|
||||||
},
|
},
|
||||||
"sabnzbd": {
|
"sabnzbd": {
|
||||||
"rate": "",
|
"rate": "Скорость",
|
||||||
"queue": "Очередь",
|
"queue": "Очередь",
|
||||||
"timeleft": "Осталось"
|
"timeleft": "Осталось"
|
||||||
},
|
},
|
||||||
"rutorrent": {
|
"rutorrent": {
|
||||||
"active": "Активно",
|
"active": "Активно",
|
||||||
"upload": "Загрузка",
|
"upload": "Отдача",
|
||||||
"download": "Скачивание"
|
"download": "Скачивание"
|
||||||
},
|
},
|
||||||
"transmission": {
|
"transmission": {
|
||||||
"download": "Скачивание",
|
"download": "Скачивание",
|
||||||
"upload": "Загрузка",
|
"upload": "Отдача",
|
||||||
"leech": "Лич",
|
"leech": "Лич",
|
||||||
"seed": "Сид"
|
"seed": "Сид"
|
||||||
},
|
},
|
||||||
@@ -295,7 +295,7 @@
|
|||||||
"available": "Доступно"
|
"available": "Доступно"
|
||||||
},
|
},
|
||||||
"seerr": {
|
"seerr": {
|
||||||
"pending": "Pending",
|
"pending": "Ожидают",
|
||||||
"approved": "Одобрено",
|
"approved": "Одобрено",
|
||||||
"available": "Доступно",
|
"available": "Доступно",
|
||||||
"completed": "Завершено",
|
"completed": "Завершено",
|
||||||
@@ -344,16 +344,16 @@
|
|||||||
"address": "Адрес",
|
"address": "Адрес",
|
||||||
"expires": "Истекает",
|
"expires": "Истекает",
|
||||||
"never": "Никогда",
|
"never": "Никогда",
|
||||||
"user": "User",
|
"user": "Пользователь",
|
||||||
"hostname": "Hostname",
|
"hostname": "Имя хоста",
|
||||||
"name": "Name",
|
"name": "Имя",
|
||||||
"client_version": "Client Version",
|
"client_version": "Версия клиента",
|
||||||
"os": "OS",
|
"os": "ОС",
|
||||||
"created": "Created",
|
"created": "Создано",
|
||||||
"authorized": "Authorized",
|
"authorized": "Авторизовано",
|
||||||
"is_external": "Is External",
|
"is_external": "Внешний",
|
||||||
"update_available": "Update Available",
|
"update_available": "Доступно обновление",
|
||||||
"tags": "Tags",
|
"tags": "Теги",
|
||||||
"last_seen": "Последнее посещение",
|
"last_seen": "Последнее посещение",
|
||||||
"now": "Только что",
|
"now": "Только что",
|
||||||
"years": "{{number}}г",
|
"years": "{{number}}г",
|
||||||
@@ -363,8 +363,8 @@
|
|||||||
"minutes": "{{number}}м",
|
"minutes": "{{number}}м",
|
||||||
"seconds": "{{number}}с",
|
"seconds": "{{number}}с",
|
||||||
"ago": "{{value}} назад",
|
"ago": "{{value}} назад",
|
||||||
"true": "Yes",
|
"true": "Да",
|
||||||
"false": "No"
|
"false": "Нет"
|
||||||
},
|
},
|
||||||
"technitium": {
|
"technitium": {
|
||||||
"totalQueries": "Запросы",
|
"totalQueries": "Запросы",
|
||||||
@@ -632,12 +632,12 @@
|
|||||||
},
|
},
|
||||||
"pangolin": {
|
"pangolin": {
|
||||||
"orgs": "Orgs",
|
"orgs": "Orgs",
|
||||||
"sites": "Sites",
|
"sites": "Сайты",
|
||||||
"resources": "Resources",
|
"resources": "Ресурсы",
|
||||||
"targets": "Targets",
|
"targets": "Цели",
|
||||||
"traffic": "Traffic",
|
"traffic": "Трафик",
|
||||||
"in": "In",
|
"in": "Входящий",
|
||||||
"out": "Out"
|
"out": "Исходящий"
|
||||||
},
|
},
|
||||||
"peanut": {
|
"peanut": {
|
||||||
"battery_charge": "Заряд батареи",
|
"battery_charge": "Заряд батареи",
|
||||||
@@ -736,8 +736,8 @@
|
|||||||
"volumeAvailable": "Доступно"
|
"volumeAvailable": "Доступно"
|
||||||
},
|
},
|
||||||
"dispatcharr": {
|
"dispatcharr": {
|
||||||
"channels": "Channels",
|
"channels": "Каналы",
|
||||||
"streams": "Streams"
|
"streams": "Потоки"
|
||||||
},
|
},
|
||||||
"mylar": {
|
"mylar": {
|
||||||
"series": "Серии",
|
"series": "Серии",
|
||||||
@@ -828,10 +828,10 @@
|
|||||||
"series": "Серии"
|
"series": "Серии"
|
||||||
},
|
},
|
||||||
"booklore": {
|
"booklore": {
|
||||||
"libraries": "Libraries",
|
"libraries": "Библиотеки",
|
||||||
"books": "Books",
|
"books": "Книги",
|
||||||
"reading": "Reading",
|
"reading": "Читаю",
|
||||||
"finished": "Finished"
|
"finished": "Завершено"
|
||||||
},
|
},
|
||||||
"jdownloader": {
|
"jdownloader": {
|
||||||
"downloadCount": "Очередь",
|
"downloadCount": "Очередь",
|
||||||
@@ -937,17 +937,17 @@
|
|||||||
"criticals": "Критические"
|
"criticals": "Критические"
|
||||||
},
|
},
|
||||||
"ntfy": {
|
"ntfy": {
|
||||||
"title": "Title",
|
"title": "Название",
|
||||||
"priority": "Priority",
|
"priority": "Приоритет",
|
||||||
"lastReceived": "Last Received",
|
"lastReceived": "Last Received",
|
||||||
"message": "Message",
|
"message": "Сообщение",
|
||||||
"tags": "Tags",
|
"tags": "Теги",
|
||||||
"none": "None",
|
"none": "Отсутствует",
|
||||||
"min": "Min",
|
"min": "Минимальный",
|
||||||
"low": "Low",
|
"low": "Низкий",
|
||||||
"default": "Default",
|
"default": "По-умолчанию",
|
||||||
"high": "High",
|
"high": "Высокий",
|
||||||
"urgent": "Urgent"
|
"urgent": "Срочный"
|
||||||
},
|
},
|
||||||
"plantit": {
|
"plantit": {
|
||||||
"events": "События",
|
"events": "События",
|
||||||
@@ -1087,7 +1087,7 @@
|
|||||||
},
|
},
|
||||||
"gitlab": {
|
"gitlab": {
|
||||||
"groups": "Группы",
|
"groups": "Группы",
|
||||||
"issues": "Issues",
|
"issues": "Задачи",
|
||||||
"merges": "Мердж-реквесты",
|
"merges": "Мердж-реквесты",
|
||||||
"projects": "Проекты"
|
"projects": "Проекты"
|
||||||
},
|
},
|
||||||
@@ -1150,26 +1150,26 @@
|
|||||||
"nextRenewingSubscription": "Следующая оплата"
|
"nextRenewingSubscription": "Следующая оплата"
|
||||||
},
|
},
|
||||||
"unraid": {
|
"unraid": {
|
||||||
"STARTED": "Started",
|
"STARTED": "Запущено",
|
||||||
"STOPPED": "Stopped",
|
"STOPPED": "Остановлено",
|
||||||
"NEW_ARRAY": "Новый массив",
|
"NEW_ARRAY": "Новый массив",
|
||||||
"RECON_DISK": "Reconstructing Disk",
|
"RECON_DISK": "Восстановление Диска",
|
||||||
"DISABLE_DISK": "Disk Disabled",
|
"DISABLE_DISK": "Диск отключен",
|
||||||
"SWAP_DSBL": "Swap Disable",
|
"SWAP_DSBL": "Swap отключён",
|
||||||
"INVALID_EXPANSION": "Invalid Expansion",
|
"INVALID_EXPANSION": "Неверное Расширение",
|
||||||
"PARITY_NOT_BIGGEST": "Parity Not Biggest",
|
"PARITY_NOT_BIGGEST": "Parity Not Biggest",
|
||||||
"TOO_MANY_MISSING_DISKS": "Too Many Missing Disks",
|
"TOO_MANY_MISSING_DISKS": "Слишком много отсутствующих дисков",
|
||||||
"NEW_DISK_TOO_SMALL": "New Disk Too Small",
|
"NEW_DISK_TOO_SMALL": "Новый диск слишком мал",
|
||||||
"NO_DATA_DISKS": "No Data Disks",
|
"NO_DATA_DISKS": "Нет дисков данных",
|
||||||
"notifications": "Уведомления",
|
"notifications": "Уведомления",
|
||||||
"status": "Статус",
|
"status": "Статус",
|
||||||
"cpu": "ЦП",
|
"cpu": "ЦП",
|
||||||
"memoryUsed": "Использовано ОЗУ",
|
"memoryUsed": "Использовано ОЗУ",
|
||||||
"memoryAvailable": "Memory Available",
|
"memoryAvailable": "Доступная память",
|
||||||
"arrayUsed": "Array Used",
|
"arrayUsed": "Array Used",
|
||||||
"arrayFree": "Array Free",
|
"arrayFree": "Array Free",
|
||||||
"poolUsed": "{{pool}} Used",
|
"poolUsed": "{{pool}} Использовано",
|
||||||
"poolFree": "{{pool}} Free"
|
"poolFree": "{{pool}} Свободно"
|
||||||
},
|
},
|
||||||
"backrest": {
|
"backrest": {
|
||||||
"num_plans": "Plans",
|
"num_plans": "Plans",
|
||||||
@@ -1180,29 +1180,29 @@
|
|||||||
"bytes_added_30": "Bytes Added"
|
"bytes_added_30": "Bytes Added"
|
||||||
},
|
},
|
||||||
"yourspotify": {
|
"yourspotify": {
|
||||||
"songs": "Songs",
|
"songs": "Треков",
|
||||||
"time": "Время",
|
"time": "Время",
|
||||||
"artists": "Artists"
|
"artists": "Исполнителей"
|
||||||
},
|
},
|
||||||
"arcane": {
|
"arcane": {
|
||||||
"containers": "Containers",
|
"containers": "Контейнеров",
|
||||||
"images": "Images",
|
"images": "Образов",
|
||||||
"image_updates": "Image Updates",
|
"image_updates": "Обновлений",
|
||||||
"images_unused": "Unused",
|
"images_unused": "Не используется",
|
||||||
"environment_required": "Environment ID Required"
|
"environment_required": "Требуется ID окружения"
|
||||||
},
|
},
|
||||||
"dockhand": {
|
"dockhand": {
|
||||||
"running": "Running",
|
"running": "Запущено",
|
||||||
"stopped": "Stopped",
|
"stopped": "Остановлено",
|
||||||
"cpu": "CPU",
|
"cpu": "ЦП",
|
||||||
"memory": "Memory",
|
"memory": "ОЗУ",
|
||||||
"images": "Images",
|
"images": "Образов",
|
||||||
"volumes": "Volumes",
|
"volumes": "Томов",
|
||||||
"events_today": "Events Today",
|
"events_today": "Событий сегодня",
|
||||||
"pending_updates": "Pending Updates",
|
"pending_updates": "Обновлений",
|
||||||
"stacks": "Stacks",
|
"stacks": "Стеков",
|
||||||
"paused": "Paused",
|
"paused": "На паузе",
|
||||||
"total": "Total",
|
"total": "Всего",
|
||||||
"environment_not_found": "Среда не найдена"
|
"environment_not_found": "Среда не найдена"
|
||||||
},
|
},
|
||||||
"sparkyfitness": {
|
"sparkyfitness": {
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ import { Cookie, CookieJar } from "tough-cookie";
|
|||||||
|
|
||||||
const cookieJar = new CookieJar();
|
const cookieJar = new CookieJar();
|
||||||
|
|
||||||
export function setCookieHeader(url, params) {
|
export function setCookieHeader(url, params, { overwrite = false } = {}) {
|
||||||
// add cookie header, if we have one in the jar
|
// add cookie header, if we have one in the jar
|
||||||
const existingCookie = cookieJar.getCookieStringSync(url.toString());
|
const existingCookie = cookieJar.getCookieStringSync(url.toString());
|
||||||
if (existingCookie) {
|
if (existingCookie) {
|
||||||
params.headers = params.headers ?? {};
|
params.headers = params.headers ?? {};
|
||||||
const cookieHeader = params.cookieHeader ?? "Cookie";
|
const cookieHeader = params.cookieHeader ?? "Cookie";
|
||||||
if (!params.headers[cookieHeader]) {
|
if (overwrite || !params.headers[cookieHeader]) {
|
||||||
params.headers[cookieHeader] = existingCookie;
|
params.headers[cookieHeader] = existingCookie;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,4 +54,17 @@ describe("utils/proxy/cookie-jar", () => {
|
|||||||
|
|
||||||
expect(params.headers.Cookie).toBe("manual=1");
|
expect(params.headers.Cookie).toBe("manual=1");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("overwrites an existing cookie header when requested", async () => {
|
||||||
|
const { addCookieToJar, setCookieHeader } = await import("./cookie-jar");
|
||||||
|
|
||||||
|
const url = new URL("http://example5.test/path");
|
||||||
|
addCookieToJar(url, { "set-cookie": ["sid=1; Path=/"] });
|
||||||
|
|
||||||
|
const params = { headers: { Cookie: "stale=1" } };
|
||||||
|
setCookieHeader(url, params, { overwrite: true });
|
||||||
|
|
||||||
|
expect(params.headers.Cookie).toContain("sid=1");
|
||||||
|
expect(params.headers.Cookie).not.toContain("stale=1");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ export default function createUnifiProxyHandler({
|
|||||||
}
|
}
|
||||||
|
|
||||||
addCookieToJar(url, responseHeaders);
|
addCookieToJar(url, responseHeaders);
|
||||||
setCookieHeader(url, params);
|
setCookieHeader(url, params, { overwrite: true });
|
||||||
|
|
||||||
[status, contentType, data, responseHeaders] = await httpProxy(url, params);
|
[status, contentType, data, responseHeaders] = await httpProxy(url, params);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ function addCookieHandler(url, params) {
|
|||||||
// handle cookies during redirects
|
// handle cookies during redirects
|
||||||
params.beforeRedirect = (options, responseInfo) => {
|
params.beforeRedirect = (options, responseInfo) => {
|
||||||
addCookieToJar(options.href, responseInfo.headers);
|
addCookieToJar(options.href, responseInfo.headers);
|
||||||
setCookieHeader(options.href, options);
|
setCookieHeader(options.href, options, { overwrite: true });
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -348,7 +348,9 @@ describe("utils/proxy/http httpProxy", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
expect(cookieJar.addCookieToJar).toHaveBeenCalledWith("http://example.com/redirect", { "set-cookie": ["a=b"] });
|
expect(cookieJar.addCookieToJar).toHaveBeenCalledWith("http://example.com/redirect", { "set-cookie": ["a=b"] });
|
||||||
expect(cookieJar.setCookieHeader).toHaveBeenCalledWith("http://example.com/redirect", expect.any(Object));
|
expect(cookieJar.setCookieHeader).toHaveBeenCalledWith("http://example.com/redirect", expect.any(Object), {
|
||||||
|
overwrite: true,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("supports gzip-compressed responses", async () => {
|
it("supports gzip-compressed responses", async () => {
|
||||||
|
|||||||
@@ -8,6 +8,13 @@ export default function validateWidgetData(widget, endpoint, data) {
|
|||||||
let dataParsed = data;
|
let dataParsed = data;
|
||||||
let error;
|
let error;
|
||||||
let mapping;
|
let mapping;
|
||||||
|
const mappings = widgets[widget.type]?.mappings;
|
||||||
|
if (mappings) {
|
||||||
|
mapping = Object.values(mappings).find((m) => m.endpoint === endpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapping?.allowEmpty && Buffer.isBuffer(data) && data.length === 0) return true;
|
||||||
|
|
||||||
if (Buffer.isBuffer(data)) {
|
if (Buffer.isBuffer(data)) {
|
||||||
try {
|
try {
|
||||||
dataParsed = JSON.parse(data);
|
dataParsed = JSON.parse(data);
|
||||||
@@ -23,15 +30,11 @@ export default function validateWidgetData(widget, endpoint, data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dataParsed && Object.entries(dataParsed).length) {
|
if (dataParsed && Object.entries(dataParsed).length) {
|
||||||
const mappings = widgets[widget.type]?.mappings;
|
mapping?.validate?.forEach((key) => {
|
||||||
if (mappings) {
|
if (dataParsed[key] === undefined) {
|
||||||
mapping = Object.values(mappings).find((m) => m.endpoint === endpoint);
|
valid = false;
|
||||||
mapping?.validate?.forEach((key) => {
|
}
|
||||||
if (dataParsed[key] === undefined) {
|
});
|
||||||
valid = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { describe, expect, it, vi } from "vitest";
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
const { loggerError } = vi.hoisted(() => ({
|
const { loggerError } = vi.hoisted(() => ({
|
||||||
loggerError: vi.fn(),
|
loggerError: vi.fn(),
|
||||||
@@ -18,6 +18,10 @@ vi.mock("widgets/widgets", () => ({
|
|||||||
endpoint: "foo",
|
endpoint: "foo",
|
||||||
validate: ["a", "b"],
|
validate: ["a", "b"],
|
||||||
},
|
},
|
||||||
|
empty: {
|
||||||
|
endpoint: "empty",
|
||||||
|
allowEmpty: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -26,6 +30,10 @@ vi.mock("widgets/widgets", () => ({
|
|||||||
import validateWidgetData from "./validate-widget-data";
|
import validateWidgetData from "./validate-widget-data";
|
||||||
|
|
||||||
describe("utils/proxy/validate-widget-data", () => {
|
describe("utils/proxy/validate-widget-data", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
it("returns false when buffer JSON cannot be parsed", () => {
|
it("returns false when buffer JSON cannot be parsed", () => {
|
||||||
expect(validateWidgetData({ type: "test" }, "foo", Buffer.from("not json"))).toBe(false);
|
expect(validateWidgetData({ type: "test" }, "foo", Buffer.from("not json"))).toBe(false);
|
||||||
expect(loggerError).toHaveBeenCalled();
|
expect(loggerError).toHaveBeenCalled();
|
||||||
@@ -41,4 +49,9 @@ describe("utils/proxy/validate-widget-data", () => {
|
|||||||
expect(validateWidgetData({ type: "test" }, "foo", Buffer.from(JSON.stringify({ a: 1 })))).toBe(false);
|
expect(validateWidgetData({ type: "test" }, "foo", Buffer.from(JSON.stringify({ a: 1 })))).toBe(false);
|
||||||
expect(loggerError).toHaveBeenCalled();
|
expect(loggerError).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("allows empty buffer responses for mappings that explicitly allow them", () => {
|
||||||
|
expect(validateWidgetData({ type: "test" }, "empty", Buffer.from(""))).toBe(true);
|
||||||
|
expect(loggerError).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -50,10 +50,10 @@ export default function Component({ service }) {
|
|||||||
streams?.channels &&
|
streams?.channels &&
|
||||||
streams.channels.map((activeStream) => (
|
streams.channels.map((activeStream) => (
|
||||||
<StreamEntry
|
<StreamEntry
|
||||||
title={activeStream.stream_name}
|
title={activeStream.channel_name ?? activeStream.stream_name}
|
||||||
clients={activeStream.clients.length}
|
clients={activeStream.clients.length}
|
||||||
bitrate={activeStream.avg_bitrate}
|
bitrate={activeStream.avg_bitrate}
|
||||||
key={activeStream.stream_name}
|
key={activeStream.channel_name ?? activeStream.stream_name}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ describe("widgets/dispatcharr/component", () => {
|
|||||||
useWidgetAPI.mockReturnValueOnce({ data: [{}, {}, {}], error: undefined }).mockReturnValueOnce({
|
useWidgetAPI.mockReturnValueOnce({ data: [{}, {}, {}], error: undefined }).mockReturnValueOnce({
|
||||||
data: {
|
data: {
|
||||||
count: 1,
|
count: 1,
|
||||||
channels: [{ stream_name: "Stream1", clients: [{}, {}], avg_bitrate: "1000kbps" }],
|
channels: [{ channel_name: "Stream1", clients: [{}, {}], avg_bitrate: "1000kbps" }],
|
||||||
},
|
},
|
||||||
error: undefined,
|
error: undefined,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import getServiceWidget from "utils/config/service-helpers";
|
import getServiceWidget from "utils/config/service-helpers";
|
||||||
import createLogger from "utils/logger";
|
import createLogger from "utils/logger";
|
||||||
import { asJson, formatApiCall, sanitizeErrorURL } from "utils/proxy/api-helpers";
|
import { asJson, formatApiCall, sanitizeErrorURL } from "utils/proxy/api-helpers";
|
||||||
import { addCookieToJar } from "utils/proxy/cookie-jar";
|
import { addCookieToJar, setCookieHeader } from "utils/proxy/cookie-jar";
|
||||||
import { httpProxy } from "utils/proxy/http";
|
import { httpProxy } from "utils/proxy/http";
|
||||||
import widgets from "widgets/widgets";
|
import widgets from "widgets/widgets";
|
||||||
|
|
||||||
@@ -57,6 +57,7 @@ export default async function frigateProxyHandler(req, res, map) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addCookieToJar(url, loginResponseHeaders);
|
addCookieToJar(url, loginResponseHeaders);
|
||||||
|
setCookieHeader(url, params, { overwrite: true });
|
||||||
// Retry original request with cookie set
|
// Retry original request with cookie set
|
||||||
[status, , data] = await httpProxy(url, params);
|
[status, , data] = await httpProxy(url, params);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ const { httpProxy, getServiceWidget, cookieJar, logger } = vi.hoisted(() => ({
|
|||||||
getServiceWidget: vi.fn(),
|
getServiceWidget: vi.fn(),
|
||||||
cookieJar: {
|
cookieJar: {
|
||||||
addCookieToJar: vi.fn(),
|
addCookieToJar: vi.fn(),
|
||||||
|
setCookieHeader: vi.fn(),
|
||||||
},
|
},
|
||||||
logger: {
|
logger: {
|
||||||
debug: vi.fn(),
|
debug: vi.fn(),
|
||||||
@@ -130,6 +131,9 @@ describe("widgets/frigate/proxy", () => {
|
|||||||
await frigateProxyHandler(req, res);
|
await frigateProxyHandler(req, res);
|
||||||
|
|
||||||
expect(cookieJar.addCookieToJar).toHaveBeenCalled();
|
expect(cookieJar.addCookieToJar).toHaveBeenCalled();
|
||||||
|
expect(cookieJar.setCookieHeader).toHaveBeenCalledWith("http://frigate/api/stats", expect.any(Object), {
|
||||||
|
overwrite: true,
|
||||||
|
});
|
||||||
expect(res.statusCode).toBe(200);
|
expect(res.statusCode).toBe(200);
|
||||||
expect(res.body).toEqual({ num_cameras: 2, uptime: 123, version: "1.0" });
|
expect(res.body).toEqual({ num_cameras: 2, uptime: 123, version: "1.0" });
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
|
import { asJson } from "utils/proxy/api-helpers";
|
||||||
import credentialedProxyHandler from "utils/proxy/handlers/credentialed";
|
import credentialedProxyHandler from "utils/proxy/handlers/credentialed";
|
||||||
|
|
||||||
|
const noMessages = {
|
||||||
|
title: null,
|
||||||
|
message: null,
|
||||||
|
priority: 3,
|
||||||
|
time: null,
|
||||||
|
tags: [],
|
||||||
|
};
|
||||||
|
|
||||||
const widget = {
|
const widget = {
|
||||||
api: "{url}/{endpoint}",
|
api: "{url}/{endpoint}",
|
||||||
proxyHandler: credentialedProxyHandler,
|
proxyHandler: credentialedProxyHandler,
|
||||||
@@ -7,6 +16,14 @@ const widget = {
|
|||||||
mappings: {
|
mappings: {
|
||||||
messages: {
|
messages: {
|
||||||
endpoint: "{topic}/json?poll=1&since=latest",
|
endpoint: "{topic}/json?poll=1&since=latest",
|
||||||
|
allowEmpty: true,
|
||||||
|
map: (data) => {
|
||||||
|
if (Buffer.isBuffer(data) && data.length === 0) {
|
||||||
|
return noMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
return asJson(data);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { describe, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
|
|
||||||
import { expectWidgetConfigShape } from "test-utils/widget-config";
|
import { expectWidgetConfigShape } from "test-utils/widget-config";
|
||||||
|
|
||||||
@@ -8,4 +8,18 @@ describe("ntfy widget config", () => {
|
|||||||
it("exports a valid widget config", () => {
|
it("exports a valid widget config", () => {
|
||||||
expectWidgetConfigShape(widget);
|
expectWidgetConfigShape(widget);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("maps an empty latest message response to the no messages state", () => {
|
||||||
|
expect(widget.mappings.messages.map(Buffer.from(""))).toEqual({
|
||||||
|
title: null,
|
||||||
|
message: null,
|
||||||
|
priority: 3,
|
||||||
|
time: null,
|
||||||
|
tags: [],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("parses latest message responses", () => {
|
||||||
|
expect(widget.mappings.messages.map(Buffer.from('{"message":"hello"}'))).toEqual({ message: "hello" });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ const widget = {
|
|||||||
},
|
},
|
||||||
"nodes/localhost/tasks": {
|
"nodes/localhost/tasks": {
|
||||||
endpoint: "nodes/localhost/tasks",
|
endpoint: "nodes/localhost/tasks",
|
||||||
|
params: ["errors", "limit", "since"],
|
||||||
},
|
},
|
||||||
"nodes/localhost/status": {
|
"nodes/localhost/status": {
|
||||||
endpoint: "nodes/localhost/status",
|
endpoint: "nodes/localhost/status",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { describe, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
|
|
||||||
import { expectWidgetConfigShape } from "test-utils/widget-config";
|
import { expectWidgetConfigShape } from "test-utils/widget-config";
|
||||||
|
|
||||||
@@ -8,4 +8,8 @@ describe("proxmoxbackupserver widget config", () => {
|
|||||||
it("exports a valid widget config", () => {
|
it("exports a valid widget config", () => {
|
||||||
expectWidgetConfigShape(widget);
|
expectWidgetConfigShape(widget);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("requires failed task query params for the tasks endpoint", () => {
|
||||||
|
expect(widget.mappings["nodes/localhost/tasks"].params).toEqual(["errors", "limit", "since"]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -41,12 +41,12 @@ export default async function qbittorrentProxyHandler(req, res) {
|
|||||||
if (status === 403) {
|
if (status === 403) {
|
||||||
[status, data] = await login(widget);
|
[status, data] = await login(widget);
|
||||||
|
|
||||||
if (status !== 200) {
|
if (![200, 204].includes(status)) {
|
||||||
logger.error("HTTP %d logging in to qBittorrent. Data: %s", status, data);
|
logger.error("HTTP %d logging in to qBittorrent. Data: %s", status, data);
|
||||||
return res.status(status).end(data);
|
return res.status(status).end(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.toString() !== "Ok.") {
|
if (status === 200 && data.toString() !== "Ok.") {
|
||||||
logger.error("Error logging in to qBittorrent: Data: %s", data);
|
logger.error("Error logging in to qBittorrent: Data: %s", data);
|
||||||
return res.status(401).end(data);
|
return res.status(401).end(data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,25 @@ describe("widgets/qbittorrent/proxy", () => {
|
|||||||
expect(res.body).toEqual(Buffer.from("data"));
|
expect(res.body).toEqual(Buffer.from("data"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("accepts qBittorrent 5.2.0 no-content login responses", async () => {
|
||||||
|
getServiceWidget.mockResolvedValue({ url: "http://qb", username: "u", password: "p" });
|
||||||
|
|
||||||
|
httpProxy
|
||||||
|
.mockResolvedValueOnce([403, "application/json", Buffer.from("nope")])
|
||||||
|
.mockResolvedValueOnce([204, null, Buffer.from("")])
|
||||||
|
.mockResolvedValueOnce([200, "application/json", Buffer.from("data")]);
|
||||||
|
|
||||||
|
const req = { query: { group: "g", service: "svc", endpoint: "torrents/info", index: "0" } };
|
||||||
|
const res = createMockRes();
|
||||||
|
|
||||||
|
await qbittorrentProxyHandler(req, res);
|
||||||
|
|
||||||
|
expect(httpProxy).toHaveBeenCalledTimes(3);
|
||||||
|
expect(httpProxy.mock.calls[1][0]).toBe("http://qb/api/v2/auth/login");
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
expect(res.body).toEqual(Buffer.from("data"));
|
||||||
|
});
|
||||||
|
|
||||||
it("returns 401 when login succeeds but response body is not Ok.", async () => {
|
it("returns 401 when login succeeds but response body is not Ok.", async () => {
|
||||||
getServiceWidget.mockResolvedValue({ url: "http://qb", username: "u", password: "p" });
|
getServiceWidget.mockResolvedValue({ url: "http://qb", username: "u", password: "p" });
|
||||||
|
|
||||||
|
|||||||
@@ -30,10 +30,12 @@ export default function Component({ service }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (statsData.completed === undefined) {
|
if (
|
||||||
// Newer versions added "completed", fallback to available
|
statsData.completed === undefined &&
|
||||||
widget.fields = widget.fields.filter((field) => field !== "completed");
|
(widget.fields.includes("completed") || widget.fields.includes("available"))
|
||||||
widget.fields.push("available");
|
) {
|
||||||
|
// Fallback to "available" if "completed" requested but not available
|
||||||
|
widget.fields = widget.fields.map((field) => (field === "completed" ? "available" : field));
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -86,6 +86,9 @@ describe("widgets/unifi/proxy", () => {
|
|||||||
expect(httpProxy).toHaveBeenCalledTimes(4);
|
expect(httpProxy).toHaveBeenCalledTimes(4);
|
||||||
expect(httpProxy.mock.calls[1][0].toString()).toContain("/proxy/network/api/self");
|
expect(httpProxy.mock.calls[1][0].toString()).toContain("/proxy/network/api/self");
|
||||||
expect(cookieJar.addCookieToJar).toHaveBeenCalled();
|
expect(cookieJar.addCookieToJar).toHaveBeenCalled();
|
||||||
|
expect(cookieJar.setCookieHeader).toHaveBeenLastCalledWith(expect.any(URL), expect.any(Object), {
|
||||||
|
overwrite: true,
|
||||||
|
});
|
||||||
expect(res.statusCode).toBe(200);
|
expect(res.statusCode).toBe(200);
|
||||||
expect(res.body).toEqual(Buffer.from("data"));
|
expect(res.body).toEqual(Buffer.from("data"));
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user