Compare commits

...

123 Commits

Author SHA1 Message Date
github-actions[bot]
948580917d chore(main): release 4.8.0 (#1377)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-01 14:55:55 -07:00
Eli Bosley
39e83b2aa1 feat: move activation code logic into the API (#1369)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added comprehensive activation code customization service with dynamic
theming, partner branding, and UI updates.
- Introduced new GraphQL types and public queries for activation code,
partner info, and theme data.
- Implemented new web UI stores and components for activation modal,
partner logos, and theme management.
- **Improvements**
- Removed legacy activation code scripts, PHP components, and plugin
references, streamlining activation logic.
- Enhanced configuration and environment support for activation and
theming features.
- Improved error handling, validation, and type safety in activation and
customization modules.
- **Bug Fixes**
- Fixed color code validation and path handling in customization
service.
- **Chores**
  - Added pre-commit linting hooks and related configuration.
  - Cleaned up test and development environment files.
- **Tests**
- Added extensive tests covering activation customization service
initialization, data handling, and file modifications.
  - Removed obsolete tests related to legacy activation code store.
- **Refactor**
- Migrated activation and partner branding logic from legacy scripts and
PHP to TypeScript services and GraphQL resolvers.
- Reorganized store and component architecture for activation-related
features.
- **Style**
- Updated UI components for improved branding, theming, accessibility,
and layout consistency.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Zack Spear <hi@zackspear.com>
2025-05-01 17:40:36 -04:00
Eli Bosley
831050f4e8 fix: 400 error when submitting connect settings 2025-05-01 17:03:19 -04:00
Eli Bosley
7ace6d3076 chore: change hotfix to a plus sign 2025-05-01 13:56:32 -04:00
Zack Spear
1ff3d7285e chore: update eligibility copy (#1376) 2025-05-01 10:30:35 -07:00
Pujit Mehrotra
874a507e60 [WIP] fix: authentication when booting into GUI mode (#1368)
Added detection of GUI mode to conditionally enhance session handling.
2025-04-30 23:31:26 -04:00
Michael Datelle
32c6fe6295 test: create tests for components batch 2 (#1365)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Refactor**
- Improved component tests by integrating Pinia's testing utilities for
more reliable store mocking and state management.
- Updated test setup to streamline plugin usage and remove unnecessary
configuration.
- Enhanced test clarity by relying on store state changes and Vue's
reactivity instead of manual mock updates.
- Simplified test cases by focusing on passed props and standardized
store mocking.
- **Chores**
  - Updated test directory structure for better organization.
  - Added additional test mocks for dependencies.
- **New Features**
- Added comprehensive tests for the ColorSwitcher component, verifying
UI elements and theme store interactions.
- Introduced tests for the DevSettings component, confirming UI
rendering and interaction behavior.
- Added detailed tests for the DowngradeOs component covering store
interactions and conditional UI rendering.
- Added new test suites for DummyServerSwitcher component, ensuring
correct rendering and reactive state updates.
- Added new test suites for HeaderOsVersion component, validating
version badge rendering and error state handling.
- Added new test suite for the I18nHost component, validating
internationalization context provisioning and error handling.
- Added a comprehensive test suite for the Modal component, covering UI
behavior, styling, and event handling.
- Added new test suite for the Registration component, verifying
rendering based on server state.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: mdatelle <mike@datelle.net>
2025-04-29 12:44:31 -04:00
Eli Bosley
586653ccc1 chore: add a prefix scalar instead of prefix plugin (#1361)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a new `PrefixedID` scalar type for all GraphQL IDs,
ensuring unique identifiers across multiple servers by prefixing IDs
with a server identifier.
- Added detailed documentation for the `PrefixedID` scalar in the API
schema.
- Grouped VM and parity check mutations under dedicated fields for
better organization.
- Added new scalar `Port` and input type `AccessUrlInput` for improved
type safety.

- **Refactor**
- Replaced all usages of standard `ID` or `String` with `PrefixedID` for
IDs in queries, mutations, and models.
- Consolidated ID handling by extending a common `Node` base class
across models, removing redundant `id` declarations.
- Updated GraphQL argument types and resolver signatures to explicitly
use `PrefixedID`.
- Updated GraphQL code generation to map `PrefixedID` to TypeScript
`string`.

- **Bug Fixes**
- Enhanced test assertions to verify API key creation timestamps are
strings.
  - Fixed internal property naming for registration ID.

- **Chores**
- Removed legacy ID prefix Apollo Server plugin in favor of the new
scalar approach.
  - Cleaned up imports and unused fields related to ID handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-04-29 12:22:18 -04:00
github-actions[bot]
c5a394eddf chore(main): release 4.7.0 (#1332)
🤖 I have created a release *beep* *boop*
---


## [4.7.0](https://github.com/unraid/api/compare/v4.6.6...v4.7.0)
(2025-04-24)


### Features

* add basic docker network listing
([#1317](https://github.com/unraid/api/issues/1317))
([c4fdff8](c4fdff8149))
* add permission documentation by using a custom decorator
([#1355](https://github.com/unraid/api/issues/1355))
([45ecab6](45ecab6914))
* basic vm controls ([#1293](https://github.com/unraid/api/issues/1293))
([bc3ca92](bc3ca92fb0))
* code first graphql
([#1347](https://github.com/unraid/api/issues/1347))
([f5724ab](f5724abffb))


### Bug Fixes

* container names always null
([#1335](https://github.com/unraid/api/issues/1335))
([8a5b238](8a5b23856c))
* **deps:** update all non-major dependencies
([#1337](https://github.com/unraid/api/issues/1337))
([2345732](234573264c))
* hide reboot notice for patch releases
([#1341](https://github.com/unraid/api/issues/1341))
([4b57439](4b5743906a))
* move docker mutations to the mutations resolver
([#1333](https://github.com/unraid/api/issues/1333))
([1bbe7d2](1bbe7d27b0))
* PR build issue
([457d338](457d338150))
* remove some unused fields from the report object
([#1342](https://github.com/unraid/api/issues/1342))
([cd323ac](cd323acd49))
* sso unreliable if API outputs more than raw json
([#1353](https://github.com/unraid/api/issues/1353))
([e65775f](e65775f878))
* vms now can detect starting of libvirt and start local hypervisor
([#1356](https://github.com/unraid/api/issues/1356))
([ad0f4c8](ad0f4c8b55))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-24 09:24:52 -04:00
Eli Bosley
1d30b25a0a chore: Update CallbackFeedback.vue 2025-04-24 09:23:14 -04:00
Pujit Mehrotra
026b0b344c chore: cli commands for api plugin install & generation (#1352)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a CLI tool to scaffold new Unraid API plugins, including
templates for configuration, persistence, and GraphQL resolvers.
- Added plugin management commands to the CLI for installing, removing,
and listing plugins as peer dependencies.
- Implemented robust configuration state management with validation,
persistence, and error handling.
  - Added scheduled and debounced persistence for configuration changes.
  - Provided utilities for file existence checks and CSV string parsing.
- Enhanced GraphQL schema with new queries and mutations for health
checks and demo configuration.

- **Improvements**
- Updated configuration and environment handling to support modular,
persistent plugin configs.
- Improved logging and error handling throughout CLI and service layers.
- Refined dependency management for plugins, including support for
bundled dependencies.

- **Bug Fixes**
- Improved error handling during Docker service initialization to
prevent unhandled exceptions.

- **Chores**
- Added and updated development dependencies and TypeScript
configurations for better compatibility and type safety.

- **Refactor**
- Restructured internal modules to support dynamic plugin loading and
configuration injection.
  - Removed deprecated plugin schema extension logic and related code.

- **Documentation**
- Updated and added configuration files and templates for easier plugin
development and management.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-04-22 13:30:11 -04:00
Michael Datelle
72860e71fe test: create tests for stores batch 3 (#1358)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added comprehensive test coverage for the purchase, replaceRenew,
modal, notifications, theme, trial, unraidApi, unraidApiSettings,
updateOs, updateOsActions, updateOsChangelog, activationCode, and
callbackActions stores.
- Exposed callback error state in the callbackActions store for external
access.
  - Made error state publicly accessible in the replaceRenew store.

- **Tests**
- Introduced new test files covering state, getters, actions, and side
effects for multiple stores including modal, notifications, purchase,
replaceRenew, theme, trial, unraidApi, unraidApiSettings, updateOs,
updateOsActions, updateOsChangelog, activationCode, and callbackActions.
- Enhanced existing test suites with additional mocks, reactive state
handling, and expanded test cases for improved coverage and robustness.

- **Refactor**
- Improved code clarity and readability in modal, notifications,
purchase, replaceRenew, trial, theme, updateOsActions, callbackActions,
and unraidApi stores through import reorganization and formatting
adjustments.
- Updated imports to include reactive and computed utilities for
enhanced state management in several stores.
- Standardized import styles and streamlined store definitions in the
unraidApiSettings store.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: mdatelle <mike@datelle.net>
2025-04-16 17:06:52 -04:00
renovate[bot]
1236b7743e chore(deps): update dependency vite-plugin-node to v5 (#1283)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
|
[vite-plugin-node](https://redirect.github.com/axe-me/vite-plugin-node)
| [`^4.0.0` ->
`^5.0.0`](https://renovatebot.com/diffs/npm/vite-plugin-node/4.0.0/5.0.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/vite-plugin-node/5.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/vite-plugin-node/5.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/vite-plugin-node/4.0.0/5.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vite-plugin-node/4.0.0/5.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>axe-me/vite-plugin-node (vite-plugin-node)</summary>

###
[`v5.0.0`](https://redirect.github.com/axe-me/vite-plugin-node/blob/HEAD/CHANGELOG.md#500)

-   update vite to 6.x.x

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/unraid/api).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMDcuMSIsInVwZGF0ZWRJblZlciI6IjM5LjIwNy4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-15 09:39:59 -04:00
Eli Bosley
ea77de8800 chore: update cache functionality to use nestjs-cache module (#1360)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Enhanced caching controls allow dynamic management of cache usage when
retrieving container and network data.
- Real-time event notifications are published on container lifecycle
changes for improved updates.

- **Refactor**
- Unified caching logic across Docker modules using a centralized cache
manager.
  - Updated query parameters to support flexible cache skipping options.
- Introduced explicit cache invalidation and warming mechanisms for
improved data freshness.

- **Tests**
- Expanded test coverage to validate caching mechanisms and event
publishing.

- **Chores**
  - Added new caching dependencies to support improved cache management.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-04-15 09:33:47 -04:00
Eli Bosley
ad0f4c8b55 fix: vms now can detect starting of libvirt and start local hypervisor (#1356)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Enhanced virtual machine services now benefit from improved
initialization, dynamic monitoring, and cleaner shutdown, ensuring a
smoother operational experience.
- Strengthened input validation for array state changes helps users
avoid improper commands and enhances overall reliability.

- **Bug Fixes**
- Refined state and disk management logic prevents redundant operations
and incorrect transitions, leading to a more stable system.

- **Refactor**
- Streamlined status reporting delivers clearer and more accurate array
state information for end-users.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-04-14 14:59:06 -04:00
Michael Datelle
d74d9f1246 test: create tests for stores batch 2 (#1351)
This is batch 2 of the web store tests. I started implementing the
recommended approach in the Pinia docs for the store tests and was able
to eliminate most of the mocking files. The server.test.ts file still
uses `pinia/testing` for now since I was having trouble with some of the
dependencies in the store due to it's complexity.

I also updated the `web-testing-rules`for Cursor in an effort to
streamline the AI's approach when helping with tests. There's some
things it still struggles with and seems like it doesn't always take the
rules into consideration until after it hits a snag. It likes to try and
create a mock for the store it's actually testing even though there's a
rule in place and has to be reminded.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

- **Tests**
- Added comprehensive test suites for account management and activation
flows to ensure smoother user interactions.
- Introduced new test coverage for callback actions, validating state
management and action handling.
- Added a new test file for the account store, covering various actions
and their interactions.
- Introduced a new test file for the activation code store, verifying
state management and modal visibility.
- Established a new test file for dropdown functionality, ensuring
accurate state management and action methods.
- Added a new test suite for the Errors store, covering error handling
and modal interactions.
- Enhanced test guidelines for Vue components and Pinia stores,
providing clearer documentation and best practices.
- Introduced a new test file for the InstallKey store, validating key
installation processes and error handling.
- Added a new test file for the dropdown store, ensuring accurate
visibility state management and action methods.

- **Refactor**
- Streamlined the structure of account action payloads for consistent
behavior.
- Improved code formatting and reactivity setups to enhance overall
operational stability.
- Enhanced reactivity capabilities in various stores by introducing new
Vue composition API functions.
- Improved code readability and organization in the installKey store and
other related files.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: mdatelle <mike@datelle.net>
2025-04-14 12:30:27 -04:00
Eli Bosley
45ecab6914 feat: add permission documentation by using a custom decorator (#1355)
* usePermissions applies both authz + graphQL directive logic to allow
permissions and documentation in one place

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a new GraphQL permission directive that documents required
permissions for API fields.
- Added enums for defining action verbs (create, update, delete, read)
and possession types (any, own, own any) to enable granular access
control.
- Added a new health field to the Query type for improved API health
monitoring.

- **Chores**
- Consolidated permission handling by updating import sources and
retiring legacy authorization tests and code, enhancing overall
maintainability.
  - Updated configuration version in the API settings.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-04-14 12:27:15 -04:00
Eli Bosley
e65775f878 fix: sso unreliable if API outputs more than raw json (#1353)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Bug Fixes**
- Enhanced the SSO login process by improving the handling of response
data. This update increases reliability when unexpected response formats
occur during authentication.
- **New Features**
- Introduced a new function for validating user credentials and SSO
tokens, enhancing the login functionality with improved error handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-04-14 12:10:22 -04:00
Eli Bosley
33ad1fd63b chore: fix flaky api key test (#1357)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Tests**
- Improved test validations to flexibly verify dynamic timestamp values
in API responses.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-04-14 11:45:45 -04:00
renovate[bot]
234573264c fix(deps): update all non-major dependencies (#1337)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
|
[@pinia/nuxt](https://redirect.github.com/vuejs/pinia/tree/v3/packages/nuxt#readme)
([source](https://redirect.github.com/vuejs/pinia)) | [`^0.10.0` ->
`^0.11.0`](https://renovatebot.com/diffs/npm/@pinia%2fnuxt/0.10.1/0.11.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@pinia%2fnuxt/0.11.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@pinia%2fnuxt/0.11.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@pinia%2fnuxt/0.10.1/0.11.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@pinia%2fnuxt/0.10.1/0.11.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [lucide-vue-next](https://lucide.dev)
([source](https://redirect.github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-vue-next))
| [`^0.487.0` ->
`^0.488.0`](https://renovatebot.com/diffs/npm/lucide-vue-next/0.487.0/0.488.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/lucide-vue-next/0.488.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/lucide-vue-next/0.488.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/lucide-vue-next/0.487.0/0.488.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/lucide-vue-next/0.487.0/0.488.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [pnpm](https://pnpm.io)
([source](https://redirect.github.com/pnpm/pnpm/tree/HEAD/pnpm)) |
[`10.7.1` ->
`10.8.1`](https://renovatebot.com/diffs/npm/pnpm/10.7.1/10.8.1) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/pnpm/10.8.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/pnpm/10.8.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/pnpm/10.7.1/10.8.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/pnpm/10.7.1/10.8.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[vuetify-nuxt-module](https://redirect.github.com/vuetifyjs/nuxt-module)
| [`0.18.5` ->
`0.18.6`](https://renovatebot.com/diffs/npm/vuetify-nuxt-module/0.18.5/0.18.6)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/vuetify-nuxt-module/0.18.6?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/vuetify-nuxt-module/0.18.6?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/vuetify-nuxt-module/0.18.5/0.18.6?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vuetify-nuxt-module/0.18.5/0.18.6?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>lucide-icons/lucide (lucide-vue-next)</summary>

###
[`v0.488.0`](https://redirect.github.com/lucide-icons/lucide/releases/tag/0.488.0):
Version 0.488.0

[Compare
Source](https://redirect.github.com/lucide-icons/lucide/compare/0.487.0...0.488.0)

#### What's Changed

- docs(readme): fix packages table by
[@&#8203;realguse](https://redirect.github.com/realguse) in
[https://github.com/lucide-icons/lucide/pull/2976](https://redirect.github.com/lucide-icons/lucide/pull/2976)
- fix(dev): point urls on packages page to correct page by
[@&#8203;briz123](https://redirect.github.com/briz123) in
[https://github.com/lucide-icons/lucide/pull/2983](https://redirect.github.com/lucide-icons/lucide/pull/2983)
- build(deps-dev): bump vite from 5.4.14 to 5.4.15 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/lucide-icons/lucide/pull/2946](https://redirect.github.com/lucide-icons/lucide/pull/2946)
- Typo fix for
[@&#8203;lucide/astro](https://redirect.github.com/lucide/astro) badge
by [@&#8203;dotspencer](https://redirect.github.com/dotspencer) in
[https://github.com/lucide-icons/lucide/pull/3004](https://redirect.github.com/lucide-icons/lucide/pull/3004)
- removed flutter package link by
[@&#8203;shamaamahh](https://redirect.github.com/shamaamahh) in
[https://github.com/lucide-icons/lucide/pull/2999](https://redirect.github.com/lucide-icons/lucide/pull/2999)
- feat(ci): added npm package provenance attestation by
[@&#8203;jguddas](https://redirect.github.com/jguddas) in
[https://github.com/lucide-icons/lucide/pull/3016](https://redirect.github.com/lucide-icons/lucide/pull/3016)
- fix(icons): changed `text` icon by
[@&#8203;jguddas](https://redirect.github.com/jguddas) in
[https://github.com/lucide-icons/lucide/pull/3029](https://redirect.github.com/lucide-icons/lucide/pull/3029)
- fix(icons): changed `letter-text` icon by
[@&#8203;jguddas](https://redirect.github.com/jguddas) in
[https://github.com/lucide-icons/lucide/pull/3030](https://redirect.github.com/lucide-icons/lucide/pull/3030)
- fix(icons): changed `text-select` icon by
[@&#8203;jguddas](https://redirect.github.com/jguddas) in
[https://github.com/lucide-icons/lucide/pull/3028](https://redirect.github.com/lucide-icons/lucide/pull/3028)

#### New Contributors

- [@&#8203;dotspencer](https://redirect.github.com/dotspencer) made
their first contribution in
[https://github.com/lucide-icons/lucide/pull/3004](https://redirect.github.com/lucide-icons/lucide/pull/3004)
- [@&#8203;shamaamahh](https://redirect.github.com/shamaamahh) made
their first contribution in
[https://github.com/lucide-icons/lucide/pull/2999](https://redirect.github.com/lucide-icons/lucide/pull/2999)

**Full Changelog**:
https://github.com/lucide-icons/lucide/compare/0.487.0...0.488.0

</details>

<details>
<summary>pnpm/pnpm (pnpm)</summary>

###
[`v10.8.1`](https://redirect.github.com/pnpm/pnpm/blob/HEAD/pnpm/CHANGELOG.md#1081)

[Compare
Source](https://redirect.github.com/pnpm/pnpm/compare/v10.8.0...v10.8.1)

##### Patch Changes

- Removed bright white highlighting, which didn't look good on some
light themes
[#&#8203;9389](https://redirect.github.com/pnpm/pnpm/pull/9389).
- If there is no pnpm related configuration in `package.json`,
`onlyBuiltDependencies` will be written to `pnpm-workspace.yaml` file
[#&#8203;9404](https://redirect.github.com/pnpm/pnpm/pull/9404).

###
[`v10.8.0`](https://redirect.github.com/pnpm/pnpm/blob/HEAD/pnpm/CHANGELOG.md#1080)

[Compare
Source](https://redirect.github.com/pnpm/pnpm/compare/v10.7.1...v10.8.0)

##### Minor Changes

- **Experimental.** A new hook is supported for updating configuration
settings. The hook can be provided via `.pnpmfile.cjs`. For example:

    ```js
    module.exports = {
      hooks: {
        updateConfig: (config) => ({
          ...config,
          nodeLinker: "hoisted",
        }),
      },
    };
    ```
- Now you can use the `pnpm add` command with the `--config` flag to
install new configurational dependencies
[#&#8203;9377](https://redirect.github.com/pnpm/pnpm/pull/9377).

##### Patch Changes

- Do not hang indefinitely, when there is a glob that starts with `!/`
in `pnpm-workspace.yaml`. This fixes a regression introduced by
[#&#8203;9169](https://redirect.github.com/pnpm/pnpm/pull/9169).
- `pnpm audit --fix` should update the overrides in
`pnpm-workspace.yaml`.
- `pnpm link` should update overrides in `pnpm-workspace.yaml`, not in
`package.json`
[#&#8203;9365](https://redirect.github.com/pnpm/pnpm/pull/9365).

</details>

<details>
<summary>vuetifyjs/nuxt-module (vuetify-nuxt-module)</summary>

###
[`v0.18.6`](https://redirect.github.com/vuetifyjs/nuxt-module/releases/tag/v0.18.6)

[Compare
Source](https://redirect.github.com/vuetifyjs/nuxt-module/compare/v0.18.5...v0.18.6)

#####    🚀 Features

- **labs**: Enable labs components auto-import by default  -  by
[@&#8203;userquin](https://redirect.github.com/userquin) in
[https://github.com/vuetifyjs/nuxt-module/issues/309](https://redirect.github.com/vuetifyjs/nuxt-module/issues/309)
[<samp>(92366)</samp>](https://redirect.github.com/vuetifyjs/nuxt-module/commit/9236675)

#####    🏎 Performance

- **styles**: Use `fsp.access` and rethrow legitimate errors  -  by
[@&#8203;userquin](https://redirect.github.com/userquin) in
[https://github.com/vuetifyjs/nuxt-module/issues/308](https://redirect.github.com/vuetifyjs/nuxt-module/issues/308)
[<samp>(b136e)</samp>](https://redirect.github.com/vuetifyjs/nuxt-module/commit/b136e56)

#####     [View changes on
GitHub](https://redirect.github.com/vuetifyjs/nuxt-module/compare/v0.18.5...v0.18.6)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/unraid/api).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMjcuMyIsInVwZGF0ZWRJblZlciI6IjM5LjIzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-14 09:36:55 -04:00
Eli Bosley
f5724abffb feat: code first graphql (#1347)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Enhanced API capabilities with improved GraphQL interfaces for remote
access, parity checks, notifications, and virtual machine controls.
- Introduction of dynamic remote access settings and refined online
status and service monitoring.
- New `ParityCheckMutationsResolver` for managing parity check
operations through GraphQL.

- **Refactor**
- Consolidated and renamed internal types and schema definitions to
improve consistency and performance.
  - Removed deprecated legacy schemas to streamline the API.
- Updated import paths for various types to reflect new module
structures.

- **Chore**
- Updated environment configurations and test setups to support the new
logging and configuration mechanisms.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-04-11 15:03:01 -04:00
Pujit Mehrotra
8bb9efcb68 chore(api): enable using workspace plugins in production (#1343)
## Summary by CodeRabbit

- **New Features**
- Introduced an automated step in the post-build process to copy plugin
assets.
- Enhanced the plugin import process by supporting multiple sourcing
options.
  - Adds a demo `health` query via a workspace plugin.

- **Documentation**
- Added a detailed guide explaining API plugin configuration and local
workspace integration.

- **Refactor**
- Improved dependency handling by marking certain workspace plugins as
optional.
- Updated deployment synchronization to ensure destination directories
exactly mirror the source.
- Refined logging levels and type-safety for improved reliability and
debugging.
2025-04-10 14:17:39 -04:00
Pujit Mehrotra
97ab6fbe32 refactor(api): vendor node_modules instead of pnpm store (#1346)
due to issues and redundancies in vendoring postinstall side-effects, such as compiled bindings for libvirt, we reverted to vendoring `node_modules`, installed via `npm` instead of a global pnpm store generated by `pnpm`.

This should resolve runtime issues with e.g. the libvirt bindings because `node_modules` will contain the correct "side-effects."

## Summary by CodeRabbit

- **New Features**
- Introduced a command to remove stale archive files during the cleanup
process.
  - Added functionality to archive the `node_modules` directory.
- Enhanced dependency resolution with new overrides for specific
packages.

- **Chores**
- Updated dependency settings by replacing one key dependency with an
alternative and removing two unused ones, ensuring optimal deployment.
- Enhanced the installation process to operate strictly in offline mode.
- Updated artifact naming conventions for clarity and consistency in
workflows.
- Modified volume mappings in the Docker Compose configuration to
reflect new artifact names.
- Improved error handling in the GitHub Actions workflow by adding
checks for required files.
- Updated references in the build process to use a vendor store instead
of the PNPM store.
- Removed the management of PNPM store archives from the build process.
2025-04-09 15:17:50 -04:00
Eli Bosley
36a7a28ed5 chore: move node to /usr/libexec (#1345)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Chores**
  - Updated the Node.js runtime configuration for consistent execution.

- **Refactor**
- Centralized the Node.js binary path into a configurable parameter for
improved maintainability.

- **New Features**
- Introduced a new entity declaration for `NODE_DIR` to streamline
Node.js binary management in the plugin.
- Updated the Node.js interpreter path in the application configuration.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1209701840918649
2025-04-09 15:10:05 -04:00
Michael Datelle
03be042410 test: create tests for stores (#1338)
This gets the original 3 component tests refactored to better follow the
Vue Testing Library philosophy and test behavior. This also adds a new
test file for the server store. Additional batches of tests will be
added in proceeding PR's.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Chores**  
- Streamlined internal code organization and improved maintenance
through refined import structures and cleanup of redundant files.

- **Tests**  
- Expanded and restructured automated tests across core components,
including new test files for `Auth`, `DownloadApiLogs`, and `KeyActions`
to ensure robust behavior.
- Enhanced test configuration and mock implementations for a more
reliable, consistent testing environment.
- Introduced best practices for testing Vue components and Pinia stores.

These updates optimize performance and stability behind the scenes
without altering the end-user experience.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: mdatelle <mike@datelle.net>
2025-04-09 11:57:11 -04:00
Eli Bosley
cd323acd49 fix: remove some unused fields from the report object (#1342)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Enhanced configuration settings by adding secure placeholders for
sensitive data.

- **Chores**
- Refreshed internal timestamp records to reflect current download
times.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-04-08 16:12:44 -04:00
Eli Bosley
457d338150 fix: PR build issue 2025-04-08 15:47:37 -04:00
Eli Bosley
04caaf3b25 chore: move disks into the service (#1336)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Enhanced disk status details with a new color attribute offering
richer state information.
  - Expanded filesystem support with additional ext4 and ntfs options.
- Streamlined query responses by removing outdated Docker container
queries.
- Introduced a new `DisksModule` for better organization of disk-related
functionalities.
- **Bug Fixes**
  - Improved clarity of disk status descriptions.
- **Refactor**
- Improved structure and organization of disk-related functionalities,
including the introduction of a dedicated service for disk management.
- **Tests**
- Strengthened test coverage to ensure reliable disk information
retrieval and status reporting.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-04-08 15:41:22 -04:00
Eli Bosley
4b5743906a fix: hide reboot notice for patch releases (#1341)
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-04-08 12:01:49 -07:00
Pujit Mehrotra
f65788aa94 refactor(api): use nestjs modules as the api plugin interface (#1321)
Changes plugin interface to expect Nest modules instead of a custom
plain JS object.

## Summary by CodeRabbit

- **New Features**
- Introduced updated health check plugins, including a new connect
plugin exposing a GraphQL health query and configuration logging.

- **Refactor**
- Streamlined the overall plugin registration and management across API,
CLI, and GraphQL modules for improved clarity and logging.
- Simplified the `CliModule` and `PluginService` to reduce complexity
and enhance maintainability.

- **Chores**
- Updated dependency configurations and build scripts while introducing
new TypeScript setups to enhance maintainability and consistency.
- Added new `package.json` and `tsconfig.json` files for the
`unraid-api-plugin-connect` and `unraid-api-plugin-health` projects.
- Modified GitHub Actions workflow to update tag format for pull
requests.
2025-04-08 10:08:32 -04:00
Eli Bosley
8a5b23856c fix: container names always null (#1335) 2025-04-08 08:56:11 -04:00
Eli Bosley
23c60dad0c chore: move to independent docker events (#1334)
- update dockerode to v4
- remove docker-event-emitter dependency

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a real-time Docker event monitoring service that improves
container status updates.
- Consolidated Docker functionalities within a dedicated module for
enhanced management.

- **Refactor**
- Streamlined Docker event handling to boost stability and simplify
operations.
- Updated the structure of the resolvers module to encapsulate
Docker-related functionality.
  - Made certain methods public for easier access and interaction.

- **Chores**
- Upgraded Docker-related dependencies and removed deprecated packages
to improve performance.
  - Removed unused imports to clean up the codebase.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-04-07 10:47:13 -04:00
Eli Bosley
1bbe7d27b0 fix: move docker mutations to the mutations resolver (#1333)
Thanks to @S3ppo on Discord for flagging this issue


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a dedicated mutation field that centralizes Docker
operations via the API.
- Added a new method for Docker-related mutations in the mutation
resolver.

- **Refactor**
- Streamlined Docker container controls by renaming the start/stop
operations for improved clarity.
	- Removed legacy fields to provide a more unified mutation interface.

- **Bug Fixes**
- Enhanced error handling during container start/stop operations to
ensure consistent behavior.

- **Tests**
- Updated test cases to reflect the new naming and behavior, ensuring
reliable Docker operation validations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-04-04 12:43:34 -04:00
Eli Bosley
bc3ca92fb0 feat: basic vm controls (#1293)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced new GraphQL operations for comprehensive virtual machine
control (start, stop, pause, resume, force stop, reboot, reset).
- Enhanced API authentication and authorization with standardized roles
and permission checks.
- Added a configuration template that streamlines server setup and
improves remote access and parity management.
- New functionality for managing parity checks within the array service,
including state validation and conditional command execution.
- New types and mutations for array and virtual machine management in
the GraphQL schema.
- Added a new directive for authorization control within the GraphQL
schema.
- Introduced a new utility for generating authentication enum type
definitions.
- Added a new configuration file template for server access and
authentication details.
- Updated the configuration file version to reflect the latest changes.

- **Improvements**
  - Upgraded core dependencies for better stability and performance.
- Refined notification handling and error feedback for a more responsive
user experience.
- Improved error handling and logging for API key management and
validation processes.
  - Updated configuration versioning for enhanced compatibility.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-04-04 09:52:03 -04:00
Eli Bosley
c4fdff8149 feat: add basic docker network listing (#1317)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Enhanced Docker management now supports flexible client integration
for improved container operations.
  - Added a new method for retrieving Docker networks.

- **Bug Fixes**
- Removed outdated Docker network retrieval functionality to streamline
operations.
- Eliminated Docker event monitoring, ensuring a more stable application
initialization process.

- **Refactor**
- Streamlined the GraphQL API by removing legacy Docker container
queries and subscriptions.
- Removed Docker-related state management from the Redux store for
better clarity and performance.
- Removed deprecated Docker monitoring functionalities to simplify the
codebase.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-04-04 09:09:58 -04:00
Michael Datelle
0e008aaf1e test: setup initial test, config and testing libraries (#1309)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced comprehensive testing utilities for Vue components
utilizing the composition API.
- Enhanced testing coverage for the `DownloadApiLogs` and `KeyActions`
components, ensuring robust functionality and user interaction
validation.
- Added mock implementations for various libraries and components to
facilitate isolated unit testing.
- Improved flexibility in the `DummyServerSwitcher` component's input
handling.
- Added a new test setup file to configure the testing environment for
Vue applications.
- Added new test files for `AuthComponent` and `KeyActions` with
comprehensive test cases.
- Introduced a new mock implementation for UI components to streamline
testing.
- Added a new mock implementation for the `useRequest` composable to
prevent hanging issues during tests.
- Added a new mock implementation for the server store used by the Auth
component.

- **Bug Fixes**
- Improved sanitization process to block inline styles for a safer and
more consistent display.

- **Documentation**
- Added README documentation for Vue Component Testing Utilities,
detailing usage and examples.
  - Updated ESLint configuration to ignore coverage directory files.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: mdatelle <mike@datelle.net>
Co-authored-by: Eli Bosley <ekbosley@gmail.com>
2025-04-03 15:50:49 -04:00
Eli Bosley
da8dac3940 chore: add linter to unraid ui and simplify tsconfigs (#1308)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Chores**
- Introduced a linting step in the build process to enhance code
quality.
- Updated configuration settings with a version upgrade and adjustments
to network port specifications.
- Refined package and TypeScript configurations for improved module
resolution and maintainability.

- **Style**
- Standardized code formatting with consistent quotation usage,
semicolon additions, and reorganized import paths for clarity.
- Enhanced readability of SVG markup and component templates through
formatting adjustments.
- Simplified property definitions and improved code organization within
components for better readability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-04-03 15:31:11 -04:00
Eli Bosley
187a6ec670 chore: fix html escaper call 2025-04-03 12:45:58 -04:00
Eli Bosley
819ba0bd71 chore: build packages in CI 2025-04-03 12:41:30 -04:00
Eli Bosley
1217d0b100 chore: fix shell interpretation of release notes 2025-04-03 12:18:33 -04:00
Eli Bosley
15dc458751 chore: export release notes to path and then parse them 2025-04-03 12:16:47 -04:00
Eli Bosley
a151dc1f73 chore: don't upload node_modules to release folder 2025-04-03 12:11:39 -04:00
github-actions[bot]
006fe1e762 chore(main): release 4.6.6 (#1328)
🤖 I have created a release *beep* *boop*
---


## [4.6.6](https://github.com/unraid/api/compare/v4.6.5...v4.6.6)
(2025-04-03)


### Bug Fixes

* issue with invalid builds for prod and tagging
([7e89cd2](7e89cd2a3e))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-03 11:59:59 -04:00
Eli Bosley
7e89cd2a3e fix: issue with invalid builds for prod and tagging 2025-04-03 11:59:25 -04:00
github-actions[bot]
38a9e36fcd chore(main): release 4.6.5 (#1327)
🤖 I have created a release *beep* *boop*
---


## [4.6.5](https://github.com/unraid/api/compare/v4.6.4...v4.6.5)
(2025-04-03)


### Bug Fixes

* unique artifact ID
([0f682b5](0f682b5f23))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-03 11:52:33 -04:00
Eli Bosley
d701151729 chore: release tag corrected 2025-04-03 11:51:58 -04:00
Eli Bosley
0f682b5f23 fix: unique artifact ID 2025-04-03 11:50:43 -04:00
github-actions[bot]
3fff76d155 chore(main): release 4.6.4 (#1325)
🤖 I have created a release *beep* *boop*
---


## [4.6.4](https://github.com/unraid/api/compare/v4.6.3...v4.6.4)
(2025-04-03)


### Bug Fixes

* cleanup build pipeline
([#1326](https://github.com/unraid/api/issues/1326))
([60f16bd](60f16bde41))
* remove unneeded workflow secret pass
([4bb00dd](4bb00dd981))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-03 11:46:05 -04:00
Eli Bosley
d8d7075ed8 chore: staging asset wrong directory upload 2025-04-03 11:41:02 -04:00
Eli Bosley
e27e38645f chore: release_created is a string 2025-04-03 11:34:57 -04:00
Eli Bosley
4bb00dd981 fix: remove unneeded workflow secret pass 2025-04-03 11:28:33 -04:00
Eli Bosley
60f16bde41 fix: cleanup build pipeline (#1326)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Added an enhanced, automated process to build and deploy the plugin
across both staging and production environments.
- Releases are now published immediately instead of being created as
drafts, ensuring quicker access to updates.

- **Chores**
- Streamlined and consolidated deployment workflows for improved
consistency and reliability throughout the release process.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-04-03 11:25:15 -04:00
github-actions[bot]
cacb1c1d3d chore(main): release 4.6.3 (#1324)
🤖 I have created a release *beep* *boop*
---


## [4.6.3](https://github.com/unraid/api/compare/v4.6.2...v4.6.3)
(2025-04-03)


### Bug Fixes

* copy dynamix.unraid.net
([662d5f6](662d5f64c9))
* make backup of txz
([37e72f9](37e72f9729))
* ordering in build script
([a562f77](a562f77163))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-03 10:41:07 -04:00
Eli Bosley
a562f77163 fix: ordering in build script 2025-04-03 10:33:11 -04:00
Eli Bosley
37e72f9729 fix: make backup of txz 2025-04-03 10:32:33 -04:00
Eli Bosley
662d5f64c9 fix: copy dynamix.unraid.net 2025-04-03 10:32:06 -04:00
github-actions[bot]
79397eecff chore(main): release 4.6.2 (#1323)
🤖 I have created a release *beep* *boop*
---


## [4.6.2](https://github.com/unraid/api/compare/v4.6.1...v4.6.2)
(2025-04-03)


### Bug Fixes

* build issue
([99d8b31](99d8b31fa8))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-03 10:23:43 -04:00
Eli Bosley
99d8b31fa8 fix: build issue 2025-04-03 10:20:55 -04:00
github-actions[bot]
d0827df60e chore(main): release 4.6.1 (#1322)
🤖 I have created a release *beep* *boop*
---


## [4.6.1](https://github.com/unraid/api/compare/v4.6.0...v4.6.1)
(2025-04-03)


### Bug Fixes

* don't mv deploy on prod release
([9568aab](9568aabd17))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-03 10:10:20 -04:00
Eli Bosley
9568aabd17 fix: don't mv deploy on prod release 2025-04-03 10:07:26 -04:00
github-actions[bot]
5a61aec841 chore(main): release 4.6.0 (#1311)
🤖 I have created a release *beep* *boop*
---


## [4.6.0](https://github.com/unraid/api/compare/v4.5.0...v4.6.0)
(2025-04-03)


### Features

* add gui settings field for sso users
([#1310](https://github.com/unraid/api/issues/1310))
([5ba3fa6](5ba3fa67a2))


### Bug Fixes

* build
([ed67af9](ed67af9568))
* **plugin:** flaky masking of benign warning during pnpm install
([#1313](https://github.com/unraid/api/issues/1313))
([1f10b63](1f10b63c8b))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-03 09:59:38 -04:00
Eli Bosley
ed67af9568 fix: build 2025-04-03 09:58:41 -04:00
Pujit Mehrotra
5ba3fa67a2 feat: add gui settings field for sso users (#1310)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Bulk SSO account management is now supported, allowing users to update
multiple SSO account IDs at once.
- Connect settings now include SSO account identifiers for streamlined
configuration.
- Expanded array management functionality introduces advanced operations
for managing disk arrays.
- New fields for SSO user IDs have been added to various settings and
queries.

- **Style & Documentation**
- Improved formatting and support for rich HTML in form descriptions
enhance clarity and presentation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Eli Bosley <ekbosley@gmail.com>
2025-04-03 09:50:12 -04:00
Pujit Mehrotra
1f10b63c8b fix(plugin): flaky masking of benign warning during pnpm install (#1313)
The masking logic has a different effect in TTY and non-TTY environments
bc pnpm will change the `install` reporter. Now, we:

- set `--reporter=append-only` for consistency
- replace the grep loop with `sed` to mask and redirect the benign
"Ignored build scripts" warning

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Refactor**
- Streamlined the background logging during dependency installations to
improve overall efficiency and reduce complexity. This update enhances
maintainability without any visible changes to the user experience.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-04-03 09:20:55 -04:00
Zack Spear
df168224ea refactor: webgui sync script to copy uui build (#1318)
- enhances `pnpm sync-webgui-repo` to include Unraid UI build + sync
options
- changed the dev intended ThemeSwitcher to use local / session storage

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- The theme switcher now respects your saved preferences, ensuring a
more personalized interface.
- The component build and synchronization process has been enhanced with
new options for UI components and clearer feedback during operations.
- New computed properties added for better state management in account
and purchase functionalities.

- **Bug Fixes**
- Improved error handling and logging during the component build
process.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-04-03 09:17:21 -04:00
Pujit Mehrotra
3911be38bc chore: keep preview plg when merging release-please pr's (#1312)
prevents staging plugin from breaking due to being populated with prod entities

## Summary by CodeRabbit

- **Chores**
- Enhanced the deployment process to clearly distinguish between
production and preview releases.
- Added verification steps to ensure all required production assets are
present, improving the overall reliability of plugin updates.
2025-04-02 14:40:18 -04:00
github-actions[bot]
15153855f7 chore(main): release 4.5.0 (#1279)
🤖 I have created a release *beep* *boop*
---


## [4.5.0](https://github.com/unraid/api/compare/v4.4.1...v4.5.0)
(2025-04-02)


### Features

* add webgui theme switcher component
([#1304](https://github.com/unraid/api/issues/1304))
([e2d00dc](e2d00dc346))
* api plugin system & offline versioned dependency vendoring
([#1252](https://github.com/unraid/api/issues/1252))
([9f492bf](9f492bf217))
* **api:** add `unraid-api --delete` command
([#1289](https://github.com/unraid/api/issues/1289))
([2f09445](2f09445f2e))
* basic array controls
([#1291](https://github.com/unraid/api/issues/1291))
([61fe696](61fe6966ca))
* basic docker controls
([#1292](https://github.com/unraid/api/issues/1292))
([12eddf8](12eddf894e))
* copy to webgui repo script docs + wc build options
([#1285](https://github.com/unraid/api/issues/1285))
([e54f189](e54f189630))


### Bug Fixes

* additional url fixes
([4b2763c](4b2763c7f9))
* **api:** redirect benign pnpm postinstall warning to log file
([#1290](https://github.com/unraid/api/issues/1290))
([7fb7849](7fb78494cb))
* **deps:** update dependency chalk to v5
([#1296](https://github.com/unraid/api/issues/1296))
([6bed638](6bed63805f))
* **deps:** update dependency diff to v7
([#1297](https://github.com/unraid/api/issues/1297))
([3c6683c](3c6683c814))
* disable all config watchers
([#1306](https://github.com/unraid/api/issues/1306))
([5c1b435](5c1b4352cf))
* extract callbacks to library
([#1280](https://github.com/unraid/api/issues/1280))
([2266139](2266139742))
* OEM plugin issues ([#1288](https://github.com/unraid/api/issues/1288))
([d5a3d0d](d5a3d0dfac))
* replace files lost during pruning
([d0d2ff6](d0d2ff65ed))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-02 13:24:42 -04:00
Eli Bosley
65b7747c0e chore: remove flaky test 2025-04-02 13:16:17 -04:00
Eli Bosley
5c1b4352cf fix: disable all config watchers (#1306)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Updated CLI operations now use sequential stop and start actions for
service reloads and SSO user modifications, ensuring a more controlled
update process.
- Introduced a new `<uui-toaster>` component for notifications,
replacing the previous jGrowl notification system and enhancing user
experience.
- Added functionality for managing live updates based on window focus,
improving responsiveness during user interaction.

- **Refactor**
- Streamlined configuration updates by removing automatic monitoring,
resulting in a simpler update workflow.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-04-02 13:09:47 -04:00
Eli Bosley
9004313ff8 chore: lint to fix build 2025-04-02 12:23:20 -04:00
Eli Bosley
7a421ce4ec chore: fix dev console and allowed-headers 2025-04-02 11:28:21 -04:00
renovate[bot]
3c6683c814 fix(deps): update dependency diff to v7 (#1297)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [diff](https://redirect.github.com/kpdecker/jsdiff) | [`^5.1.0` ->
`^7.0.0`](https://renovatebot.com/diffs/npm/diff/5.2.0/7.0.0) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/diff/7.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/diff/7.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/diff/5.2.0/7.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/diff/5.2.0/7.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>kpdecker/jsdiff (diff)</summary>

###
[`v7.0.0`](https://redirect.github.com/kpdecker/jsdiff/blob/HEAD/release-notes.md#700)

[Compare
Source](https://redirect.github.com/kpdecker/jsdiff/compare/v6.0.0...7.0.0)

Just a single (breaking) bugfix, undoing a behaviour change introduced
accidentally in 6.0.0:

- [#&#8203;554](https://redirect.github.com/kpdecker/jsdiff/pull/554)
**`diffWords` treats numbers and underscores as word characters again.**
This behaviour was broken in v6.0.0.

###
[`v6.0.0`](https://redirect.github.com/kpdecker/jsdiff/blob/HEAD/release-notes.md#600)

[Compare
Source](https://redirect.github.com/kpdecker/jsdiff/compare/v5.2.0...v6.0.0)

This is a release containing many, *many* breaking changes. The
objective of this release was to carry out a mass fix, in one go, of all
the open bugs and design problems that required breaking changes to fix.
A substantial, but exhaustive, changelog is below.


[Commits](https://redirect.github.com/kpdecker/jsdiff/compare/v5.2.0...v6.0.0)

- [#&#8203;497](https://redirect.github.com/kpdecker/jsdiff/pull/497)
**`diffWords` behavior has been radically changed.** Previously, even
with `ignoreWhitespace: true`, runs of whitespace were tokens, which led
to unhelpful and unintuitive diffing behavior in typical texts.
Specifically, even when two texts contained overlapping passages,
`diffWords` would sometimes choose to delete all the words from the old
text and insert them anew in their new positions in order to avoid
having to delete or insert whitespace tokens. Whitespace sequences are
no longer tokens as of this release, which affects both the generated
diffs and the `count`s.

    Runs of whitespace are still tokens in `diffWordsWithSpace`.

As part of the changes to `diffWords`, **a new `.postProcess` method has
been added on the base `Diff` type**, which can be overridden in custom
`Diff` implementations.

**`diffLines` with `ignoreWhitespace: true` will no longer ignore the
insertion or deletion of entire extra lines of whitespace at the end of
the text**. Previously, these would not show up as insertions or
deletions, as a side effect of a hack in the base diffing algorithm
meant to help ignore whitespace in `diffWords`. More generally, **the
undocumented special handling in the core algorithm for ignored
terminals has been removed entirely.** (This special case behavior used
to rewrite the final two change objects in a scenario where the final
change object was an addition or deletion and its `value` was treated as
equal to the empty string when compared using the diff object's
`.equals` method.)

- [#&#8203;500](https://redirect.github.com/kpdecker/jsdiff/pull/500)
**`diffChars` now diffs Unicode code points** instead of UTF-16 code
units.

- [#&#8203;508](https://redirect.github.com/kpdecker/jsdiff/pull/508)
**`parsePatch` now always runs in what was previously "strict" mode; the
undocumented `strict` option has been removed.** Previously, by default,
`parsePatch` (and other patch functions that use it under the hood to
parse patches) would accept a patch where the line counts in the headers
were inconsistent with the actual patch content - e.g. where a hunk
started with the header `@@&#8203; -1,3 +1,6 @&#8203;@&#8203;`,
indicating that the content below spanned 3 lines in the old file and 6
lines in the new file, but then the actual content below the header
consisted of some different number of lines, say 10 lines of context, 5
deletions, and 1 insertion. Actually trying to work with these patches
using `applyPatch` or `merge`, however, would produce incorrect results
instead of just ignoring the incorrect headers, making this "feature"
more of a trap than something actually useful. It's been ripped out, and
now we are always "strict" and will reject patches where the line counts
in the headers aren't consistent with the actual patch content.

- [#&#8203;435](https://redirect.github.com/kpdecker/jsdiff/pull/435)
**Fix `parsePatch` handling of control characters.** `parsePatch` used
to interpret various unusual control characters - namely vertical tabs,
form feeds, lone carriage returns without a line feed, and EBCDIC NELs -
as line breaks when parsing a patch file. This was inconsistent with the
behavior of both JsDiff's own `diffLines` method and also the Unix
`diff` and `patch` utils, which all simply treat those control
characters as ordinary characters. The result of this discrepancy was
that some well-formed patches - produced either by `diff` or by JsDiff
itself and handled properly by the `patch` util - would be wrongly
parsed by `parsePatch`, with the effect that it would disregard the
remainder of a hunk after encountering one of these control characters.

- [#&#8203;439](https://redirect.github.com/kpdecker/jsdiff/pull/439)
**Prefer diffs that order deletions before insertions.** When faced with
a choice between two diffs with an equal total edit distance, the Myers
diff algorithm generally prefers one that does deletions before
insertions rather than insertions before deletions. For instance, when
diffing `abcd` against `acbd`, it will prefer a diff that says to delete
the `b` and then insert a new `b` after the `c`, over a diff that says
to insert a `c` before the `b` and then delete the existing `c`. JsDiff
deviated from the published Myers algorithm in a way that led to it
having the opposite preference in many cases, including that example.
This is now fixed, meaning diffs output by JsDiff will more accurately
reflect what the published Myers diff algorithm would output.

- [#&#8203;455](https://redirect.github.com/kpdecker/jsdiff/pull/455)
**The `added` and `removed` properties of change objects are now
guaranteed to be set to a boolean value.** (Previously, they would be
set to `undefined` or omitted entirely instead of setting them to
false.)

- [#&#8203;464](https://redirect.github.com/kpdecker/jsdiff/pull/464)
Specifying `{maxEditLength: 0}` now sets a max edit length of 0 instead
of no maximum.

- [#&#8203;460](https://redirect.github.com/kpdecker/jsdiff/pull/460)
**Added `oneChangePerToken` option.**

- [#&#8203;467](https://redirect.github.com/kpdecker/jsdiff/pull/467)
**Consistent ordering of arguments to `comparator(left, right)`.**
Values from the old array will now consistently be passed as the first
argument (`left`) and values from the new array as the second argument
(`right`). Previously this was almost (but not quite) always the other
way round.

- [#&#8203;480](https://redirect.github.com/kpdecker/jsdiff/pull/480)
**Passing `maxEditLength` to `createPatch` & `createTwoFilesPatch` now
works properly** (i.e. returns undefined if the max edit distance is
exceeded; previous behavior was to crash with a `TypeError` if the edit
distance was exceeded).

- [#&#8203;486](https://redirect.github.com/kpdecker/jsdiff/pull/486)
**The `ignoreWhitespace` option of `diffLines` behaves more sensibly
now.** `value`s in returned change objects now include leading/trailing
whitespace even when `ignoreWhitespace` is used, just like how with
`ignoreCase` the `value`s still reflect the case of one of the original
texts instead of being all-lowercase. `ignoreWhitespace` is also now
compatible with `newlineIsToken`. Finally, **`diffTrimmedLines` is
deprecated** (and removed from the docs) in favour of using `diffLines`
with `ignoreWhitespace: true`; the two are, and always have been,
equivalent.

- [#&#8203;490](https://redirect.github.com/kpdecker/jsdiff/pull/490)
**When calling diffing functions in async mode by passing a `callback`
option, the diff result will now be passed as the *first* argument to
the callback instead of the second.** (Previously, the first argument
was never used at all and would always have value `undefined`.)

- [#&#8203;489](redirect.github.com/kpdecker/jsdiff/pull/489)
**`this.options` no longer exists on `Diff` objects.** Instead,
`options` is now passed as an argument to methods that rely on options,
like `equals(left, right, options)`. This fixes a race condition in
async mode, where diffing behaviour could be changed mid-execution if a
concurrent usage of the same `Diff` instances overwrote its `options`.

- [#&#8203;518](https://redirect.github.com/kpdecker/jsdiff/pull/518)
**`linedelimiters` no longer exists** on patch objects; instead, when a
patch with Windows-style CRLF line endings is parsed, **the lines in
`lines` will end with `\r`**. There is now a **new
`autoConvertLineEndings` option, on by default**, which makes it so that
when a patch with Windows-style line endings is applied to a source file
with Unix style line endings, the patch gets autoconverted to use
Unix-style line endings, and when a patch with Unix-style line endings
is applied to a source file with Windows-style line endings, it gets
autoconverted to use Windows-style line endings.

- [#&#8203;521](https://redirect.github.com/kpdecker/jsdiff/pull/521)
**the `callback` option is now supported by `structuredPatch`,
`createPatch`, and `createTwoFilesPatch`**

- [#&#8203;529](https://redirect.github.com/kpdecker/jsdiff/pull/529)
**`parsePatch` can now parse patches where lines starting with `--` or
`++` are deleted/inserted**; previously, there were edge cases where the
parser would choke on valid patches or give wrong results.

- [#&#8203;530](https://redirect.github.com/kpdecker/jsdiff/pull/530)
**Added `ignoreNewlineAtEof` option to `diffLines`**

- [#&#8203;533](https://redirect.github.com/kpdecker/jsdiff/pull/533)
**`applyPatch` uses an entirely new algorithm for fuzzy matching.**
Differences between the old and new algorithm are as follows:
- The `fuzzFactor` now indicates the maximum [*Levenshtein*
distance](https://en.wikipedia.org/wiki/Levenshtein_distance) that there
can be between the context shown in a hunk and the actual file content
at a location where we try to apply the hunk. (Previously, it
represented a maximum [*Hamming*
distance](https://en.wikipedia.org/wiki/Hamming_distance), meaning that
a single insertion or deletion in the source file could stop a hunk from
applying even with a high `fuzzFactor`.)
- A hunk containing a deletion can now only be applied in a context
where the line to be deleted actually appears verbatim. (Previously, as
long as enough context lines in the hunk matched, `applyPatch` would
apply the hunk anyway and delete a completely different line.)
- The context line immediately before and immediately after an insertion
must match exactly between the hunk and the file for a hunk to apply.
(Previously this was not required.)

- [#&#8203;535](https://redirect.github.com/kpdecker/jsdiff/pull/535)
**A bug in patch generation functions is now fixed** that would
sometimes previously cause `\ No newline at end of file` to appear in
the wrong place in the generated patch, resulting in the patch being
invalid. **These invalid patches can also no longer be applied
successfully with `applyPatch`.** (It was already the case that tools
other than jsdiff, like GNU `patch`, would consider them malformed and
refuse to apply them; versions of jsdiff with this fix now do the same
thing if you ask them to apply a malformed patch emitted by jsdiff v5.)

- [#&#8203;535](https://redirect.github.com/kpdecker/jsdiff/pull/535)
**Passing `newlineIsToken: true` to *patch*-generation functions is no
longer allowed.** (Passing it to `diffLines` is still supported - it's
only functions like `createPatch` where passing `newlineIsToken` is now
an error.) Allowing it to be passed never really made sense, since in
cases where the option had any effect on the output at all, the effect
tended to be causing a garbled patch to be created that couldn't
actually be applied to the source file.

- [#&#8203;539](https://redirect.github.com/kpdecker/jsdiff/pull/539)
**`diffWords` now takes an optional `intlSegmenter` option** which
should be an `Intl.Segmenter` with word-level granularity. This provides
better tokenization of text into words than the default behaviour, even
for English but especially for some other languages for which the
default behaviour is poor.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [x] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/unraid/api).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMDcuMSIsInVwZGF0ZWRJblZlciI6IjM5LjIwNy4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-02 09:42:46 -04:00
renovate[bot]
6bed63805f fix(deps): update dependency chalk to v5 (#1296)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [chalk](https://redirect.github.com/chalk/chalk) | [`^4.1.2` ->
`^5.0.0`](https://renovatebot.com/diffs/npm/chalk/4.1.2/5.4.1) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/chalk/5.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/chalk/5.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/chalk/4.1.2/5.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/chalk/4.1.2/5.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>chalk/chalk (chalk)</summary>

###
[`v5.4.1`](https://redirect.github.com/chalk/chalk/releases/tag/v5.4.1)

[Compare
Source](https://redirect.github.com/chalk/chalk/compare/v5.4.0...v5.4.1)

- Fix `navigator` not defined `ReferenceError`
([#&#8203;642](https://redirect.github.com/chalk/chalk/issues/642))
[`4ebb62d`](https://redirect.github.com/chalk/chalk/commit/4ebb62d)

###
[`v5.4.0`](https://redirect.github.com/chalk/chalk/releases/tag/v5.4.0)

[Compare
Source](https://redirect.github.com/chalk/chalk/compare/v5.3.0...v5.4.0)

- Update `CIRCLECI` environments to return level 3 color support
[`f838120`](https://redirect.github.com/chalk/chalk/commit/f838120)

###
[`v5.3.0`](https://redirect.github.com/chalk/chalk/releases/tag/v5.3.0)

[Compare
Source](https://redirect.github.com/chalk/chalk/compare/v5.2.0...v5.3.0)

- Add `sideEffects` field to package.json
[`5aafc0a`](https://redirect.github.com/chalk/chalk/commit/5aafc0a)
- Add support for Gitea Actions
([#&#8203;603](https://redirect.github.com/chalk/chalk/issues/603))
[`29b8569`](https://redirect.github.com/chalk/chalk/commit/29b8569)

###
[`v5.2.0`](https://redirect.github.com/chalk/chalk/releases/tag/v5.2.0)

[Compare
Source](https://redirect.github.com/chalk/chalk/compare/v5.1.2...v5.2.0)

- Improve Deno compatibility
([#&#8203;579](https://redirect.github.com/chalk/chalk/issues/579))
[`7443e9f`](https://redirect.github.com/chalk/chalk/commit/7443e9f)
- Detect true-color support for GitHub Actions
([#&#8203;579](https://redirect.github.com/chalk/chalk/issues/579))
[`7443e9f`](https://redirect.github.com/chalk/chalk/commit/7443e9f)
- Detect true-color support for Kitty terminal
([#&#8203;579](https://redirect.github.com/chalk/chalk/issues/579))
[`7443e9f`](https://redirect.github.com/chalk/chalk/commit/7443e9f)
- Fix test for Azure DevOps environment
([#&#8203;579](https://redirect.github.com/chalk/chalk/issues/579))
[`7443e9f`](https://redirect.github.com/chalk/chalk/commit/7443e9f)

###
[`v5.1.2`](https://redirect.github.com/chalk/chalk/releases/tag/v5.1.2)

[Compare
Source](https://redirect.github.com/chalk/chalk/compare/v5.1.1...v5.1.2)

- Fix exported styles names
([#&#8203;569](https://redirect.github.com/chalk/chalk/issues/569))
[`a34bcf6`](https://redirect.github.com/chalk/chalk/commit/a34bcf6)

###
[`v5.1.1`](https://redirect.github.com/chalk/chalk/releases/tag/v5.1.1)

[Compare
Source](https://redirect.github.com/chalk/chalk/compare/v5.1.0...v5.1.1)

- Improved the names of exports introduced in 5.1.0
([#&#8203;567](https://redirect.github.com/chalk/chalk/issues/567))
[`6e0df05`](https://redirect.github.com/chalk/chalk/commit/6e0df05)
    -   We of course preserved the old names.

###
[`v5.1.0`](https://redirect.github.com/chalk/chalk/releases/tag/v5.1.0)

[Compare
Source](https://redirect.github.com/chalk/chalk/compare/v5.0.1...v5.1.0)

- Expose style names
([#&#8203;566](https://redirect.github.com/chalk/chalk/issues/566))
[`d7d7571`](https://redirect.github.com/chalk/chalk/commit/d7d7571)

###
[`v5.0.1`](https://redirect.github.com/chalk/chalk/releases/tag/v5.0.1)

[Compare
Source](https://redirect.github.com/chalk/chalk/compare/v5.0.0...v5.0.1)

- Add `main` field to package.json for backwards compatibility with some
developer tools
[`85f7e96`](https://redirect.github.com/chalk/chalk/commit/85f7e96)

###
[`v5.0.0`](https://redirect.github.com/chalk/chalk/releases/tag/v5.0.0)

[Compare
Source](https://redirect.github.com/chalk/chalk/compare/v4.1.2...v5.0.0)

##### Breaking

- **This package is now pure ESM. Please [read
this](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c).**
- If you use TypeScript, you need to use TypeScript 4.7 or later.
[Why.](https://redirect.github.com/microsoft/TypeScript/issues/46452)
- If you use a bundler, make sure it supports ESM and that you have
correctly configured it for ESM.
- The Chalk issue tracker is not a support channel for your favorite
build/bundler tool.
- It's totally fine to stay on Chalk v4. It's been stable for years.
- Require Node.js 12.20
[`fa16f4e`](https://redirect.github.com/chalk/chalk/commit/fa16f4e)
- Move some properties off the default export to individual named
exports:
    -   `chalk.Instance` → `Chalk`
    -   `chalk.supportsColor` → `supportsColor`
    -   `chalk.stderr` → `chalkStderr`
    -   `chalk.stderr.supportsColor` → `supportsColorStderr`
- Remove `.keyword()`, `.hsl()`, `.hsv()`, `.hwb()`, and `.ansi()`
coloring methods
([#&#8203;433](https://redirect.github.com/chalk/chalk/issues/433))
[`4cf2e40`](https://redirect.github.com/chalk/chalk/commit/4cf2e40)
- These were not commonly used and added a lot of bloat to Chalk. You
can achieve the same by using the [`color-convert`
package](https://redirect.github.com/Qix-/color-convert).
- The tagged template literal support moved into a separate package:
[`chalk-template`](https://redirect.github.com/chalk/chalk-template)
([#&#8203;524](https://redirect.github.com/chalk/chalk/issues/524))
[`c987c61`](https://redirect.github.com/chalk/chalk/commit/c987c61)

```diff
-import chalk from 'chalk';
+import chalkTemplate from 'chalk-template';

-chalk`2 + 3 = {bold ${2 + 3}}`;
+chalkTemplate`2 + 3 = {bold ${2 + 3}}`;
```

##### Improvements

- Bundle dependencies
[`04fdbd6`](https://redirect.github.com/chalk/chalk/commit/04fdbd6)
    -   This means Chalk no longer has any dependencies 🎉
- [The install size is less than half of
v4.](https://packagephobia.com/result?p=chalk)
- Add `overline` style
([#&#8203;433](https://redirect.github.com/chalk/chalk/issues/433))
[`4cf2e40`](https://redirect.github.com/chalk/chalk/commit/4cf2e40)
- Preserve function prototype methods
([#&#8203;434](https://redirect.github.com/chalk/chalk/issues/434))
[`0fba91b`](https://redirect.github.com/chalk/chalk/commit/0fba91b)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/unraid/api).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMDcuMSIsInVwZGF0ZWRJblZlciI6IjM5LjIwNy4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-02 09:40:22 -04:00
renovate[bot]
f7f40d7906 fix(deps): update all non-major dependencies (#1278)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
|
[@graphql-codegen/typescript-resolvers](https://redirect.github.com/dotansimha/graphql-code-generator)
([source](https://redirect.github.com/dotansimha/graphql-code-generator/tree/HEAD/packages/plugins/typescript/resolvers))
| [`4.4.4` ->
`4.5.0`](https://renovatebot.com/diffs/npm/@graphql-codegen%2ftypescript-resolvers/4.4.4/4.5.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@graphql-codegen%2ftypescript-resolvers/4.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@graphql-codegen%2ftypescript-resolvers/4.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@graphql-codegen%2ftypescript-resolvers/4.4.4/4.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@graphql-codegen%2ftypescript-resolvers/4.4.4/4.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [lucide-vue-next](https://lucide.dev)
([source](https://redirect.github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-vue-next))
| [`^0.483.0` ->
`^0.487.0`](https://renovatebot.com/diffs/npm/lucide-vue-next/0.483.0/0.487.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/lucide-vue-next/0.487.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/lucide-vue-next/0.487.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/lucide-vue-next/0.483.0/0.487.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/lucide-vue-next/0.483.0/0.487.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [pnpm](https://pnpm.io)
([source](https://redirect.github.com/pnpm/pnpm/tree/HEAD/pnpm)) |
[`10.6.5` ->
`10.7.1`](https://renovatebot.com/diffs/npm/pnpm/10.6.5/10.7.1) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/pnpm/10.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/pnpm/10.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/pnpm/10.6.5/10.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/pnpm/10.6.5/10.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[vuetify-nuxt-module](https://redirect.github.com/vuetifyjs/nuxt-module)
| [`0.18.4` ->
`0.18.5`](https://renovatebot.com/diffs/npm/vuetify-nuxt-module/0.18.4/0.18.5)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/vuetify-nuxt-module/0.18.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/vuetify-nuxt-module/0.18.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/vuetify-nuxt-module/0.18.4/0.18.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vuetify-nuxt-module/0.18.4/0.18.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>dotansimha/graphql-code-generator
(@&#8203;graphql-codegen/typescript-resolvers)</summary>

###
[`v4.5.0`](https://redirect.github.com/dotansimha/graphql-code-generator/blob/HEAD/packages/plugins/typescript/resolvers/CHANGELOG.md#450)

[Compare
Source](https://redirect.github.com/dotansimha/graphql-code-generator/compare/@graphql-codegen/typescript-resolvers@4.4.4...@graphql-codegen/typescript-resolvers@4.5.0)

##### Minor Changes

-
[#&#8203;10315](https://redirect.github.com/dotansimha/graphql-code-generator/pull/10315)
[`f6909d1`](f6909d1797)
Thanks [@&#8203;eddeee888](https://redirect.github.com/eddeee888)! -
Implement semanticNonNull custom directive

##### Patch Changes

- Updated dependencies
\[[`f6909d1`](f6909d1797)]:
-
[@&#8203;graphql-codegen/visitor-plugin-common](https://redirect.github.com/graphql-codegen/visitor-plugin-common)[@&#8203;5](https://redirect.github.com/5).8.0
-
[@&#8203;graphql-codegen/typescript](https://redirect.github.com/graphql-codegen/typescript)[@&#8203;4](https://redirect.github.com/4).1.6

</details>

<details>
<summary>lucide-icons/lucide (lucide-vue-next)</summary>

###
[`v0.487.0`](https://redirect.github.com/lucide-icons/lucide/releases/tag/0.487.0):
Version 0.487.0

[Compare
Source](https://redirect.github.com/lucide-icons/lucide/compare/0.486.0...0.487.0)

#### What's Changed

- feat(icons): added `spline-pointer` icon by
[@&#8203;Kaleidosium](https://redirect.github.com/Kaleidosium) in
[https://github.com/lucide-icons/lucide/pull/2932](https://redirect.github.com/lucide-icons/lucide/pull/2932)

#### New Contributors

- [@&#8203;Kaleidosium](https://redirect.github.com/Kaleidosium) made
their first contribution in
[https://github.com/lucide-icons/lucide/pull/2932](https://redirect.github.com/lucide-icons/lucide/pull/2932)

**Full Changelog**:
https://github.com/lucide-icons/lucide/compare/0.486.0...0.487.0

###
[`v0.486.0`](https://redirect.github.com/lucide-icons/lucide/releases/tag/0.486.0):
Version 0.486.0

[Compare
Source](https://redirect.github.com/lucide-icons/lucide/compare/0.485.0...0.486.0)

#### What's Changed

-
feat([@&#8203;lucide/astro](https://redirect.github.com/lucide/astro)):
add lucide package for Astro by
[@&#8203;MoustaphaDev](https://redirect.github.com/MoustaphaDev) in
[https://github.com/lucide-icons/lucide/pull/2665](https://redirect.github.com/lucide-icons/lucide/pull/2665)

#### New Contributors

- [@&#8203;MoustaphaDev](https://redirect.github.com/MoustaphaDev) made
their first contribution in
[https://github.com/lucide-icons/lucide/pull/2665](https://redirect.github.com/lucide-icons/lucide/pull/2665)

**Full Changelog**:
https://github.com/lucide-icons/lucide/compare/0.485.0...0.486.0

###
[`v0.485.0`](https://redirect.github.com/lucide-icons/lucide/releases/tag/0.485.0):
Version 0.485.0

[Compare
Source](https://redirect.github.com/lucide-icons/lucide/compare/0.484.0...0.485.0)

#### What's Changed

- feat(icons): added `banknote-arrow-down` icon by
[@&#8203;joffx](https://redirect.github.com/joffx) in
[https://github.com/lucide-icons/lucide/pull/2948](https://redirect.github.com/lucide-icons/lucide/pull/2948)
- feat(icons): added `banknote-x` icon by
[@&#8203;joffx](https://redirect.github.com/joffx) in
[https://github.com/lucide-icons/lucide/pull/2949](https://redirect.github.com/lucide-icons/lucide/pull/2949)

**Full Changelog**:
https://github.com/lucide-icons/lucide/compare/0.484.0...0.485.0

###
[`v0.484.0`](https://redirect.github.com/lucide-icons/lucide/releases/tag/0.484.0):
Version 0.484.0

[Compare
Source](https://redirect.github.com/lucide-icons/lucide/compare/0.483.0...0.484.0)

#### What's Changed

- build(deps): bump tj-actions/changed-files from 41 to 46 in
/.github/workflows by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/lucide-icons/lucide/pull/2920](https://redirect.github.com/lucide-icons/lucide/pull/2920)
- fix(packages): consistent icon name class by
[@&#8203;danteissaias](https://redirect.github.com/danteissaias) in
[https://github.com/lucide-icons/lucide/pull/2878](https://redirect.github.com/lucide-icons/lucide/pull/2878)
- feat(ci): add `x.com` to brand filter by
[@&#8203;jguddas](https://redirect.github.com/jguddas) in
[https://github.com/lucide-icons/lucide/pull/2939](https://redirect.github.com/lucide-icons/lucide/pull/2939)
- fix(icons): arcified candy & candy-off by
[@&#8203;karsa-mistmere](https://redirect.github.com/karsa-mistmere) in
[https://github.com/lucide-icons/lucide/pull/2944](https://redirect.github.com/lucide-icons/lucide/pull/2944)

#### New Contributors

- [@&#8203;danteissaias](https://redirect.github.com/danteissaias) made
their first contribution in
[https://github.com/lucide-icons/lucide/pull/2878](https://redirect.github.com/lucide-icons/lucide/pull/2878)

**Full Changelog**:
https://github.com/lucide-icons/lucide/compare/0.483.0...0.484.0

</details>

<details>
<summary>pnpm/pnpm (pnpm)</summary>

###
[`v10.7.1`](https://redirect.github.com/pnpm/pnpm/releases/tag/v10.7.1):
pnpm 10.7.1

[Compare
Source](https://redirect.github.com/pnpm/pnpm/compare/v10.7.0...v10.7.1)

#### Patch Changes

- `pnpm config set` should convert the settings to their correct type
before adding them to `pnpm-workspace.yaml`
[#&#8203;9355](https://redirect.github.com/pnpm/pnpm/issues/9355).
- `pnpm config get` should read auth related settings via npm CLI
[#&#8203;9345](https://redirect.github.com/pnpm/pnpm/issues/9345).
- Replace leading `~/` in a path in `.npmrc` with the home directory
[#&#8203;9217](https://redirect.github.com/pnpm/pnpm/issues/9217).

#### Platinum Sponsors

<table>
  <tbody>
    <tr>
      <td align="center" valign="middle">
<a href="https://bit.dev/?utm_source=pnpm&utm_medium=release_notes"
target="_blank"><img src="https://pnpm.io/img/users/bit.svg" width="80"
alt="Bit"></a>
      </td>
      <td align="center" valign="middle">
<a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes"
target="_blank"><img src="https://pnpm.io/img/users/sanity.svg"
width="180" alt="Bit"></a>
      </td>
      <td align="center" valign="middle">
<a href="https://syntax.fm/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/syntaxfm.svg" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/syntaxfm_light.svg" />
<img src="https://pnpm.io/img/users/syntaxfm.svg" width="90"
alt="Syntax" />
          </picture>
        </a>
      </td>
    </tr>
  </tbody>
</table>

#### Gold Sponsors

<table>
  <tbody>
    <tr>
      <td align="center" valign="middle">
<a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/discord.svg" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/discord_light.svg" />
<img src="https://pnpm.io/img/users/discord.svg" width="220"
alt="Discord" />
          </picture>
        </a>
      </td>
      <td align="center" valign="middle">
<a href="https://uscreen.de/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/uscreen.svg" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/uscreen_light.svg" />
<img src="https://pnpm.io/img/users/uscreen.svg" width="180"
alt="u|screen" />
          </picture>
        </a>
      </td>
    </tr>
    <tr>
      <td align="center" valign="middle">
<a
href="https://www.jetbrains.com/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/jetbrains.svg" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/jetbrains.svg" />
<img src="https://pnpm.io/img/users/jetbrains.svg" width="180"
alt="JetBrains" />
          </picture>
        </a>
      </td>
      <td align="center" valign="middle">
<a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/nx.svg?0" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/nx_light.svg?0" />
<img src="https://pnpm.io/img/users/nx.svg" width="70" alt="Nx" />
          </picture>
        </a>
      </td>
    </tr>
    <tr>
      <td align="center" valign="middle">
<a
href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/coderabbit.svg" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/coderabbit_light.svg" />
<img src="https://pnpm.io/img/users/coderabbit.svg" width="220"
alt="CodeRabbit" />
          </picture>
        </a>
      </td>
      <td align="center" valign="middle">
<a href="https://route4me.com/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
<img src="https://pnpm.io/img/users/route4me.svg" width="220"
alt="Route4Me" />
        </a>
      </td>
    </tr>
    <tr>
      <td align="center" valign="middle">
<a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/workleap.svg" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/workleap_light.svg" />
<img src="https://pnpm.io/img/users/workleap.svg" width="190"
alt="Workleap" />
          </picture>
        </a>
      </td>
      <td align="center" valign="middle">
<a
href="https://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes"
target="_blank">
          <picture>
<source media="(prefers-color-scheme: light)"
srcset="https://pnpm.io/img/users/stackblitz.svg" />
<source media="(prefers-color-scheme: dark)"
srcset="https://pnpm.io/img/users/stackblitz_light.svg" />
<img src="https://pnpm.io/img/users/stackblitz.svg" width="190"
alt="Stackblitz" />
          </picture>
        </a>
      </td>
    </tr>
  </tbody>
</table>

###
[`v10.7.0`](https://redirect.github.com/pnpm/pnpm/blob/HEAD/pnpm/CHANGELOG.md#1070)

[Compare
Source](https://redirect.github.com/pnpm/pnpm/compare/v10.6.5...v10.7.0)

##### Minor Changes

- `pnpm config get` and `list` also show settings set in
`pnpm-workspace.yaml` files
[#&#8203;9316](https://redirect.github.com/pnpm/pnpm/pull/9316).

- It should be possible to use env variables in `pnpm-workspace.yaml`
setting names and value.

- Add an ability to patch dependencies by version ranges. Exact versions
override version ranges, which in turn override name-only patches.
Version range `*` is the same as name-only, except that patch
application failure will not be ignored.

    For example:

    ```yaml
    patchedDependencies:
      foo: patches/foo-1.patch
      foo@^2.0.0: patches/foo-2.patch
      foo@2.1.0: patches/foo-3.patch
    ```

The above configuration would apply `patches/foo-3.patch` to
`foo@2.1.0`, `patches/foo-2.patch` to all `foo` versions which satisfy
`^2.0.0` except `2.1.0`, and `patches/foo-1.patch` to the remaining
`foo` versions.

    > \[!WARNING]
> The version ranges should not overlap. If you want to specialize a sub
range, make sure to exclude it from the other keys. For example:
    >
    > ```yaml
    > # pnpm-workspace.yaml
    > patchedDependencies:
    >   # the specialized sub range
    >   'foo@2.2.0-2.8.0': patches/foo.2.2.0-2.8.0.patch
    >   # the more general patch, excluding the sub range above
    >   'foo@>=2.0.0 <2.2.0 || >2.8.0': 'patches/foo.gte2.patch
    > ```
    >
> In most cases, however, it's sufficient to just define an exact
version to override the range.

- `pnpm config set --location=project` saves the setting to a
`pnpm-workspace.yaml` file if no `.npmrc` file is present in the
directory
[#&#8203;9316](https://redirect.github.com/pnpm/pnpm/pull/9316).

- Rename `pnpm.allowNonAppliedPatches` to `pnpm.allowUnusedPatches`. The
old name is still supported but it would print a deprecation warning
message.

- Add `pnpm.ignorePatchFailures` to manage whether pnpm would ignore
patch application failures.

If `ignorePatchFailures` is not set, pnpm would throw an error when
patches with exact versions or version ranges fail to apply, and it
would ignore failures from name-only patches.

If `ignorePatchFailures` is explicitly set to `false`, pnpm would throw
an error when any type of patch fails to apply.

If `ignorePatchFailures` is explicitly set to `true`, pnpm would print a
warning when any type of patch fails to apply.

##### Patch Changes

- Remove dependency paths from audit output to prevent out-of-memory
errors
[#&#8203;9280](https://redirect.github.com/pnpm/pnpm/issues/9280).

</details>

<details>
<summary>vuetifyjs/nuxt-module (vuetify-nuxt-module)</summary>

###
[`v0.18.5`](https://redirect.github.com/vuetifyjs/nuxt-module/releases/tag/v0.18.5)

[Compare
Source](https://redirect.github.com/vuetifyjs/nuxt-module/compare/v0.18.4...v0.18.5)

#####    🐞 Bug Fixes

- **styles**: Resolve new scss component styles  -  by
[@&#8203;userquin](https://redirect.github.com/userquin) in
[https://github.com/vuetifyjs/nuxt-module/issues/305](https://redirect.github.com/vuetifyjs/nuxt-module/issues/305)
[<samp>(82139)</samp>](https://redirect.github.com/vuetifyjs/nuxt-module/commit/8213962)

#####     [View changes on
GitHub](https://redirect.github.com/vuetifyjs/nuxt-module/compare/v0.18.4...v0.18.5)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/unraid/api).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMDcuMSIsInVwZGF0ZWRJblZlciI6IjM5LjIyNy4zIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-02 09:40:11 -04:00
Zack Spear
e2d00dc346 feat: add webgui theme switcher component (#1304)
For now just used in Dev Mode to help assist in testing webgui CSS
changes.

- Introduced a new `UnraidThemeSwitcher` component to allow users to
change themes dynamically.
- Updated `nuxt.config.ts` to register the new component.
- Created `ThemeSwitcher.ce.vue` with functionality to handle theme
changes and update the UI accordingly.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a theme switcher, allowing users to easily swap between
available application themes.
- Expanded the configuration to register the new theme switcher as a
custom element for seamless integration.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-04-01 14:13:42 -07:00
Pujit Mehrotra
48c6ad7afa chore: fix license badge & add community links (#1300)
shields.io couldn't "recognize" our license.md, so it's statically
generated now.

## Summary by CodeRabbit

- **Documentation**
- Revised the project description and updated the documentation URL for
clearer API guidance.
  - Enhanced visual presentation by centering project shields.
  - Added a new badge to highlight the use of Vite.
- Restructured contact information into a new "Community" section with
updated channels.
  - Updated licensing details to reflect the GPL-2.0 license.
2025-03-31 16:22:26 -04:00
Eli Bosley
12eddf894e feat: basic docker controls (#1292)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Chores**
- Updated configuration settings by resetting various parameters to
default values.
	- Enhanced module integration with new Docker components.
- **New Features**
	- Introduced GraphQL API endpoints to start and stop Docker containers.
	- Added a backend service to manage Docker container operations.
- **Tests**
- Expanded test suites covering Docker resolvers and service methods to
ensure reliable container management.
- **Refactor**
- Consolidated code imports and streamlined internal calls for clearer
structure.
	- Enhanced type safety for Docker container retrieval parameters.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-03-31 16:21:06 -04:00
Eli Bosley
61fe6966ca feat: basic array controls (#1291)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Expanded API operations for array management, including new mutations
for state changes and disk handling.
- Introduced new enumeration and input types for managing array states
in the GraphQL schema.
- Added a new resolver for handling array mutations in the GraphQL API.

- **Chores**
- Upgraded configuration version to 4.4.1 and refined connectivity
status reporting.

- **Refactor**
- Streamlined request processing with improved error handling to provide
clearer feedback on connectivity issues.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-03-31 15:47:33 -04:00
renovate[bot]
b4c8efa483 fix(deps): update dependency ignore to v7 (#1299)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [ignore](https://redirect.github.com/kaelzhang/node-ignore) |
[`^5.2.4` ->
`^7.0.0`](https://renovatebot.com/diffs/npm/ignore/5.3.2/7.0.3) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/ignore/7.0.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/ignore/7.0.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/ignore/5.3.2/7.0.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/ignore/5.3.2/7.0.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>kaelzhang/node-ignore (ignore)</summary>

###
[`v7.0.3`](52f8e855b6...7.0.3)

[Compare
Source](52f8e855b6...7.0.3)

###
[`v7.0.2`](https://redirect.github.com/kaelzhang/node-ignore/compare/7.0.1...52f8e855b6aca711579c008f38829f48e5a4c78b)

[Compare
Source](https://redirect.github.com/kaelzhang/node-ignore/compare/7.0.1...52f8e855b6aca711579c008f38829f48e5a4c78b)

###
[`v7.0.1`](https://redirect.github.com/kaelzhang/node-ignore/compare/7.0.0...7.0.1)

[Compare
Source](https://redirect.github.com/kaelzhang/node-ignore/compare/7.0.0...7.0.1)

###
[`v7.0.0`](https://redirect.github.com/kaelzhang/node-ignore/releases/tag/7.0.0)

[Compare
Source](ee70c66d32...7.0.0)

#### Minor feature

The primary feature introduced by `7.0.0` is the `.checkIgnore()`
method, which is most equivalent to `git check-ignore -v`. And also it
allows to pass `{pattern, mark?}` as the parameter of `.add()` so that
we could imitate the mechanism of `git check-ignore` as:

```js
ig.add({
  pattern: 'foo/*',
  mark: '60'
})

const {
  ignored,
  rule
} = checkIgnore('foo/')

if (ignored) {
  console.log(`.gitignore:${result}:${rule.mark}:${rule.pattern} foo/`)
}

// .gitignore:60:foo/* foo/
```

#### Potential Incompatibilities

The only situation that `7.0.0` might bring incompatibility is to
`.add()` a `< 7.0.0` instance into a `>= 7.0.0` instance, which might
occur when the current workspace has multiple `node-ignore` versions
installed, please be careful.

```js
const {anotherIgnoreInstance} = require('./ignore-6.0-instance')

// A 7.0.0 instance
ignore().add(anotherIgnoreInstance)

// It will break your code
```

Otherwise, in most cases, if you never do something above or there is
only one version of `node-ignore` installed in the current workspace, it
is quite safe to upgrade to `7.0.0`.

###
[`v6.0.2`](https://redirect.github.com/kaelzhang/node-ignore/compare/6.0.1...ee70c66d32e900f6e793c733a4ca27a1dafb3819)

[Compare
Source](https://redirect.github.com/kaelzhang/node-ignore/compare/6.0.1...ee70c66d32e900f6e793c733a4ca27a1dafb3819)

###
[`v6.0.1`](https://redirect.github.com/kaelzhang/node-ignore/releases/tag/6.0.1):
6.x (&#x3D;&#x3D; 5.3.2)

[Compare
Source](https://redirect.github.com/kaelzhang/node-ignore/compare/6.0.0...6.0.1)

### 6.x

-   The release of `6.x` is due to a mistake.
- Making an upgrade from `5.x` to 6.x for now actually changes nothing
and does no harm, everyone could just upgrade or ignore the version.
    -   Actually `6.0.2` is `5.3.2`
-   The next major release will be `7.0.0`

###
[`v6.0.0`](https://redirect.github.com/kaelzhang/node-ignore/compare/5.3.2...6.0.0)

[Compare
Source](https://redirect.github.com/kaelzhang/node-ignore/compare/5.3.2...6.0.0)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/unraid/api).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMDcuMSIsInVwZGF0ZWRJblZlciI6IjM5LjIwNy4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-31 15:38:37 -04:00
Eli Bosley
dc9d5ad661 chore: fix license path in readme 2025-03-31 15:16:05 -04:00
Pujit Mehrotra
4964cf557b chore: update license fields in package.json (#1298)
Sets license for all node.js packages to `GPL-2.0-or-later`

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Chores**
- Simplified license compliance verification by removing legacy script
logic.
- Updated licensing terms across components to GPL-2.0-or-later for
broader compatibility.
- **Documentation**
- Revised setup instructions to indicate that the use of the Just build
tool is now optional.
- **New Features**
- Added fallback support in the build automation tool to ensure smoother
operations when targets are missing.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-03-31 14:52:49 -04:00
Zack Spear
e54f189630 feat: copy to webgui repo script docs + wc build options (#1285)
Previously the historical script only use to copy built web components
into the webgui repo.

The new script provides additional commands to find files in the API
repo's plugin dir and attempts to find "new" files. Then a command to
act upon each of these new file to sync in either direction, skip it, or
ignore it.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced an interactive synchronization tool that streamlines file
transfers between projects.
- Added a new command to easily trigger the synchronization process,
leveraging enhanced file management and notification capabilities.

- **Chores**
- Updated version control settings to ignore temporary synchronization
files.
  - Removed an outdated file copying script for improved maintenance.
  - Added new dependencies to support enhanced functionality.
- Modified a script to exclude specific files from deletion during the
activation code setup process.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-03-31 14:36:33 -04:00
Pujit Mehrotra
9f7218da79 chore: update license to GPL-2.0-or-later (#1295)
to accomodate GPL-3.0 based dependencies.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Documentation**
- Revised licensing documentation to clearly state that the project is
distributed under GNU GPL v2 (or later) with complete terms provided.
- **Chores**
  - Updated overall license declarations to a more flexible version.
- Introduced new compliance tools to automatically verify that
dependency licenses meet the accepted criteria.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-03-31 14:34:33 -04:00
Eli Bosley
d5a3d0dfac fix: OEM plugin issues (#1288)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- The file synchronization tool now requires an explicitly defined
destination and offers a new option to remove remote password files
before syncing. Additionally, synchronization now omits ownership,
group, and permission metadata for smoother transfers.
- The activation flow has been refined, with legacy authentication
modifications removed to deliver a cleaner welcome modal experience.
- A new variable has been introduced to enhance server state management.

- **Refactor**
- Internal configuration adjustments have been made to enhance component
delivery and streamline system actions.

- **Bug Fixes**
- Updated handling of remote user and host parameters in the
synchronization script for improved functionality.
- Simplified the activation code removal process by focusing solely on
the `.set-password.php` file restoration.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Zack Spear <hi@zackspear.com>
2025-03-28 16:39:15 -04:00
Pujit Mehrotra
2266139742 fix: extract callbacks to library (#1280)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Chores**
  - Updated environment configuration to enhance secure handling.
  - Integrated a shared dependency for consistent callback management.

- **Refactor**
  - Streamlined callback actions management for improved performance.
- Upgraded the operating system version from a beta release to stable
(7.0.0), delivering enhanced reliability.
- Centralized callback actions store usage across components for better
state management.
- Removed deprecated callback management code to improve clarity and
maintainability.

- **New Features**
- Introduced a new redirect component to enhance user navigation
experience.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Eli Bosley <ekbosley@gmail.com>
Co-authored-by: Zack Spear <hi@zackspear.com>
2025-03-28 16:11:29 -04:00
Pujit Mehrotra
7fb78494cb fix(api): redirect benign pnpm postinstall warning to log file (#1290)
which lives at `/var/log/unraid-api/build-scripts.log`
2025-03-28 13:50:41 -04:00
Pujit Mehrotra
2f09445f2e feat(api): add unraid-api --delete command (#1289)
- Added a `command:raw` package.json script to let devs run `dist/cli.js` without rebuilding, enabling experimentation in the transpiled script.
- `unraid-api --delete` allows users to select and remove keys with confirmation
prompts.
2025-03-28 10:17:22 -04:00
Eli Bosley
fa6a5c56b6 chore: update ranging strategy for renovate (#1286)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Chores**
- Updated the dependency update configuration to adopt a replace
strategy for version ranges, ensuring smoother and clearer version
management.
- Added a new dependency, `@unraid/shared-callbacks`, for enhanced
functionality.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-03-28 10:12:07 -04:00
Eli Bosley
234017a828 chore: add self to work intent template 2025-03-27 17:12:32 -04:00
Eli Bosley
0210b9e62e chore: wrong charactrer 2025-03-27 17:11:17 -04:00
Eli Bosley
4b2763c7f9 fix: additional url fixes 2025-03-27 17:10:51 -04:00
Eli Bosley
ed44796d5d Update readme.md 2025-03-27 17:07:49 -04:00
Pujit Mehrotra
d23a89f0b3 chore: re-add .env.staging in api 2025-03-27 16:01:38 -04:00
Pujit Mehrotra
d0d2ff65ed fix: replace files lost during pruning 2025-03-27 15:47:29 -04:00
Pujit Mehrotra
9f492bf217 feat: api plugin system & offline versioned dependency vendoring (#1252)
- **New Features**
- Created a dynamic plugin system for the API to enable community
augmentation of GraphQL, CLI, and Cron functionalities capabilities.
- Included an example plugin under `packages/unraid-api-plugin-health`
that adds a new graphql query for API health checks.
- Added `rc.unraid-api` commands for backing up, restoring, and
installing production dependencies, streamlining maintenance and
deployment.
- Improved dependency vendoring by bundling a versioned pnpm store
(instead of `node_modules`). Versioning will allow users to add plugins
to a specific api release without requiring an internet connection on
subsequent reboots.

- **Chores**
- Upgraded build workflows and versioning processes to ensure more
reliable artifact handling and production packaging.
2025-03-27 13:23:55 -04:00
github-actions[bot]
c4b4d26af0 chore(main): release 4.4.1 (#1270)
🤖 I have created a release *beep* *boop*
---


## [4.4.1](https://github.com/unraid/api/compare/v4.4.0...v4.4.1)
(2025-03-26)


### Bug Fixes

* .env.production from allowing console logs on build
([#1273](https://github.com/unraid/api/issues/1273))
([49f6365](49f636541b))
* patch version override logic incorrect
([#1275](https://github.com/unraid/api/issues/1275))
([0bcfb47](0bcfb47bbc))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-26 20:01:06 -04:00
Eli Bosley
0bcfb47bbc fix: patch version override logic incorrect (#1275)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Bug Fixes**
- Improved the system’s version update mechanism so that updates are
applied only when the current system version matches the expected
version. This enhancement ensures more consistent and reliable version
checks during the update process.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-03-26 17:57:30 -04:00
Michael Datelle
b0099421f3 refactor: swap out radix with reka (#1271)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Refactor**
- Improved type safety and consistency across UI components by
leveraging centralized type definitions.

- **Chores**
- Updated and consolidated UI component dependencies by migrating from a
previous library to a new one and refining package configurations.

- **Style**
- Standardized code formatting for uniform syntax and improved
readability.

- **Tests**
- Expanded testing configuration to include additional file types for
enhanced test coverage.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: mdatelle <mike@datelle.net>
2025-03-26 14:56:43 -04:00
Zack Spear
49f636541b fix: .env.production from allowing console logs on build (#1273)
`VITE_ALLOW_CONSOLE_LOGS` should not be present in `.env.production`. We
don't want basic debugs logs in prod.

Found this because the latest OS release `7.1.0-beta.1.6` which included
the latest web components had debug logs included.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Chores**
- Disabled non-essential console logging in the production environment
for a cleaner runtime experience.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-03-26 09:16:14 -04:00
github-actions[bot]
419c794e03 chore(main): release 4.4.0 (#1241)
🤖 I have created a release *beep* *boop*
---


## [4.4.0](https://github.com/unraid/api/compare/v4.3.1...v4.4.0)
(2025-03-25)


### Features

* add ReplaceKey functionality to plugin
([#1264](https://github.com/unraid/api/issues/1264))
([7e6be67](7e6be67f61))
* downgrade page replace key check
([#1263](https://github.com/unraid/api/issues/1263))
([6a92f61](6a92f61f1a))
* make log viewer component dynamic
([#1242](https://github.com/unraid/api/issues/1242))
([a356bf0](a356bf03fb))
* ReplaceKey functionality in Registration and Update pages
([#1246](https://github.com/unraid/api/issues/1246))
([f3e6a00](f3e6a0011e))
* UnraidCheckExec for Check OS Updates via UPC dropdown
([#1265](https://github.com/unraid/api/issues/1265))
([3a20930](3a20930ead))


### Bug Fixes

* **deps:** update all non-major dependencies
([#1236](https://github.com/unraid/api/issues/1236))
([9d63e56](9d63e56374))
* **deps:** update all non-major dependencies
([#1247](https://github.com/unraid/api/issues/1247))
([57a6c49](57a6c49f8a))
* **deps:** update all non-major dependencies
([#1251](https://github.com/unraid/api/issues/1251))
([ad3906e](ad3906e682))
* **deps:** update all non-major dependencies
([#1253](https://github.com/unraid/api/issues/1253))
([bbb02e9](bbb02e991c))
* **deps:** update dependency @nestjs/passport to v11
([#1244](https://github.com/unraid/api/issues/1244))
([9e54237](9e54237670))
* **deps:** update dependency graphql-subscriptions to v3
([#1209](https://github.com/unraid/api/issues/1209))
([c9789ac](c9789ac1f2))
* **deps:** update dependency ini to v5
([#1217](https://github.com/unraid/api/issues/1217))
([590ab73](590ab7327f))
* **deps:** update dependency jose to v6
([#1248](https://github.com/unraid/api/issues/1248))
([03ece33](03ece335b8))
* **deps:** update dependency marked to v15
([#1249](https://github.com/unraid/api/issues/1249))
([8f78b3f](8f78b3f1ca))
* **deps:** update dependency pino-pretty to v13
([#1250](https://github.com/unraid/api/issues/1250))
([1892e23](1892e23c22))
* **deps:** update dependency pm2 to v6
([#1258](https://github.com/unraid/api/issues/1258))
([d8afc8f](d8afc8f4c9))
* **deps:** update dependency shadcn-vue to v1
([#1259](https://github.com/unraid/api/issues/1259))
([cb2020d](cb2020dee6))
* **deps:** update dependency vue-i18n to v11
([#1261](https://github.com/unraid/api/issues/1261))
([2c01ba9](2c01ba9610))
* **deps:** update vueuse monorepo to v13 (major)
([#1262](https://github.com/unraid/api/issues/1262))
([9ce10a7](9ce10a72b2))
* make scripts executable when building the plugin
([#1255](https://github.com/unraid/api/issues/1255))
([7bc9949](7bc9949110))
* node installation not persisting across reboots
([#1256](https://github.com/unraid/api/issues/1256))
([3bfcc8e](3bfcc8e8c0))
* update configValid state to ineligible in var.ini and adjust rel…
([#1268](https://github.com/unraid/api/issues/1268))
([cc85fba](cc85fba207))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-25 09:43:58 -04:00
renovate[bot]
bbb02e991c fix(deps): update all non-major dependencies (#1253)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@apollo/client](https://www.apollographql.com/docs/react/)
([source](https://redirect.github.com/apollographql/apollo-client)) |
[`3.13.4` ->
`3.13.5`](https://renovatebot.com/diffs/npm/@apollo%2fclient/3.13.4/3.13.5)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@apollo%2fclient/3.13.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@apollo%2fclient/3.13.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@apollo%2fclient/3.13.4/3.13.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@apollo%2fclient/3.13.4/3.13.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [@eslint/js](https://eslint.org)
([source](https://redirect.github.com/eslint/eslint/tree/HEAD/packages/js))
| [`9.22.0` ->
`9.23.0`](https://renovatebot.com/diffs/npm/@eslint%2fjs/9.22.0/9.23.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@eslint%2fjs/9.23.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@eslint%2fjs/9.23.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@eslint%2fjs/9.22.0/9.23.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@eslint%2fjs/9.22.0/9.23.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [@nestjs/apollo](https://redirect.github.com/nestjs/graphql) |
[`13.0.3` ->
`13.0.4`](https://renovatebot.com/diffs/npm/@nestjs%2fapollo/13.0.3/13.0.4)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@nestjs%2fapollo/13.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@nestjs%2fapollo/13.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@nestjs%2fapollo/13.0.3/13.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@nestjs%2fapollo/13.0.3/13.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [@nestjs/common](https://nestjs.com)
([source](https://redirect.github.com/nestjs/nest/tree/HEAD/packages/common))
| [`11.0.11` ->
`11.0.12`](https://renovatebot.com/diffs/npm/@nestjs%2fcommon/11.0.11/11.0.12)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@nestjs%2fcommon/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@nestjs%2fcommon/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@nestjs%2fcommon/11.0.11/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@nestjs%2fcommon/11.0.11/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [@nestjs/core](https://nestjs.com)
([source](https://redirect.github.com/nestjs/nest/tree/HEAD/packages/core))
| [`11.0.11` ->
`11.0.12`](https://renovatebot.com/diffs/npm/@nestjs%2fcore/11.0.11/11.0.12)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@nestjs%2fcore/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@nestjs%2fcore/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@nestjs%2fcore/11.0.11/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@nestjs%2fcore/11.0.11/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [@nestjs/graphql](https://redirect.github.com/nestjs/graphql) |
[`13.0.3` ->
`13.0.4`](https://renovatebot.com/diffs/npm/@nestjs%2fgraphql/13.0.3/13.0.4)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@nestjs%2fgraphql/13.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@nestjs%2fgraphql/13.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@nestjs%2fgraphql/13.0.3/13.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@nestjs%2fgraphql/13.0.3/13.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [@nestjs/platform-fastify](https://nestjs.com)
([source](https://redirect.github.com/nestjs/nest/tree/HEAD/packages/platform-fastify))
| [`11.0.11` ->
`11.0.12`](https://renovatebot.com/diffs/npm/@nestjs%2fplatform-fastify/11.0.11/11.0.12)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@nestjs%2fplatform-fastify/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@nestjs%2fplatform-fastify/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@nestjs%2fplatform-fastify/11.0.11/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@nestjs%2fplatform-fastify/11.0.11/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [@nestjs/testing](https://nestjs.com)
([source](https://redirect.github.com/nestjs/nest/tree/HEAD/packages/testing))
| [`11.0.11` ->
`11.0.12`](https://renovatebot.com/diffs/npm/@nestjs%2ftesting/11.0.11/11.0.12)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@nestjs%2ftesting/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@nestjs%2ftesting/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@nestjs%2ftesting/11.0.11/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@nestjs%2ftesting/11.0.11/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [@nuxt/devtools](https://devtools.nuxt.com)
([source](https://redirect.github.com/nuxt/devtools/tree/HEAD/packages/devtools))
| [`2.3.0` ->
`2.3.1`](https://renovatebot.com/diffs/npm/@nuxt%2fdevtools/2.3.0/2.3.1)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@nuxt%2fdevtools/2.3.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@nuxt%2fdevtools/2.3.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@nuxt%2fdevtools/2.3.0/2.3.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@nuxt%2fdevtools/2.3.0/2.3.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [@rollup/rollup-linux-x64-gnu](https://rollupjs.org/)
([source](https://redirect.github.com/rollup/rollup)) | [`4.36.0` ->
`4.37.0`](https://renovatebot.com/diffs/npm/@rollup%2frollup-linux-x64-gnu/4.36.0/4.37.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@rollup%2frollup-linux-x64-gnu/4.37.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@rollup%2frollup-linux-x64-gnu/4.37.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@rollup%2frollup-linux-x64-gnu/4.36.0/4.37.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@rollup%2frollup-linux-x64-gnu/4.36.0/4.37.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[@storybook/addon-essentials](https://redirect.github.com/storybookjs/storybook/tree/next/code/addons/essentials)
([source](https://redirect.github.com/storybookjs/storybook/tree/HEAD/code/addons/essentials))
| [`8.6.7` ->
`8.6.9`](https://renovatebot.com/diffs/npm/@storybook%2faddon-essentials/8.6.7/8.6.9)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2faddon-essentials/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2faddon-essentials/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2faddon-essentials/8.6.7/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2faddon-essentials/8.6.7/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[@storybook/addon-interactions](https://redirect.github.com/storybookjs/storybook/tree/next/code/addons/interactions)
([source](https://redirect.github.com/storybookjs/storybook/tree/HEAD/code/addons/interactions))
| [`8.6.7` ->
`8.6.9`](https://renovatebot.com/diffs/npm/@storybook%2faddon-interactions/8.6.7/8.6.9)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2faddon-interactions/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2faddon-interactions/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2faddon-interactions/8.6.7/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2faddon-interactions/8.6.7/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[@storybook/addon-links](https://redirect.github.com/storybookjs/storybook/tree/next/code/addons/links)
([source](https://redirect.github.com/storybookjs/storybook/tree/HEAD/code/addons/links))
| [`8.6.7` ->
`8.6.9`](https://renovatebot.com/diffs/npm/@storybook%2faddon-links/8.6.7/8.6.9)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2faddon-links/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2faddon-links/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2faddon-links/8.6.7/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2faddon-links/8.6.7/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[@storybook/builder-vite](https://redirect.github.com/storybookjs/storybook/tree/next/code/builders/builder-vite/#readme)
([source](https://redirect.github.com/storybookjs/storybook/tree/HEAD/code/builders/builder-vite))
| [`8.6.7` ->
`8.6.9`](https://renovatebot.com/diffs/npm/@storybook%2fbuilder-vite/8.6.7/8.6.9)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2fbuilder-vite/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2fbuilder-vite/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2fbuilder-vite/8.6.7/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2fbuilder-vite/8.6.7/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[@storybook/vue3-vite](https://redirect.github.com/storybookjs/storybook/tree/next/code/frameworks/vue3-vite)
([source](https://redirect.github.com/storybookjs/storybook/tree/HEAD/code/frameworks/vue3-vite))
| [`8.6.7` ->
`8.6.9`](https://renovatebot.com/diffs/npm/@storybook%2fvue3-vite/8.6.7/8.6.9)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2fvue3-vite/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2fvue3-vite/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2fvue3-vite/8.6.7/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2fvue3-vite/8.6.7/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [@swc/core](https://swc.rs)
([source](https://redirect.github.com/swc-project/swc)) | [`1.11.11` ->
`1.11.13`](https://renovatebot.com/diffs/npm/@swc%2fcore/1.11.11/1.11.13)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@swc%2fcore/1.11.13?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@swc%2fcore/1.11.13?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@swc%2fcore/1.11.11/1.11.13?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@swc%2fcore/1.11.11/1.11.13?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[@types/diff](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/diff)
([source](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/diff))
| [`7.0.1` ->
`7.0.2`](https://renovatebot.com/diffs/npm/@types%2fdiff/7.0.1/7.0.2) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/@types%2fdiff/7.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@types%2fdiff/7.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@types%2fdiff/7.0.1/7.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@types%2fdiff/7.0.1/7.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[@types/node](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node)
([source](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node))
| [`22.13.10` ->
`22.13.13`](https://renovatebot.com/diffs/npm/@types%2fnode/22.13.10/22.13.13)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@types%2fnode/22.13.13?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@types%2fnode/22.13.13?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@types%2fnode/22.13.10/22.13.13?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@types%2fnode/22.13.10/22.13.13?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [eslint](https://eslint.org)
([source](https://redirect.github.com/eslint/eslint)) | [`9.22.0` ->
`9.23.0`](https://renovatebot.com/diffs/npm/eslint/9.22.0/9.23.0) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/eslint/9.23.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/eslint/9.23.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/eslint/9.22.0/9.23.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/eslint/9.22.0/9.23.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[eslint-plugin-prettier](https://redirect.github.com/prettier/eslint-plugin-prettier)
| [`5.2.3` ->
`5.2.5`](https://renovatebot.com/diffs/npm/eslint-plugin-prettier/5.2.3/5.2.5)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/eslint-plugin-prettier/5.2.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/eslint-plugin-prettier/5.2.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/eslint-plugin-prettier/5.2.3/5.2.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/eslint-plugin-prettier/5.2.3/5.2.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [graphql-scalars](https://redirect.github.com/Urigo/graphql-scalars) |
[`1.24.1` ->
`1.24.2`](https://renovatebot.com/diffs/npm/graphql-scalars/1.24.1/1.24.2)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/graphql-scalars/1.24.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/graphql-scalars/1.24.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/graphql-scalars/1.24.1/1.24.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/graphql-scalars/1.24.1/1.24.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [nestjs-pino](https://redirect.github.com/iamolegga/nestjs-pino) |
[`4.3.1` ->
`4.4.0`](https://renovatebot.com/diffs/npm/nestjs-pino/4.3.1/4.4.0) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/nestjs-pino/4.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/nestjs-pino/4.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/nestjs-pino/4.3.1/4.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/nestjs-pino/4.3.1/4.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [nuxt](https://nuxt.com)
([source](https://redirect.github.com/nuxt/nuxt/tree/HEAD/packages/nuxt))
| [`3.16.0` ->
`3.16.1`](https://renovatebot.com/diffs/npm/nuxt/3.16.0/3.16.1) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/nuxt/3.16.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/nuxt/3.16.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/nuxt/3.16.0/3.16.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/nuxt/3.16.0/3.16.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [reka-ui](https://redirect.github.com/unovue/reka-ui) | [`2.1.0` ->
`2.1.1`](https://renovatebot.com/diffs/npm/reka-ui/2.1.0/2.1.1) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/reka-ui/2.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/reka-ui/2.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/reka-ui/2.1.0/2.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/reka-ui/2.1.0/2.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[storybook](https://redirect.github.com/storybookjs/storybook/tree/next/code/lib/cli)
([source](https://redirect.github.com/storybookjs/storybook/tree/HEAD/code/lib/cli))
| [`8.6.7` ->
`8.6.9`](https://renovatebot.com/diffs/npm/storybook/8.6.7/8.6.9) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/storybook/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/storybook/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/storybook/8.6.7/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/storybook/8.6.7/8.6.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[typescript-eslint](https://typescript-eslint.io/packages/typescript-eslint)
([source](https://redirect.github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint))
| [`8.26.1` ->
`8.28.0`](https://renovatebot.com/diffs/npm/typescript-eslint/8.26.1/8.28.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/typescript-eslint/8.28.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/typescript-eslint/8.28.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/typescript-eslint/8.26.1/8.28.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/typescript-eslint/8.26.1/8.28.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [vite](https://vite.dev)
([source](https://redirect.github.com/vitejs/vite/tree/HEAD/packages/vite))
| [`6.2.2` ->
`6.2.3`](https://renovatebot.com/diffs/npm/vite/6.2.2/6.2.3) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/vite/6.2.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/vite/6.2.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/vite/6.2.2/6.2.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vite/6.2.2/6.2.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [vitest](https://redirect.github.com/vitest-dev/vitest)
([source](https://redirect.github.com/vitest-dev/vitest/tree/HEAD/packages/vitest))
| [`3.0.7` ->
`3.0.9`](https://renovatebot.com/diffs/npm/vitest/3.0.7/3.0.9) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/vitest/3.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/vitest/3.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/vitest/3.0.7/3.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vitest/3.0.7/3.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [vuetify](https://vuetifyjs.com)
([source](https://redirect.github.com/vuetifyjs/vuetify/tree/HEAD/packages/vuetify))
| [`3.7.17` ->
`3.7.18`](https://renovatebot.com/diffs/npm/vuetify/3.7.17/3.7.18) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/vuetify/3.7.18?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/vuetify/3.7.18?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/vuetify/3.7.17/3.7.18?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vuetify/3.7.17/3.7.18?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [zx](https://google.github.io/zx/)
([source](https://redirect.github.com/google/zx)) | [`8.3.2` ->
`8.4.1`](https://renovatebot.com/diffs/npm/zx/8.3.2/8.4.1) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/zx/8.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/zx/8.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/zx/8.3.2/8.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/zx/8.3.2/8.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>apollographql/apollo-client (@&#8203;apollo/client)</summary>

###
[`v3.13.5`](https://redirect.github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#3135)

[Compare
Source](https://redirect.github.com/apollographql/apollo-client/compare/v3.13.4...v3.13.5)

##### Patch Changes

-
[#&#8203;12461](https://redirect.github.com/apollographql/apollo-client/pull/12461)
[`12c8d06`](12c8d06f1e)
Thanks [@&#8203;jerelmiller](https://redirect.github.com/jerelmiller)! -
Fix an issue where a `cache-first` query would return the result for
previous variables when a cache update is issued after simultaneously
changing variables and skipping the query.

</details>

<details>
<summary>eslint/eslint (@&#8203;eslint/js)</summary>

###
[`v9.23.0`](https://redirect.github.com/eslint/eslint/compare/v9.22.0...20591c49ff27435b1555111a929a6966febc249f)

[Compare
Source](https://redirect.github.com/eslint/eslint/compare/v9.22.0...v9.23.0)

</details>

<details>
<summary>nestjs/graphql (@&#8203;nestjs/apollo)</summary>

###
[`v13.0.4`](https://redirect.github.com/nestjs/graphql/releases/tag/v13.0.4)

[Compare
Source](https://redirect.github.com/nestjs/graphql/compare/v13.0.3...v13.0.4)

##### 13.0.4 (2025-03-24)

##### Enhancements

-   `graphql`
- [#&#8203;3503](https://redirect.github.com/nestjs/graphql/pull/3503)
feat(graphql): add support for transforming the resolvers
([@&#8203;JoshVee](https://redirect.github.com/JoshVee))

##### Dependencies

-   `graphql`
- [#&#8203;3487](https://redirect.github.com/nestjs/graphql/pull/3487)
fix(deps): update dependency ws to v8.18.1
([@&#8203;renovate\[bot\]](https://redirect.github.com/apps/renovate))
- [#&#8203;3488](https://redirect.github.com/nestjs/graphql/pull/3488)
fix(deps): update graphql-tools monorepo
([@&#8203;renovate\[bot\]](https://redirect.github.com/apps/renovate))
-   `mercurius`
- [#&#8203;3494](https://redirect.github.com/nestjs/graphql/pull/3494)
chore(deps): update dependency mercurius to v16.1.0
([@&#8203;renovate\[bot\]](https://redirect.github.com/apps/renovate))

##### Committers: 1

- Josh Vawdrey ([@&#8203;JoshVee](https://redirect.github.com/JoshVee))

</details>

<details>
<summary>nestjs/nest (@&#8203;nestjs/common)</summary>

###
[`v11.0.12`](https://redirect.github.com/nestjs/nest/compare/v11.0.11...c58f49a3cc7b48916a98dcb81764ce77950d535a)

[Compare
Source](https://redirect.github.com/nestjs/nest/compare/v11.0.11...v11.0.12)

</details>

<details>
<summary>nestjs/nest (@&#8203;nestjs/core)</summary>

###
[`v11.0.12`](https://redirect.github.com/nestjs/nest/compare/v11.0.11...c58f49a3cc7b48916a98dcb81764ce77950d535a)

[Compare
Source](https://redirect.github.com/nestjs/nest/compare/v11.0.11...v11.0.12)

</details>

<details>
<summary>nestjs/nest (@&#8203;nestjs/platform-fastify)</summary>

###
[`v11.0.12`](https://redirect.github.com/nestjs/nest/releases/tag/v11.0.12)

[Compare
Source](https://redirect.github.com/nestjs/nest/compare/v11.0.11...v11.0.12)

#### v11.0.12 (2025-03-19)

##### Bug fixes

-   `core`
- [#&#8203;14803](https://redirect.github.com/nestjs/nest/pull/14803)
fix(core): infinite loop on broken circular reference
([@&#8203;kamilmysliwiec](https://redirect.github.com/kamilmysliwiec))
-
[https://github.com/nestjs/nest/pull/14792](https://redirect.github.com/nestjs/nest/pull/14792)
dependencies not resolving for request-scoped lazy providers
([@&#8203;anizozina](https://redirect.github.com/anizozina))

##### Enhancements

-   `core`
- [#&#8203;14802](https://redirect.github.com/nestjs/nest/pull/14802)
feat(core): add options to the legacy route converter
([@&#8203;kamilmysliwiec](https://redirect.github.com/kamilmysliwiec))

</details>

<details>
<summary>nestjs/nest (@&#8203;nestjs/testing)</summary>

###
[`v11.0.12`](https://redirect.github.com/nestjs/nest/compare/v11.0.11...c58f49a3cc7b48916a98dcb81764ce77950d535a)

[Compare
Source](https://redirect.github.com/nestjs/nest/compare/v11.0.11...v11.0.12)

</details>

<details>
<summary>nuxt/devtools (@&#8203;nuxt/devtools)</summary>

###
[`v2.3.1`](https://redirect.github.com/nuxt/devtools/blob/HEAD/CHANGELOG.md#231-2025-03-20)

[Compare
Source](https://redirect.github.com/nuxt/devtools/compare/v2.3.0...v2.3.1)

##### Bug Fixes

- downgrade `execa` to be compatible with Node v18, fix
[#&#8203;821](https://redirect.github.com/nuxt/devtools/issues/821)
([f15c7dc](f15c7dca3a))

</details>

<details>
<summary>rollup/rollup (@&#8203;rollup/rollup-linux-x64-gnu)</summary>

###
[`v4.37.0`](https://redirect.github.com/rollup/rollup/blob/HEAD/CHANGELOG.md#4370)

[Compare
Source](https://redirect.github.com/rollup/rollup/compare/v4.36.0...v4.37.0)

*2025-03-23*

##### Features

- Support Musl Linux on Riscv64 architectures
([#&#8203;5726](https://redirect.github.com/rollup/rollup/issues/5726))
- Handles class decorators placed before the `export` keyword
([#&#8203;5871](https://redirect.github.com/rollup/rollup/issues/5871))

##### Bug Fixes

- Log Rust panic messages to the console when using the WASM build
([#&#8203;5875](https://redirect.github.com/rollup/rollup/issues/5875))

##### Pull Requests

- [#&#8203;5726](https://redirect.github.com/rollup/rollup/pull/5726):
Add support for linux riscv64 musl
([@&#8203;fossdd](https://redirect.github.com/fossdd),
[@&#8203;leso-kn](https://redirect.github.com/leso-kn))
- [#&#8203;5871](https://redirect.github.com/rollup/rollup/pull/5871):
feat: support decorators before or after export
([@&#8203;TrickyPi](https://redirect.github.com/TrickyPi))
- [#&#8203;5875](https://redirect.github.com/rollup/rollup/pull/5875):
capture Rust panic messages and output them to the console.
([@&#8203;luyahan](https://redirect.github.com/luyahan),
[@&#8203;lukastaegert](https://redirect.github.com/lukastaegert))
- [#&#8203;5883](https://redirect.github.com/rollup/rollup/pull/5883):
Pin digest of 3rd party actions
([@&#8203;re-taro](https://redirect.github.com/re-taro))
- [#&#8203;5885](https://redirect.github.com/rollup/rollup/pull/5885):
fix(deps): lock file maintenance minor/patch updates
([@&#8203;renovate](https://redirect.github.com/renovate)\[bot])

</details>

<details>
<summary>storybookjs/storybook
(@&#8203;storybook/addon-essentials)</summary>

###
[`v8.6.9`](https://redirect.github.com/storybookjs/storybook/blob/HEAD/CHANGELOG.md#869)

[Compare
Source](https://redirect.github.com/storybookjs/storybook/compare/v8.6.8...v8.6.9)

- Next: Fix react aliases in next vite plugin -
[#&#8203;30914](https://redirect.github.com/storybookjs/storybook/pull/30914),
thanks [@&#8203;kasperpeulen](https://redirect.github.com/kasperpeulen)!

###
[`v8.6.8`](https://redirect.github.com/storybookjs/storybook/blob/HEAD/CHANGELOG.md#868)

[Compare
Source](https://redirect.github.com/storybookjs/storybook/compare/v8.6.7...v8.6.8)

- Angular: Export all files in Angular package.json -
[#&#8203;30849](https://redirect.github.com/storybookjs/storybook/pull/30849),
thanks [@&#8203;kasperpeulen](https://redirect.github.com/kasperpeulen)!
- CLI: Don't add packageManager entry to package.json automatically -
[#&#8203;30855](https://redirect.github.com/storybookjs/storybook/pull/30855),
thanks [@&#8203;kasperpeulen](https://redirect.github.com/kasperpeulen)!
- React: Allow portable stories to be used in SSR -
[#&#8203;30847](https://redirect.github.com/storybookjs/storybook/pull/30847),
thanks [@&#8203;kasperpeulen](https://redirect.github.com/kasperpeulen)!
- Svelte: Adjust Svelte typings to include Svelte 5 function components
-
[#&#8203;30852](https://redirect.github.com/storybookjs/storybook/pull/30852),
thanks [@&#8203;dummdidumm](https://redirect.github.com/dummdidumm)!
- Telemetry: Make sure that telemetry doesn't fail on init -
[#&#8203;30857](https://redirect.github.com/storybookjs/storybook/pull/30857),
thanks [@&#8203;kasperpeulen](https://redirect.github.com/kasperpeulen)!
- Vite: Update HMR filter to target specific story file types -
[#&#8203;30845](https://redirect.github.com/storybookjs/storybook/pull/30845),
thanks [@&#8203;kasperpeulen](https://redirect.github.com/kasperpeulen)!

</details>

<details>
<summary>storybookjs/storybook (@&#8203;storybook/addon-links)</summary>

###
[`v8.6.9`](https://redirect.github.com/storybookjs/storybook/compare/v8.6.8...207c2f46348303bf86950865cf7a193b5a60ab69)

[Compare
Source](https://redirect.github.com/storybookjs/storybook/compare/v8.6.8...v8.6.9)

###
[`v8.6.8`](https://redirect.github.com/storybookjs/storybook/blob/HEAD/CHANGELOG.md#868)

[Compare
Source](https://redirect.github.com/storybookjs/storybook/compare/v8.6.7...v8.6.8)

- Angular: Export all files in Angular package.json -
[#&#8203;30849](https://redirect.github.com/storybookjs/storybook/pull/30849),
thanks [@&#8203;kasperpeulen](https://redirect.github.com/kasperpeulen)!
- CLI: Don't add packageManager entry to package.json automatically -
[#&#8203;30855](https://redirect.github.com/storybookjs/storybook/pull/30855),
thanks [@&#8203;kasperpeulen](https://redirect.github.com/kasperpeulen)!
- React: Allow portable stories to be used in SSR -
[#&#8203;30847](https://redirect.github.com/storybookjs/storybook/pull/30847),
thanks [@&#8203;kasperpeulen](https://redirect.github.com/kasperpeulen)!
- Svelte: Adjust Svelte typings to include Svelte 5 function components
-
[#&#8203;30852](https://redirect.github.com/storybookjs/storybook/pull/30852),
thanks [@&#8203;dummdidumm](https://redirect.github.com/dummdidumm)!
- Telemetry: Make sure that telemetry doesn't fail on init -
[#&#8203;30857](https://redirect.github.com/storybookjs/storybook/pull/30857),
thanks [@&#8203;kasperpeulen](https://redirect.github.com/kasperpeulen)!
- Vite: Update HMR filter to target specific story file types -
[#&#8203;30845](https://redirect.github.com/storybookjs/storybook/pull/30845),
thanks [@&#8203;kasperpeulen](https://redirect.github.com/kasperpeulen)!

</details>

<details>
<summary>swc-project/swc (@&#8203;swc/core)</summary>

###
[`v1.11.13`](https://redirect.github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11113---2025-03-24)

[Compare
Source](https://redirect.github.com/swc-project/swc/compare/v1.11.12...v1.11.13)

##### Features

- **(es/minifier)** Merge alt's cons with cons
([#&#8203;10256](https://redirect.github.com/swc-project/swc/issues/10256))
([589bcd7](589bcd70c4))

- **(swc_core)** Expose features of `swc_parallel`
([#&#8203;10258](https://redirect.github.com/swc-project/swc/issues/10258))
([042f19f](042f19ff66))

##### Performance

- **(es/minifier)** Merge `expr_simplifier` into pure optimizer
([#&#8203;10202](https://redirect.github.com/swc-project/swc/issues/10202))
([9c9b0ba](9c9b0baaac))

###
[`v1.11.12`](https://redirect.github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11112---2025-03-23)

[Compare
Source](https://redirect.github.com/swc-project/swc/compare/v1.11.11...v1.11.12)

##### Bug Fixes

- **(es/minifier)** Make `inline_globals` noop by default
([#&#8203;10231](https://redirect.github.com/swc-project/swc/issues/10231))
([b192dc8](b192dc82e6))

- **(es/minifier)** Fix access to `GLOBALS` in char freq compute
([#&#8203;10239](https://redirect.github.com/swc-project/swc/issues/10239))
([6286663](6286663868))

- **(es/parser)** Fix span of wrong `await` tokens
([#&#8203;10252](https://redirect.github.com/swc-project/swc/issues/10252))
([5c28dc3](5c28dc3964))

- **(es/types)** Fix broken types
([#&#8203;10224](https://redirect.github.com/swc-project/swc/issues/10224))
([540bdf8](540bdf868d))

##### Documentation

- **(es)** Improve documentation
([#&#8203;10247](https://redirect.github.com/swc-project/swc/issues/10247))
([549e38d](549e38db9e))

##### Features

- **(es/fast-lexer)** Enhance identifier handling with Unicode support
([#&#8203;10226](https://redirect.github.com/swc-project/swc/issues/10226))
([482b63a](482b63a905))

- **(es/minifier)** Invoke IIFE into block
([#&#8203;10220](https://redirect.github.com/swc-project/swc/issues/10220))
([c9a6c23](c9a6c23787))

- **(es/minifier)** Remove needless blocks
([#&#8203;10234](https://redirect.github.com/swc-project/swc/issues/10234))
([0817970](08179702bf))

- **(swc_parallel)** Introduce `rayon` mode
([#&#8203;10237](https://redirect.github.com/swc-project/swc/issues/10237))
([3c2213c](3c2213c829))

- **(ts/fast-strip)** Add start/end span information
([#&#8203;10251](https://redirect.github.com/swc-project/swc/issues/10251))
([ab39a62](ab39a62528))

- **(ts/fast-strip)** Improve error message snippet
([#&#8203;10253](https://redirect.github.com/swc-project/swc/issues/10253))
([f4f426c](f4f426c9c9))

- **(ts/fast-strip)** Remove line numbers
([#&#8203;10254](https://redirect.github.com/swc-project/swc/issues/10254))
([40e216d](40e216db82))

##### Performance

- **(es/minifier)** Merge `dead_branch_remover` into pure optimizer
([#&#8203;10201](https://redirect.github.com/swc-project/swc/issues/10201))
([6841523](6841523977))

</details>

<details>
<summary>eslint/eslint (eslint)</summary>

###
[`v9.23.0`](https://redirect.github.com/eslint/eslint/compare/v9.22.0...2aaadceec13e6df89a0c56e2b6ce4a145c1ac3aa)

[Compare
Source](https://redirect.github.com/eslint/eslint/compare/v9.22.0...v9.23.0)

</details>

<details>
<summary>prettier/eslint-plugin-prettier
(eslint-plugin-prettier)</summary>

###
[`v5.2.5`](https://redirect.github.com/prettier/eslint-plugin-prettier/blob/HEAD/CHANGELOG.md#525)

[Compare
Source](https://redirect.github.com/prettier/eslint-plugin-prettier/compare/v5.2.4...v5.2.5)

##### Patch Changes

-
[#&#8203;721](https://redirect.github.com/prettier/eslint-plugin-prettier/pull/721)
[`4f5513d`](4f5513de4c)
Thanks [@&#8203;JounQin](https://redirect.github.com/JounQin)! - fix:
clarify correct `eslint-config-prettier` peer range

###
[`v5.2.4`](https://redirect.github.com/prettier/eslint-plugin-prettier/blob/HEAD/CHANGELOG.md#524)

[Compare
Source](https://redirect.github.com/prettier/eslint-plugin-prettier/compare/v5.2.3...v5.2.4)

##### Patch Changes

-
[#&#8203;715](https://redirect.github.com/prettier/eslint-plugin-prettier/pull/715)
[`b8cfe56`](b8cfe56e34)
Thanks [@&#8203;JounQin](https://redirect.github.com/JounQin)! - chore:
hourcekeeping, bump all (dev) deps

</details>

<details>
<summary>Urigo/graphql-scalars (graphql-scalars)</summary>

###
[`v1.24.2`](https://redirect.github.com/Urigo/graphql-scalars/blob/HEAD/CHANGELOG.md#1242)

[Compare
Source](https://redirect.github.com/Urigo/graphql-scalars/compare/v1.24.1...v1.24.2)

##### Patch Changes

-
[#&#8203;2791](https://redirect.github.com/graphql-hive/graphql-scalars/pull/2791)

[`3e1e924`](3e1e924b93)
Thanks [@&#8203;dotansimha](https://redirect.github.com/dotansimha)! -
Enable npm provenance

</details>

<details>
<summary>iamolegga/nestjs-pino (nestjs-pino)</summary>

###
[`v4.4.0`](https://redirect.github.com/iamolegga/nestjs-pino/releases/tag/4.4.0):
: allow publishing source map files

[Compare
Source](https://redirect.github.com/iamolegga/nestjs-pino/compare/4.3.1...4.4.0)

#### What's Changed

- build(deps-dev): bump prettier from 3.5.1 to 3.5.2 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2255](https://redirect.github.com/iamolegga/nestjs-pino/pull/2255)
- build(deps-dev): bump
[@&#8203;eslint/js](https://redirect.github.com/eslint/js) from 9.20.0
to 9.21.0 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2256](https://redirect.github.com/iamolegga/nestjs-pino/pull/2256)
- build(deps-dev): bump
[@&#8203;types/node](https://redirect.github.com/types/node) from
22.13.4 to 22.13.5 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2257](https://redirect.github.com/iamolegga/nestjs-pino/pull/2257)
- build(deps-dev): bump ts-jest from 29.2.5 to 29.2.6 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2258](https://redirect.github.com/iamolegga/nestjs-pino/pull/2258)
- build(deps-dev): bump
[@&#8203;eslint/eslintrc](https://redirect.github.com/eslint/eslintrc)
from 3.2.0 to 3.3.0 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2261](https://redirect.github.com/iamolegga/nestjs-pino/pull/2261)
- build(deps-dev): bump
[@&#8203;eslint/compat](https://redirect.github.com/eslint/compat) from
1.2.6 to 1.2.7 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2262](https://redirect.github.com/iamolegga/nestjs-pino/pull/2262)
- build(deps-dev): bump rxjs from 7.8.1 to 7.8.2 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2259](https://redirect.github.com/iamolegga/nestjs-pino/pull/2259)
- build(deps-dev): bump eslint from 9.20.1 to 9.21.0 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2260](https://redirect.github.com/iamolegga/nestjs-pino/pull/2260)
- build(deps-dev): bump
[@&#8203;typescript-eslint/eslint-plugin](https://redirect.github.com/typescript-eslint/eslint-plugin)
from 8.24.1 to 8.25.0 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2263](https://redirect.github.com/iamolegga/nestjs-pino/pull/2263)
- build(deps-dev): bump
[@&#8203;typescript-eslint/parser](https://redirect.github.com/typescript-eslint/parser)
from 8.24.1 to 8.25.0 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2264](https://redirect.github.com/iamolegga/nestjs-pino/pull/2264)
- build(deps-dev): bump eslint-config-prettier from 10.0.1 to 10.0.2 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2265](https://redirect.github.com/iamolegga/nestjs-pino/pull/2265)
- build(deps-dev): bump
[@&#8203;nestjs/testing](https://redirect.github.com/nestjs/testing)
from 11.0.10 to 11.0.11 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2267](https://redirect.github.com/iamolegga/nestjs-pino/pull/2267)
- build(deps-dev): bump
[@&#8203;types/node](https://redirect.github.com/types/node) from
22.13.5 to 22.13.8 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2268](https://redirect.github.com/iamolegga/nestjs-pino/pull/2268)
- build(deps-dev): bump
[@&#8203;nestjs/platform-express](https://redirect.github.com/nestjs/platform-express)
from 11.0.10 to 11.0.11 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2269](https://redirect.github.com/iamolegga/nestjs-pino/pull/2269)
- build(deps-dev): bump prettier from 3.5.2 to 3.5.3 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2271](https://redirect.github.com/iamolegga/nestjs-pino/pull/2271)
- build(deps-dev): bump
[@&#8203;nestjs/core](https://redirect.github.com/nestjs/core) from
11.0.10 to 11.0.11 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2272](https://redirect.github.com/iamolegga/nestjs-pino/pull/2272)
- build(deps-dev): bump
[@&#8203;nestjs/platform-fastify](https://redirect.github.com/nestjs/platform-fastify)
from 11.0.10 to 11.0.11 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2273](https://redirect.github.com/iamolegga/nestjs-pino/pull/2273)
- build(deps-dev): bump
[@&#8203;nestjs/common](https://redirect.github.com/nestjs/common) from
11.0.10 to 11.0.11 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2274](https://redirect.github.com/iamolegga/nestjs-pino/pull/2274)
- build(deps-dev): bump
[@&#8203;types/node](https://redirect.github.com/types/node) from
22.13.8 to 22.13.9 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2275](https://redirect.github.com/iamolegga/nestjs-pino/pull/2275)
- build(deps-dev): bump
[@&#8203;typescript-eslint/eslint-plugin](https://redirect.github.com/typescript-eslint/eslint-plugin)
from 8.25.0 to 8.26.0 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2276](https://redirect.github.com/iamolegga/nestjs-pino/pull/2276)
- build(deps-dev): bump
[@&#8203;typescript-eslint/parser](https://redirect.github.com/typescript-eslint/parser)
from 8.25.0 to 8.26.0 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2277](https://redirect.github.com/iamolegga/nestjs-pino/pull/2277)
- build(deps-dev): bump eslint from 9.21.0 to 9.22.0 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2278](https://redirect.github.com/iamolegga/nestjs-pino/pull/2278)
- build(deps-dev): bump
[@&#8203;types/node](https://redirect.github.com/types/node) from
22.13.9 to 22.13.10 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2280](https://redirect.github.com/iamolegga/nestjs-pino/pull/2280)
- build(deps-dev): bump eslint-config-prettier from 10.0.2 to 10.1.1 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2281](https://redirect.github.com/iamolegga/nestjs-pino/pull/2281)
- build(deps-dev): bump
[@&#8203;typescript-eslint/parser](https://redirect.github.com/typescript-eslint/parser)
from 8.26.0 to 8.26.1 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2284](https://redirect.github.com/iamolegga/nestjs-pino/pull/2284)
- build(deps-dev): bump
[@&#8203;typescript-eslint/eslint-plugin](https://redirect.github.com/typescript-eslint/eslint-plugin)
from 8.26.0 to 8.26.1 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2285](https://redirect.github.com/iamolegga/nestjs-pino/pull/2285)
- build(deps-dev): bump typescript from 5.7.3 to 5.8.2 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2270](https://redirect.github.com/iamolegga/nestjs-pino/pull/2270)
- chore(package): allow publishing source map files by
[@&#8203;H4ad](https://redirect.github.com/H4ad) in
[https://github.com/iamolegga/nestjs-pino/pull/2288](https://redirect.github.com/iamolegga/nestjs-pino/pull/2288)

#### New Contributors

- [@&#8203;H4ad](https://redirect.github.com/H4ad) made their first
contribution in
[https://github.com/iamolegga/nestjs-pino/pull/2288](https://redirect.github.com/iamolegga/nestjs-pino/pull/2288)

**Full Changelog**:
https://github.com/iamolegga/nestjs-pino/compare/4.3.1...4.4.0

</details>

<details>
<summary>nuxt/nuxt (nuxt)</summary>

###
[`v3.16.1`](https://redirect.github.com/nuxt/nuxt/releases/tag/v3.16.1)

[Compare
Source](https://redirect.github.com/nuxt/nuxt/compare/v3.16.0...v3.16.1)

[compare
changes](https://redirect.github.com/nuxt/nuxt/compare/v3.16.0...v3.16.1)

##### 🔥 Performance

- **nuxt:** Use browser cache for payloads
([#&#8203;31379](https://redirect.github.com/nuxt/nuxt/pull/31379))

##### 🩹 Fixes

- **nuxt:** Restore nuxt aliases to nitro compilerOptions.paths
([#&#8203;31278](https://redirect.github.com/nuxt/nuxt/pull/31278))
- **nuxt:** Use new `mocked-exports`
([#&#8203;31295](https://redirect.github.com/nuxt/nuxt/pull/31295))
- **nuxt:** Check resolved options for polyfills
([#&#8203;31307](https://redirect.github.com/nuxt/nuxt/pull/31307))
- **nuxt:** Render style component html
([#&#8203;31337](https://redirect.github.com/nuxt/nuxt/pull/31337))
- **nuxt:** Add missing lazy hydration prop in regex
([#&#8203;31359](https://redirect.github.com/nuxt/nuxt/pull/31359))
- **nuxt:** Fully resolve nuxt dependencies
([#&#8203;31436](https://redirect.github.com/nuxt/nuxt/pull/31436))
- **vite:** Don't show interim vite build output files
([#&#8203;31439](https://redirect.github.com/nuxt/nuxt/pull/31439))
- **nuxt:** Ignore prerendering unprefixed public assets
([151912ec3](https://redirect.github.com/nuxt/nuxt/commit/151912ec3))
- **nuxt:** Use more performant router catchall pattern
([#&#8203;31450](https://redirect.github.com/nuxt/nuxt/pull/31450))
- **nuxt:** Prevent param duplication in `typedPages` implementation
([#&#8203;31331](https://redirect.github.com/nuxt/nuxt/pull/31331))
- **nuxt:** Sort route paths before creating route tree
([#&#8203;31454](https://redirect.github.com/nuxt/nuxt/pull/31454))

##### 📖 Documentation

- Update link to vercel edge network
([ec20802a5](https://redirect.github.com/nuxt/nuxt/commit/ec20802a5))
- Improve HMR performance note for Windows users
([#&#8203;31301](https://redirect.github.com/nuxt/nuxt/pull/31301))
- Correct WSL note phrasing
([#&#8203;31322](https://redirect.github.com/nuxt/nuxt/pull/31322))
- Fix typo
([#&#8203;31341](https://redirect.github.com/nuxt/nuxt/pull/31341))
- Adjust `app.head` example
([#&#8203;31350](https://redirect.github.com/nuxt/nuxt/pull/31350))
- Include package manager options in update script
([#&#8203;31346](https://redirect.github.com/nuxt/nuxt/pull/31346))
- Add missing comma
([#&#8203;31362](https://redirect.github.com/nuxt/nuxt/pull/31362))
- Add mention of `addServerTemplate` to modules guide
([#&#8203;31369](https://redirect.github.com/nuxt/nuxt/pull/31369))
- Add `rspack` and remove `test-utils` for monorepo guide
([#&#8203;31371](https://redirect.github.com/nuxt/nuxt/pull/31371))
- Adjust example
([#&#8203;31372](https://redirect.github.com/nuxt/nuxt/pull/31372))
- Update experimental docs
([#&#8203;31388](https://redirect.github.com/nuxt/nuxt/pull/31388))
- Use `ini` syntax block highlighting for `.env` files
([f79fabe46](https://redirect.github.com/nuxt/nuxt/commit/f79fabe46))
- Improve `useHydration` docs
([#&#8203;31427](https://redirect.github.com/nuxt/nuxt/pull/31427))
- Update broken docs links
([#&#8203;31430](https://redirect.github.com/nuxt/nuxt/pull/31430))
- Mention possibility of prerendering api routes
([#&#8203;31234](https://redirect.github.com/nuxt/nuxt/pull/31234))

##### 🏡 Chore

- Fix gitignore
([6fe9dff7e](https://redirect.github.com/nuxt/nuxt/commit/6fe9dff7e))
- Bump axios dependency in lockfile
([c3352e80b](https://redirect.github.com/nuxt/nuxt/commit/c3352e80b))
- Lint repo
([2ab20bfdc](https://redirect.github.com/nuxt/nuxt/commit/2ab20bfdc))
- Add scorecard badge
([#&#8203;31302](https://redirect.github.com/nuxt/nuxt/pull/31302))
- Dedupe
([be5d85f2b](https://redirect.github.com/nuxt/nuxt/commit/be5d85f2b))

#####  Tests

- Migrate runtime compiler test to playwright (+ add test cases)
([#&#8203;31405](https://redirect.github.com/nuxt/nuxt/pull/31405))
- Migrate spa preloader tests to playwright
([#&#8203;31273](https://redirect.github.com/nuxt/nuxt/pull/31273))
- Use `srvx` and random port for remote provider
([#&#8203;31432](https://redirect.github.com/nuxt/nuxt/pull/31432))

##### 🤖 CI

- Automate release on merge of of v3/v4
([6ae5b5fdb](https://redirect.github.com/nuxt/nuxt/commit/6ae5b5fdb))
- Fix workflow quoting
([fef39cf3c](https://redirect.github.com/nuxt/nuxt/commit/fef39cf3c))

##### ❤️ Contributors

- Daniel Roe
([@&#8203;danielroe](https://redirect.github.com/danielroe))
- Anoesj Sadraee ([@&#8203;Anoesj](https://redirect.github.com/Anoesj))
- Peter Radko ([@&#8203;Gwynerva](https://redirect.github.com/Gwynerva))
- Adam DeHaven
([@&#8203;adamdehaven](https://redirect.github.com/adamdehaven))
- Alex Liu
([@&#8203;Mini-ghost](https://redirect.github.com/Mini-ghost))
- Julien Huang
([@&#8203;huang-julien](https://redirect.github.com/huang-julien))
- Francesco Agnoletto
([@&#8203;Kornil](https://redirect.github.com/Kornil))
- Guillaume Chau ([@&#8203;Akryum](https://redirect.github.com/Akryum))
- imreegall ([@&#8203;imreegall](https://redirect.github.com/imreegall))
-   xjccc ([@&#8203;xjccc](https://redirect.github.com/xjccc))
-   Sam Blowes ([@&#8203;blowsie](https://redirect.github.com/blowsie))
-   Nimit012 ([@&#8203;Nimit012](https://redirect.github.com/Nimit012))
- Camille Coutens ([@&#8203;Kamsou](https://redirect.github.com/Kamsou))

</details>

<details>
<summary>unovue/reka-ui (reka-ui)</summary>

###
[`v2.1.1`](https://redirect.github.com/unovue/reka-ui/releases/tag/v2.1.1)

[Compare
Source](https://redirect.github.com/unovue/reka-ui/compare/v2.1.0...v2.1.1)

#####    🐞 Bug Fixes

-   **Calendar**:
- Properly calculate focus for next month when pagedNavigation is false
 -  by [@&#8203;epr3](https://redirect.github.com/epr3) in
[https://github.com/unovue/reka-ui/issues/1742](https://redirect.github.com/unovue/reka-ui/issues/1742)
[<samp>(7b91b)</samp>](https://redirect.github.com/unovue/reka-ui/commit/7b91bc08)
- Handle number of months > 2  -  by
[@&#8203;epr3](https://redirect.github.com/epr3) in
[https://github.com/unovue/reka-ui/issues/1744](https://redirect.github.com/unovue/reka-ui/issues/1744)
[<samp>(71023)</samp>](https://redirect.github.com/unovue/reka-ui/commit/71023c87)
-   **Combobox**:
- InjectComboboxItemContext is incorrect  -  by
[@&#8203;g12i](https://redirect.github.com/g12i) in
[https://github.com/unovue/reka-ui/issues/1722](https://redirect.github.com/unovue/reka-ui/issues/1722)
[<samp>(1b68e)</samp>](https://redirect.github.com/unovue/reka-ui/commit/1b68e5b5)
-   **HoverCard**:
- Default open type  -  by
[@&#8203;zernonia](https://redirect.github.com/zernonia) in
[https://github.com/unovue/reka-ui/issues/1732](https://redirect.github.com/unovue/reka-ui/issues/1732)
[<samp>(16ffc)</samp>](https://redirect.github.com/unovue/reka-ui/commit/16ffcc27)
-   **NavigationMenu**:
- Wrong instance of activetrigger being reference  -  by
[@&#8203;zernonia](https://redirect.github.com/zernonia) in
[https://github.com/unovue/reka-ui/issues/1741](https://redirect.github.com/unovue/reka-ui/issues/1741)
[<samp>(b72a9)</samp>](https://redirect.github.com/unovue/reka-ui/commit/b72a90b2)
-   **RangeCalendar**:
- Programatically set value doesn't update the calendar  -  by
[@&#8203;zernonia](https://redirect.github.com/zernonia) in
[https://github.com/unovue/reka-ui/issues/1739](https://redirect.github.com/unovue/reka-ui/issues/1739)
[<samp>(80001)</samp>](https://redirect.github.com/unovue/reka-ui/commit/80001892)
-   **Select**:
- Position issue for value missing in content  -  by
[@&#8203;zernonia](https://redirect.github.com/zernonia) in
[https://github.com/unovue/reka-ui/issues/1745](https://redirect.github.com/unovue/reka-ui/issues/1745)
[<samp>(770c2)</samp>](https://redirect.github.com/unovue/reka-ui/commit/770c292a)
-   **Slider**:
- Thumb has incorrect tag by default  -  by
[@&#8203;zernonia](https://redirect.github.com/zernonia) in
[https://github.com/unovue/reka-ui/issues/1734](https://redirect.github.com/unovue/reka-ui/issues/1734)
[<samp>(f8ebc)</samp>](https://redirect.github.com/unovue/reka-ui/commit/f8ebc9ec)
-   **TagsInput**:
- Fix comparing model values  -  by
[@&#8203;g12i](https://redirect.github.com/g12i) in
[https://github.com/unovue/reka-ui/issues/1723](https://redirect.github.com/unovue/reka-ui/issues/1723)
[<samp>(5dfb7)</samp>](https://redirect.github.com/unovue/reka-ui/commit/5dfb70c3)
-   **Toast**:
- Add missing swipeMove, swipeCancel, and swipeEnd events  -  by
[@&#8203;hartbit](https://redirect.github.com/hartbit) in
[https://github.com/unovue/reka-ui/

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/unraid/api).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMDcuMSIsInVwZGF0ZWRJblZlciI6IjM5LjIwNy4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-25 09:29:31 -04:00
renovate[bot]
8f78b3f1ca fix(deps): update dependency marked to v15 (#1249)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [marked](https://marked.js.org)
([source](https://redirect.github.com/markedjs/marked)) | [`^12.0.2` ->
`^15.0.0`](https://renovatebot.com/diffs/npm/marked/12.0.2/15.0.7) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/marked/15.0.7?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/marked/15.0.7?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/marked/12.0.2/15.0.7?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/marked/12.0.2/15.0.7?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>markedjs/marked (marked)</summary>

###
[`v15.0.7`](https://redirect.github.com/markedjs/marked/releases/tag/v15.0.7)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v15.0.6...v15.0.7)

##### Bug Fixes

- fix table rendered as heading
([#&#8203;3612](https://redirect.github.com/markedjs/marked/issues/3612))
([9ae87de](9ae87de7cb))

###
[`v15.0.6`](https://redirect.github.com/markedjs/marked/releases/tag/v15.0.6)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v15.0.5...v15.0.6)

##### Bug Fixes

- fix strikethrough inside strong and em to follow gfm
([#&#8203;3577](https://redirect.github.com/markedjs/marked/issues/3577))
([7712a53](7712a5324f))

###
[`v15.0.5`](https://redirect.github.com/markedjs/marked/releases/tag/v15.0.5)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v15.0.4...v15.0.5)

##### Bug Fixes

- allow strikethrough inside strong and em to follow gfm
([#&#8203;3569](https://redirect.github.com/markedjs/marked/issues/3569))
([8a01658](8a01658cac))

###
[`v15.0.4`](https://redirect.github.com/markedjs/marked/releases/tag/v15.0.4)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v15.0.3...v15.0.4)

##### Bug Fixes

- fix list with no items looping forever
([#&#8203;3560](https://redirect.github.com/markedjs/marked/issues/3560))
([e4198ed](e4198ed70d))

###
[`v15.0.3`](https://redirect.github.com/markedjs/marked/releases/tag/v15.0.3)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v15.0.2...v15.0.3)

##### Bug Fixes

- update punctuation regex syntax to fix babel mistaken transpile
([#&#8203;3547](https://redirect.github.com/markedjs/marked/issues/3547))
([9b988c4](9b988c47bd))

###
[`v15.0.2`](https://redirect.github.com/markedjs/marked/releases/tag/v15.0.2)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v15.0.1...v15.0.2)

##### Bug Fixes

- update punctuation regex syntax for compatibility
([#&#8203;3540](https://redirect.github.com/markedjs/marked/issues/3540))
([fd015f1](fd015f147d))

###
[`v15.0.1`](https://redirect.github.com/markedjs/marked/releases/tag/v15.0.1)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v15.0.0...v15.0.1)

##### Bug Fixes

- Remove unused plus typescript tightening
([#&#8203;3527](https://redirect.github.com/markedjs/marked/issues/3527))
([1f579f7](1f579f7628))

###
[`v15.0.0`](https://redirect.github.com/markedjs/marked/releases/tag/v15.0.0)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v14.1.4...v15.0.0)

##### Bug Fixes

- escape html in renderer
([#&#8203;3495](https://redirect.github.com/markedjs/marked/issues/3495))
([58d66e5](58d66e59d1))
- Move all regexps to rules
([#&#8203;3519](https://redirect.github.com/markedjs/marked/issues/3519))
([1f88deb](1f88deb58a))

##### BREAKING CHANGES

-   escape html in renderers instead of tokenizers for all tokens.

###
[`v14.1.4`](https://redirect.github.com/markedjs/marked/releases/tag/v14.1.4)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v14.1.3...v14.1.4)

##### Bug Fixes

- fix del with escaped tilde
([#&#8203;3517](https://redirect.github.com/markedjs/marked/issues/3517))
([0afe87d](0afe87d7fb))
- fix html comment after list
([#&#8203;3518](https://redirect.github.com/markedjs/marked/issues/3518))
([a612576](a612576ff6))

###
[`v14.1.3`](https://redirect.github.com/markedjs/marked/releases/tag/v14.1.3)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v14.1.2...v14.1.3)

##### Bug Fixes

- include single nested parens in emStrong link mask
([#&#8203;3475](https://redirect.github.com/markedjs/marked/issues/3475))
([2b7efa8](2b7efa8dda))
- kill SIGINT signal at man for marked --help
([#&#8203;3483](https://redirect.github.com/markedjs/marked/issues/3483))
([b1fd3ea](b1fd3eafd8))

###
[`v14.1.2`](https://redirect.github.com/markedjs/marked/releases/tag/v14.1.2)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v14.1.1...v14.1.2)

##### Bug Fixes

- fix html following list
([#&#8203;3444](https://redirect.github.com/markedjs/marked/issues/3444))
([9d7b728](9d7b728749))

###
[`v14.1.1`](https://redirect.github.com/markedjs/marked/releases/tag/v14.1.1)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v14.1.0...v14.1.1)

##### Bug Fixes

- Don't replace tabs with spaces
([#&#8203;3438](https://redirect.github.com/markedjs/marked/issues/3438))
([9ed6456](9ed6456a37))

###
[`v14.1.0`](https://redirect.github.com/markedjs/marked/releases/tag/v14.1.0)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v14.0.0...v14.1.0)

##### Bug Fixes

- don't export block or inline
([#&#8203;3427](https://redirect.github.com/markedjs/marked/issues/3427))
([3f0430a](3f0430a45e))

##### Features

- add provideLexer and provideParser hooks
([#&#8203;3424](https://redirect.github.com/markedjs/marked/issues/3424))
([447f5af](447f5af7e4))

###
[`v14.0.0`](https://redirect.github.com/markedjs/marked/releases/tag/v14.0.0)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v13.0.3...v14.0.0)

##### Bug Fixes

- allow async option to dictate type returned
([#&#8203;3341](https://redirect.github.com/markedjs/marked/issues/3341))
([b5a5004](b5a50041ae))
- Remove useNewRenderer
([#&#8203;3342](https://redirect.github.com/markedjs/marked/issues/3342))
([e64f226](e64f226539))

##### BREAKING CHANGES

-   Remove old renderer
- throw an error if `async: false` is set when an extension sets `async:
true`

###
[`v13.0.3`](https://redirect.github.com/markedjs/marked/releases/tag/v13.0.3)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v13.0.2...v13.0.3)

##### Bug Fixes

- fix recursion-like stack overflow error caused by the old render…
([#&#8203;3380](https://redirect.github.com/markedjs/marked/issues/3380))
([89af0b8](89af0b85b1))

###
[`v13.0.2`](https://redirect.github.com/markedjs/marked/releases/tag/v13.0.2)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v13.0.1...v13.0.2)

##### Bug Fixes

- fix list item with blank first line
([#&#8203;3351](https://redirect.github.com/markedjs/marked/issues/3351))
([d28e4c6](d28e4c65ea))

###
[`v13.0.1`](https://redirect.github.com/markedjs/marked/releases/tag/v13.0.1)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v13.0.0...v13.0.1)

##### Bug Fixes

- fix this type in extension methods
([#&#8203;3339](https://redirect.github.com/markedjs/marked/issues/3339))
([520b9ad](520b9ad355))

###
[`v13.0.0`](https://redirect.github.com/markedjs/marked/releases/tag/v13.0.0)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v12.0.2...v13.0.0)

##### Bug Fixes

- Fix blockquote code continuation
([#&#8203;3264](https://redirect.github.com/markedjs/marked/issues/3264))
([7ab8185](7ab818502e))
- Add parser as a property on the Renderer object
([#&#8203;3291](https://redirect.github.com/markedjs/marked/issues/3291))
- Send block text tokens to the text renderer
([#&#8203;3291](https://redirect.github.com/markedjs/marked/issues/3291))

##### Features

- Send token objects to renderers
([#&#8203;3291](https://redirect.github.com/markedjs/marked/issues/3291))
([1ce59ea](1ce59ea827))
- Add space renderer that returns empty string by default
([#&#8203;3291](https://redirect.github.com/markedjs/marked/issues/3291))
- Add header and align properties to TableCell token
([#&#8203;3291](https://redirect.github.com/markedjs/marked/issues/3291))
- Add TableRow token
([#&#8203;3291](https://redirect.github.com/markedjs/marked/issues/3291))
- Add Checkbox token
([#&#8203;3291](https://redirect.github.com/markedjs/marked/issues/3291))

##### BREAKING CHANGES

- Add space token after blockquote and hr if there are multiple newlines
- Send token objects to renderers and move logic to parse tokens from
the parser to the renderers.
- Most extensions that update marked renderers should still work with
this version but will break in a future major version.
- Extensions that change marked renderers will need to be updated and
use new option `useNewRenderer` and accept a token object instead of
multiple parameters. See updated [Renderer
docs](https://marked.js.org/using_pro#renderer)

        ```js
        // v12 renderer extension

        const extension = {
          renderer: {
            heading(text, level) {
              // increase level by 1
              return `<h${level + 1}>${text}</h${level + 1}>`;
            }
          }
        };

        marked.use(extension);
        ```

        ```js
        // v13 renderer extension

        const extension = {
          useNewRenderer: true,
          renderer: {
            heading(token) {
              // increase depth by 1
              const text = this.parser.parseInline(token.tokens);
              const level = token.depth;
              return `<h${level + 1}>${text}</h${level + 1}>`;
            }
          }
        };

        marked.use(extension);
        ```

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/unraid/api).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMDcuMSIsInVwZGF0ZWRJblZlciI6IjM5LjIwNy4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Eli Bosley <ekbosley@gmail.com>
2025-03-25 09:29:09 -04:00
Michael Datelle
a1d02b486a refactor: swap out dropdown with reka components (#1245)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a new `DropdownMenu` component in user profiles with
dynamic content rendering.
- Added a new `Popover` component with interactive Storybook demos,
improving component discoverability.
- Added a new `DropdownMenuArrow` component to enhance dropdown visuals.
- Implemented new CSS custom properties for charts, enhancing styling
capabilities in light and dark themes.
- Enhanced dropdown functionality by encapsulating dropdown logic in a
new `UpcDropdownMenu` component.
- Added a new `Select` component for improved user interaction within
the `Sheet` component.
- Introduced a new `SheetWithSelect` story to showcase selection
functionality within the `Sheet` component.
- Updated the `Sidebar` component to improve modal behavior and content
positioning.
- Enhanced `UserProfile` components with a new feedback function for
better status indication.

- **Style**
- Refined layouts by replacing fixed widths with flexible, responsive
designs.
- Updated global styling with a refreshed chart color palette and
expanded dark mode support.

- **Refactor**
- Migrated components to use a unified UI library, streamlining
interactions and boosting consistency.
- Improved type safety in `BrandLoading` component by utilizing a new
type for variants and sizes.
- Updated component imports and organization to enhance maintainability.

- **Bug Fixes**
- Removed unused promotional code and components, simplifying the
codebase and improving performance.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: mdatelle <mike@datelle.net>
Co-authored-by: Zack Spear <hi@zackspear.com>
Co-authored-by: Eli Bosley <ekbosley@gmail.com>
2025-03-24 17:24:52 -04:00
Eli Bosley
cc85fba207 fix: update configValid state to ineligible in var.ini and adjust rel… (#1268)
…ated tests

- Changed `configValid` value from "yes" to "ineligible" in `var.ini`.
- Updated tests in `emhttp.test.ts` and `var.test.ts` to reflect the new
state.
- Refactored `var.ts` to handle the new `configErrorState` logic based
on `configValid`.
- Adjusted `config.resolver.ts` to return the correct error state.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Enhanced configuration status reporting to indicate when settings are
ineligible, improving clarity on configuration validity.

- **Chores**
  - Updated recorded download times to maintain accurate logging.
- Refined the installation process with streamlined dependency linkage
and improved script readability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Zack Spear <hi@zackspear.com>
2025-03-24 14:19:30 -04:00
Eli Bosley
5958d33fce chore: cleanup the cleanup scripts (#1266)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Updated the plugin installation endpoint to use a new port for
improved connectivity.
- Streamlined installation and removal processes for a more reliable
setup and clearer cleanup feedback.
- Introduced a new script to manage cleanup operations, enhancing system
maintenance during removals.
- **Chores**
- Expanded file monitoring to support additional file types, ensuring
timely updates.
- Optimized background operations that configure essential components
for enhanced overall performance.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-03-24 12:35:25 -04:00
Zack Spear
3a20930ead feat: UnraidCheckExec for Check OS Updates via UPC dropdown (#1265)
- Added `UnraidCheckExec.php` to separate concerns between UnraidCheck
and ReplaceKey, allowing for JSON responses.
- Updated `unraidcheck` script to parse query strings for compatibility
with the new class.
- Modified `webgui.ts` to call `UnraidCheckExec.php` instead of
`UnraidCheck.php` for update checks.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Updated the plugin installation process to ensure critical files
remain protected during updates.
- Introduced a dedicated update check component that now returns results
in a JSON format.
- Enhanced the web interface’s update check functionality with
streamlined request parameters.

- **Refactor**
- Separated update checking responsibilities for improved logic clarity
and overall reliability.
- Updated the interface for the update check payload to enhance
parameter handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-03-21 14:05:17 -07:00
Eli Bosley
bf81a63f8e chore: ensure files are uploaded with proper content encoding (#1254) 2025-03-21 10:28:33 -04:00
Zack Spear
7e6be67f61 feat: add ReplaceKey functionality to plugin (#1264)
This change enhances the plugin's capability to manage license keys
effectively.

- Introduced `ReplaceKey.php` from the webgui repo for handling
auto-extended key check & installation
- Updated dynamix.unraid.net.plg to include the new ReplaceKey.php in
restore and preserve files.
- Changed the `check()` method call in `Registration.page` to use the
`force` parameter per
https://app.asana.com/0/1204220153625175/1209573221367693/f
- Moved the `require_once` for `reboot-details.php` in Downgrade.page
and Update.page to ensure it's included after the `ReplaceKey` check.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Enhanced license key management now validates and updates credentials
more reliably.
- Essential configuration files are preserved throughout updates and
uninstalls to maintain system integrity.

- **Chores**
- Optimized the update and registration workflows for a smoother, more
stable user experience.
- Adjusted internal processing steps to prepare for upcoming
improvements in update checks.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-03-20 14:29:55 -07:00
Zack Spear
6a92f61f1a feat: downgrade page replace key check (#1263)
Joins Update.page and Registration.page in having Replace Key check due
to relation between OS Version & License OS Eligibility

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Introduced an enhanced system validation step during initialization
that verifies key functionality before processing reboot details,
improving system reliability.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-03-20 14:08:49 -07:00
renovate[bot]
9cad1a9454 fix(deps): update dependency graphql-ws to v6 (#1210)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [graphql-ws](https://the-guild.dev/graphql/ws)
([source](https://redirect.github.com/enisdenjo/graphql-ws)) |
[`^5.16.0` ->
`^6.0.0`](https://renovatebot.com/diffs/npm/graphql-ws/5.16.2/6.0.4) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/graphql-ws/6.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/graphql-ws/6.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/graphql-ws/5.16.2/6.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/graphql-ws/5.16.2/6.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>enisdenjo/graphql-ws (graphql-ws)</summary>

###
[`v6.0.4`](https://redirect.github.com/enisdenjo/graphql-ws/blob/HEAD/CHANGELOG.md#604)

[Compare
Source](https://redirect.github.com/enisdenjo/graphql-ws/compare/v6.0.3...v6.0.4)

##### Patch Changes

-
[#&#8203;625](https://redirect.github.com/enisdenjo/graphql-ws/pull/625)
[`b4a656d`](b4a656d585)
Thanks [@&#8203;HermanBilous](https://redirect.github.com/HermanBilous)!
- Use Math.pow for retry delay calculation

###
[`v6.0.3`](https://redirect.github.com/enisdenjo/graphql-ws/blob/HEAD/CHANGELOG.md#603)

[Compare
Source](https://redirect.github.com/enisdenjo/graphql-ws/compare/v6.0.2...v6.0.3)

##### Patch Changes

-
[`747c01c`](747c01c73e)
Thanks [@&#8203;enisdenjo](https://redirect.github.com/enisdenjo)! -
Drop `ExecutionPatchResult` and `FormattedExecutionPatchResult` types

Neither of the types are officially supported (yet) and the future
versions of graphql-js adding support for stream/defer will a different
signature for the incremental execution result.

###
[`v6.0.2`](https://redirect.github.com/enisdenjo/graphql-ws/blob/HEAD/CHANGELOG.md#602)

[Compare
Source](https://redirect.github.com/enisdenjo/graphql-ws/compare/v6.0.1...v6.0.2)

##### Patch Changes

-
[#&#8203;621](https://redirect.github.com/enisdenjo/graphql-ws/pull/621)
[`6b180e8`](6b180e8fc2)
Thanks [@&#8203;pleunv](https://redirect.github.com/pleunv)! -
FormattedExecutionResult errors field returns GraphQLFormattedError

###
[`v6.0.1`](https://redirect.github.com/enisdenjo/graphql-ws/blob/HEAD/CHANGELOG.md#601)

[Compare
Source](https://redirect.github.com/enisdenjo/graphql-ws/compare/v6.0.0...v6.0.1)

##### Patch Changes

-
[#&#8203;618](https://redirect.github.com/enisdenjo/graphql-ws/pull/618)
[`6be34c7`](6be34c7969)
Thanks [@&#8203;enisdenjo](https://redirect.github.com/enisdenjo)! -
Remove exports for CommonJS for Deno exports in package.json

[Deno supports ECMAScript modules
exclusively.](https://docs.deno.com/runtime/fundamentals/modules/)

-
[#&#8203;618](https://redirect.github.com/enisdenjo/graphql-ws/pull/618)
[`6be34c7`](6be34c7969)
Thanks [@&#8203;enisdenjo](https://redirect.github.com/enisdenjo)! -
Define exports for CommonJS TypeScript definitions in package.json

###
[`v6.0.0`](https://redirect.github.com/enisdenjo/graphql-ws/blob/HEAD/CHANGELOG.md#600)

[Compare
Source](https://redirect.github.com/enisdenjo/graphql-ws/compare/v5.16.2...v6.0.0)

##### Major Changes

-
[`b668b30`](b668b304a8)
Thanks [@&#8203;enisdenjo](https://redirect.github.com/enisdenjo)! -
[@&#8203;fastify/websocket](https://redirect.github.com/fastify/websocket)
WebSocket in the context extra has been renamed from `connection` to
`socket`

##### Migrating from v5 to v6

```diff
import { makeHandler } from 'graphql-ws/use/@&#8203;fastify/websocket';

makeHandler({
  schema(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
  context(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
  onConnect(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
  onDisconnect(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
  onClose(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
  onSubscribe(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
  onOperation(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
  onError(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
  onNext(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
  onComplete(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
});
```

-
[#&#8203;613](https://redirect.github.com/enisdenjo/graphql-ws/pull/613)
[`3f11aba`](3f11aba495)
Thanks [@&#8203;enisdenjo](https://redirect.github.com/enisdenjo)! -
Drop support for `ws` v7

    `ws` v7 has been deprecated. Please upgrade and use v8.

-
[#&#8203;613](https://redirect.github.com/enisdenjo/graphql-ws/pull/613)
[`3f11aba`](3f11aba495)
Thanks [@&#8203;enisdenjo](https://redirect.github.com/enisdenjo)! -
Drop support for deprecated `fastify-websocket`

[`fastify-websocket` has been deprecated since
v4.3.0.](https://www.npmjs.com/package/fastify-websocket). Please
upgrade and use
[`@fastify/websocket`](https://redirect.github.com/fastify/fastify-websocket).

-
[#&#8203;613](https://redirect.github.com/enisdenjo/graphql-ws/pull/613)
[`3f11aba`](3f11aba495)
Thanks [@&#8203;enisdenjo](https://redirect.github.com/enisdenjo)! - The
`/lib/` part from imports has been removed, for example
`graphql-ws/lib/use/ws` becomes `graphql-ws/use/ws`

##### Migrating from v5 to v6

Simply remove the `/lib/` part from your graphql-ws imports that use a
handler.

##### ws

```diff
- import { useServer } from 'graphql-ws/lib/use/ws';
+ import { useServer } from 'graphql-ws/use/ws';
```

##### uWebSockets.js

```diff
- import { makeBehavior } from 'graphql-ws/lib/use/uWebSockets';
+ import { makeBehavior } from 'graphql-ws/use/uWebSockets';
```

#####
[@&#8203;fastify/websocket](https://redirect.github.com/fastify/websocket)

```diff
- import { makeHandler } from 'graphql-ws/lib/use/@&#8203;fastify/websocket';
+ import { makeHandler } from 'graphql-ws/use/@&#8203;fastify/websocket';
```

##### Bun

```diff
- import { handleProtocols, makeHandler } from 'graphql-ws/lib/use/bun';
+ import { handleProtocols, makeHandler } from 'graphql-ws/use/bun';
```

##### Deno

```diff
- import { makeHandler } from 'https://esm.sh/graphql-ws/lib/use/deno';
+ import { makeHandler } from 'https://esm.sh/graphql-ws/use/deno';
```

-
[#&#8203;613](https://redirect.github.com/enisdenjo/graphql-ws/pull/613)
[`3f11aba`](3f11aba495)
Thanks [@&#8203;enisdenjo](https://redirect.github.com/enisdenjo)! -
`ErrorMessage` uses and `onError` returns `GraphQLFormattedError`
(instead of `GraphQLError`)

Thanks [@&#8203;benjie](https://redirect.github.com/benjie) for working
on this in
[#&#8203;599](https://redirect.github.com/enisdenjo/graphql-ws/issues/599)

-
[#&#8203;613](https://redirect.github.com/enisdenjo/graphql-ws/pull/613)
[`3f11aba`](3f11aba495)
Thanks [@&#8203;enisdenjo](https://redirect.github.com/enisdenjo)! -
Least supported Node version is v20

Node v10 has been deprecated for years now. There is no reason to
support it. Bumping the engine to the current LTS (v20) also allows the
code to be leaner and use less polyfills.

-
[#&#8203;613](https://redirect.github.com/enisdenjo/graphql-ws/pull/613)
[`3f11aba`](3f11aba495)
Thanks [@&#8203;enisdenjo](https://redirect.github.com/enisdenjo)! -
Least supported `graphql` peer dependency is ^15.10.1 and ^16

Users are advised to use the latest of `graphql` because of various
improvements in performance and security.

-
[#&#8203;613](https://redirect.github.com/enisdenjo/graphql-ws/pull/613)
[`3f11aba`](3f11aba495)
Thanks [@&#8203;enisdenjo](https://redirect.github.com/enisdenjo)! -
`NextMessage` uses and `onNext` returns `FormattedExecutionResult`
(instead of `ExecutionResult`)

-
[#&#8203;613](https://redirect.github.com/enisdenjo/graphql-ws/pull/613)
[`3f11aba`](3f11aba495)
Thanks [@&#8203;enisdenjo](https://redirect.github.com/enisdenjo)! -
`schema`, `context`, `onSubscribe`, `onOperation`, `onError`, `onNext`
and `onComplete` hooks don't have the full accompanying message anymore,
only the ID and the relevant part from the message

There is really no need to pass the full `SubscribeMessage` to the
`onSubscribe` hook. The only relevant parts from the message are the
`id` and the `payload`, the `type` is useless since the hook inherently
has it (`onNext` is `next` type, `onError` is `error` type, etc).

The actual techincal reason for not having the full message is to avoid
serialising results and errors twice. Both `onNext` and `onError` allow
the user to augment the result and return it to be used instead.
`onNext` originally had the `NextMessage` argument which already has the
`FormattedExecutionResult`, and `onError` originally had the
`ErrorMessage` argument which already has the `GraphQLFormattedError`,
and they both also returned `FormattedExecutionResult` and
`GraphQLFormattedError` respectivelly - meaning, if the user serialised
the results - the serialisation would happen **twice**.

Additionally, the `onOperation`, `onError`, `onNext` and `onComplete`
now have the `payload` which is the `SubscribeMessage.payload`
(`SubscribePayload`) for easier access to the original query as well as
execution params extensions.

##### Migrating from v5 to v6

##### `schema`

```diff
import { ExecutionArgs } from 'graphql';
import { ServerOptions, SubscribePayload } from 'graphql-ws';

const opts: ServerOptions = {
- schema(ctx, message, argsWithoutSchema: Omit<ExecutionArgs, 'schema'>) {
-   const messageId = message.id;
-   const messagePayload: SubscribePayload = message.payload;
- },
+ schema(ctx, id, payload) {
+   const messageId = id;
+   const messagePayload: SubscribePayload = payload;
+ },
};
```

##### `context`

```diff
import { ExecutionArgs } from 'graphql';
import { ServerOptions, SubscribePayload } from 'graphql-ws';

const opts: ServerOptions = {
- context(ctx, message, args: ExecutionArgs) {
-   const messageId = message.id;
-   const messagePayload: SubscribePayload = message.payload;
- },
+ context(ctx, id, payload, args: ExecutionArgs) {
+   const messageId = id;
+   const messagePayload: SubscribePayload = payload;
+ },
};
```

##### `onSubscribe`

```diff
import { ServerOptions, SubscribePayload } from 'graphql-ws';

const opts: ServerOptions = {
- onSubscribe(ctx, message) {
-   const messageId = message.id;
-   const messagePayload: SubscribePayload = message.payload;
- },
+ onSubscribe(ctx, id, payload) {
+   const messageId = id;
+   const messagePayload: SubscribePayload = payload;
+ },
};
```

##### `onOperation`

The `SubscribeMessage.payload` is not useful here at all, the `payload`
has been parsed to ready-to-use graphql execution args and should be
used instead.

```diff
import { ExecutionArgs } from 'graphql';
import { ServerOptions, SubscribePayload, OperationResult } from 'graphql-ws';

const opts: ServerOptions = {
- onOperation(ctx, message, args: ExecutionArgs, result: OperationResult) {
-   const messageId = message.id;
-   const messagePayload: SubscribePayload = message.payload;
- },
+ onOperation(ctx, id, payload, args: ExecutionArgs, result: OperationResult) {
+   const messageId = id;
+   const messagePayload: SubscribePayload = payload;
+ },
};
```

##### `onError`

The `ErrorMessage.payload` (`GraphQLFormattedError[]`) is not useful
here at all, the user has access to `GraphQLError[]` that are true
instances of the error containing object references to `originalError`s
and other properties. The user can always convert and return
`GraphQLFormattedError[]` by using the `.toJSON()` method.

```diff
import { GraphQLError, GraphQLFormattedError } from 'graphql';
import { ServerOptions, SubscribePayload } from 'graphql-ws';

const opts: ServerOptions = {
- onError(ctx, message, errors) {
-   const messageId = message.id;
-   const graphqlErrors: readonly GraphQLError[] = errors;
-   const errorMessagePayload: readonly GraphQLFormattedError[] = message.payload;
- },
+ onError(ctx, id, payload, errors) {
+   const messageId = id;
+   const graphqlErrors: readonly GraphQLError[] = errors;
+   const subscribeMessagePayload: SubscribePayload = payload;
+   const errorMessagePayload: readonly GraphQLFormattedError[] = errors.map((e) => e.toJSON());
+ },
};
```

##### `onNext`

The `NextMessage.payload` (`FormattedExecutionResult`) is not useful
here at all, the user has access to `ExecutionResult` that contains
actual object references to error instances. The user can always convert
and return `FormattedExecutionResult` by serialising the errors with
`GraphQLError.toJSON()` method.

```diff
import { ExecutionArgs, ExecutionResult, FormattedExecutionResult } from 'graphql';
import { ServerOptions, SubscribePayload } from 'graphql-ws';

const opts: ServerOptions = {
- onNext(ctx, message, args: ExecutionArgs, result: ExecutionResult) {
-   const messageId = message.id;
-   const nextMessagePayload: FormattedExecutionResult = message.payload;
- },
+ onNext(ctx, id, payload, args: ExecutionArgs, result: ExecutionResult) {
+   const messageId = id;
+   const subscribeMessagePayload: SubscribePayload = payload;
+   const nextMessagePayload: FormattedExecutionResult = { ...result, errors: result.errors?.map((e) => e.toJSON()) };
+ },
};
```

##### `onComplete`

```diff
import { ServerOptions, SubscribePayload } from 'graphql-ws';

const opts: ServerOptions = {
- onComplete(ctx, message) {
-   const messageId = message.id;
- },
+ onComplete(ctx, id, payload) {
+   const messageId = id;
+   const subscribeMessagePayload: SubscribePayload = payload;
+ },
};
```

-
[#&#8203;613](https://redirect.github.com/enisdenjo/graphql-ws/pull/613)
[`3f11aba`](3f11aba495)
Thanks [@&#8203;enisdenjo](https://redirect.github.com/enisdenjo)! -
Errors thrown from subscription iterables will be caught and reported
through the `ErrorMessage`

Compared to the behaviour before, which terminated the whole WebSocket
connection - those errors are now gracefully reported and terminate only
the specific subscription that threw the error.

There's been [an editorial change in the GraphQL Spec suggesting this
being the correct
approach](https://redirect.github.com/graphql/graphql-spec/pull/1099).

Also, if you'd like to get involved and ideally drop your opinion about
whether iterable errors should be reported as errors or
`ExecutionResult`s with `errors` field set, [please read more
here](https://redirect.github.com/graphql/graphql-spec/pull/1127).

##### Migrating from v5 to v6

If you had used the suggested "ws server usage with custom subscribe
method that gracefully handles thrown errors" recipe, you can simply
remove it since this behaviour is now baked in.

```diff
import { subscribe } from 'graphql';
import { useServer } from 'graphql-ws/use/ws';
import { WebSocketServer } from 'ws'; // yarn add ws

const wsServer = new WebSocketServer({
  port: 4000,
  path: '/graphql',
});

useServer(
  {
    schema,
-   async subscribe(...args) {
-     const result = await subscribe(...args);
-     if ('next' in result) {
-       // is an async iterable, augment the next method to handle thrown errors
-       const originalNext = result.next;
-       result.next = async () => {
-         try {
-           return await originalNext();
-         } catch (err) {
-           // gracefully handle the error thrown from the next method
-           return { value: { errors: [err] } };
-         }
-       };
-     }
-     return result;
-   },
  },
  wsServer,
);
```

-
[#&#8203;613](https://redirect.github.com/enisdenjo/graphql-ws/pull/613)
[`3f11aba`](3f11aba495)
Thanks [@&#8203;enisdenjo](https://redirect.github.com/enisdenjo)! -
Remove deprecated `isMessage`, use `validateMessage` instead

##### Migrating from v5 to v6

Replace all ocurrances of `isMessage` with `validateMessage`. Note that
`validateMessage` throws if the message is not valid, compared with
`isMessage` that simply returned true/false.

```diff
- import { isMessage } from 'graphql-ws';
+ import { validateMessage } from 'graphql-ws';

function isGraphQLWSMessage(val) {
- return isMessage(val);
+ try {
+   validateMessage(val);
+   return true;
+ } catch {
+   return false;
+ }
}
```

-
[#&#8203;613](https://redirect.github.com/enisdenjo/graphql-ws/pull/613)
[`3f11aba`](3f11aba495)
Thanks [@&#8203;enisdenjo](https://redirect.github.com/enisdenjo)! -
Removed deprecated `isFatalConnectionProblem`, use `shouldRetry` instead

##### Migrating from v5 to v6

Replace all ocurrances of `isFatalConnectionProblem` with `shouldRetry`.
Note that the result is inverted, where you returned `false` in
`isFatalConnectionProblem` you should return `true` in `shouldRetry`.

```diff
import { createClient } from 'graphql-ws';

const client = createClient({
  url: 'ws://localhost:4000/graphql',
- isFatalConnectionProblem: () => false,
+ shouldRetry: () => true,
});
```

##### Minor Changes

-
[#&#8203;613](https://redirect.github.com/enisdenjo/graphql-ws/pull/613)
[`3f11aba`](3f11aba495)
Thanks [@&#8203;enisdenjo](https://redirect.github.com/enisdenjo)! -
Client is truly zero-dependency, not even a peer dependency on `graphql`

In non-browser environments, you can use only the client and not even
depend on `graphql` by importing from `graphql-ws/client`.

    ```ts
    import { createClient } from 'graphql-ws/client';

    const client = createClient({
      url: 'ws://localhost:4000/graphql',
    });
    ```

Note that, in browser envirments (and of course having your bundler use
the [`browser` package.json
field](https://docs.npmjs.com/cli/v11/configuring-npm/package-json#browser)),
you don't have to import from `graphql-ws/client` - simply importing
from `graphql-ws` will only have the `createClient` available.

-
[#&#8203;615](https://redirect.github.com/enisdenjo/graphql-ws/pull/615)
[`29dd26a`](29dd26a509)
Thanks [@&#8203;enisdenjo](https://redirect.github.com/enisdenjo)! -
Define optional peer dependencies and least supported versions

Using the
[`peerDependencies`](https://docs.npmjs.com/cli/v11/configuring-npm/package-json#peerdependencies)
in combination with
[`peerDependenciesMeta`](https://docs.npmjs.com/cli/v11/configuring-npm/package-json#peerdependenciesmeta)
configuration in `package.json`.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/unraid/api).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNzYuMiIsInVwZGF0ZWRJblZlciI6IjM5LjE3Ni4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-20 15:57:04 -04:00
renovate[bot]
2c01ba9610 fix(deps): update dependency vue-i18n to v11 (#1261)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
|
[vue-i18n](https://redirect.github.com/intlify/vue-i18n/tree/master/packages/vue-i18n#readme)
([source](https://redirect.github.com/intlify/vue-i18n/tree/HEAD/packages/vue-i18n))
| [`^10.0.5` ->
`^11.0.0`](https://renovatebot.com/diffs/npm/vue-i18n/10.0.6/11.1.2) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/vue-i18n/11.1.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/vue-i18n/11.1.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/vue-i18n/10.0.6/11.1.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vue-i18n/10.0.6/11.1.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>intlify/vue-i18n (vue-i18n)</summary>

###
[`v11.1.2`](https://redirect.github.com/intlify/vue-i18n/releases/tag/v11.1.2)

[Compare
Source](https://redirect.github.com/intlify/vue-i18n/compare/v11.1.1...v11.1.2)

<!-- Release notes generated using configuration in .github/release.yml
at v11.1.2 -->

#### What's Changed

##### 🔒 Security Fixes

- fix: prototype pollution in `handleFlatJson`, about details see
https://github.com/intlify/vue-i18n/security/advisories/GHSA-p2ph-7g93-hw3m

**Full Changelog**:
https://github.com/intlify/vue-i18n/compare/v11.1.1...v11.1.2

###
[`v11.1.1`](https://redirect.github.com/intlify/vue-i18n/releases/tag/v11.1.1)

[Compare
Source](https://redirect.github.com/intlify/vue-i18n/compare/v11.1.0...v11.1.1)

<!-- Release notes generated using configuration in .github/release.yml
at v11.1.1 -->

**Full Changelog**:
https://github.com/intlify/vue-i18n/compare/v11.1.0...v11.1.1

###
[`v11.1.0`](https://redirect.github.com/intlify/vue-i18n/releases/tag/v11.1.0)

[Compare
Source](https://redirect.github.com/intlify/vue-i18n/compare/v11.0.1...v11.1.0)

<!-- Release notes generated using configuration in .github/release.yml
at v11.1.0 -->

#### What's Changed

##### 🌟 Features

- feat: configurable `ComponentCustomProperties['$i18n']` type by
[@&#8203;BobbieGoede](https://redirect.github.com/BobbieGoede) in
[https://github.com/intlify/vue-i18n/pull/2094](https://redirect.github.com/intlify/vue-i18n/pull/2094)

##### 📝️ Documentations

- fix: vue-i18n v8 EOL by
[@&#8203;kazupon](https://redirect.github.com/kazupon) in
[https://github.com/intlify/vue-i18n/pull/2060](https://redirect.github.com/intlify/vue-i18n/pull/2060)

**Full Changelog**:
https://github.com/intlify/vue-i18n/compare/v11.0.1...v11.1.0

###
[`v11.0.1`](https://redirect.github.com/intlify/vue-i18n/blob/HEAD/CHANGELOG.md#v1101-2024-12-26T074058Z)

[Compare
Source](https://redirect.github.com/intlify/vue-i18n/compare/v11.0.0...v11.0.1)

This changelog is generated by [GitHub
Releases](https://redirect.github.com/intlify/vue-i18n/releases/tag/v11.0.1)

<!-- Release notes generated using configuration in .github/release.yml
at v11.0.1 -->

#### What's Changed

#####  Improvement Features

- fix: v-t custom directive warning when it will run by
[@&#8203;kazupon](https://redirect.github.com/kazupon) in
[https://github.com/intlify/vue-i18n/pull/2057](https://redirect.github.com/intlify/vue-i18n/pull/2057)

**Full Changelog**:
https://github.com/intlify/vue-i18n/compare/v11.0.0...v11.0.1

###
[`v11.0.0`](https://redirect.github.com/intlify/vue-i18n/blob/HEAD/CHANGELOG.md#v1100-2024-12-24T150100Z)

[Compare
Source](https://redirect.github.com/intlify/vue-i18n/compare/v10.0.6...v11.0.0)

This changelog is generated by [GitHub
Releases](https://redirect.github.com/intlify/vue-i18n/releases/tag/v11.0.0)

<!-- Release notes generated using configuration in .github/release.yml
at v11.0.0 -->

#### What's Changed

##### Deprecate Legacy API mode

The Legacy API mode was the API mode compatible with v8 for Vue 2. When
v9 was released, the Legacy API was provided to smooth the migration
from v8 to v9.

Legacy API mode will be deprecated in v11, as previous vue-i18n releases
have already provided the following to support migration to Composition
API mode

- Migration from Legacy API mode to Composition API mode, see the
[docs](https://vue-i18n.intlify.dev/guide/migration/vue3.html)
- Composition API usage, see the
[docs](https://vue-i18n.intlify.dev/guide/advanced/composition.html)

For compatibility, Legacy API mode still works in v11, but will be
removed entirely in v12, so Legacy API mode will not work after that
version.

##### Deprecate Custom Directive `v-t`

The advantage of `v-t` was that it could optimize performance using the
vue compiler transform and the pre-translation of `vue-i18n-extension`.

This feature was supported from Vue 2.
About details see the blog
[article](https://medium.com/@&#8203;kazu_pon/performance-optimization-of-vue-i18n-83099eb45c2d)

In Vue 3, due to the Composition API, the pre-translation of
[`vue-i18n-extension`](https://redirect.github.com/intlify/vue-i18n-extensions)
is now limited only for global scope.

In addition, Vue 3 Virtual DOM optimization has been introduced, and the
optimization provided by `vue-i18n-extension` is no longer very
effective. We need to require settings for SSR, the benefits of using
`v-t` have disappeared. And DX of templates using `v-t` is not good.
Custom directives do not work with key completion in editors (e.g.
vscode).

For compatibility, `v-t` mode still works in v11, but will be removed
entirely in v12, so `v-t` will not work after that version.

##### Drop `tc` and `$tc` for Legacy API mode

These APIs had already deprecated in warning about being dropped in v11.
docs
[says](https://vue-i18n.intlify.dev/guide/migration/breaking10.html#deprecate-tc-and-tc-for-legacy-api-mode)

##### Vue I18n maintenance Status

Vue I18n v8 is no longer supported after 2025. Vue I18n v9 and Vue I18n
v10 is in maintenance mode after 2025 July.

With the release of Vue I18n v11, that version will become mainstream.

The maintenance detail status of Vue I18n v9 and Vue I18n v10 is as
follows:

<img
src="https://raw.githubusercontent.com/intlify/vue-i18n/master/docs/public/lifecycle2025.svg"
/>

You can check the maintenance status on the
[docs](https://vue-i18n.intlify.dev/guide/maintenance.html)

#####  Braeking Changes

- feat!: deprecate Legacy API mode by
[@&#8203;kazupon](https://redirect.github.com/kazupon) in
[https://github.com/intlify/vue-i18n/pull/2016](https://redirect.github.com/intlify/vue-i18n/pull/2016)
- breaking: drop `$tc` and `tc` by
[@&#8203;kazupon](https://redirect.github.com/kazupon) in
[https://github.com/intlify/vue-i18n/pull/2017](https://redirect.github.com/intlify/vue-i18n/pull/2017)
- feat!: deprecate `v-t` custom directive by
[@&#8203;kazupon](https://redirect.github.com/kazupon) in
[https://github.com/intlify/vue-i18n/pull/2045](https://redirect.github.com/intlify/vue-i18n/pull/2045)

#####  Improvement Features

- fix: `tm` function should accept `DefineLocaleMessage` key type by
[@&#8203;BobbieGoede](https://redirect.github.com/BobbieGoede) in
[https://github.com/intlify/vue-i18n/pull/2014](https://redirect.github.com/intlify/vue-i18n/pull/2014)

##### 🔒 Security Fixes

- fix: security vulnerability fix porting by
[@&#8203;kazupon](https://redirect.github.com/kazupon) in
[https://github.com/intlify/vue-i18n/pull/2034](https://redirect.github.com/intlify/vue-i18n/pull/2034)

##### 📝️ Documentations

- Change config prop for quasar flags by
[@&#8203;chrissyast](https://redirect.github.com/chrissyast) in
[https://github.com/intlify/vue-i18n/pull/2003](https://redirect.github.com/intlify/vue-i18n/pull/2003)
- docs: Pluralization Page by
[@&#8203;Sammuel09](https://redirect.github.com/Sammuel09) in
[https://github.com/intlify/vue-i18n/pull/1998](https://redirect.github.com/intlify/vue-i18n/pull/1998)
- docs: fix composition section by
[@&#8203;Sammuel09](https://redirect.github.com/Sammuel09) in
[https://github.com/intlify/vue-i18n/pull/2008](https://redirect.github.com/intlify/vue-i18n/pull/2008)
- fix(docs): correct output in composition api example by
[@&#8203;pejeio](https://redirect.github.com/pejeio) in
[https://github.com/intlify/vue-i18n/pull/2012](https://redirect.github.com/intlify/vue-i18n/pull/2012)
- docs: not use deprecated api by
[@&#8203;kazupon](https://redirect.github.com/kazupon) in
[https://github.com/intlify/vue-i18n/pull/2013](https://redirect.github.com/intlify/vue-i18n/pull/2013)
- docs: fix wrong plural example by
[@&#8203;kazupon](https://redirect.github.com/kazupon) in
[https://github.com/intlify/vue-i18n/pull/2033](https://redirect.github.com/intlify/vue-i18n/pull/2033)
- docx(pluralization.md): Correct spelling from 'gloal' to 'global' by
[@&#8203;PuppyOne](https://redirect.github.com/PuppyOne) in
[https://github.com/intlify/vue-i18n/pull/2038](https://redirect.github.com/intlify/vue-i18n/pull/2038)
- Fix typo by [@&#8203;shaedrich](https://redirect.github.com/shaedrich)
in
[https://github.com/intlify/vue-i18n/pull/2040](https://redirect.github.com/intlify/vue-i18n/pull/2040)
- Fix another typo by
[@&#8203;shaedrich](https://redirect.github.com/shaedrich) in
[https://github.com/intlify/vue-i18n/pull/2041](https://redirect.github.com/intlify/vue-i18n/pull/2041)
- docs: add maintenance status by
[@&#8203;kazupon](https://redirect.github.com/kazupon) in
[https://github.com/intlify/vue-i18n/pull/2044](https://redirect.github.com/intlify/vue-i18n/pull/2044)

#### 👋 New Contributors

- [@&#8203;chrissyast](https://redirect.github.com/chrissyast) made
their first contribution in
[https://github.com/intlify/vue-i18n/pull/2003](https://redirect.github.com/intlify/vue-i18n/pull/2003)
- [@&#8203;Sammuel09](https://redirect.github.com/Sammuel09) made their
first contribution in
[https://github.com/intlify/vue-i18n/pull/1998](https://redirect.github.com/intlify/vue-i18n/pull/1998)
- [@&#8203;pejeio](https://redirect.github.com/pejeio) made their first
contribution in
[https://github.com/intlify/vue-i18n/pull/2012](https://redirect.github.com/intlify/vue-i18n/pull/2012)
- [@&#8203;PuppyOne](https://redirect.github.com/PuppyOne) made their
first contribution in
[https://github.com/intlify/vue-i18n/pull/2038](https://redirect.github.com/intlify/vue-i18n/pull/2038)
- [@&#8203;shaedrich](https://redirect.github.com/shaedrich) made their
first contribution in
[https://github.com/intlify/vue-i18n/pull/2040](https://redirect.github.com/intlify/vue-i18n/pull/2040)

**Full Changelog**:
https://github.com/intlify/vue-i18n/compare/v10.0.4...v11.0.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/unraid/api).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMDcuMSIsInVwZGF0ZWRJblZlciI6IjM5LjIwNy4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-20 15:56:01 -04:00
renovate[bot]
9ce10a72b2 fix(deps): update vueuse monorepo to v13 (major) (#1262)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
|
[@vueuse/components](https://redirect.github.com/vueuse/vueuse/tree/main/packages/components#readme)
([source](https://redirect.github.com/vueuse/vueuse/tree/HEAD/packages/components))
| [`^12.0.0` ->
`^13.0.0`](https://renovatebot.com/diffs/npm/@vueuse%2fcomponents/12.8.2/13.0.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@vueuse%2fcomponents/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@vueuse%2fcomponents/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@vueuse%2fcomponents/12.8.2/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@vueuse%2fcomponents/12.8.2/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [@vueuse/core](https://redirect.github.com/vueuse/vueuse)
([source](https://redirect.github.com/vueuse/vueuse/tree/HEAD/packages/core))
| [`^12.0.0` ->
`^13.0.0`](https://renovatebot.com/diffs/npm/@vueuse%2fcore/12.8.2/13.0.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@vueuse%2fcore/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@vueuse%2fcore/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@vueuse%2fcore/12.8.2/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@vueuse%2fcore/12.8.2/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[@vueuse/integrations](https://redirect.github.com/vueuse/vueuse/tree/main/packages/integrations#readme)
([source](https://redirect.github.com/vueuse/vueuse/tree/HEAD/packages/integrations))
| [`^12.0.0` ->
`^13.0.0`](https://renovatebot.com/diffs/npm/@vueuse%2fintegrations/12.8.2/13.0.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@vueuse%2fintegrations/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@vueuse%2fintegrations/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@vueuse%2fintegrations/12.8.2/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@vueuse%2fintegrations/12.8.2/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[@vueuse/nuxt](https://redirect.github.com/vueuse/vueuse/tree/main/packages/nuxt#readme)
([source](https://redirect.github.com/vueuse/vueuse/tree/HEAD/packages/nuxt))
| [`^12.0.0` ->
`^13.0.0`](https://renovatebot.com/diffs/npm/@vueuse%2fnuxt/12.8.2/13.0.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@vueuse%2fnuxt/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@vueuse%2fnuxt/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@vueuse%2fnuxt/12.8.2/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@vueuse%2fnuxt/12.8.2/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>vueuse/vueuse (@&#8203;vueuse/components)</summary>

###
[`v13.0.0`](https://redirect.github.com/vueuse/vueuse/releases/tag/v13.0.0)

[Compare
Source](https://redirect.github.com/vueuse/vueuse/compare/v12.8.2...v13.0.0)

#####    🚨 Breaking Changes

- Drop CJS build, now it's ESM-only  -  by
[@&#8203;antfu](https://redirect.github.com/antfu) in
[https://github.com/vueuse/vueuse/issues/4581](https://redirect.github.com/vueuse/vueuse/issues/4581)
[<samp>(5e046)</samp>](https://redirect.github.com/vueuse/vueuse/commit/5e0467bf)

#####     [View changes on
GitHub](https://redirect.github.com/vueuse/vueuse/compare/v12.8.2...v13.0.0)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these
updates again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/unraid/api).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMDcuMSIsInVwZGF0ZWRJblZlciI6IjM5LjIwNy4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-20 15:03:30 -04:00
Zack Spear
f3e6a0011e feat: ReplaceKey functionality in Registration and Update pages (#1246)
- Handles auto-extensions key check and install of extend license key
with new OS Updates Expiration date

Related to https://github.com/unraid/webgui/pull/2071 but not 100%
dependent on them.

@elibosley, do we want to use the `force` param on the `check()` method
for either of these pages?

Additionally, what do you think about any potential integration with
`UnraidCheck.php` – which is used for the UPC's "Check for Updates"
button and the user configured automatically scheduled update check?

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Enhanced plugin registration and update processes with an integrated
key validation step that verifies system parameters automatically.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1209573221367688
2025-03-20 14:50:20 -04:00
renovate[bot]
cb2020dee6 fix(deps): update dependency shadcn-vue to v1 (#1259)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [shadcn-vue](https://redirect.github.com/unovue/shadcn-vue)
([source](https://redirect.github.com/unovue/shadcn-vue/tree/HEAD/packages/cli))
| [`^0.11.3` ->
`^1.0.0`](https://renovatebot.com/diffs/npm/shadcn-vue/0.11.4/1.0.3) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/shadcn-vue/1.0.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/shadcn-vue/1.0.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/shadcn-vue/0.11.4/1.0.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/shadcn-vue/0.11.4/1.0.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>unovue/shadcn-vue (shadcn-vue)</summary>

###
[`v1.0.3`](https://redirect.github.com/unovue/shadcn-vue/releases/tag/v1.0.3)

[Compare
Source](https://redirect.github.com/unovue/shadcn-vue/compare/v1.0.2...v1.0.3)

#####    🐞 Bug Fixes

- Tags input with combobox demo  -  by
[@&#8203;zernonia](https://redirect.github.com/zernonia)
[<samp>(15bd4)</samp>](https://redirect.github.com/unovue/shadcn-vue/commit/15bd4314)
- Remove type inference for default valueformmater due to upstream
compiler bug  -  by
[@&#8203;zernonia](https://redirect.github.com/zernonia)
[<samp>(098fe)</samp>](https://redirect.github.com/unovue/shadcn-vue/commit/098fe5ad)
- Transform js issue  -  by
[@&#8203;zernonia](https://redirect.github.com/zernonia)
[<samp>(b1e49)</samp>](https://redirect.github.com/unovue/shadcn-vue/commit/b1e49fe6)

#####     [View changes on
GitHub](https://redirect.github.com/unovue/shadcn-vue/compare/v1.0.2...v1.0.3)

###
[`v1.0.2`](https://redirect.github.com/unovue/shadcn-vue/releases/tag/v1.0.2)

[Compare
Source](https://redirect.github.com/unovue/shadcn-vue/compare/v1.0.1...v1.0.2)

#####    🐞 Bug Fixes

- AvatarImage to have slots  -  by
[@&#8203;zernonia](https://redirect.github.com/zernonia)
[<samp>(1c9c5)</samp>](https://redirect.github.com/unovue/shadcn-vue/commit/1c9c5445)
- Old `checked` api  -  by
[@&#8203;zernonia](https://redirect.github.com/zernonia)
[<samp>(239ff)</samp>](https://redirect.github.com/unovue/shadcn-vue/commit/239ff691)
- Js detype error when missing local reference to props  -  by
[@&#8203;zernonia](https://redirect.github.com/zernonia)
[<samp>(f00c0)</samp>](https://redirect.github.com/unovue/shadcn-vue/commit/f00c0de0)
- **Chart**: Invalid chart legend size  -  by
[@&#8203;hooray](https://redirect.github.com/hooray) and
[@&#8203;zernonia](https://redirect.github.com/zernonia) in
[https://github.com/unovue/shadcn-vue/issues/997](https://redirect.github.com/unovue/shadcn-vue/issues/997)
[<samp>(4f3e8)</samp>](https://redirect.github.com/unovue/shadcn-vue/commit/4f3e829f)
- **Demo**: Clear input field after sending message in CardChat.vue  - 
by [@&#8203;IceyWu](https://redirect.github.com/IceyWu) in
[https://github.com/unovue/shadcn-vue/issues/959](https://redirect.github.com/unovue/shadcn-vue/issues/959)
[<samp>(6aaa1)</samp>](https://redirect.github.com/unovue/shadcn-vue/commit/6aaa1dd9)
- **registry**: Button default styling  -  by
[@&#8203;zernonia](https://redirect.github.com/zernonia)
[<samp>(6a544)</samp>](https://redirect.github.com/unovue/shadcn-vue/commit/6a544f99)

#####     [View changes on
GitHub](https://redirect.github.com/unovue/shadcn-vue/compare/v1.0.1...v1.0.2)

###
[`v1.0.1`](https://redirect.github.com/unovue/shadcn-vue/releases/tag/v1.0.1)

[Compare
Source](https://redirect.github.com/unovue/shadcn-vue/compare/v1.0.0...v1.0.1)

#####    🐞 Bug Fixes

- **CLI**: Init, support js, update docs  -  by
[@&#8203;zernonia](https://redirect.github.com/zernonia) in
[https://github.com/unovue/shadcn-vue/issues/1053](https://redirect.github.com/unovue/shadcn-vue/issues/1053)
[<samp>(cdfe2)</samp>](https://redirect.github.com/unovue/shadcn-vue/commit/cdfe2e8e)

#####     [View changes on
GitHub](https://redirect.github.com/unovue/shadcn-vue/compare/v1.0.0...v1.0.1)

###
[`v1.0.0`](https://redirect.github.com/unovue/shadcn-vue/releases/tag/v1.0.0)

[Compare
Source](https://redirect.github.com/unovue/shadcn-vue/compare/v0.11.4...v1.0.0)

#####    🚀 Features

- Reka-ui & updated cli  -  by
[@&#8203;zernonia](https://redirect.github.com/zernonia) in
[https://github.com/unovue/shadcn-vue/issues/917](https://redirect.github.com/unovue/shadcn-vue/issues/917)
[<samp>(bc6da)</samp>](https://redirect.github.com/unovue/shadcn-vue/commit/bc6dae3d)

#####     [View changes on
GitHub](https://redirect.github.com/unovue/shadcn-vue/compare/v0.11.4...v1.0.0)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/unraid/api).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMDcuMSIsInVwZGF0ZWRJblZlciI6IjM5LjIwNy4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-20 10:29:16 -04:00
renovate[bot]
db189abec4 chore(deps): update dependency @types/pify to v6 (#1228)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| @&#8203;types/pify | [`^5.0.4` ->
`^6.0.0`](https://renovatebot.com/diffs/npm/@types%2fpify/5.0.4/6.1.0) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/@types%2fpify/6.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@types%2fpify/6.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@types%2fpify/5.0.4/6.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@types%2fpify/5.0.4/6.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/unraid/api).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMDcuMSIsInVwZGF0ZWRJblZlciI6IjM5LjIwNy4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-20 10:25:18 -04:00
renovate[bot]
d8afc8f4c9 fix(deps): update dependency pm2 to v6 (#1258)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [pm2](http://pm2.keymetrics.io/)
([source](https://redirect.github.com/Unitech/pm2)) | [`^5.4.2` ->
`^6.0.0`](https://renovatebot.com/diffs/npm/pm2/5.4.3/6.0.5) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/pm2/6.0.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/pm2/6.0.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/pm2/5.4.3/6.0.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/pm2/5.4.3/6.0.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>Unitech/pm2 (pm2)</summary>

###
[`v6.0.5`](https://redirect.github.com/Unitech/pm2/blob/HEAD/CHANGELOG.md#605)

[Compare
Source](5e20239d63...v6.0.5)

- Bun support - Fixes
[#&#8203;5893](https://redirect.github.com/Unitech/pm2/issues/5893)
[#&#8203;5774](https://redirect.github.com/Unitech/pm2/issues/5774)
[#&#8203;5682](https://redirect.github.com/Unitech/pm2/issues/5682)
[#&#8203;5675](https://redirect.github.com/Unitech/pm2/issues/5675)
[#&#8203;5777](https://redirect.github.com/Unitech/pm2/issues/5777)
- Disable git parsing by default
[#&#8203;5909](https://redirect.github.com/Unitech/pm2/issues/5909)
[#&#8203;2182](https://redirect.github.com/Unitech/pm2/issues/2182)
[#&#8203;5801](https://redirect.github.com/Unitech/pm2/issues/5801)
[#&#8203;5051](https://redirect.github.com/Unitech/pm2/issues/5051)
[#&#8203;5696](https://redirect.github.com/Unitech/pm2/issues/5696)
- Add WEBP content type for pm2 serve
[#&#8203;5900](https://redirect.github.com/Unitech/pm2/issues/5900)
[@&#8203;tbo47](https://redirect.github.com/tbo47)
- Enable PM2 module update from tarball
[#&#8203;5906](https://redirect.github.com/Unitech/pm2/issues/5906)
[@&#8203;AYOKINYA](https://redirect.github.com/AYOKINYA)
- Fix treekil on FreeBSD
[#&#8203;5896](https://redirect.github.com/Unitech/pm2/issues/5896)
[@&#8203;skeyby](https://redirect.github.com/skeyby)
- fix allowing to update namespaced pm2 NPM module
([@&#8203;org/module-name](https://redirect.github.com/org/module-name))
[#&#8203;5915](https://redirect.github.com/Unitech/pm2/issues/5915)
[@&#8203;endelendel](https://redirect.github.com/endelendel)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/unraid/api).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMDcuMSIsInVwZGF0ZWRJblZlciI6IjM5LjIwNy4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-20 10:25:06 -04:00
Pujit Mehrotra
3bfcc8e8c0 fix: node installation not persisting across reboots (#1256)
thank you to SteveHawk on the unraid.net forums for surfacing this:
https://forums.unraid.net/topic/188319-persist-node-package-download/

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Bug Fixes**
- Improved the plugin’s file-cleanup process by correcting the reference
used to identify outdated Node.js archive files. This update ensures
that file management functions as intended, contributing to more
reliable plugin behavior.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-03-20 10:18:40 -04:00
renovate[bot]
1892e23c22 fix(deps): update dependency pino-pretty to v13 (#1250)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [pino-pretty](https://redirect.github.com/pinojs/pino-pretty) |
[`^11.3.0` ->
`^13.0.0`](https://renovatebot.com/diffs/npm/pino-pretty/11.3.0/13.0.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/pino-pretty/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/pino-pretty/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/pino-pretty/11.3.0/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/pino-pretty/11.3.0/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>pinojs/pino-pretty (pino-pretty)</summary>

###
[`v13.0.0`](https://redirect.github.com/pinojs/pino-pretty/releases/tag/v13.0.0)

[Compare
Source](https://redirect.github.com/pinojs/pino-pretty/compare/v12.1.0...v13.0.0)

#### What's Changed

- chore: replace readable-stream with built-in stream by
[@&#8203;benmccann](https://redirect.github.com/benmccann) in
[https://github.com/pinojs/pino-pretty/pull/542](https://redirect.github.com/pinojs/pino-pretty/pull/542)

#### New Contributors

- [@&#8203;benmccann](https://redirect.github.com/benmccann) made their
first contribution in
[https://github.com/pinojs/pino-pretty/pull/542](https://redirect.github.com/pinojs/pino-pretty/pull/542)

**Full Changelog**:
https://github.com/pinojs/pino-pretty/compare/v12.1.0...v13.0.0

###
[`v12.1.0`](https://redirect.github.com/pinojs/pino-pretty/releases/tag/v12.1.0)

[Compare
Source](https://redirect.github.com/pinojs/pino-pretty/compare/v12.0.0...v12.1.0)

#### What's Changed

- fix: unescape \ for levelKey by
[@&#8203;eliw00d](https://redirect.github.com/eliw00d) in
[https://github.com/pinojs/pino-pretty/pull/538](https://redirect.github.com/pinojs/pino-pretty/pull/538)

**Full Changelog**:
https://github.com/pinojs/pino-pretty/compare/v12.0.0...v12.1.0

###
[`v12.0.0`](https://redirect.github.com/pinojs/pino-pretty/releases/tag/v12.0.0)

[Compare
Source](https://redirect.github.com/pinojs/pino-pretty/compare/v11.3.0...v12.0.0)

#### What's Changed

- build(deps-dev): lock typescript minor version by
[@&#8203;Fdawgs](https://redirect.github.com/Fdawgs) in
[https://github.com/pinojs/pino-pretty/pull/534](https://redirect.github.com/pinojs/pino-pretty/pull/534)
- Bump typescript from 5.0.4 to 5.6.3 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/pinojs/pino-pretty/pull/535](https://redirect.github.com/pinojs/pino-pretty/pull/535)
- Drop support for Node.js 14 & 16 by
[@&#8203;eliw00d](https://redirect.github.com/eliw00d) in
[https://github.com/pinojs/pino-pretty/pull/540](https://redirect.github.com/pinojs/pino-pretty/pull/540)

#### New Contributors

- [@&#8203;eliw00d](https://redirect.github.com/eliw00d) made their
first contribution in
[https://github.com/pinojs/pino-pretty/pull/540](https://redirect.github.com/pinojs/pino-pretty/pull/540)

**Full Changelog**:
https://github.com/pinojs/pino-pretty/compare/v11.3.0...v12.0.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/unraid/api).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMDcuMSIsInVwZGF0ZWRJblZlciI6IjM5LjIwNy4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-19 22:18:44 -04:00
renovate[bot]
03ece335b8 fix(deps): update dependency jose to v6 (#1248)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [jose](https://redirect.github.com/panva/jose) | [`^5.9.6` ->
`^6.0.0`](https://renovatebot.com/diffs/npm/jose/5.10.0/6.0.10) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/jose/6.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/jose/6.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/jose/5.10.0/6.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/jose/5.10.0/6.0.10?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>panva/jose (jose)</summary>

###
[`v6.0.10`](https://redirect.github.com/panva/jose/blob/HEAD/CHANGELOG.md#6010-2025-03-12)

[Compare
Source](https://redirect.github.com/panva/jose/compare/v6.0.9...v6.0.10)

##### Refactor

- removed unused claims methods
([74719cf](74719cfcfb))
- reorganize jwt claim set utils
([1f12d88](1f12d88ee8))

###
[`v6.0.9`](https://redirect.github.com/panva/jose/blob/HEAD/CHANGELOG.md#609-2025-03-11)

[Compare
Source](https://redirect.github.com/panva/jose/compare/v6.0.8...v6.0.9)

##### Documentation

- add more symbol document, ignore ts-private fields
([8b73687](8b73687595))
- bump typedoc
([6163a8b](6163a8b6a7))
- drop cdnjs links in README
([a910038](a9100383ab))
- drop denoland/x links in README and add jsr
([3662b9e](3662b9ec44))
- fix key export links from docs/README.md
([c8edfc2](c8edfc2941))

##### Refactor

- always assume structuredClone is present
([f7898a9](f7898a9487))
- hide internal private fields and drop ProduceJWT inheritance
([ab18881](ab18881a57))
- less objects when JWE JWT Replicated Header Parameters are used
([c763a0e](c763a0e373))

###
[`v6.0.8`](https://redirect.github.com/panva/jose/blob/HEAD/CHANGELOG.md#608-2025-02-26)

[Compare
Source](https://redirect.github.com/panva/jose/compare/v6.0.7...v6.0.8)

##### Fixes

- export \[customFetch] symbol from the default entrypoint
([1615614](1615614964)),
closes [#&#8203;762](https://redirect.github.com/panva/jose/issues/762)

###
[`v6.0.7`](https://redirect.github.com/panva/jose/blob/HEAD/CHANGELOG.md#607-2025-02-25)

[Compare
Source](https://redirect.github.com/panva/jose/compare/v6.0.6...v6.0.7)

##### Documentation

- improve generate key/secret and import function descriptions
([cd06359](cd06359597))

##### Fixes

- use \[customFetch] when provided to createRemoteJWKSet
([35f6509](35f6509ff4)),
closes [#&#8203;760](https://redirect.github.com/panva/jose/issues/760)

###
[`v6.0.6`](https://redirect.github.com/panva/jose/blob/HEAD/CHANGELOG.md#606-2025-02-23)

[Compare
Source](https://redirect.github.com/panva/jose/compare/v6.0.5...v6.0.6)

##### Refactor

- move base64url around
([e1350ef](e1350eff87))

##### Documentation

- add various exported symbol descriptions
([3b8ff71](3b8ff717ad))
- add various exported symbol descriptions
([fc4e7da](fc4e7dab4c))
- add various exported symbol descriptions
([74f02c8](74f02c833e))
- update base64url function descriptions
([03d72c8](03d72c8a55))

###
[`v6.0.5`](https://redirect.github.com/panva/jose/blob/HEAD/CHANGELOG.md#605-2025-02-23)

[Compare
Source](https://redirect.github.com/panva/jose/compare/v6.0.4...v6.0.5)

##### Refactor

- **types:** make JWKParameters.kty compatible with
[@&#8203;types/node](https://redirect.github.com/types/node) and
[@&#8203;types/web](https://redirect.github.com/types/web)
([bb6ccfe](bb6ccfed3e))

##### Documentation

- add various exported symbol descriptions
([f52c2ff](f52c2ff0c3))

###
[`v6.0.4`](https://redirect.github.com/panva/jose/blob/HEAD/CHANGELOG.md#604-2025-02-22)

[Compare
Source](https://redirect.github.com/panva/jose/compare/v6.0.3...v6.0.4)

##### Refactor

- optimize base64 with tc39/proposal-arraybuffer-base64
([8a0da69](8a0da6968e)),
closes [#&#8203;752](https://redirect.github.com/panva/jose/issues/752)
- update getSPKI to use crypto.createPublicKey when available
([92392a0](92392a0aa2)),
closes [#&#8203;752](https://redirect.github.com/panva/jose/issues/752)
- use Double HMAC pattern for AES-CBC tag comparison
([f3ba4c7](f3ba4c715f)),
closes [#&#8203;752](https://redirect.github.com/panva/jose/issues/752)

###
[`v6.0.3`](https://redirect.github.com/panva/jose/blob/HEAD/CHANGELOG.md#603-2025-02-22)

[Compare
Source](https://redirect.github.com/panva/jose/compare/v6.0.2...v6.0.3)

##### Documentation

- remove root module tag so that README.md shows up on jsr.io
([ee70698](ee7069818b))

###
[`v6.0.2`](https://redirect.github.com/panva/jose/blob/HEAD/CHANGELOG.md#602-2025-02-22)

[Compare
Source](https://redirect.github.com/panva/jose/compare/v6.0.1...v6.0.2)

##### Documentation

- add module tags to all entrypoints
([a5687aa](a5687aaed4))

###
[`v6.0.1`](https://redirect.github.com/panva/jose/blob/HEAD/CHANGELOG.md#601-2025-02-22)

[Compare
Source](https://redirect.github.com/panva/jose/compare/v6.0.0...v6.0.1)

##### Fixes

- **types:** update build to include extensions in type imports
([9b96672](9b96672ef7))

###
[`v6.0.0`](https://redirect.github.com/panva/jose/blob/HEAD/CHANGELOG.md#600-2025-02-22)

[Compare
Source](https://redirect.github.com/panva/jose/compare/v5.10.0...v6.0.0)

##### ⚠ BREAKING CHANGES

-   The PEMImportOptions type interface is renamed to KeyImportOptions.
-   all builds and bundles now use ES2022 as target
- createRemoteJWKSet now uses fetch, because of that its Node.js only
options.agent property has been removed and new fetch-related options
were added
-   drop support for Ed448 and X448
- drop support for JWK key_ops and CryptoKey usages "(un)wrapKey" and
"deriveKey"
- resolved keys returned as part of verify/decrypt operations (when get
key functions are used) are always normalized to either Uint8Array /
CryptoKey depending on what's more efficient for the executed operation
-   Key "Type" Generics are removed
- CJS-style require is now only possible when require(esm) support is
present in the Node.js runtime
- private KeyObject instances can no longer be used for verify
operations
- private KeyObject instances can no longer be used for encryption
operations
- generateSecret, generateKeyPair, importPKCS8, importSPKI, importJWK,
and importX509 now yield a CryptoKey instead of a KeyObject in Node.js
-   drop support for Node.js 18.x and earlier
- runtime-specific npm releases (jose-browser-runtime,
jose-node-cjs-runtime, and jose-node-esm-runtime) are no longer
maintained or supported
-   removed secp256k1 JWS support
-   removed deprecated experimental APIs
-   removed RSA1\_5 JWE support

##### Features

- enable CryptoKey and KeyObject inputs in JWK thumbprint functions
([6fc9c44](6fc9c4461a))
- JSON Web Key is now an allowed input everywhere
([ebda967](ebda9674e9))

##### Refactor

- always use infered CryptoKey
([c4abaa2](c4abaa265e))
- backport the
[`Ed25519`](https://redirect.github.com/panva/jose/commit/Ed25519) JWS
Algorithm Identifier support
([7a94cb9](7a94cb997a))
- drop support for Ed448 and X448
([2fae1c4](2fae1c447b))
- drop support for JWK key_ops and CryptoKey usages "(un)wrapKey" and
"deriveKey"
([ef918be](ef918be8ba))
- ensure export functions continue to work with KeyObject inputs
([28e9e68](28e9e684bb))
- hardcode the cryptoRuntime export since it is now always WebCryptoAPI
([e00f273](e00f2737fd))
- JWK import extractable default for public keys is now true
([64dcebe](64dcebef36))
- PEM import extractable default for public keys is now true
([4e9f114](4e9f1143c7))
- removed deprecated APIs
([5352083](5352083dc6))
- removed secp256k1 JWS support
([e2b58a5](e2b58a5ca5))
- restructure src/lib and src/runtime now that runtime is fixed
([9b236ce](9b236cec4e))
- target is now ES2022 everywhere
([aa590d5](aa590d569f))
- update importJWK args to align with other import functions
([355a2dd](355a2dd33a))
- WebCryptoAPI is now the only crypto used
([161de46](161de466a2))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/unraid/api).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMDcuMSIsInVwZGF0ZWRJblZlciI6IjM5LjIwNy4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-19 22:18:27 -04:00
Eli Bosley
7bc9949110 fix: make scripts executable when building the plugin (#1255)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Enhanced script functionality to automatically set correct executable
permissions for files within "scripts" directories, ensuring that all
relevant scripts run as expected.
- Added symbolic link management for various Node.js binaries, improving
accessibility and organization within the application.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-03-19 21:13:30 -04:00
renovate[bot]
ad3906e682 fix(deps): update all non-major dependencies (#1251)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [graphql-scalars](https://redirect.github.com/Urigo/graphql-scalars) |
[`1.24.1` ->
`1.24.2`](https://renovatebot.com/diffs/npm/graphql-scalars/1.24.1/1.24.2)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/graphql-scalars/1.24.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/graphql-scalars/1.24.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/graphql-scalars/1.24.1/1.24.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/graphql-scalars/1.24.1/1.24.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [nestjs-pino](https://redirect.github.com/iamolegga/nestjs-pino) |
[`4.3.1` ->
`4.4.0`](https://renovatebot.com/diffs/npm/nestjs-pino/4.3.1/4.4.0) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/nestjs-pino/4.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/nestjs-pino/4.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/nestjs-pino/4.3.1/4.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/nestjs-pino/4.3.1/4.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [pnpm](https://pnpm.io)
([source](https://redirect.github.com/pnpm/pnpm/tree/HEAD/pnpm)) |
[`10.6.4` ->
`10.6.5`](https://renovatebot.com/diffs/npm/pnpm/10.6.4/10.6.5) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/pnpm/10.6.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/pnpm/10.6.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/pnpm/10.6.4/10.6.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/pnpm/10.6.4/10.6.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [vitest](https://redirect.github.com/vitest-dev/vitest)
([source](https://redirect.github.com/vitest-dev/vitest/tree/HEAD/packages/vitest))
| [`3.0.7` ->
`3.0.9`](https://renovatebot.com/diffs/npm/vitest/3.0.7/3.0.9) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/vitest/3.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/vitest/3.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/vitest/3.0.7/3.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vitest/3.0.7/3.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [zx](https://google.github.io/zx/)
([source](https://redirect.github.com/google/zx)) | [`8.3.2` ->
`8.4.1`](https://renovatebot.com/diffs/npm/zx/8.3.2/8.4.1) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/zx/8.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/zx/8.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/zx/8.3.2/8.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/zx/8.3.2/8.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>Urigo/graphql-scalars (graphql-scalars)</summary>

###
[`v1.24.2`](https://redirect.github.com/Urigo/graphql-scalars/blob/HEAD/CHANGELOG.md#1242)

[Compare
Source](https://redirect.github.com/Urigo/graphql-scalars/compare/v1.24.1...v1.24.2)

##### Patch Changes

-
[#&#8203;2791](https://redirect.github.com/graphql-hive/graphql-scalars/pull/2791)

[`3e1e924`](3e1e924b93)
Thanks [@&#8203;dotansimha](https://redirect.github.com/dotansimha)! -
Enable npm provenance

</details>

<details>
<summary>iamolegga/nestjs-pino (nestjs-pino)</summary>

###
[`v4.4.0`](https://redirect.github.com/iamolegga/nestjs-pino/releases/tag/4.4.0):
: allow publishing source map files

[Compare
Source](https://redirect.github.com/iamolegga/nestjs-pino/compare/4.3.1...4.4.0)

#### What's Changed

- build(deps-dev): bump prettier from 3.5.1 to 3.5.2 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2255](https://redirect.github.com/iamolegga/nestjs-pino/pull/2255)
- build(deps-dev): bump
[@&#8203;eslint/js](https://redirect.github.com/eslint/js) from 9.20.0
to 9.21.0 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2256](https://redirect.github.com/iamolegga/nestjs-pino/pull/2256)
- build(deps-dev): bump
[@&#8203;types/node](https://redirect.github.com/types/node) from
22.13.4 to 22.13.5 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2257](https://redirect.github.com/iamolegga/nestjs-pino/pull/2257)
- build(deps-dev): bump ts-jest from 29.2.5 to 29.2.6 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2258](https://redirect.github.com/iamolegga/nestjs-pino/pull/2258)
- build(deps-dev): bump
[@&#8203;eslint/eslintrc](https://redirect.github.com/eslint/eslintrc)
from 3.2.0 to 3.3.0 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2261](https://redirect.github.com/iamolegga/nestjs-pino/pull/2261)
- build(deps-dev): bump
[@&#8203;eslint/compat](https://redirect.github.com/eslint/compat) from
1.2.6 to 1.2.7 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2262](https://redirect.github.com/iamolegga/nestjs-pino/pull/2262)
- build(deps-dev): bump rxjs from 7.8.1 to 7.8.2 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2259](https://redirect.github.com/iamolegga/nestjs-pino/pull/2259)
- build(deps-dev): bump eslint from 9.20.1 to 9.21.0 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2260](https://redirect.github.com/iamolegga/nestjs-pino/pull/2260)
- build(deps-dev): bump
[@&#8203;typescript-eslint/eslint-plugin](https://redirect.github.com/typescript-eslint/eslint-plugin)
from 8.24.1 to 8.25.0 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2263](https://redirect.github.com/iamolegga/nestjs-pino/pull/2263)
- build(deps-dev): bump
[@&#8203;typescript-eslint/parser](https://redirect.github.com/typescript-eslint/parser)
from 8.24.1 to 8.25.0 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2264](https://redirect.github.com/iamolegga/nestjs-pino/pull/2264)
- build(deps-dev): bump eslint-config-prettier from 10.0.1 to 10.0.2 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2265](https://redirect.github.com/iamolegga/nestjs-pino/pull/2265)
- build(deps-dev): bump
[@&#8203;nestjs/testing](https://redirect.github.com/nestjs/testing)
from 11.0.10 to 11.0.11 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2267](https://redirect.github.com/iamolegga/nestjs-pino/pull/2267)
- build(deps-dev): bump
[@&#8203;types/node](https://redirect.github.com/types/node) from
22.13.5 to 22.13.8 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2268](https://redirect.github.com/iamolegga/nestjs-pino/pull/2268)
- build(deps-dev): bump
[@&#8203;nestjs/platform-express](https://redirect.github.com/nestjs/platform-express)
from 11.0.10 to 11.0.11 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2269](https://redirect.github.com/iamolegga/nestjs-pino/pull/2269)
- build(deps-dev): bump prettier from 3.5.2 to 3.5.3 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2271](https://redirect.github.com/iamolegga/nestjs-pino/pull/2271)
- build(deps-dev): bump
[@&#8203;nestjs/core](https://redirect.github.com/nestjs/core) from
11.0.10 to 11.0.11 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2272](https://redirect.github.com/iamolegga/nestjs-pino/pull/2272)
- build(deps-dev): bump
[@&#8203;nestjs/platform-fastify](https://redirect.github.com/nestjs/platform-fastify)
from 11.0.10 to 11.0.11 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2273](https://redirect.github.com/iamolegga/nestjs-pino/pull/2273)
- build(deps-dev): bump
[@&#8203;nestjs/common](https://redirect.github.com/nestjs/common) from
11.0.10 to 11.0.11 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2274](https://redirect.github.com/iamolegga/nestjs-pino/pull/2274)
- build(deps-dev): bump
[@&#8203;types/node](https://redirect.github.com/types/node) from
22.13.8 to 22.13.9 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2275](https://redirect.github.com/iamolegga/nestjs-pino/pull/2275)
- build(deps-dev): bump
[@&#8203;typescript-eslint/eslint-plugin](https://redirect.github.com/typescript-eslint/eslint-plugin)
from 8.25.0 to 8.26.0 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2276](https://redirect.github.com/iamolegga/nestjs-pino/pull/2276)
- build(deps-dev): bump
[@&#8203;typescript-eslint/parser](https://redirect.github.com/typescript-eslint/parser)
from 8.25.0 to 8.26.0 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2277](https://redirect.github.com/iamolegga/nestjs-pino/pull/2277)
- build(deps-dev): bump eslint from 9.21.0 to 9.22.0 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2278](https://redirect.github.com/iamolegga/nestjs-pino/pull/2278)
- build(deps-dev): bump
[@&#8203;types/node](https://redirect.github.com/types/node) from
22.13.9 to 22.13.10 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2280](https://redirect.github.com/iamolegga/nestjs-pino/pull/2280)
- build(deps-dev): bump eslint-config-prettier from 10.0.2 to 10.1.1 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2281](https://redirect.github.com/iamolegga/nestjs-pino/pull/2281)
- build(deps-dev): bump
[@&#8203;typescript-eslint/parser](https://redirect.github.com/typescript-eslint/parser)
from 8.26.0 to 8.26.1 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2284](https://redirect.github.com/iamolegga/nestjs-pino/pull/2284)
- build(deps-dev): bump
[@&#8203;typescript-eslint/eslint-plugin](https://redirect.github.com/typescript-eslint/eslint-plugin)
from 8.26.0 to 8.26.1 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2285](https://redirect.github.com/iamolegga/nestjs-pino/pull/2285)
- build(deps-dev): bump typescript from 5.7.3 to 5.8.2 by
[@&#8203;dependabot](https://redirect.github.com/dependabot) in
[https://github.com/iamolegga/nestjs-pino/pull/2270](https://redirect.github.com/iamolegga/nestjs-pino/pull/2270)
- chore(package): allow publishing source map files by
[@&#8203;H4ad](https://redirect.github.com/H4ad) in
[https://github.com/iamolegga/nestjs-pino/pull/2288](https://redirect.github.com/iamolegga/nestjs-pino/pull/2288)

#### New Contributors

- [@&#8203;H4ad](https://redirect.github.com/H4ad) made their first
contribution in
[https://github.com/iamolegga/nestjs-pino/pull/2288](https://redirect.github.com/iamolegga/nestjs-pino/pull/2288)

**Full Changelog**:
https://github.com/iamolegga/nestjs-pino/compare/4.3.1...4.4.0

</details>

<details>
<summary>pnpm/pnpm (pnpm)</summary>

###
[`v10.6.5`](https://redirect.github.com/pnpm/pnpm/compare/v10.6.4...v10.6.5)

[Compare
Source](https://redirect.github.com/pnpm/pnpm/compare/v10.6.4...v10.6.5)

</details>

<details>
<summary>vitest-dev/vitest (vitest)</summary>

###
[`v3.0.9`](https://redirect.github.com/vitest-dev/vitest/releases/tag/v3.0.9)

[Compare
Source](https://redirect.github.com/vitest-dev/vitest/compare/v3.0.8...v3.0.9)

#####    🐞 Bug Fixes

- Typings of `ctx.skip()` as `never`  -  by
[@&#8203;sirlancelot](https://redirect.github.com/sirlancelot) in
[https://github.com/vitest-dev/vitest/issues/7608](https://redirect.github.com/vitest-dev/vitest/issues/7608)
[<samp>(09f35)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/09f35301)
- Cleanup vitest in public `resolveConfig` API  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7623](https://redirect.github.com/vitest-dev/vitest/issues/7623)
[<samp>(db14a)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/db14ab71)
- Fix `toHaveBeenCalledWith(asymmetricMatcher)` with `undefined`
arguments  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7624](https://redirect.github.com/vitest-dev/vitest/issues/7624)
[<samp>(0fb21)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/0fb21faa)
- Race condition in RPC filesystem cache.  -  by
[@&#8203;dts](https://redirect.github.com/dts) in
[https://github.com/vitest-dev/vitest/issues/7531](https://redirect.github.com/vitest-dev/vitest/issues/7531)
[<samp>(b7f55)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/b7f55261)
- Fix `getState().testPath` during collection with no isolation  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7640](https://redirect.github.com/vitest-dev/vitest/issues/7640)
[<samp>(3fb3f)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/3fb3fbf8)
- Support custom toString method in %s format  -  by
[@&#8203;pengooseDev](https://redirect.github.com/pengooseDev) in
[https://github.com/vitest-dev/vitest/issues/7637](https://redirect.github.com/vitest-dev/vitest/issues/7637)
[<samp>(46d93)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/46d93a2e)
-   **browser**:
- Fail playwright timeouts earlier than a test timeout  -  by
[@&#8203;sheremet-va](https://redirect.github.com/sheremet-va) and
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7565](https://redirect.github.com/vitest-dev/vitest/issues/7565)
[<samp>(5eb4c)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/5eb4cd1f)
- Remove
[@&#8203;testing-library/dom](https://redirect.github.com/testing-library/dom)
from dependencies
[#&#8203;7555](https://redirect.github.com/vitest-dev/vitest/issues/7555))"
 -  by [@&#8203;sheremet-va](https://redirect.github.com/sheremet-va) in
[https://github.com/vitest-dev/vitest/issues/7628](https://redirect.github.com/vitest-dev/vitest/issues/7628)
and
[https://github.com/vitest-dev/vitest/issues/7555](https://redirect.github.com/vitest-dev/vitest/issues/7555)
[<samp>(94b27)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/94b27af5)
-   **coverage**:
- Browser mode + `coverage.all`  -  by
[@&#8203;AriPerkkio](https://redirect.github.com/AriPerkkio) in
[https://github.com/vitest-dev/vitest/issues/7597](https://redirect.github.com/vitest-dev/vitest/issues/7597)
[<samp>(422ba)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/422ba66b)
-   **runner**:
- Show stacktrace on hook timeout error  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7502](https://redirect.github.com/vitest-dev/vitest/issues/7502)
[<samp>(268a1)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/268a19e1)
-   **vite-node**:
- Fix source map of inlined node_modules  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7557](https://redirect.github.com/vitest-dev/vitest/issues/7557)
[<samp>(34aa3)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/34aa322b)
- Fix missing `buildStart`  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7652](https://redirect.github.com/vitest-dev/vitest/issues/7652)
[<samp>(29f5a)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/29f5a848)
-   **web-worker**:
- Ensure `removeEventListener` is bound to worker  -  by
[@&#8203;joelgallant](https://redirect.github.com/joelgallant) in
[https://github.com/vitest-dev/vitest/issues/7631](https://redirect.github.com/vitest-dev/vitest/issues/7631)
[<samp>(ff42b)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/ff42bcb3)

#####     [View changes on
GitHub](https://redirect.github.com/vitest-dev/vitest/compare/v3.0.8...v3.0.9)

###
[`v3.0.8`](https://redirect.github.com/vitest-dev/vitest/releases/tag/v3.0.8)

[Compare
Source](https://redirect.github.com/vitest-dev/vitest/compare/v3.0.7...v3.0.8)

#####    🐞 Bug Fixes

- Fix fetch cache multiple writes  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7546](https://redirect.github.com/vitest-dev/vitest/issues/7546)
[<samp>(1a8b4)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/1a8b4337)
- Use browser.isolate instead of config.isolate  -  by
[@&#8203;sheremet-va](https://redirect.github.com/sheremet-va) in
[https://github.com/vitest-dev/vitest/issues/7560](https://redirect.github.com/vitest-dev/vitest/issues/7560)
[<samp>(4b5ed)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/4b5ed902)
- Remove vestigial spy stub, import directly from `@vitest/spy`  -  by
[@&#8203;mrginglymus](https://redirect.github.com/mrginglymus) in
[https://github.com/vitest-dev/vitest/issues/7575](https://redirect.github.com/vitest-dev/vitest/issues/7575)
[<samp>(7f7ff)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/7f7ff11c)
- Correctly split the argv string  -  by
[@&#8203;btea](https://redirect.github.com/btea) in
[https://github.com/vitest-dev/vitest/issues/7533](https://redirect.github.com/vitest-dev/vitest/issues/7533)
[<samp>(4325a)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/4325ac67)
-   **browser**:
- Remove
[@&#8203;testing-library/dom](https://redirect.github.com/testing-library/dom)
from dependencies  -  by
[@&#8203;sheremet-va](https://redirect.github.com/sheremet-va) in
[https://github.com/vitest-dev/vitest/issues/7555](https://redirect.github.com/vitest-dev/vitest/issues/7555)
[<samp>(5387a)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/5387a5b3)
- Improve source map handling for bundled files  -  by
[@&#8203;sheremet-va](https://redirect.github.com/sheremet-va) in
[https://github.com/vitest-dev/vitest/issues/7534](https://redirect.github.com/vitest-dev/vitest/issues/7534)
[<samp>(e2c57)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/e2c570b6)
- Print related test file and potential test in unhandled errors  -  by
[@&#8203;sheremet-va](https://redirect.github.com/sheremet-va) in
[https://github.com/vitest-dev/vitest/issues/7564](https://redirect.github.com/vitest-dev/vitest/issues/7564)
[<samp>(fee90)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/fee90d85)
-   **runner**:
- Fix `beforeEach/All` cleanup callback timeout  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7500](https://redirect.github.com/vitest-dev/vitest/issues/7500)
[<samp>(0c292)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/0c2924b7)
- Fix and simplify `Task.suite` initialization  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7414](https://redirect.github.com/vitest-dev/vitest/issues/7414)
[<samp>(ca9ff)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/ca9ffac5)
-   **snapshot**:
- Allow inline snapshot calls on same location with same snapshot  -  by
[@&#8203;jycouet](https://redirect.github.com/jycouet) and
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7464](https://redirect.github.com/vitest-dev/vitest/issues/7464)
[<samp>(d5cb8)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/d5cb8212)
-   **vite-node**:
- Fix `buildStart` on Vite 6  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7480](https://redirect.github.com/vitest-dev/vitest/issues/7480)
[<samp>(c0f47)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/c0f47e03)

#####     [View changes on
GitHub](https://redirect.github.com/vitest-dev/vitest/compare/v3.0.7...v3.0.8)

</details>

<details>
<summary>google/zx (zx)</summary>

###
[`v8.4.1`](https://redirect.github.com/google/zx/releases/tag/8.4.1): –
Rusty Elbow

[Compare
Source](https://redirect.github.com/google/zx/compare/8.4.0...8.4.1)

Logger enhancements are arriving in this release.
[#&#8203;1119](https://redirect.github.com/google/zx/issues/1119)
[#&#8203;1122](https://redirect.github.com/google/zx/pull/1122)
[#&#8203;1123](https://redirect.github.com/google/zx/pull/1123)
[#&#8203;1125](https://redirect.github.com/google/zx/pull/1125)

- You can customize the output by defining your own formatters for each
log entry kind.

```ts
$.log.formatters = {
  cmd: (entry: LogEntry) => `CMD: ${entry.cmd}`,
  fetch: (entry: LogEntry) => `FETCH: ${entry.url}`
  //...
}
```

- Cmd highlighter now *should* properly detect bins and arguments. If
still not, please report it in
[#&#8203;1122](https://redirect.github.com/google/zx/pull/1122)
- Switched to TS 5.8
[#&#8203;1120](https://redirect.github.com/google/zx/pull/1120)
- Applied [zizmor](https://woodruffw.github.io/zizmor/) to check GHA
workflows
[#&#8203;1126](https://redirect.github.com/google/zx/pull/1126)
- Prettier is now enabled as a pre-commit hook
[#&#8203;1118](https://redirect.github.com/google/zx/pull/1118)

###
[`v8.4.0`](https://redirect.github.com/google/zx/releases/tag/8.4.0): –
Drip Detective

[Compare
Source](https://redirect.github.com/google/zx/compare/8.3.2...8.4.0)

Try the new batch of enhancements: `npm i zx@8.4.0`
https://www.npmjs.com/package/zx/v/8.4.0

#### Changes

- The CLI option `--prefer-local` now allows linking both external
binaries and packages
[#&#8203;1116](https://redirect.github.com/google/zx/pull/1116)
[#&#8203;1117](https://redirect.github.com/google/zx/pull/1117)

```js
const cwd = tmpdir()
const external = tmpdir()
await fs.outputJson(path.join(external, 'node_modules/a/package.json'), {
  name: 'a',
  version: '1.0.0',
  type: 'module',
  exports: './index.js',
})
await fs.outputFile(
  path.join(external, 'node_modules/a/index.js'),
  `
export const a = 'AAA'
`
)
const script = `
import {a} from 'a'
console.log(a);
`
const out = await $`zx --cwd=${cwd} --prefer-local=${external} --test <<< ${script}`
assert.equal(out.stdout, 'AAA\n')
```

- The `quote` has been slightly changed for a conner case, when zx
literal gets an array.
[#&#8203;999](https://redirect.github.com/google/zx/issues/999)
[#&#8203;1113](https://redirect.github.com/google/zx/issues/1113)

```js
const p = $({prefix: '', postfix: ''})`echo ${[1, '', '*', '2']}`

// before
p.cmd //  `echo 1  $'*' 2`) 

// after
p.cmd //  `echo 1 $'' $'*' 2`) 
```

- Provided support for custom script extensions via CLI
[#&#8203;1104](https://redirect.github.com/google/zx/pull/1104)
[#&#8203;1105](https://redirect.github.com/google/zx/pull/1105)

```bash
zx script.zx           # Unknown file extension "\.zx"
zx --ext=mjs script.zx # OK
```

- Enhanced `nothrow` option to suppress any errors
[#&#8203;1108](https://redirect.github.com/google/zx/pull/1108)
[#&#8203;1109](https://redirect.github.com/google/zx/pull/1109)

```js
const err = new Error('BrokenSpawn')
const o = await $({
  nothrow: true,
  spawn() {
    throw err
  },
})`echo foo`
o.ok       // false
o.exitCode // null
o.message  // BrokenSpawn...
o.cause    // err
```

- `@types/node` and `@types/fs-extra` deps replaced with triple-slash
typing refs
[#&#8203;1102](https://redirect.github.com/google/zx/pull/1102)
- Made `ProcessOutput` iterable
[#&#8203;1101](https://redirect.github.com/google/zx/pull/1101)
- Handle inappropriate `ProcessPromise` instantiation
[#&#8203;1097](https://redirect.github.com/google/zx/pull/1097)
[#&#8203;1098](https://redirect.github.com/google/zx/pull/1098)
- Pass origin error as `ProcessOuput` cause
[#&#8203;1110](https://redirect.github.com/google/zx/pull/1110)
- Separated build and release steps
[#&#8203;1106](https://redirect.github.com/google/zx/pull/1106)
-   Internal improvements
- Introduced API bus
[#&#8203;1083](https://redirect.github.com/google/zx/pull/1083)
- Optimized `ProcessOutput` inners
[#&#8203;1096](https://redirect.github.com/google/zx/pull/1096)
[#&#8203;1095](https://redirect.github.com/google/zx/pull/1095)
- Pinned deps
[#&#8203;1099](https://redirect.github.com/google/zx/pull/1099)
[#&#8203;1100](https://redirect.github.com/google/zx/pull/1100)
- Switched to explicit `.ts` extensions for relative imports
[#&#8203;1111](https://redirect.github.com/google/zx/pull/1111)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/unraid/api).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMDcuMSIsInVwZGF0ZWRJblZlciI6IjM5LjIwNy4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-19 10:34:25 -04:00
Eli Bosley
a356bf03fb feat: make log viewer component dynamic (#1242)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a new Log Viewer configuration component to enhance the
management and application of log settings.

- **Chores**
- Removed the legacy log viewer interface to streamline log management
and improve the overall user experience.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-03-19 10:33:12 -04:00
renovate[bot]
57a6c49f8a fix(deps): update all non-major dependencies (#1247)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@nestjs/common](https://nestjs.com)
([source](https://redirect.github.com/nestjs/nest/tree/HEAD/packages/common))
| [`11.0.11` ->
`11.0.12`](https://renovatebot.com/diffs/npm/@nestjs%2fcommon/11.0.11/11.0.12)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@nestjs%2fcommon/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@nestjs%2fcommon/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@nestjs%2fcommon/11.0.11/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@nestjs%2fcommon/11.0.11/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [@nestjs/core](https://nestjs.com)
([source](https://redirect.github.com/nestjs/nest/tree/HEAD/packages/core))
| [`11.0.11` ->
`11.0.12`](https://renovatebot.com/diffs/npm/@nestjs%2fcore/11.0.11/11.0.12)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@nestjs%2fcore/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@nestjs%2fcore/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@nestjs%2fcore/11.0.11/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@nestjs%2fcore/11.0.11/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [@nestjs/platform-fastify](https://nestjs.com)
([source](https://redirect.github.com/nestjs/nest/tree/HEAD/packages/platform-fastify))
| [`11.0.11` ->
`11.0.12`](https://renovatebot.com/diffs/npm/@nestjs%2fplatform-fastify/11.0.11/11.0.12)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@nestjs%2fplatform-fastify/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@nestjs%2fplatform-fastify/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@nestjs%2fplatform-fastify/11.0.11/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@nestjs%2fplatform-fastify/11.0.11/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [@nestjs/testing](https://nestjs.com)
([source](https://redirect.github.com/nestjs/nest/tree/HEAD/packages/testing))
| [`11.0.11` ->
`11.0.12`](https://renovatebot.com/diffs/npm/@nestjs%2ftesting/11.0.11/11.0.12)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@nestjs%2ftesting/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@nestjs%2ftesting/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@nestjs%2ftesting/11.0.11/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@nestjs%2ftesting/11.0.11/11.0.12?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [vitest](https://redirect.github.com/vitest-dev/vitest)
([source](https://redirect.github.com/vitest-dev/vitest/tree/HEAD/packages/vitest))
| [`3.0.7` ->
`3.0.9`](https://renovatebot.com/diffs/npm/vitest/3.0.7/3.0.9) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/vitest/3.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/vitest/3.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/vitest/3.0.7/3.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vitest/3.0.7/3.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [zx](https://google.github.io/zx/)
([source](https://redirect.github.com/google/zx)) | [`8.3.2` ->
`8.4.1`](https://renovatebot.com/diffs/npm/zx/8.3.2/8.4.1) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/zx/8.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/zx/8.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/zx/8.3.2/8.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/zx/8.3.2/8.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>nestjs/nest (@&#8203;nestjs/common)</summary>

###
[`v11.0.12`](https://redirect.github.com/nestjs/nest/compare/v11.0.11...c58f49a3cc7b48916a98dcb81764ce77950d535a)

[Compare
Source](https://redirect.github.com/nestjs/nest/compare/v11.0.11...c58f49a3cc7b48916a98dcb81764ce77950d535a)

</details>

<details>
<summary>nestjs/nest (@&#8203;nestjs/core)</summary>

###
[`v11.0.12`](https://redirect.github.com/nestjs/nest/compare/v11.0.11...c58f49a3cc7b48916a98dcb81764ce77950d535a)

[Compare
Source](https://redirect.github.com/nestjs/nest/compare/v11.0.11...c58f49a3cc7b48916a98dcb81764ce77950d535a)

</details>

<details>
<summary>nestjs/nest (@&#8203;nestjs/platform-fastify)</summary>

###
[`v11.0.12`](https://redirect.github.com/nestjs/nest/compare/v11.0.11...c58f49a3cc7b48916a98dcb81764ce77950d535a)

[Compare
Source](https://redirect.github.com/nestjs/nest/compare/v11.0.11...c58f49a3cc7b48916a98dcb81764ce77950d535a)

</details>

<details>
<summary>nestjs/nest (@&#8203;nestjs/testing)</summary>

###
[`v11.0.12`](https://redirect.github.com/nestjs/nest/compare/v11.0.11...c58f49a3cc7b48916a98dcb81764ce77950d535a)

[Compare
Source](https://redirect.github.com/nestjs/nest/compare/v11.0.11...c58f49a3cc7b48916a98dcb81764ce77950d535a)

</details>

<details>
<summary>vitest-dev/vitest (vitest)</summary>

###
[`v3.0.9`](https://redirect.github.com/vitest-dev/vitest/releases/tag/v3.0.9)

[Compare
Source](https://redirect.github.com/vitest-dev/vitest/compare/v3.0.8...v3.0.9)

#####    🐞 Bug Fixes

- Typings of `ctx.skip()` as `never`  -  by
[@&#8203;sirlancelot](https://redirect.github.com/sirlancelot) in
[https://github.com/vitest-dev/vitest/issues/7608](https://redirect.github.com/vitest-dev/vitest/issues/7608)
[<samp>(09f35)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/09f35301)
- Cleanup vitest in public `resolveConfig` API  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7623](https://redirect.github.com/vitest-dev/vitest/issues/7623)
[<samp>(db14a)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/db14ab71)
- Fix `toHaveBeenCalledWith(asymmetricMatcher)` with `undefined`
arguments  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7624](https://redirect.github.com/vitest-dev/vitest/issues/7624)
[<samp>(0fb21)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/0fb21faa)
- Race condition in RPC filesystem cache.  -  by
[@&#8203;dts](https://redirect.github.com/dts) in
[https://github.com/vitest-dev/vitest/issues/7531](https://redirect.github.com/vitest-dev/vitest/issues/7531)
[<samp>(b7f55)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/b7f55261)
- Fix `getState().testPath` during collection with no isolation  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7640](https://redirect.github.com/vitest-dev/vitest/issues/7640)
[<samp>(3fb3f)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/3fb3fbf8)
- Support custom toString method in %s format  -  by
[@&#8203;pengooseDev](https://redirect.github.com/pengooseDev) in
[https://github.com/vitest-dev/vitest/issues/7637](https://redirect.github.com/vitest-dev/vitest/issues/7637)
[<samp>(46d93)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/46d93a2e)
-   **browser**:
- Fail playwright timeouts earlier than a test timeout  -  by
[@&#8203;sheremet-va](https://redirect.github.com/sheremet-va) and
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7565](https://redirect.github.com/vitest-dev/vitest/issues/7565)
[<samp>(5eb4c)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/5eb4cd1f)
- Remove
[@&#8203;testing-library/dom](https://redirect.github.com/testing-library/dom)
from dependencies
[#&#8203;7555](https://redirect.github.com/vitest-dev/vitest/issues/7555))"
 -  by [@&#8203;sheremet-va](https://redirect.github.com/sheremet-va) in
[https://github.com/vitest-dev/vitest/issues/7628](https://redirect.github.com/vitest-dev/vitest/issues/7628)
and
[https://github.com/vitest-dev/vitest/issues/7555](https://redirect.github.com/vitest-dev/vitest/issues/7555)
[<samp>(94b27)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/94b27af5)
-   **coverage**:
- Browser mode + `coverage.all`  -  by
[@&#8203;AriPerkkio](https://redirect.github.com/AriPerkkio) in
[https://github.com/vitest-dev/vitest/issues/7597](https://redirect.github.com/vitest-dev/vitest/issues/7597)
[<samp>(422ba)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/422ba66b)
-   **runner**:
- Show stacktrace on hook timeout error  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7502](https://redirect.github.com/vitest-dev/vitest/issues/7502)
[<samp>(268a1)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/268a19e1)
-   **vite-node**:
- Fix source map of inlined node_modules  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7557](https://redirect.github.com/vitest-dev/vitest/issues/7557)
[<samp>(34aa3)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/34aa322b)
- Fix missing `buildStart`  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7652](https://redirect.github.com/vitest-dev/vitest/issues/7652)
[<samp>(29f5a)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/29f5a848)
-   **web-worker**:
- Ensure `removeEventListener` is bound to worker  -  by
[@&#8203;joelgallant](https://redirect.github.com/joelgallant) in
[https://github.com/vitest-dev/vitest/issues/7631](https://redirect.github.com/vitest-dev/vitest/issues/7631)
[<samp>(ff42b)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/ff42bcb3)

#####     [View changes on
GitHub](https://redirect.github.com/vitest-dev/vitest/compare/v3.0.8...v3.0.9)

###
[`v3.0.8`](https://redirect.github.com/vitest-dev/vitest/releases/tag/v3.0.8)

[Compare
Source](https://redirect.github.com/vitest-dev/vitest/compare/v3.0.7...v3.0.8)

#####    🐞 Bug Fixes

- Fix fetch cache multiple writes  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7546](https://redirect.github.com/vitest-dev/vitest/issues/7546)
[<samp>(1a8b4)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/1a8b4337)
- Use browser.isolate instead of config.isolate  -  by
[@&#8203;sheremet-va](https://redirect.github.com/sheremet-va) in
[https://github.com/vitest-dev/vitest/issues/7560](https://redirect.github.com/vitest-dev/vitest/issues/7560)
[<samp>(4b5ed)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/4b5ed902)
- Remove vestigial spy stub, import directly from `@vitest/spy`  -  by
[@&#8203;mrginglymus](https://redirect.github.com/mrginglymus) in
[https://github.com/vitest-dev/vitest/issues/7575](https://redirect.github.com/vitest-dev/vitest/issues/7575)
[<samp>(7f7ff)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/7f7ff11c)
- Correctly split the argv string  -  by
[@&#8203;btea](https://redirect.github.com/btea) in
[https://github.com/vitest-dev/vitest/issues/7533](https://redirect.github.com/vitest-dev/vitest/issues/7533)
[<samp>(4325a)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/4325ac67)
-   **browser**:
- Remove
[@&#8203;testing-library/dom](https://redirect.github.com/testing-library/dom)
from dependencies  -  by
[@&#8203;sheremet-va](https://redirect.github.com/sheremet-va) in
[https://github.com/vitest-dev/vitest/issues/7555](https://redirect.github.com/vitest-dev/vitest/issues/7555)
[<samp>(5387a)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/5387a5b3)
- Improve source map handling for bundled files  -  by
[@&#8203;sheremet-va](https://redirect.github.com/sheremet-va) in
[https://github.com/vitest-dev/vitest/issues/7534](https://redirect.github.com/vitest-dev/vitest/issues/7534)
[<samp>(e2c57)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/e2c570b6)
- Print related test file and potential test in unhandled errors  -  by
[@&#8203;sheremet-va](https://redirect.github.com/sheremet-va) in
[https://github.com/vitest-dev/vitest/issues/7564](https://redirect.github.com/vitest-dev/vitest/issues/7564)
[<samp>(fee90)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/fee90d85)
-   **runner**:
- Fix `beforeEach/All` cleanup callback timeout  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7500](https://redirect.github.com/vitest-dev/vitest/issues/7500)
[<samp>(0c292)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/0c2924b7)
- Fix and simplify `Task.suite` initialization  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7414](https://redirect.github.com/vitest-dev/vitest/issues/7414)
[<samp>(ca9ff)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/ca9ffac5)
-   **snapshot**:
- Allow inline snapshot calls on same location with same snapshot  -  by
[@&#8203;jycouet](https://redirect.github.com/jycouet) and
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7464](https://redirect.github.com/vitest-dev/vitest/issues/7464)
[<samp>(d5cb8)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/d5cb8212)
-   **vite-node**:
- Fix `buildStart` on Vite 6  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7480](https://redirect.github.com/vitest-dev/vitest/issues/7480)
[<samp>(c0f47)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/c0f47e03)

#####     [View changes on
GitHub](https://redirect.github.com/vitest-dev/vitest/compare/v3.0.7...v3.0.8)

</details>

<details>
<summary>google/zx (zx)</summary>

###
[`v8.4.1`](https://redirect.github.com/google/zx/releases/tag/8.4.1): –
Rusty Elbow

[Compare
Source](https://redirect.github.com/google/zx/compare/8.4.0...8.4.1)

Logger enhancements are arriving in this release.
[#&#8203;1119](https://redirect.github.com/google/zx/issues/1119)
[#&#8203;1122](https://redirect.github.com/google/zx/pull/1122)
[#&#8203;1123](https://redirect.github.com/google/zx/pull/1123)
[#&#8203;1125](https://redirect.github.com/google/zx/pull/1125)

- You can customize the output by defining your own formatters for each
log entry kind.

```ts
$.log.formatters = {
  cmd: (entry: LogEntry) => `CMD: ${entry.cmd}`,
  fetch: (entry: LogEntry) => `FETCH: ${entry.url}`
  //...
}
```

- Cmd highlighter now *should* properly detect bins and arguments. If
still not, please report it in
[#&#8203;1122](https://redirect.github.com/google/zx/pull/1122)
- Switched to TS 5.8
[#&#8203;1120](https://redirect.github.com/google/zx/pull/1120)
- Applied [zizmor](https://woodruffw.github.io/zizmor/) to check GHA
workflows
[#&#8203;1126](https://redirect.github.com/google/zx/pull/1126)
- Prettier is now enabled as a pre-commit hook
[#&#8203;1118](https://redirect.github.com/google/zx/pull/1118)

###
[`v8.4.0`](https://redirect.github.com/google/zx/releases/tag/8.4.0): –
Drip Detective

[Compare
Source](https://redirect.github.com/google/zx/compare/8.3.2...8.4.0)

Try the new batch of enhancements: `npm i zx@8.4.0`
https://www.npmjs.com/package/zx/v/8.4.0

#### Changes

- The CLI option `--prefer-local` now allows linking both external
binaries and packages
[#&#8203;1116](https://redirect.github.com/google/zx/pull/1116)
[#&#8203;1117](https://redirect.github.com/google/zx/pull/1117)

```js
const cwd = tmpdir()
const external = tmpdir()
await fs.outputJson(path.join(external, 'node_modules/a/package.json'), {
  name: 'a',
  version: '1.0.0',
  type: 'module',
  exports: './index.js',
})
await fs.outputFile(
  path.join(external, 'node_modules/a/index.js'),
  `
export const a = 'AAA'
`
)
const script = `
import {a} from 'a'
console.log(a);
`
const out = await $`zx --cwd=${cwd} --prefer-local=${external} --test <<< ${script}`
assert.equal(out.stdout, 'AAA\n')
```

- The `quote` has been slightly changed for a conner case, when zx
literal gets an array.
[#&#8203;999](https://redirect.github.com/google/zx/issues/999)
[#&#8203;1113](https://redirect.github.com/google/zx/issues/1113)

```js
const p = $({prefix: '', postfix: ''})`echo ${[1, '', '*', '2']}`

// before
p.cmd //  `echo 1  $'*' 2`) 

// after
p.cmd //  `echo 1 $'' $'*' 2`) 
```

- Provided support for custom script extensions via CLI
[#&#8203;1104](https://redirect.github.com/google/zx/pull/1104)
[#&#8203;1105](https://redirect.github.com/google/zx/pull/1105)

```bash
zx script.zx           # Unknown file extension "\.zx"
zx --ext=mjs script.zx # OK
```

- Enhanced `nothrow` option to suppress any errors
[#&#8203;1108](https://redirect.github.com/google/zx/pull/1108)
[#&#8203;1109](https://redirect.github.com/google/zx/pull/1109)

```js
const err = new Error('BrokenSpawn')
const o = await $({
  nothrow: true,
  spawn() {
    throw err
  },
})`echo foo`
o.ok       // false
o.exitCode // null
o.message  // BrokenSpawn...
o.cause    // err
```

- `@types/node` and `@types/fs-extra` deps replaced with triple-slash
typing refs
[#&#8203;1102](https://redirect.github.com/google/zx/pull/1102)
- Made `ProcessOutput` iterable
[#&#8203;1101](https://redirect.github.com/google/zx/pull/1101)
- Handle inappropriate `ProcessPromise` instantiation
[#&#8203;1097](https://redirect.github.com/google/zx/pull/1097)
[#&#8203;1098](https://redirect.github.com/google/zx/pull/1098)
- Pass origin error as `ProcessOuput` cause
[#&#8203;1110](https://redirect.github.com/google/zx/pull/1110)
- Separated build and release steps
[#&#8203;1106](https://redirect.github.com/google/zx/pull/1106)
-   Internal improvements
- Introduced API bus
[#&#8203;1083](https://redirect.github.com/google/zx/pull/1083)
- Optimized `ProcessOutput` inners
[#&#8203;1096](https://redirect.github.com/google/zx/pull/1096)
[#&#8203;1095](https://redirect.github.com/google/zx/pull/1095)
- Pinned deps
[#&#8203;1099](https://redirect.github.com/google/zx/pull/1099)
[#&#8203;1100](https://redirect.github.com/google/zx/pull/1100)
- Switched to explicit `.ts` extensions for relative imports
[#&#8203;1111](https://redirect.github.com/google/zx/pull/1111)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/unraid/api).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMDcuMSIsInVwZGF0ZWRJblZlciI6IjM5LjIwNy4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-19 10:01:29 -04:00
680 changed files with 37848 additions and 17295 deletions

View File

@@ -0,0 +1,12 @@
---
description:
globs: api/**/*,api/*
alwaysApply: false
---
* pnpm ONLY
* always run scripts from api/package.json unless requested
* prefer adding new files to the nest repo located at api/src/unraid-api/ instead of the legacy code
* Test suite is VITEST, do not use jest
* Prefer to not mock simple dependencies

View File

@@ -0,0 +1,8 @@
---
description:
globs:
alwaysApply: true
---
Never add comments unless they are needed for clarity of function
Be CONCISE, keep replies shorter than a paragraph if at all passible.

View File

@@ -0,0 +1,240 @@
---
description:
globs: **/*.test.ts,**/__test__/components/**/*.ts,**/__test__/store/**/*.ts,**/__test__/mocks/**/*.ts
alwaysApply: false
---
## Vue Component Testing Best Practices
- This is a Nuxt.js app but we are testing with vitest outside of the Nuxt environment
- Nuxt is currently set to auto import so some vue files may need compute or ref imported
- Use pnpm when running termical commands and stay within the web directory.
- The directory for tests is located under `web/__test__` when running test just run `pnpm test`
### Setup
- Use `mount` from Vue Test Utils for component testing
- Stub complex child components that aren't the focus of the test
- Mock external dependencies and services
```typescript
import { mount } from '@vue/test-utils';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { createTestingPinia } from '@pinia/testing'
import { useSomeStore } from '@/stores/myStore'
import YourComponent from '~/components/YourComponent.vue';
// Mock dependencies
vi.mock('~/helpers/someHelper', () => ({
SOME_CONSTANT: 'mocked-value',
}));
describe('YourComponent', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('renders correctly', () => {
const wrapper = mount(YourComponent, {
global: {
plugins: [createTestingPinia()],
stubs: {
// Stub child components when needed
ChildComponent: true,
},
},
});
const store = useSomeStore() // uses the testing pinia!
// state can be directly manipulated
store.name = 'my new name'
// actions are stubbed by default, meaning they don't execute their code by default.
// See below to customize this behavior.
store.someAction()
expect(store.someAction).toHaveBeenCalledTimes(1)
// Assertions on components
expect(wrapper.text()).toContain('Expected content');
});
});
```
### Testing Patterns
- Test component behavior and output, not implementation details
- Verify that the expected elements are rendered
- Test component interactions (clicks, inputs, etc.)
- Check for expected prop handling and event emissions
- Use `createTestingPinia()` for mocking stores in components
### Finding Elements
- Use semantic queries like `find('button')` or `find('[data-test="id"]')` but prefer not to use data test ID's
- Find components with `findComponent(ComponentName)`
- Use `findAll` to check for multiple elements
### Assertions
- Assert on rendered text content with `wrapper.text()`
- Assert on element attributes with `element.attributes()`
- Verify element existence with `expect(element.exists()).toBe(true)`
- Check component state through rendered output
### Component Interaction
- Trigger events with `await element.trigger('click')`
- Set input values with `await input.setValue('value')`
- Test emitted events with `wrapper.emitted()`
### Mocking
- Mock external services and API calls
- Prefer not using mocks whenever possible
- Use `vi.mock()` for module-level mocks
- Specify return values for component methods with `vi.spyOn()`
- Reset mocks between tests with `vi.clearAllMocks()`
- Frequently used mocks are stored under `web/test/mocks`
### Async Testing
- Use `await nextTick()` for DOM updates
- Use `flushPromises()` for more complex promise chains
- Always await async operations before making assertions
## Store Testing with Pinia
### Basic Setup
- When testing Store files use `createPinia` and `setActivePinia`
```typescript
import { createPinia, setActivePinia } from 'pinia';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { useYourStore } from '~/store/your-store';
// Mock declarations must be at top level due to hoisting
const mockDependencyFn = vi.fn();
// Module mocks must use factory functions
vi.mock('~/store/dependency', () => ({
useDependencyStore: () => ({
someMethod: mockDependencyFn,
someProperty: 'mockValue'
})
}));
describe('Your Store', () => {
let store: ReturnType<typeof useYourStore>;
beforeEach(() => {
setActivePinia(createPinia());
store = useYourStore();
vi.clearAllMocks();
});
afterEach(() => {
vi.resetAllMocks();
});
it('tests some action', () => {
store.someAction();
expect(mockDependencyFn).toHaveBeenCalled();
});
});
```
### Important Guidelines
1. **Store Initialization**
- Use `createPinia()` instead of `createTestingPinia()` for most cases
- Only use `createTestingPinia` if you specifically need its testing features
- Let stores initialize with their natural default state instead of forcing initial state
- Do not mock the store we're actually testing in the test file. That's why we're using `createPinia()`
2. **Vue Reactivity**
- Ensure Vue reactivity imports are added to original store files as they may be missing because Nuxt auto import was turned on
- Don't rely on Nuxt auto-imports in tests
```typescript
// Required in store files, even with Nuxt auto-imports
import { computed, ref, watchEffect } from 'vue';
```
3. **Mocking Best Practices**
- Place all mock declarations at the top level
- Use factory functions for module mocks to avoid hoisting issues
```typescript
// ❌ Wrong - will cause hoisting issues
const mockFn = vi.fn();
vi.mock('module', () => ({ method: mockFn }));
// ✅ Correct - using factory function
vi.mock('module', () => {
const mockFn = vi.fn();
return { method: mockFn };
});
```
4. **Testing Actions**
- Test action side effects and state changes
- Verify actions are called with correct parameters
- Mock external dependencies appropriately
```typescript
it('should handle action correctly', () => {
store.yourAction();
expect(mockDependencyFn).toHaveBeenCalledWith(
expectedArg1,
expectedArg2
);
expect(store.someState).toBe(expectedValue);
});
```
5. **Common Pitfalls**
- Don't mix mock declarations and module mocks incorrectly
- Avoid relying on Nuxt's auto-imports in test environment
- Clear mocks between tests to ensure isolation
- Remember that `vi.mock()` calls are hoisted
### Testing State & Getters
- Test computed properties by accessing them directly
- Verify state changes after actions
- Test getter dependencies are properly mocked
```typescript
it('computes derived state correctly', () => {
store.setState('new value');
expect(store.computedValue).toBe('expected result');
});
```
### Testing Complex Interactions
- Test store interactions with other stores
- Verify proper error handling
- Test async operations completely
```typescript
it('handles async operations', async () => {
const promise = store.asyncAction();
expect(store.status).toBe('loading');
await promise;
expect(store.status).toBe('success');
});
```
### Testing Actions
- Verify actions are called with the right parameters
- Test action side effects if not stubbed
- Override specific action implementations when needed
```typescript
// Test action calls
store.yourAction(params);
expect(store.yourAction).toHaveBeenCalledWith(params);
// Test with real implementation
const pinia = createTestingPinia({
createSpy: vi.fn,
stubActions: false,
});
```
### Testing State & Getters
- Set initial state for focused testing
- Test computed properties by accessing them directly
- Verify state changes by updating the store

View File

@@ -3,7 +3,7 @@ name: Work Intent
about: Request approval for planned development work (must be approved before starting)
title: 'Work Intent: '
labels: work-intent, unapproved
assignees: ''
assignees: 'elibosley'
---
<!--

190
.github/workflows/build-plugin.yml vendored Normal file
View File

@@ -0,0 +1,190 @@
name: Build Plugin Component
on:
workflow_call:
inputs:
RELEASE_CREATED:
type: string
required: true
description: "Whether a release was created"
RELEASE_TAG:
type: string
required: false
description: "Name of the tag when a release is created"
TAG:
type: string
required: false
description: "Tag for the build (e.g. PR number or version)"
BUCKET_PATH:
type: string
required: true
description: "Path in the bucket where artifacts should be stored"
BASE_URL:
type: string
required: true
description: "Base URL for the plugin builds"
secrets:
CF_ACCESS_KEY_ID:
required: true
CF_SECRET_ACCESS_KEY:
required: true
CF_BUCKET_PREVIEW:
required: true
CF_ENDPOINT:
required: true
jobs:
build-plugin:
name: Build and Deploy Plugin
defaults:
run:
working-directory: plugin
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Node
uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
- uses: pnpm/action-setup@v4
name: Install pnpm
with:
run_install: false
- name: Get pnpm store directory
id: pnpm-cache
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- name: Get API Version
id: vars
run: |
GIT_SHA=$(git rev-parse --short HEAD)
IS_TAGGED=$(git describe --tags --abbrev=0 --exact-match || echo '')
PACKAGE_LOCK_VERSION=$(jq -r '.version' package.json)
API_VERSION=$([[ -n "$IS_TAGGED" ]] && echo "$PACKAGE_LOCK_VERSION" || echo "${PACKAGE_LOCK_VERSION}+${GIT_SHA}")
echo "API_VERSION=${API_VERSION}" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: |
cd ${{ github.workspace }}
pnpm install --frozen-lockfile --filter @unraid/connect-plugin
- name: Download Unraid UI Components
uses: actions/download-artifact@v4
with:
name: unraid-wc-ui
path: ${{ github.workspace }}/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/unraid-components/uui
merge-multiple: true
- name: Download Unraid Web Components
uses: actions/download-artifact@v4
with:
pattern: unraid-wc-rich
path: ${{ github.workspace }}/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/unraid-components/nuxt
merge-multiple: true
- name: Download Unraid API
uses: actions/download-artifact@v4
with:
name: unraid-api
path: ${{ github.workspace }}/plugin/api/
- name: Download PNPM Store
uses: actions/download-artifact@v4
with:
name: packed-node-modules
path: ${{ github.workspace }}/plugin/
- name: Extract Unraid API
run: |
mkdir -p ${{ github.workspace }}/plugin/source/dynamix.unraid.net/usr/local/unraid-api
tar -xzf ${{ github.workspace }}/plugin/api/unraid-api.tgz -C ${{ github.workspace }}/plugin/source/dynamix.unraid.net/usr/local/unraid-api
- name: Build Plugin and TXZ Based on Event and Tag
id: build-plugin
run: |
cd ${{ github.workspace }}/plugin
ls -al
pnpm run build:txz
pnpm run build:plugin --tag="${{ inputs.TAG }}" --base-url="${{ inputs.BASE_URL }}"
- name: Ensure Plugin Files Exist
run: |
ls -al ./deploy
if [ ! -f ./deploy/*.plg ]; then
echo "Error: .plg file not found in plugin/deploy/"
exit 1
fi
if [ ! -f ./deploy/*.txz ]; then
echo "Error: .txz file not found in plugin/deploy/"
exit 1
fi
if [ ! -f ./deploy/*.tar.xz ]; then
echo "Error: .tar.xz file not found in plugin/deploy/"
exit 1
fi
- name: Upload to GHA
uses: actions/upload-artifact@v4
with:
name: unraid-plugin-${{ github.run_id }}-${{ inputs.RELEASE_TAG }}
path: plugin/deploy/
- name: Upload Release Assets
if: inputs.RELEASE_CREATED == 'true'
env:
GITHUB_TOKEN: ${{ github.token }}
RELEASE_TAG: ${{ inputs.RELEASE_TAG }}
run: |
# For each file in release directory
for file in deploy/*; do
echo "Uploading $file to release..."
gh release upload "${RELEASE_TAG}" "$file" --clobber
done
- name: Workflow Dispatch and wait
if: inputs.RELEASE_CREATED == 'true'
uses: the-actions-org/workflow-dispatch@v4.0.0
with:
workflow: release-production.yml
inputs: '{ "version": "${{ steps.vars.outputs.API_VERSION }}" }'
token: ${{ secrets.WORKFLOW_TRIGGER_PAT }}
- name: Upload to Cloudflare
if: inputs.RELEASE_CREATED == 'false'
env:
AWS_ACCESS_KEY_ID: ${{ secrets.CF_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: auto
run: |
# Sync the deploy directory to the Cloudflare bucket with explicit content encoding and public-read ACL
aws s3 sync deploy/ s3://${{ secrets.CF_BUCKET_PREVIEW }}/${{ inputs.BUCKET_PATH }} \
--endpoint-url ${{ secrets.CF_ENDPOINT }} \
--checksum-algorithm CRC32 \
--no-guess-mime-type \
--content-encoding none \
--acl public-read
- name: Comment URL
if: github.event_name == 'pull_request'
uses: thollander/actions-comment-pull-request@v3
with:
comment-tag: prlink
mode: recreate
message: |
This plugin has been deployed to Cloudflare R2 and is available for testing.
Download it at this URL:
```
${{ inputs.BASE_URL }}/tag/${{ inputs.TAG }}/dynamix.unraid.net.plg
```

View File

@@ -13,7 +13,6 @@ concurrency:
jobs:
release-please:
name: Release Please
# Only run release-please on pushes to main
runs-on: ubuntu-latest
permissions:
contents: write
@@ -21,6 +20,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
# Only run release-please on pushes to main
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
- id: release
@@ -47,7 +47,7 @@ jobs:
- name: Cache APT Packages
uses: awalsh128/cache-apt-pkgs-action@v1.4.3
with:
packages: bash procps python3 libvirt-dev jq zstd git build-essential
packages: bash procps python3 libvirt-dev jq zstd git build-essential libvirt-daemon-system
version: 1.0
- name: Install pnpm
@@ -72,6 +72,45 @@ jobs:
- name: PNPM Install
run: pnpm install --frozen-lockfile
- name: Setup libvirt
run: |
# Create required groups (if they don't already exist)
sudo groupadd -f libvirt
sudo groupadd -f kvm
# Create libvirt user if not present, and add it to the kvm group
sudo useradd -m -s /bin/bash -g libvirt libvirt || true
sudo usermod -aG kvm libvirt || true
# Set up libvirt directories and permissions
sudo mkdir -p /var/run/libvirt /var/log/libvirt /etc/libvirt
sudo chown root:libvirt /var/run/libvirt /var/log/libvirt
sudo chmod g+w /var/run/libvirt /var/log/libvirt
# Configure libvirt by appending required settings
sudo tee -a /etc/libvirt/libvirtd.conf > /dev/null <<EOF
unix_sock_group = "libvirt"
unix_sock_rw_perms = "0770"
auth_unix_rw = "none"
EOF
# Add the current user to libvirt and kvm groups (note: this change wont apply to the current session)
sudo usermod -aG libvirt,kvm $USER
sudo mkdir -p /var/run/libvirt
sudo chown root:libvirt /var/run/libvirt
sudo chmod 775 /var/run/libvirt
# Start libvirtd in the background
sudo /usr/sbin/libvirtd --daemon
# Wait a bit longer for libvirtd to start
sleep 5
# Verify libvirt is running using sudo to bypass group membership delays
sudo virsh list --all || true
- name: Lint
run: pnpm run lint
@@ -152,6 +191,11 @@ jobs:
with:
name: unraid-api
path: ${{ github.workspace }}/api/deploy/unraid-api.tgz
- name: Upload Node Modules to Github artifacts
uses: actions/upload-artifact@v4
with:
name: packed-node-modules
path: ${{ github.workspace }}/api/deploy/packed-node-modules.tar.xz
build-unraid-ui-webcomponents:
name: Build Unraid UI Library (Webcomponent Version)
@@ -198,6 +242,9 @@ jobs:
cd ${{ github.workspace }}
pnpm install --frozen-lockfile --filter @unraid/ui
- name: Lint
run: pnpm run lint
- name: Build
run: pnpm run build:wc
@@ -279,7 +326,7 @@ jobs:
name: unraid-wc-rich
path: web/.nuxt/nuxt-custom-elements/dist/unraid-components
build-plugin:
build-plugin-staging-pr:
name: Build and Deploy Plugin
needs:
- release-please
@@ -287,142 +334,36 @@ jobs:
- build-web
- build-unraid-ui-webcomponents
- test-api
defaults:
run:
working-directory: plugin
runs-on: ubuntu-latest
steps:
- name: Set Timezone
uses: szenius/set-timezone@v2.0
with:
timezoneLinux: "America/Los_Angeles"
- name: Checkout repo
uses: actions/checkout@v4
with:
fetch-depth: 0
uses: ./.github/workflows/build-plugin.yml
with:
RELEASE_CREATED: false
TAG: ${{ github.event.pull_request.number && format('PR{0}', github.event.pull_request.number) || '' }}
BUCKET_PATH: ${{ github.event.pull_request.number && format('unraid-api/tag/PR{0}', github.event.pull_request.number) || 'unraid-api' }}
BASE_URL: "https://preview.dl.unraid.net/unraid-api"
secrets:
CF_ACCESS_KEY_ID: ${{ secrets.CF_ACCESS_KEY_ID }}
CF_SECRET_ACCESS_KEY: ${{ secrets.CF_SECRET_ACCESS_KEY }}
CF_BUCKET_PREVIEW: ${{ secrets.CF_BUCKET_PREVIEW }}
CF_ENDPOINT: ${{ secrets.CF_ENDPOINT }}
- name: Install Node
uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
- uses: pnpm/action-setup@v4
name: Install pnpm
with:
run_install: false
- name: Get pnpm store directory
id: pnpm-cache
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: |
cd ${{ github.workspace }}
pnpm install --frozen-lockfile --filter @unraid/connect-plugin
- name: Download Unraid UI Components
uses: actions/download-artifact@v4
with:
name: unraid-wc-ui
path: ${{ github.workspace }}/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/unraid-components/uui
merge-multiple: true
- name: Download Unraid Web Components
uses: actions/download-artifact@v4
with:
pattern: unraid-wc-rich
path: ${{ github.workspace }}/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/unraid-components/nuxt
merge-multiple: true
- name: Download Unraid API
uses: actions/download-artifact@v4
with:
name: unraid-api
path: ${{ github.workspace }}/plugin/api/
- name: Extract Unraid API
run: |
mkdir -p ${{ github.workspace }}/plugin/source/dynamix.unraid.net/usr/local/unraid-api
tar -xzf ${{ github.workspace }}/plugin/api/unraid-api.tgz -C ${{ github.workspace }}/plugin/source/dynamix.unraid.net/usr/local/unraid-api
- name: Build Plugin and TXZ Based on Event and Tag
id: build-plugin
run: |
cd ${{ github.workspace }}/plugin
pnpm run build:txz
if [ -n "${{ github.event.pull_request.number }}" ]; then
TAG="PR${{ github.event.pull_request.number }}"
BUCKET_PATH="unraid-api/tag/${TAG}"
else
TAG=""
BUCKET_PATH="unraid-api"
fi
if [ "${{ needs.release-please.outputs.releases_created }}" == 'true' ]; then
BASE_URL="https://stable.dl.unraid.net/unraid-api"
else
BASE_URL="https://preview.dl.unraid.net/unraid-api"
fi
echo "BUCKET_PATH=${BUCKET_PATH}" >> $GITHUB_OUTPUT
echo "TAG=${TAG}" >> $GITHUB_OUTPUT
pnpm run build:plugin --tag="${TAG}" --base-url="${BASE_URL}"
- name: Ensure Plugin Files Exist
run: |
if [ ! -f ./deploy/*.plg ]; then
echo "Error: .plg file not found in plugin/deploy/"
exit 1
fi
if [ ! -f ./deploy/*.txz ]; then
echo "Error: .txz file not found in plugin/deploy/"
exit 1
fi
- name: Upload to GHA
uses: actions/upload-artifact@v4
with:
name: unraid-plugin
path: plugin/deploy/
- name: Upload to Cloudflare
if: github.event_name == 'pull_request' || startsWith(github.ref, 'refs/heads/main')
env:
AWS_ACCESS_KEY_ID: ${{ secrets.CF_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: auto
run: |
# Sync the deploy directory to the Cloudflare bucket - CRC32 is required for the checksum-algorithm on cloudflare (ref. https://community.cloudflare.com/t/an-error-occurred-internalerror-when-calling-the-putobject-operation/764905/8)
aws s3 sync deploy/ s3://${{ secrets.CF_BUCKET_PREVIEW }}/${{ steps.build-plugin.outputs.BUCKET_PATH }} --endpoint-url ${{ secrets.CF_ENDPOINT }} --checksum-algorithm CRC32
- name: Upload Release Assets
if: needs.release-please.outputs.releases_created == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
release_name=$(gh release list --repo ${{ github.repository }} --json name,isDraft --jq '.[] | select(.isDraft == true) | .name' | head -n 1)
# For each file in release directory
for file in deploy/*; do
echo "Uploading $file to release..."
gh release upload "${release_name}" "$file" --clobber
done
- name: Comment URL
if: github.event_name == 'pull_request'
uses: thollander/actions-comment-pull-request@v3
with:
comment-tag: prlink
mode: recreate
message: |
This plugin has been deployed to Cloudflare R2 and is available for testing.
Download it at this URL:
```
https://preview.dl.unraid.net/unraid-api/tag/${{ steps.build-plugin.outputs.tag }}/dynamix.unraid.net.plg
```
build-plugin-production:
if: ${{ needs.release-please.outputs.releases_created == 'true' }}
name: Build and Deploy Production Plugin
needs:
- release-please
- build-api
- build-web
- build-unraid-ui-webcomponents
- test-api
uses: ./.github/workflows/build-plugin.yml
with:
RELEASE_CREATED: true
RELEASE_TAG: ${{ needs.release-please.outputs.tag_name }}
TAG: ""
BUCKET_PATH: unraid-api
BASE_URL: "https://stable.dl.unraid.net/unraid-api"
secrets:
CF_ACCESS_KEY_ID: ${{ secrets.CF_ACCESS_KEY_ID }}
CF_SECRET_ACCESS_KEY: ${{ secrets.CF_SECRET_ACCESS_KEY }}
CF_BUCKET_PREVIEW: ${{ secrets.CF_BUCKET_PREVIEW }}
CF_ENDPOINT: ${{ secrets.CF_ENDPOINT }}

View File

@@ -1,17 +1,14 @@
name: Publish Release to Digital Ocean
name: Publish Release
on:
release:
types: [published]
workflow_dispatch:
inputs:
version:
description: 'Tag to update'
description: 'Tag to release - will replace active release'
required: true
jobs:
publish-to-digital-ocean:
publish:
runs-on: ubuntu-latest
steps:
@@ -34,6 +31,8 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: '22.x'
- run: |
echo '${{ steps.release-info.outputs.body }}' >> release-notes.txt
- run: npm install html-escaper@2 xml2js
- name: Update Plugin Changelog
uses: actions/github-script@v7
@@ -41,7 +40,8 @@ jobs:
script: |
const fs = require('fs');
const { escape } = require('html-escaper');
const releaseNotes = escape(`${{ steps.release-info.outputs.body }}`);
const releaseNotes = escape(fs.readFileSync('release-notes.txt', 'utf8'));
if (!releaseNotes) {
console.error('No release notes found');
@@ -92,6 +92,9 @@ jobs:
process.exit(1);
});
- name: Cleanup Inline Scripts
run: |
rm -rf node_modules/
- name: Upload Release Files to DO Spaces
env:
AWS_ACCESS_KEY_ID: ${{ secrets.DO_ACCESS_KEY }}
@@ -99,7 +102,12 @@ jobs:
AWS_DEFAULT_REGION: ${{ secrets.DO_SPACE_REGION }}
AWS_ENDPOINT_URL: https://${{ secrets.DO_SPACE_REGION }}.digitaloceanspaces.com
run: |
aws s3 sync . s3://${{ secrets.DO_SPACE_NAME }}/unraid-api --checksum-algorithm CRC32
# Upload files with explicit content encoding and public-read ACL
aws s3 sync . s3://${{ secrets.DO_SPACE_NAME }}/unraid-api \
--checksum-algorithm CRC32 \
--no-guess-mime-type \
--content-encoding none \
--acl public-read
- name: Upload Release Files to Cloudflare Bucket
env:
@@ -108,4 +116,9 @@ jobs:
AWS_DEFAULT_REGION: auto
AWS_ENDPOINT_URL: ${{ secrets.CF_ENDPOINT }}
run: |
aws s3 sync . s3://${{ secrets.CF_BUCKET }}/unraid-api --checksum-algorithm CRC32
# Upload files with explicit content encoding and public-read ACL
aws s3 sync . s3://${{ secrets.CF_BUCKET }}/unraid-api \
--checksum-algorithm CRC32 \
--no-guess-mime-type \
--content-encoding none \
--acl public-read

10
.gitignore vendored
View File

@@ -88,7 +88,6 @@ deploy/*
.nitro
.cache
.output
.env*
!.env.example
fb_keepalive
@@ -101,3 +100,12 @@ result
result-*
.direnv/
.envrc
# Webgui sync script helpers
web/scripts/.sync-webgui-repo-*
# Activation code data
plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/data/activation-data.php
# Config file that changes between versions
api/dev/Unraid.net/myservers.cfg

12
.husky/_/pre-commit Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/sh
if [ "$SKIP_SIMPLE_GIT_HOOKS" = "1" ]; then
echo "[INFO] SKIP_SIMPLE_GIT_HOOKS is set to 1, skipping hook."
exit 0
fi
if [ -f "$SIMPLE_GIT_HOOKS_RC" ]; then
. "$SIMPLE_GIT_HOOKS_RC"
fi
pnpm lint-staged

View File

@@ -1 +1 @@
{".":"4.3.1"}
{".":"4.8.0"}

View File

@@ -1,3 +1,13 @@
Project License Notice
----------------------
This project is licensed under the terms of the GNU General Public License version 2,
**or (at your option) any later version** published by the Free Software Foundation.
The full text of the GNU GPL v2.0 is provided below for reference.
----------------------
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991

View File

@@ -9,6 +9,10 @@ PATHS_MY_SERVERS_CONFIG=./dev/Unraid.net/myservers.cfg # My servers config file
PATHS_MY_SERVERS_FB=./dev/Unraid.net/fb_keepalive # My servers flashbackup timekeeper file
PATHS_KEYFILE_BASE=./dev/Unraid.net # Keyfile location
PATHS_MACHINE_ID=./dev/data/machine-id
PATHS_PARITY_CHECKS=./dev/states/parity-checks.log
PATHS_CONFIG_MODULES=./dev/configs
PATHS_ACTIVATION_BASE=./dev/activation
PATHS_PASSWD=./dev/passwd
ENVIRONMENT="development"
NODE_ENV="development"
PORT="3001"
@@ -20,4 +24,4 @@ BYPASS_PERMISSION_CHECKS=false
BYPASS_CORS_CHECKS=true
CHOKIDAR_USEPOLLING=true
LOG_TRANSPORT=console
LOG_LEVEL=trace
LOG_LEVEL=trace

View File

@@ -2,3 +2,4 @@ ENVIRONMENT="production"
NODE_ENV="production"
PORT="/var/run/unraid-api.sock"
MOTHERSHIP_GRAPHQL_LINK="https://mothership.unraid.net/ws"
PATHS_CONFIG_MODULES="/boot/config/plugins/dynamix.my.servers/configs"

5
api/.env.staging Normal file
View File

@@ -0,0 +1,5 @@
ENVIRONMENT="staging"
NODE_ENV="production"
PORT="/var/run/unraid-api.sock"
MOTHERSHIP_GRAPHQL_LINK="https://staging.mothership.unraid.net/ws"
PATHS_CONFIG_MODULES="/boot/config/plugins/dynamix.my.servers/configs"

View File

@@ -9,5 +9,9 @@ PATHS_MY_SERVERS_CONFIG=./dev/Unraid.net/myservers.cfg # My servers config file
PATHS_MY_SERVERS_FB=./dev/Unraid.net/fb_keepalive # My servers flashbackup timekeeper file
PATHS_KEYFILE_BASE=./dev/Unraid.net # Keyfile location
PATHS_MACHINE_ID=./dev/data/machine-id
PATHS_PARITY_CHECKS=./dev/states/parity-checks.log
PATHS_CONFIG_MODULES=./dev/configs
PATHS_ACTIVATION_BASE=./dev/activation
PATHS_PASSWD=./dev/passwd
PORT=5000
NODE_ENV="test"
NODE_ENV="test"

5
api/.gqlconfig Normal file
View File

@@ -0,0 +1,5 @@
{
schema: {
files: 'src/graphql/schema/types/**/*.graphql'
}
}

11
api/.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,11 @@
{
"recommendations": [
"mikestead.dotenv",
"eamodio.gitlens",
"dbaeumer.vscode-eslint",
"antfu.goto-alias",
"bierner.markdown-mermaid",
"github.vscode-pull-request-github",
"bierner.markdown-preview-github-styles"
]
}

View File

@@ -1,5 +1,161 @@
# Changelog
## [4.8.0](https://github.com/unraid/api/compare/v4.7.0...v4.8.0) (2025-05-01)
### Features
* move activation code logic into the API ([#1369](https://github.com/unraid/api/issues/1369)) ([39e83b2](https://github.com/unraid/api/commit/39e83b2aa156586ab4da362137194280fccefe7c))
### Bug Fixes
* 400 error when submitting connect settings ([831050f](https://github.com/unraid/api/commit/831050f4e8c3af4cbcc123a3a609025f250f0824))
## [4.7.0](https://github.com/unraid/api/compare/v4.6.6...v4.7.0) (2025-04-24)
### Features
* add basic docker network listing ([#1317](https://github.com/unraid/api/issues/1317)) ([c4fdff8](https://github.com/unraid/api/commit/c4fdff8149eb2812707605b3a98eabc795d18c5e))
* add permission documentation by using a custom decorator ([#1355](https://github.com/unraid/api/issues/1355)) ([45ecab6](https://github.com/unraid/api/commit/45ecab6914e2e4dd48438352eb9a5084a6a4b996))
* basic vm controls ([#1293](https://github.com/unraid/api/issues/1293)) ([bc3ca92](https://github.com/unraid/api/commit/bc3ca92fb02387bc019bb001809df96974737b50))
* code first graphql ([#1347](https://github.com/unraid/api/issues/1347)) ([f5724ab](https://github.com/unraid/api/commit/f5724abffbcb8c8a4885c487df4119787fd1d541))
### Bug Fixes
* container names always null ([#1335](https://github.com/unraid/api/issues/1335)) ([8a5b238](https://github.com/unraid/api/commit/8a5b23856c006827229812e558f7d1af92be80e0))
* **deps:** update all non-major dependencies ([#1337](https://github.com/unraid/api/issues/1337)) ([2345732](https://github.com/unraid/api/commit/234573264cfed1409a767927ff95f132be393ea9))
* hide reboot notice for patch releases ([#1341](https://github.com/unraid/api/issues/1341)) ([4b57439](https://github.com/unraid/api/commit/4b5743906a172f84bb46011fe2c3e0c8f64059a2))
* move docker mutations to the mutations resolver ([#1333](https://github.com/unraid/api/issues/1333)) ([1bbe7d2](https://github.com/unraid/api/commit/1bbe7d27b0e87b5ffcd57ac9cc28e64b046055be))
* PR build issue ([457d338](https://github.com/unraid/api/commit/457d338150774ddc14cde6562e226a6a565aca48))
* remove some unused fields from the report object ([#1342](https://github.com/unraid/api/issues/1342)) ([cd323ac](https://github.com/unraid/api/commit/cd323acd4905a558786b029ff5a30371c4512956))
* sso unreliable if API outputs more than raw json ([#1353](https://github.com/unraid/api/issues/1353)) ([e65775f](https://github.com/unraid/api/commit/e65775f8782714d1cc29c8f2801244b5a4043409))
* vms now can detect starting of libvirt and start local hypervisor ([#1356](https://github.com/unraid/api/issues/1356)) ([ad0f4c8](https://github.com/unraid/api/commit/ad0f4c8b55c7f7e94fbae2108f17715b1373a3ef))
## [4.6.6](https://github.com/unraid/api/compare/v4.6.5...v4.6.6) (2025-04-03)
### Bug Fixes
* issue with invalid builds for prod and tagging ([7e89cd2](https://github.com/unraid/api/commit/7e89cd2a3e06a4abc8164f2f4985ad9f6cc9388d))
## [4.6.5](https://github.com/unraid/api/compare/v4.6.4...v4.6.5) (2025-04-03)
### Bug Fixes
* unique artifact ID ([0f682b5](https://github.com/unraid/api/commit/0f682b5f23f4319a1ad8f0e8f2b5e5ae0a2293db))
## [4.6.4](https://github.com/unraid/api/compare/v4.6.3...v4.6.4) (2025-04-03)
### Bug Fixes
* cleanup build pipeline ([#1326](https://github.com/unraid/api/issues/1326)) ([60f16bd](https://github.com/unraid/api/commit/60f16bde416993771fce2ad5861a671504af4b7d))
* remove unneeded workflow secret pass ([4bb00dd](https://github.com/unraid/api/commit/4bb00dd981384083cec40d804209ec2ca18d7aae))
## [4.6.3](https://github.com/unraid/api/compare/v4.6.2...v4.6.3) (2025-04-03)
### Bug Fixes
* copy dynamix.unraid.net ([662d5f6](https://github.com/unraid/api/commit/662d5f64c94586e35bfdaae2df0716c3754b2c45))
* make backup of txz ([37e72f9](https://github.com/unraid/api/commit/37e72f9729f6ab385ed1070fbdca6028688fbd92))
* ordering in build script ([a562f77](https://github.com/unraid/api/commit/a562f7716380bde4a1ae0d6960eff51c37b9291c))
## [4.6.2](https://github.com/unraid/api/compare/v4.6.1...v4.6.2) (2025-04-03)
### Bug Fixes
* build issue ([99d8b31](https://github.com/unraid/api/commit/99d8b31fa8bef13ae6c7dcf74593bc2999a676ed))
## [4.6.1](https://github.com/unraid/api/compare/v4.6.0...v4.6.1) (2025-04-03)
### Bug Fixes
* don't mv deploy on prod release ([9568aab](https://github.com/unraid/api/commit/9568aabd17fbab9e7e2f06f723ee57dc2026583c))
## [4.6.0](https://github.com/unraid/api/compare/v4.5.0...v4.6.0) (2025-04-03)
### Features
* add gui settings field for sso users ([#1310](https://github.com/unraid/api/issues/1310)) ([5ba3fa6](https://github.com/unraid/api/commit/5ba3fa67a26828f29e1e234c6838e7beaa3fdff3))
### Bug Fixes
* build ([ed67af9](https://github.com/unraid/api/commit/ed67af956802eec95845519997bc15b32c84c6ee))
* **plugin:** flaky masking of benign warning during pnpm install ([#1313](https://github.com/unraid/api/issues/1313)) ([1f10b63](https://github.com/unraid/api/commit/1f10b63c8b015e9a2527f79e15a7042feb2d2aca))
## [4.5.0](https://github.com/unraid/api/compare/v4.4.1...v4.5.0) (2025-04-02)
### Features
* add webgui theme switcher component ([#1304](https://github.com/unraid/api/issues/1304)) ([e2d00dc](https://github.com/unraid/api/commit/e2d00dc3464f9663062ac759a8aad85e61804b91))
* api plugin system & offline versioned dependency vendoring ([#1252](https://github.com/unraid/api/issues/1252)) ([9f492bf](https://github.com/unraid/api/commit/9f492bf2175b1b909d3bec079ce901ba34765eb7))
* **api:** add `unraid-api --delete` command ([#1289](https://github.com/unraid/api/issues/1289)) ([2f09445](https://github.com/unraid/api/commit/2f09445f2ed6b23cd851ca64ac5b84cfde3cbd50))
* basic array controls ([#1291](https://github.com/unraid/api/issues/1291)) ([61fe696](https://github.com/unraid/api/commit/61fe6966caf973eec3d74c67741302dd4b507134))
* basic docker controls ([#1292](https://github.com/unraid/api/issues/1292)) ([12eddf8](https://github.com/unraid/api/commit/12eddf894e1808b61f5d4e007f3a7a39a3f2e4d6))
* copy to webgui repo script docs + wc build options ([#1285](https://github.com/unraid/api/issues/1285)) ([e54f189](https://github.com/unraid/api/commit/e54f189630f70aeff5af6bdef4271f0a01fedb74))
### Bug Fixes
* additional url fixes ([4b2763c](https://github.com/unraid/api/commit/4b2763c7f9d8b85d5b0ce066dfc9a9a80a115658))
* **api:** redirect benign pnpm postinstall warning to log file ([#1290](https://github.com/unraid/api/issues/1290)) ([7fb7849](https://github.com/unraid/api/commit/7fb78494cb23630f60a889e6252fc06754e14ef9))
* **deps:** update dependency chalk to v5 ([#1296](https://github.com/unraid/api/issues/1296)) ([6bed638](https://github.com/unraid/api/commit/6bed63805ff026be98a8e20c4d8a37cd47048357))
* **deps:** update dependency diff to v7 ([#1297](https://github.com/unraid/api/issues/1297)) ([3c6683c](https://github.com/unraid/api/commit/3c6683c81422a088c13e9545aaecececd78b8628))
* disable all config watchers ([#1306](https://github.com/unraid/api/issues/1306)) ([5c1b435](https://github.com/unraid/api/commit/5c1b4352cf71d8525f667822f8ca202e2934f463))
* extract callbacks to library ([#1280](https://github.com/unraid/api/issues/1280)) ([2266139](https://github.com/unraid/api/commit/226613974258f15d39932de94316a54aec2e29d2))
* OEM plugin issues ([#1288](https://github.com/unraid/api/issues/1288)) ([d5a3d0d](https://github.com/unraid/api/commit/d5a3d0dfac214fc433c2c0aec578de564a990dd4))
* replace files lost during pruning ([d0d2ff6](https://github.com/unraid/api/commit/d0d2ff65ed2d51223414e50bb1c2ecf82e32a071))
## [4.4.1](https://github.com/unraid/api/compare/v4.4.0...v4.4.1) (2025-03-26)
### Bug Fixes
* .env.production from allowing console logs on build ([#1273](https://github.com/unraid/api/issues/1273)) ([32acc2d](https://github.com/unraid/api/commit/32acc2d27c8bb565b38a66d8233030de3711ea12))
* patch version override logic incorrect ([#1275](https://github.com/unraid/api/issues/1275)) ([6a59756](https://github.com/unraid/api/commit/6a597561a3e21c27fff8d4530cf59cf382eaa015))
## [4.4.0](https://github.com/unraid/api/compare/v4.3.1...v4.4.0) (2025-03-25)
### Features
* add ReplaceKey functionality to plugin ([#1264](https://github.com/unraid/api/issues/1264)) ([4aadcef](https://github.com/unraid/api/commit/4aadcef1ca6b45b44885f2d2a986874e86945d4f))
* downgrade page replace key check ([#1263](https://github.com/unraid/api/issues/1263)) ([8d56d12](https://github.com/unraid/api/commit/8d56d12f67d86d7015a358727bcb303eb511ac42))
* make log viewer component dynamic ([#1242](https://github.com/unraid/api/issues/1242)) ([e6ec110](https://github.com/unraid/api/commit/e6ec110fbf81b329b72ef350643bf3c76734290a))
* ReplaceKey functionality in Registration and Update pages ([#1246](https://github.com/unraid/api/issues/1246)) ([04307c9](https://github.com/unraid/api/commit/04307c977cfd4916753140e5a20811c561d2dfb2))
* UnraidCheckExec for Check OS Updates via UPC dropdown ([#1265](https://github.com/unraid/api/issues/1265)) ([5935a3b](https://github.com/unraid/api/commit/5935a3b3c2f69ee683146c3fcc798d72996633f8))
### Bug Fixes
* **deps:** update all non-major dependencies ([#1236](https://github.com/unraid/api/issues/1236)) ([7194f85](https://github.com/unraid/api/commit/7194f859ce0178116621b4bdf28db553b037940d))
* **deps:** update all non-major dependencies ([#1247](https://github.com/unraid/api/issues/1247)) ([20b0aeb](https://github.com/unraid/api/commit/20b0aeb9d7e621ec917c928135b2c867e07ce7a4))
* **deps:** update all non-major dependencies ([#1251](https://github.com/unraid/api/issues/1251)) ([33a1a1d](https://github.com/unraid/api/commit/33a1a1ddd2f228cf001bb492f9c76bb5bc6dc8a0))
* **deps:** update all non-major dependencies ([#1253](https://github.com/unraid/api/issues/1253)) ([53fec0e](https://github.com/unraid/api/commit/53fec0efaba8f3e2dcf5f2899e3099e0e12f5162))
* **deps:** update dependency @nestjs/passport to v11 ([#1244](https://github.com/unraid/api/issues/1244)) ([edc93a9](https://github.com/unraid/api/commit/edc93a921ea93d98b7c2de9a7fed2fed650365e8))
* **deps:** update dependency graphql-subscriptions to v3 ([#1209](https://github.com/unraid/api/issues/1209)) ([c14c85f](https://github.com/unraid/api/commit/c14c85fcf7ce920edd75d15fa9b3d556f452bb88))
* **deps:** update dependency ini to v5 ([#1217](https://github.com/unraid/api/issues/1217)) ([f27660f](https://github.com/unraid/api/commit/f27660f140acb647cab1dce162af0d49d5655fb6))
* **deps:** update dependency jose to v6 ([#1248](https://github.com/unraid/api/issues/1248)) ([42e3d59](https://github.com/unraid/api/commit/42e3d59107dd800351ee1f7d175c550465ebddb4))
* **deps:** update dependency marked to v15 ([#1249](https://github.com/unraid/api/issues/1249)) ([2b6693f](https://github.com/unraid/api/commit/2b6693f404a9a3405300637d2c55bd5b65c61f0b))
* **deps:** update dependency pino-pretty to v13 ([#1250](https://github.com/unraid/api/issues/1250)) ([85fb910](https://github.com/unraid/api/commit/85fb91059a0ad7728d766cd3b429857b3fd4bd08))
* **deps:** update dependency pm2 to v6 ([#1258](https://github.com/unraid/api/issues/1258)) ([04ad2bc](https://github.com/unraid/api/commit/04ad2bc9c8c1e5fd9622655ce9881bde17388246))
* **deps:** update dependency shadcn-vue to v1 ([#1259](https://github.com/unraid/api/issues/1259)) ([1a4fe8f](https://github.com/unraid/api/commit/1a4fe8f85f50cf34df6af2c0bf55efc305fa9fff))
* **deps:** update dependency vue-i18n to v11 ([#1261](https://github.com/unraid/api/issues/1261)) ([0063286](https://github.com/unraid/api/commit/0063286e29b9a7439e6acc64973a3152370c75c3))
* **deps:** update vueuse monorepo to v13 (major) ([#1262](https://github.com/unraid/api/issues/1262)) ([94caae3](https://github.com/unraid/api/commit/94caae3d87fbfb04dfe5633030e24acddbcc0f6b))
* make scripts executable when building the plugin ([#1255](https://github.com/unraid/api/issues/1255)) ([e237f38](https://github.com/unraid/api/commit/e237f38bc4646f13461938c03d566fef781ad406))
* node installation not persisting across reboots ([#1256](https://github.com/unraid/api/issues/1256)) ([0415cf1](https://github.com/unraid/api/commit/0415cf1252ed8c7fba32a65c031dc0d21e0f5a81))
* update configValid state to ineligible in var.ini and adjust rel… ([#1268](https://github.com/unraid/api/issues/1268)) ([ef8c954](https://github.com/unraid/api/commit/ef8c9548baef99010e2f26288af33a90167e5177))
## [4.3.1](https://github.com/unraid/api/compare/v4.3.0...v4.3.1) (2025-03-18)

View File

@@ -1,17 +1,13 @@
import type { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
overwrite: true,
emitLegacyCommonJSImports: false,
verbose: true,
config: {
namingConvention: {
typeNames: './fix-array-type.cjs',
enumValues: 'change-case#upperCase',
enumValues: 'change-case-all#upperCase',
transformUnderscore: true,
useTypeImports: true,
},
scalars: {
@@ -31,6 +27,7 @@ const config: CodegenConfig = {
},
},
generates: {
// Generate Types for Mothership GraphQL Client
'src/graphql/generated/client/': {
documents: './src/graphql/mothership/*.ts',
schema: {
@@ -50,40 +47,6 @@ const config: CodegenConfig = {
},
plugins: [{ add: { content: '/* eslint-disable */' } }],
},
// Generate Types for the API Server
'src/graphql/generated/api/types.ts': {
schema: ['./src/graphql/types.ts', './src/graphql/schema/types/**/*.graphql'],
plugins: [
'typescript',
'typescript-resolvers',
{ add: { content: '/* eslint-disable */\n/* @ts-nocheck */' } },
],
config: {
contextType: '@app/graphql/schema/utils.js#Context',
useIndexSignature: true,
},
},
// Generate Operations for any built-in API Server Operations (e.g., report.ts)
'src/graphql/generated/api/operations.ts': {
documents: './src/graphql/client/api/*.ts',
schema: ['./src/graphql/types.ts', './src/graphql/schema/types/**/*.graphql'],
preset: 'import-types',
presetConfig: {
typesPath: '@app/graphql/generated/api/types.js',
},
plugins: [
'typescript-validation-schema',
'typescript-operations',
'typed-document-node',
{ add: { content: '/* eslint-disable */' } },
],
config: {
importFrom: '@app/graphql/generated/api/types.js',
strictScalars: true,
schema: 'zod',
withObjectType: true,
},
},
'src/graphql/generated/client/validators.ts': {
schema: {
[process.env.MOTHERSHIP_GRAPHQL_LINK as string]: {
@@ -102,4 +65,4 @@ const config: CodegenConfig = {
},
};
export default config;
export default config;

View File

@@ -0,0 +1 @@
┘[5╢╦О яb┴ ю└;R╛леЩ²ДА├y÷шd│яя╛Еlя▓ё"Hи╜ь;QДs≈@Вы▄╠╩1·Qy╓к|й╔+╨фM)X9jя▄тГО⌠1а2WHщ'│.ЕJё-╨MPгS╜╧:Ю▓]o9^ЮО0┴$"░ l^`╪ >3к:╦я ЯО┤q~ёш≈└с ш5ёЗ=р╟─]╗IWf╥и ⌡?:У2ВоE5[р╨Ш(÷╤Е+о│ШIмAч²%╞╓дq:ё╤эb╣┼

View File

@@ -1,5 +1,5 @@
[api]
version="4.1.3"
version="4.7.0"
extraOrigins="https://google.com,https://test.com"
[local]
sandbox="yes"

View File

@@ -0,0 +1,20 @@
[api]
version="4.4.1"
extraOrigins="https://google.com,https://test.com"
[local]
sandbox="yes"
[remote]
wanaccess="yes"
wanport="8443"
upnpEnabled="no"
apikey="_______________________BIG_API_KEY_HERE_________________________"
localApiKey="_______________________LOCAL_API_KEY_HERE_________________________"
email="test@example.com"
username="zspearmint"
avatar="https://via.placeholder.com/200"
regWizTime="1611175408732_0951-1653-3509-FBA155FA23C0"
accesstoken=""
idtoken=""
refreshtoken=""
dynamicRemoteAccessType="DISABLED"
ssoSubIds=""

View File

@@ -0,0 +1,13 @@
{
"code": "EXAMPLE_CODE_123",
"partnerName": "MyPartner Inc.",
"partnerUrl": "https://partner.example.com",
"serverName": "MyAwesomeServer",
"sysModel": "CustomBuild v1.0",
"comment": "This is a test activation code for development.",
"header": "#336699",
"headermetacolor": "#FFFFFF",
"background": "#F0F0F0",
"showBannerGradient": "yes",
"theme": "black"
}

View File

@@ -0,0 +1 @@
true

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8" ?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="442" height="221">
<defs>
<linearGradient id="gradient_0" gradientUnits="userSpaceOnUse" x1="608.84924" y1="48.058002" x2="447.47684" y2="388.15295">
<stop offset="0" stop-color="#ECC02F"/>
<stop offset="1" stop-color="#B8436B"/>
</linearGradient>
</defs>
<path fill="url(#gradient_0)" transform="scale(0.431641 0.431641)" d="M126.543 236.139C141.269 184.983 170.747 148.08 228.938 144.823C240.378 144.182 259.66 144.749 271.333 145.215C299.585 144.391 350.558 142.667 377.842 145.685C414.099 149.696 443.185 175.429 472.192 195.251L586.561 274.337C636.114 308.874 627.234 309.151 685.21 309.042L778.304 309.082C799.091 309.099 813.482 308.867 828.82 292.529C857.893 261.561 843.003 209.317 800.506 200.17C790.505 198.018 779.334 199.535 769.11 199.523L702.658 199.488C690.005 186.062 675.199 151.817 658.182 145.215L739.199 145.198C765.636 145.196 796.164 142.886 821.565 150.344C923.889 180.389 922.324 331.136 816.611 357.807C802.524 361.361 788.425 361.034 774.035 361.031L663.497 361.009C623.773 360.859 603.599 349.313 572.35 327.596L430.421 229.848C415.731 219.804 401.419 209.118 386.451 199.488C377.579 199.501 368.42 200.01 359.582 199.488L272.561 199.497C258.582 199.485 235.352 198.06 222.607 200.981C192.741 207.825 177.956 234.361 180.015 263.294C177.545 260.392 178.63 254.678 178.838 251.164C179.877 233.569 187.409 224.968 197.345 212.22C184.786 202.853 156.933 193.749 149.447 186.645C143.454 196.583 136.881 205.628 132.955 216.732C130.766 222.921 130.678 230.967 127.506 236.625L126.543 236.139Z"/>
<path fill="#308DAF" transform="scale(0.431641 0.431641)" d="M149.447 186.645C156.933 193.749 184.786 202.853 197.345 212.22C187.409 224.968 179.877 233.569 178.838 251.164C178.63 254.678 177.545 260.392 180.015 263.294C192.489 309.751 221.563 309.078 263.512 309.07L322.096 309.048C333.708 325.984 348.958 344.904 361.795 361.006L232.654 361.03C176.801 360.579 130.605 315.939 126.498 260.613C125.893 252.473 126.453 244.293 126.543 236.139L127.506 236.625C130.678 230.967 130.766 222.921 132.955 216.732C136.881 205.628 143.454 196.583 149.447 186.645Z"/>
<defs>
<linearGradient id="gradient_1" gradientUnits="userSpaceOnUse" x1="620.42566" y1="140.57172" x2="611.08759" y2="282.2207">
<stop offset="0" stop-color="#F5A22C"/>
<stop offset="1" stop-color="#E17543"/>
</linearGradient>
</defs>
<path fill="url(#gradient_1)" transform="scale(0.431641 0.431641)" d="M570.215 137.504C646.214 133.055 670.623 188.789 707.064 241.977L726.71 270.658C729.065 274.1 737.591 284.13 737.576 287.916L674.645 287.916C674.5 287.132 659.251 264.134 658.182 263.294C658.133 262.92 623.915 212.832 620.593 208.697C602.652 186.369 565.856 181.796 545.393 203.424C542.002 207.007 539.705 211.779 535.713 214.764C534.409 212.586 496.093 187.105 490.641 183.32C508.306 154.99 539.004 142.872 570.215 137.504Z"/>
<path fill="#308DAF" transform="scale(0.431641 0.431641)" d="M286.656 221.485L350.512 221.485C354.248 227.374 358.556 232.986 362.565 238.698L379.9 263.82C397.44 289.065 410.994 321.185 447.698 317.317C464.599 315.536 476.472 305.449 486.751 292.741C494.293 298.818 530.089 320.341 533.124 324.28C532.441 328.231 526.229 334.319 522.861 336.255C521.587 339.958 509.164 348.519 505.635 350.88C463.781 378.879 411.472 377.537 373.808 343.464C365.331 335.795 359.734 326.969 353.351 317.641L336.798 293.614C320.035 269.591 302.915 245.863 286.656 221.485Z"/>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -0,0 +1,3 @@
{
"demo": "hello.unraider"
}

1
api/dev/data/machine-id Normal file
View File

@@ -0,0 +1 @@
d0b5433294c110f1eed72bdb63910a9a

View File

@@ -0,0 +1 @@
version="6.12.0-beta5"

BIN
api/dev/dynamix/banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

@@ -0,0 +1 @@
case-model.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -1,36 +1,42 @@
[display]
date="%c"
time="%I:%M %p"
number=".,"
scale="-1"
tabs="1"
users="Tasks:3"
resize="0"
wwn="0"
total="1"
usage="0"
banner="image"
dashapps="icons"
theme="white"
text="1"
unit="C"
warning="70"
critical="90"
hot="45"
max="55"
sysinfo="/Tools/SystemProfiler"
date=%c
time=%I:%M %p
number=.,
scale=-1
tabs=1
users=Tasks:3
resize=0
wwn=0
total=1
usage=0
banner=image
dashapps=icons
theme=black
text=1
unit=C
warning=70
critical=90
hot=45
max=55
sysinfo=/Tools/SystemProfiler
header=336699
headermetacolor=FFFFFF
background=F0F0F0
showBannerGradient=yes
[notify]
entity="1"
normal="1"
warning="1"
alert="1"
unraid="1"
plugin="1"
docker_notify="1"
report="1"
display="0"
date="d-m-Y"
time="H:i"
position="top-right"
path="./dev/notifications"
system="*/1 * * * *"
entity=1
normal=1
warning=1
alert=1
unraid=1
plugin=1
docker_notify=1
report=1
display=0
date=d-m-Y
time=H:i
position=top-right
path=./dev/notifications
system=*/1 * * * *

36
api/dev/ident.cfg Normal file
View File

@@ -0,0 +1,36 @@
# Generated settings:
NAME="Unraid"
timeZone="America/New_York"
COMMENT="Media server"
SECURITY="user"
WORKGROUP="WORKGROUP"
DOMAIN=""
DOMAIN_SHORT=""
hideDotFiles="no"
enableFruit="yes"
USE_NETBIOS="no"
localMaster="yes"
serverMultiChannel="no"
USE_WSD="yes"
WSD_OPT=""
WSD2_OPT=""
USE_NTP="yes"
NTP_SERVER1="time1.google.com"
NTP_SERVER2="time2.google.com"
NTP_SERVER3="time3.google.com"
NTP_SERVER4="time4.google.com"
DOMAIN_LOGIN="Administrator"
DOMAIN_PASSWD=""
SYS_MODEL="Custom"
SYS_ARRAY_SLOTS="24"
USE_SSL="yes"
PORT="80"
PORTSSL="8443"
LOCAL_TLD="local"
BIND_MGT="no"
USE_TELNET="no"
PORTTELNET="23"
USE_SSH="yes"
PORTSSH="22"
USE_UPNP="yes"
START_PAGE="Main"

View File

@@ -6,6 +6,6 @@
"name": "Connect",
"permissions": [],
"roles": [
"connect"
"CONNECT"
]
}

0
api/dev/states/devs.ini Normal file
View File

View File

@@ -1,5 +1,5 @@
[api]
version="4.1.3"
version="4.7.0"
extraOrigins="https://google.com,https://test.com"
[local]
sandbox="yes"
@@ -20,5 +20,5 @@ dynamicRemoteAccessType="DISABLED"
ssoSubIds=""
allowedOrigins="/var/run/unraid-notifications.sock, /var/run/unraid-php.sock, /var/run/unraid-cli.sock, http://localhost:8080, https://localhost:4443, https://tower.local:4443, https://192.168.1.150:4443, https://tower:4443, https://192-168-1-150.thisisfourtyrandomcharacters012345678900.myunraid.net:4443, https://85-121-123-122.thisisfourtyrandomcharacters012345678900.myunraid.net:8443, https://10-252-0-1.hash.myunraid.net:4443, https://10-252-1-1.hash.myunraid.net:4443, https://10-253-3-1.hash.myunraid.net:4443, https://10-253-4-1.hash.myunraid.net:4443, https://10-253-5-1.hash.myunraid.net:4443, https://10-100-0-1.hash.myunraid.net:4443, https://10-100-0-2.hash.myunraid.net:4443, https://10-123-1-2.hash.myunraid.net:4443, https://221-123-121-112.hash.myunraid.net:4443, https://google.com, https://test.com, https://connect.myunraid.net, https://connect-staging.myunraid.net, https://dev-my.myunraid.net:4000, https://studio.apollographql.com"
[connectionStatus]
minigraph="PRE_INIT"
minigraph="ERROR_RETRYING"
upnpStatus=""

View File

@@ -0,0 +1,30 @@
[eth0]
DHCP_KEEPRESOLV="no"
DNS_SERVER1="1.1.1.1"
DNS_SERVER2="8.8.8.8"
DHCP6_KEEPRESOLV="no"
BONDING="yes"
BONDNAME=""
BONDNICS="eth0,eth1,eth2,eth3"
BONDING_MODE="1"
BONDING_MIIMON="100"
BRIDGING="yes"
BRNAME=""
BRNICS="bond0"
BRSTP="0"
BRFD="0"
DESCRIPTION:0=""
PROTOCOL:0=""
USE_DHCP:0="yes"
IPADDR:0="192.168.1.150"
NETMASK:0="255.255.255.0"
GATEWAY:0="192.168.1.1"
METRIC:0=""
USE_DHCP6:0=""
IPADDR6:0=""
NETMASK6:0=""
GATEWAY6:0=""
METRIC6:0=""
PRIVACY6:0=""
MTU=""
TYPE="access"

190
api/dev/states/sec.ini Normal file
View File

@@ -0,0 +1,190 @@
["disk1"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk2"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk3"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk4"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk5"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk6"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk7"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk8"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk9"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk10"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk11"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk12"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk13"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk14"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk15"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk16"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk17"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk18"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk19"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk20"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk21"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["disk22"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["abc"]
export="e"
fruit="no"
caseSensitive="auto"
security="public"
readList=""
writeList=""
volsizelimit=""
["flash"]
export="e"
fruit="no"
security="public"
readList=""
writeList=""

View File

@@ -0,0 +1,92 @@
["disk1"]
export="-"
security="public"
hostList=""
["disk2"]
export="-"
security="public"
hostList=""
["disk3"]
export="-"
security="public"
hostList=""
["disk4"]
export="-"
security="public"
hostList=""
["disk5"]
export="-"
security="public"
hostList=""
["disk6"]
export="-"
security="public"
hostList=""
["disk7"]
export="-"
security="public"
hostList=""
["disk8"]
export="-"
security="public"
hostList=""
["disk9"]
export="-"
security="public"
hostList=""
["disk10"]
export="-"
security="public"
hostList=""
["disk11"]
export="-"
security="public"
hostList=""
["disk12"]
export="-"
security="public"
hostList=""
["disk13"]
export="-"
security="public"
hostList=""
["disk14"]
export="-"
security="public"
hostList=""
["disk15"]
export="-"
security="public"
hostList=""
["disk16"]
export="-"
security="public"
hostList=""
["disk17"]
export="-"
security="public"
hostList=""
["disk18"]
export="-"
security="public"
hostList=""
["disk19"]
export="-"
security="public"
hostList=""
["disk20"]
export="-"
security="public"
hostList=""
["disk21"]
export="-"
security="public"
hostList=""
["disk22"]
export="-"
security="public"
hostList=""
["abc"]
export="-"
security="public"
hostList=""

68
api/dev/states/shares.ini Normal file
View File

@@ -0,0 +1,68 @@
["appdata"]
name="appdata"
nameOrig="appdata"
comment=""
allocator="highwater"
splitLevel=""
floor="0"
include=""
exclude=""
useCache="no"
cachePool="cache"
cow="auto"
color="yellow-on"
size="0"
free="9091184"
used="32831348"
luksStatus="0"
["domains"]
name="domains"
nameOrig="domains"
comment="saved VM instances"
allocator="highwater"
splitLevel="1"
floor="0"
include=""
exclude=""
useCache="prefer"
cachePool="cache"
cow="auto"
color="yellow-on"
size="0"
free="9091184"
used="32831348"
luksStatus="0"
["isos"]
name="isos"
nameOrig="isos"
comment="ISO images"
allocator="highwater"
splitLevel=""
floor="0"
include=""
exclude=""
useCache="yes"
cachePool="cache"
cow="auto"
color="yellow-on"
size="0"
free="9091184"
used="32831348"
luksStatus="0"
["system"]
name="system"
nameOrig="system"
comment="system data"
allocator="highwater"
splitLevel="1"
floor="0"
include=""
exclude=""
useCache="prefer"
cachePool="cache"
cow="auto"
color="yellow-on"
size="0"
free="9091184"
used="32831348"
luksStatus="0"

15
api/dev/states/users.ini Normal file
View File

@@ -0,0 +1,15 @@
["root"]
idx="0"
name="root"
desc="Console and webGui login account"
passwd="yes"
["xo"]
idx="1"
name="xo"
desc=""
passwd="yes"
["test_user"]
idx="2"
name="test_user"
desc=""
passwd="no"

View File

@@ -87,7 +87,7 @@ shareAvahiSMBModel="Xserve"
shfs_logging="1"
safeMode="no"
startMode="Normal"
configValid="yes"
configValid="ineligible"
joinStatus="Not joined"
deviceCount="4"
flashGUID="0000-0000-0000-000000000000"
@@ -102,6 +102,7 @@ regTm="1833409182"
regTm2="0"
regExp=""
regGen="0"
regState="ENOKEYFILE"
sbName="/boot/config/super.dat"
sbVersion="2.9.13"
sbUpdated="1596079143"

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 222.36 39.04"><defs><linearGradient id="header-logo" x1="47.53" y1="79.1" x2="170.71" y2="-44.08" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#e32929"/><stop offset="1" stop-color="#ff8d30"/></linearGradient></defs><title>unraid.net</title><path d="M146.7,29.47H135l-3,9h-6.49L138.93,0h8l13.41,38.49h-7.09L142.62,6.93l-5.83,16.88h8ZM29.69,0V25.4c0,8.91-5.77,13.64-14.9,13.64S0,34.31,0,25.4V0H6.54V25.4c0,5.17,3.19,7.92,8.25,7.92s8.36-2.75,8.36-7.92V0ZM50.86,12v26.5H44.31V0h6.11l17,26.5V0H74V38.49H67.9ZM171.29,0h6.54V38.49h-6.54Zm51.07,24.69c0,9-5.88,13.8-15.17,13.8H192.67V0H207.3c9.18,0,15.06,4.78,15.06,13.8ZM215.82,13.8c0-5.28-3.3-8.14-8.52-8.14h-8.08V32.77h8c5.33,0,8.63-2.8,8.63-8.08ZM108.31,23.92c4.34-1.6,6.93-5.28,6.93-11.55C115.24,3.68,110.18,0,102.48,0H88.84V38.49h6.55V5.66h6.87c3.8,0,6.21,1.82,6.21,6.71s-2.41,6.76-6.21,6.76H98.88l9.21,19.36h7.53Z" fill="url(#header-logo)"/></svg>

After

Width:  |  Height:  |  Size: 1008 B

View File

@@ -0,0 +1,31 @@
# Working with API plugins
Under the hood, API plugins (i.e. plugins to the `@unraid/api` project) are represented
as npm `peerDependencies`. This is npm's intended package plugin mechanism, and given that
peer dependencies are installed by default as of npm v7, it supports bi-directional plugin functionality,
where the API provides dependencies for the plugin while the plugin provides functionality to the API.
## Private Workspace plugins
### Adding a local workspace package as an API plugin
The challenge with local workspace plugins is that they aren't available via npm during production.
To solve this, we vendor them inside `dist/plugins`. To prevent the build from breaking, however,
you should mark the workspace dependency as optional. For example:
```json
{
"peerDependencies": {
"unraid-api-plugin-connect": "workspace:*"
},
"peerDependenciesMeta": {
"unraid-api-plugin-connect": {
"optional": true
}
},
}
```
By marking the workspace dependency "optional", npm will not attempt to install it.
Thus, even though the "workspace:*" identifier will be invalid during build-time and run-time,
it will not cause problems.

View File

@@ -11,7 +11,7 @@
"max_restarts": 10,
"min_uptime": 10000,
"watch": false,
"interpreter": "/usr/local/node/bin/node",
"interpreter": "/usr/local/bin/node",
"ignore_watch": ["node_modules", "src", ".env.*", "myservers.cfg"],
"log_file": "/var/log/graphql-api.log",
"kill_timeout": 10000

View File

@@ -1,18 +0,0 @@
/**
* This function wraps constant case, that turns any string into CONSTANT_CASE
* However, this function has a bug that, if you pass _ to it it will return an empty
* string. This small module fixes that
*
* @param {string*} str
* @return {string}
*/
function FixArrayType(str) {
if (str === 'Array') {
return 'ArrayType';
}
// If result is an empty string, just return the original string
return str;
}
module.exports = FixArrayType;

File diff suppressed because it is too large Load Diff

1679
api/generated-schema.graphql Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -14,3 +14,7 @@ default:
alias b := build
alias d := deploy
sync-env server:
rsync -avz --progress --stats -e ssh .env* root@{{server}}:/usr/local/unraid-api
ssh root@{{server}} 'cp /usr/local/unraid-api/.env.staging /usr/local/unraid-api/.env'

3
api/legacy/README.md Normal file
View File

@@ -0,0 +1,3 @@
# Legacy Assets
This folder will store legacy types / functionality that may be useful but is not currently a part of the API

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "@unraid/api",
"version": "4.3.1",
"version": "4.8.0",
"main": "src/cli/index.ts",
"type": "module",
"corepack": {
@@ -8,7 +8,7 @@
},
"repository": "git@github.com:unraid/api.git",
"author": "Lime Technology, Inc. <unraid.net>",
"license": "GPL-2.0-only",
"license": "GPL-2.0-or-later",
"engines": {
"pnpm": ">=8.0.0"
},
@@ -17,9 +17,10 @@
"start": "node dist/main.js",
"dev": "vite",
"command": "pnpm run build && clear && ./dist/cli.js",
"command:raw": "./dist/cli.js",
"// Build and Deploy": "",
"build": "vite build --mode=production",
"postbuild": "chmod +x dist/main.js && chmod +x dist/cli.js",
"postbuild": "chmod +x dist/main.js && chmod +x dist/cli.js && node scripts/copy-plugins.js",
"build:watch": "nodemon --watch src --ext ts,js,json --exec 'tsx ./scripts/build.ts'",
"build:docker": "./scripts/dc.sh run --rm builder",
"build:release": "tsx ./scripts/build.ts",
@@ -42,7 +43,9 @@
"container:start": "pnpm run container:stop && ./scripts/dc.sh run --rm --service-ports dev",
"container:stop": "./scripts/dc.sh stop dev",
"container:test": "./scripts/dc.sh run --rm builder pnpm run test",
"container:enter": "./scripts/dc.sh exec dev /bin/bash"
"container:enter": "./scripts/dc.sh exec dev /bin/bash",
"// Migration Scripts": "",
"migration:codefirst": "tsx ./src/unraid-api/graph/migration-script.ts"
},
"bin": {
"unraid-api": "dist/cli.js"
@@ -60,7 +63,9 @@
"@graphql-tools/utils": "^10.5.5",
"@jsonforms/core": "^3.5.1",
"@nestjs/apollo": "^13.0.3",
"@nestjs/cache-manager": "^3.0.1",
"@nestjs/common": "^11.0.11",
"@nestjs/config": "^4.0.2",
"@nestjs/core": "^11.0.11",
"@nestjs/graphql": "^13.0.3",
"@nestjs/passport": "^11.0.0",
@@ -70,14 +75,18 @@
"@reduxjs/toolkit": "^2.3.0",
"@runonflux/nat-upnp": "^1.0.2",
"@types/diff": "^7.0.1",
"@unraid/libvirt": "^1.1.3",
"@unraid/libvirt": "^2.1.0",
"accesscontrol": "^2.2.1",
"bycontract": "^2.0.11",
"bytes": "^3.1.2",
"cache-manager": "^6.4.2",
"cacheable-lookup": "^7.0.0",
"camelcase-keys": "^9.1.3",
"casbin": "^5.32.0",
"change-case": "^5.4.4",
"chokidar": "^4.0.1",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"cli-table": "^0.3.11",
"command-exists": "^1.2.9",
"convert": "^5.8.0",
@@ -85,8 +94,7 @@
"cron": "3.5.0",
"cross-fetch": "^4.0.0",
"diff": "^7.0.0",
"docker-event-emitter": "^0.3.0",
"dockerode": "^3.3.5",
"dockerode": "^4.0.5",
"dotenv": "^16.4.5",
"execa": "^9.5.1",
"exit-hook": "^4.0.0",
@@ -103,10 +111,10 @@
"graphql-tag": "^2.12.6",
"graphql-type-json": "^0.3.2",
"graphql-type-uuid": "^0.2.0",
"graphql-ws": "^5.16.0",
"graphql-ws": "^6.0.0",
"ini": "^5.0.0",
"ip": "^2.0.1",
"jose": "^5.9.6",
"jose": "^6.0.0",
"lodash-es": "^4.17.21",
"multi-ini": "^2.3.2",
"mustache": "^4.2.0",
@@ -121,8 +129,8 @@
"path-type": "^6.0.0",
"pino": "^9.5.0",
"pino-http": "^10.3.0",
"pino-pretty": "^11.3.0",
"pm2": "^5.4.2",
"pino-pretty": "^13.0.0",
"pm2": "^6.0.0",
"reflect-metadata": "^0.1.14",
"request": "^2.88.2",
"rxjs": "^7.8.2",
@@ -134,6 +142,14 @@
"zen-observable-ts": "^1.1.0",
"zod": "^3.23.8"
},
"peerDependencies": {
"unraid-api-plugin-connect": "workspace:*"
},
"peerDependenciesMeta": {
"unraid-api-plugin-connect": {
"optional": true
}
},
"devDependencies": {
"@eslint/js": "^9.21.0",
"@graphql-codegen/add": "^5.0.3",
@@ -143,7 +159,7 @@
"@graphql-codegen/typed-document-node": "^5.0.11",
"@graphql-codegen/typescript": "^4.1.1",
"@graphql-codegen/typescript-operations": "^4.3.1",
"@graphql-codegen/typescript-resolvers": "4.4.4",
"@graphql-codegen/typescript-resolvers": "4.5.0",
"@graphql-typed-document-node/core": "^3.2.0",
"@ianvs/prettier-plugin-sort-imports": "^4.4.0",
"@nestjs/testing": "^11.0.11",
@@ -161,9 +177,10 @@
"@types/ini": "^4.1.1",
"@types/ip": "^1.1.3",
"@types/lodash": "^4.17.13",
"@types/lodash-es": "^4.17.12",
"@types/mustache": "^4.2.5",
"@types/node": "^22.13.4",
"@types/pify": "^5.0.4",
"@types/pify": "^6.0.0",
"@types/semver": "^7.5.8",
"@types/sendmail": "^1.4.7",
"@types/stoppable": "^1.1.3",
@@ -186,11 +203,12 @@
"rollup-plugin-node-externals": "^8.0.0",
"standard-version": "^9.5.0",
"tsx": "^4.19.2",
"type-fest": "^4.37.0",
"typescript": "^5.6.3",
"typescript-eslint": "^8.13.0",
"unplugin-swc": "^1.5.1",
"vite": "^6.0.0",
"vite-plugin-node": "^4.0.0",
"vite-plugin-node": "^5.0.0",
"vite-tsconfig-paths": "^5.1.0",
"vitest": "^3.0.5",
"zx": "^8.3.2"
@@ -198,8 +216,15 @@
"overrides": {
"eslint": {
"jiti": "2"
},
"@as-integrations/fastify": {
"fastify": "$fastify"
},
"nest-authz": {
"@nestjs/common": "$@nestjs/common",
"@nestjs/core": "$@nestjs/core"
}
},
"private": true,
"packageManager": "pnpm@10.6.4"
"packageManager": "pnpm@10.8.1"
}

View File

@@ -1,11 +1,17 @@
#!/usr/bin/env zx
import { mkdir, readFile, rm, writeFile } from 'fs/promises';
import { mkdir, readFile, writeFile } from 'fs/promises';
import { exit } from 'process';
import type { PackageJson } from 'type-fest';
import { $, cd } from 'zx';
import { getDeploymentVersion } from './get-deployment-version.js';
type ApiPackageJson = PackageJson & {
version: string;
peerDependencies: Record<string, string>;
};
try {
// Create release and pack directories
await mkdir('./deploy/release', { recursive: true });
@@ -19,12 +25,13 @@ try {
// Get package details
const packageJson = await readFile('./package.json', 'utf-8');
const parsedPackageJson = JSON.parse(packageJson);
const parsedPackageJson = JSON.parse(packageJson) as ApiPackageJson;
const deploymentVersion = await getDeploymentVersion(process.env, parsedPackageJson.version);
// Update the package.json version to the deployment version
parsedPackageJson.version = deploymentVersion;
// omit dev dependencies from vendored dependencies in release build
parsedPackageJson.devDependencies = {};
// Create a temporary directory for packaging
await mkdir('./deploy/pack/', { recursive: true });
@@ -36,9 +43,19 @@ try {
// Change to the pack directory and install dependencies
cd('./deploy/pack');
console.log('Installing production dependencies...');
console.log('Building production node_modules...');
$.verbose = true;
await $`pnpm install --prod --ignore-workspace --node-linker hoisted`;
await $`npm install --omit=dev`;
await writeFile('package.json', JSON.stringify(parsedPackageJson, null, 4));
const sudoCheck = await $`command -v sudo`.nothrow();
const SUDO = sudoCheck.exitCode === 0 ? 'sudo' : '';
await $`${SUDO} chown -R 0:0 node_modules`;
await $`XZ_OPT=-5 tar -cJf packed-node-modules.tar.xz node_modules`;
await $`mv packed-node-modules.tar.xz ../`;
await $`${SUDO} rm -rf node_modules`;
// chmod the cli
await $`chmod +x ./dist/cli.js`;

View File

@@ -0,0 +1,59 @@
#!/usr/bin/env node
/**
* This AI-generated script copies workspace plugin dist folders to the dist/plugins directory
* to ensure they're available for dynamic imports in production.
*/
import { execSync } from 'child_process';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Get the package.json to find workspace dependencies
const packageJsonPath = path.resolve(__dirname, '../package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
// Create the plugins directory if it doesn't exist
const pluginsDir = path.resolve(__dirname, '../dist/plugins');
if (!fs.existsSync(pluginsDir)) {
fs.mkdirSync(pluginsDir, { recursive: true });
}
// Find all workspace plugins
const pluginPrefix = 'unraid-api-plugin-';
const workspacePlugins = Object.keys(packageJson.peerDependencies || {}).filter((pkgName) =>
pkgName.startsWith(pluginPrefix)
);
// Copy each plugin's dist folder to the plugins directory
for (const pkgName of workspacePlugins) {
const pluginPath = path.resolve(__dirname, `../../packages/${pkgName}`);
const pluginDistPath = path.resolve(pluginPath, 'dist');
const targetPath = path.resolve(pluginsDir, pkgName);
console.log(`Building ${pkgName}...`);
try {
execSync('pnpm build', {
cwd: pluginPath,
stdio: 'inherit',
});
console.log(`Successfully built ${pkgName}`);
} catch (error) {
console.error(`Failed to build ${pkgName}:`, error.message);
process.exit(1);
}
if (!fs.existsSync(pluginDistPath)) {
console.warn(`Plugin ${pkgName} dist folder not found at ${pluginDistPath}`);
process.exit(1);
}
console.log(`Copying ${pkgName} dist folder to ${targetPath}`);
fs.mkdirSync(targetPath, { recursive: true });
fs.cpSync(pluginDistPath, targetPath, { recursive: true });
console.log(`Successfully copied ${pkgName} dist folder`);
}
console.log('Plugin dist folders copied successfully');

View File

@@ -29,7 +29,7 @@ fi
destination_directory="/usr/local/unraid-api"
# Replace the value inside the rsync command with the user's input
rsync_command="rsync -avz --progress --stats -e ssh \"$source_directory\" \"root@${server_name}:$destination_directory\""
rsync_command="rsync -avz --delete --progress --stats -e ssh \"$source_directory\" \"root@${server_name}:$destination_directory\""
echo "Executing the following command:"
echo "$rsync_command"

View File

@@ -9,36 +9,37 @@ import { expect, test } from 'vitest';
test('Returns allowed origins', async () => {
// Load state files into store
await store.dispatch(loadStateFiles());
await store.dispatch(loadConfigFile());
await store.dispatch(loadStateFiles()).unwrap();
await store.dispatch(loadConfigFile()).unwrap();
// Get allowed origins
expect(getAllowedOrigins()).toMatchInlineSnapshot(`
[
"/var/run/unraid-notifications.sock",
"/var/run/unraid-php.sock",
"/var/run/unraid-cli.sock",
"http://localhost:8080",
"https://localhost:4443",
"https://tower.local:4443",
"https://192.168.1.150:4443",
"https://tower:4443",
"https://192-168-1-150.thisisfourtyrandomcharacters012345678900.myunraid.net:4443",
"https://85-121-123-122.thisisfourtyrandomcharacters012345678900.myunraid.net:8443",
"https://10-252-0-1.hash.myunraid.net:4443",
"https://10-252-1-1.hash.myunraid.net:4443",
"https://10-253-3-1.hash.myunraid.net:4443",
"https://10-253-4-1.hash.myunraid.net:4443",
"https://10-253-5-1.hash.myunraid.net:4443",
"https://10-100-0-1.hash.myunraid.net:4443",
"https://10-100-0-2.hash.myunraid.net:4443",
"https://10-123-1-2.hash.myunraid.net:4443",
"https://221-123-121-112.hash.myunraid.net:4443",
"https://google.com",
"https://test.com",
"https://connect.myunraid.net",
"https://connect-staging.myunraid.net",
"https://dev-my.myunraid.net:4000",
]
`);
const allowedOrigins = getAllowedOrigins();
// Test that the result is an array
expect(Array.isArray(allowedOrigins)).toBe(true);
// Test that it contains the expected socket paths
expect(allowedOrigins).toContain('/var/run/unraid-notifications.sock');
expect(allowedOrigins).toContain('/var/run/unraid-php.sock');
expect(allowedOrigins).toContain('/var/run/unraid-cli.sock');
// Test that it contains the expected local URLs
expect(allowedOrigins).toContain('http://localhost:8080');
expect(allowedOrigins).toContain('https://localhost:4443');
// Test that it contains the expected connect URLs
expect(allowedOrigins).toContain('https://connect.myunraid.net');
expect(allowedOrigins).toContain('https://connect-staging.myunraid.net');
expect(allowedOrigins).toContain('https://dev-my.myunraid.net:4000');
// Test that it contains the extra origins from config
expect(allowedOrigins).toContain('https://google.com');
expect(allowedOrigins).toContain('https://test.com');
// Test that it contains some of the remote URLs
expect(allowedOrigins).toContain('https://tower.local:4443');
expect(allowedOrigins).toContain('https://192.168.1.150:4443');
// Test that there are no duplicates
expect(allowedOrigins.length).toBe(new Set(allowedOrigins).size);
});

View File

@@ -0,0 +1,3 @@
import { test } from 'vitest';
test.todo('Returns generated data');

View File

@@ -1,209 +0,0 @@
import { expect, test, vi } from 'vitest';
import { getArrayData } from '@app/core/modules/array/get-array-data.js';
import { store } from '@app/store/index.js';
import { loadConfigFile } from '@app/store/modules/config.js';
import { loadStateFiles } from '@app/store/modules/emhttp.js';
vi.mock('@app/core/pubsub.js', () => ({
pubsub: { publish: vi.fn() },
}));
test('Creates an array event', async () => {
// Load state files into store
await store.dispatch(loadStateFiles());
await store.dispatch(loadConfigFile());
const arrayEvent = getArrayData(store.getState);
expect(arrayEvent).toMatchObject({
boot: {
comment: 'Unraid OS boot device',
critical: null,
device: 'sda',
exportable: true,
format: 'unknown',
fsFree: 3191407,
fsSize: 4042732,
fsType: 'vfat',
fsUsed: 851325,
id: 'Cruzer',
idx: 32,
name: 'flash',
numErrors: 0,
numReads: 0,
numWrites: 0,
rotational: true,
size: 3956700,
status: 'DISK_OK',
temp: null,
transport: 'usb',
type: 'Flash',
warning: null,
},
caches: [
{
comment: '',
critical: null,
device: 'sdi',
exportable: false,
format: 'MBR: 4KiB-aligned',
fsFree: 111810683,
fsSize: 250059317,
fsType: 'btrfs',
fsUsed: 137273827,
id: 'Samsung_SSD_850_EVO_250GB_S2R5NX0H643734Z',
idx: 30,
name: 'cache',
numErrors: 0,
numReads: 0,
numWrites: 0,
rotational: false,
size: 244198552,
status: 'DISK_OK',
temp: 22,
transport: 'ata',
type: 'Cache',
warning: null,
},
{
comment: null,
critical: null,
device: 'nvme0n1',
exportable: false,
format: 'MBR: 4KiB-aligned',
fsFree: null,
fsSize: null,
fsType: null,
fsUsed: null,
id: 'KINGSTON_SA2000M8250G_50026B7282669D9E',
idx: 31,
name: 'cache2',
numErrors: 0,
numReads: 0,
numWrites: 0,
rotational: false,
size: 244198552,
status: 'DISK_OK',
temp: 27,
transport: 'nvme',
type: 'Cache',
warning: null,
},
],
capacity: {
disks: {
free: '27',
total: '30',
used: '3',
},
kilobytes: {
free: '19495825571',
total: '41994745901',
used: '22498920330',
},
},
disks: [
{
comment: 'Seagate Exos',
critical: 75,
device: 'sdf',
exportable: false,
format: 'GPT: 4KiB-aligned',
fsFree: 13882739732,
fsSize: 17998742753,
fsType: 'xfs',
fsUsed: 4116003021,
id: 'ST18000NM000J-2TV103_ZR5B1W9X',
idx: 1,
name: 'disk1',
numErrors: 0,
numReads: 0,
numWrites: 0,
rotational: true,
size: 17578328012,
status: 'DISK_OK',
temp: 30,
transport: 'ata',
type: 'Data',
warning: 50,
},
{
comment: '',
critical: null,
device: 'sdj',
exportable: false,
format: 'GPT: 4KiB-aligned',
fsFree: 93140746,
fsSize: 11998001574,
fsType: 'xfs',
fsUsed: 11904860828,
id: 'WDC_WD120EDAZ-11F3RA0_5PJRD45C',
idx: 2,
name: 'disk2',
numErrors: 0,
numReads: 0,
numWrites: 0,
rotational: true,
size: 11718885324,
status: 'DISK_OK',
temp: 30,
transport: 'ata',
type: 'Data',
warning: null,
},
{
comment: '',
critical: null,
device: 'sde',
exportable: false,
format: 'GPT: 4KiB-aligned',
fsFree: 5519945093,
fsSize: 11998001574,
fsType: 'xfs',
fsUsed: 6478056481,
id: 'WDC_WD120EMAZ-11BLFA0_5PH8BTYD',
idx: 3,
name: 'disk3',
numErrors: 0,
numReads: 0,
numWrites: 0,
rotational: true,
size: 11718885324,
status: 'DISK_OK',
temp: 30,
transport: 'ata',
type: 'Data',
warning: null,
},
],
id: expect.any(String),
parities: [
{
comment: null,
critical: null,
device: 'sdh',
exportable: false,
format: 'GPT: 4KiB-aligned',
fsFree: null,
fsSize: null,
fsType: null,
fsUsed: null,
id: 'ST18000NM000J-2TV103_ZR585CPY',
idx: 0,
name: 'parity',
numErrors: 0,
numReads: 0,
numWrites: 0,
rotational: true,
size: 17578328012,
status: 'DISK_OK',
temp: 25,
transport: 'ata',
type: 'Parity',
warning: null,
},
],
state: 'STOPPED',
});
});

View File

@@ -0,0 +1,3 @@
import { test } from 'vitest';
test.todo('Returns the current content');

View File

@@ -0,0 +1,5 @@
import { test } from 'vitest';
test.todo('Returns a single disk by ID');
test.todo('Returns nothing if no disk matches the ID');

View File

@@ -0,0 +1,5 @@
import { test } from 'vitest';
test.todo('Returns all the Docker containers');
test.todo('Returns running Docker containers');

View File

@@ -0,0 +1,7 @@
import { test } from 'vitest';
test.todo('Returns all USB devices');
test.todo('Returns all PCI-e devices');
test.todo('Returns all audio devices');

View File

@@ -0,0 +1,3 @@
import { test } from 'vitest';
test.todo('Gets total count of Docker containers installed/running');

View File

@@ -0,0 +1,3 @@
import { test } from 'vitest';
test.todo('Returns baseboard info');

View File

@@ -0,0 +1,3 @@
import { test } from 'vitest';
test.todo('Gets CPU info');

View File

@@ -1,23 +0,0 @@
import { expect, test, vi } from 'vitest';
import type { SliceState } from '@app/store/modules/emhttp.js';
import { getters } from '@app/store/index.js';
test('Returns true if the array is started', async () => {
vi.spyOn(getters, 'emhttp').mockImplementation(
() => ({ var: { mdState: 'STARTED' } }) as unknown as SliceState
);
const { arrayIsRunning } = await import('@app/core/utils/array/array-is-running.js');
expect(arrayIsRunning()).toBe(true);
vi.spyOn(getters, 'emhttp').mockReset();
});
test('Returns false if the array is stopped', async () => {
vi.spyOn(getters, 'emhttp').mockImplementation(
() => ({ var: { mdState: 'Stopped' } }) as unknown as SliceState
);
const { arrayIsRunning } = await import('@app/core/utils/array/array-is-running.js');
expect(arrayIsRunning()).toBe(false);
vi.spyOn(getters, 'emhttp').mockReset();
});

View File

@@ -80,7 +80,6 @@ test('it creates a FLASH config with OPTIONAL values', () => {
// 2fa & t2fa should be ignored
basicConfig.remote['2Fa'] = 'yes';
basicConfig.local['2Fa'] = 'yes';
basicConfig.local.showT2Fa = 'yes';
basicConfig.api.extraOrigins = 'myextra.origins';
basicConfig.remote.upnpEnabled = 'yes';
@@ -120,7 +119,6 @@ test('it creates a MEMORY config with OPTIONAL values', () => {
// 2fa & t2fa should be ignored
basicConfig.remote['2Fa'] = 'yes';
basicConfig.local['2Fa'] = 'yes';
basicConfig.local.showT2Fa = 'yes';
basicConfig.api.extraOrigins = 'myextra.origins';
basicConfig.remote.upnpEnabled = 'yes';
basicConfig.connectionStatus.upnpStatus = 'Turned On';

View File

@@ -0,0 +1,3 @@
import { test } from 'vitest';
test.todo('Sleeps atomically for n milliseconds');

View File

@@ -44,7 +44,7 @@ test('Returns empty key if key location is empty', async () => {
// Check if store has state files loaded
const { status } = store.getState().registration;
expect(status).toBe(FileLoadStatus.LOADED);
expect(status).toBe(FileLoadStatus.UNLOADED);
await expect(getKeyFile()).resolves.toBe('');
});
@@ -53,10 +53,10 @@ test(
async () => {
const { getKeyFile } = await import('@app/core/utils/misc/get-key-file.js');
const { loadStateFiles } = await import('@app/store/modules/emhttp.js');
const { loadRegistrationKey } = await import('@app/store/modules/registration.js');
// Load state files into store
await store.dispatch(loadStateFiles());
await store.dispatch(loadRegistrationKey());
// Check if store has state files loaded
const { status } = store.getState().registration;
expect(status).toBe(FileLoadStatus.LOADED);

View File

@@ -0,0 +1,3 @@
import { test } from 'vitest';
test.todo('Returns machine-id');

View File

@@ -8,229 +8,240 @@ test('Returns both disk and user shares', async () => {
await store.dispatch(loadStateFiles());
expect(getShares()).toMatchInlineSnapshot(`
{
"disks": [],
"users": [
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"include": [],
"luksStatus": "0",
"name": "appdata",
"nameOrig": "appdata",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "",
"type": "user",
"used": 33619300,
},
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "saved VM instances",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"include": [],
"luksStatus": "0",
"name": "domains",
"nameOrig": "domains",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "1",
"type": "user",
"used": 33619300,
},
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "ISO images",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"include": [],
"luksStatus": "0",
"name": "isos",
"nameOrig": "isos",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "",
"type": "user",
"used": 33619300,
},
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "system data",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"include": [],
"luksStatus": "0",
"name": "system",
"nameOrig": "system",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "1",
"type": "user",
"used": 33619300,
},
],
}
`);
{
"disks": [],
"users": [
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"id": "appdata",
"include": [],
"luksStatus": "0",
"name": "appdata",
"nameOrig": "appdata",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "",
"type": "user",
"used": 33619300,
},
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "saved VM instances",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"id": "domains",
"include": [],
"luksStatus": "0",
"name": "domains",
"nameOrig": "domains",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "1",
"type": "user",
"used": 33619300,
},
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "ISO images",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"id": "isos",
"include": [],
"luksStatus": "0",
"name": "isos",
"nameOrig": "isos",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "",
"type": "user",
"used": 33619300,
},
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "system data",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"id": "system",
"include": [],
"luksStatus": "0",
"name": "system",
"nameOrig": "system",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "1",
"type": "user",
"used": 33619300,
},
],
}
`);
});
test('Returns shares by type', async () => {
await store.dispatch(loadStateFiles());
expect(getShares('user')).toMatchInlineSnapshot(`
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"include": [],
"luksStatus": "0",
"name": "appdata",
"nameOrig": "appdata",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "",
"type": "user",
"used": 33619300,
}
`);
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"id": "appdata",
"include": [],
"luksStatus": "0",
"name": "appdata",
"nameOrig": "appdata",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "",
"type": "user",
"used": 33619300,
}
`);
expect(getShares('users')).toMatchInlineSnapshot(`
[
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"include": [],
"luksStatus": "0",
"name": "appdata",
"nameOrig": "appdata",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "",
"type": "user",
"used": 33619300,
},
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "saved VM instances",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"include": [],
"luksStatus": "0",
"name": "domains",
"nameOrig": "domains",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "1",
"type": "user",
"used": 33619300,
},
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "ISO images",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"include": [],
"luksStatus": "0",
"name": "isos",
"nameOrig": "isos",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "",
"type": "user",
"used": 33619300,
},
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "system data",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"include": [],
"luksStatus": "0",
"name": "system",
"nameOrig": "system",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "1",
"type": "user",
"used": 33619300,
},
]
`);
[
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"id": "appdata",
"include": [],
"luksStatus": "0",
"name": "appdata",
"nameOrig": "appdata",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "",
"type": "user",
"used": 33619300,
},
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "saved VM instances",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"id": "domains",
"include": [],
"luksStatus": "0",
"name": "domains",
"nameOrig": "domains",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "1",
"type": "user",
"used": 33619300,
},
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "ISO images",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"id": "isos",
"include": [],
"luksStatus": "0",
"name": "isos",
"nameOrig": "isos",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "",
"type": "user",
"used": 33619300,
},
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "system data",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"id": "system",
"include": [],
"luksStatus": "0",
"name": "system",
"nameOrig": "system",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "1",
"type": "user",
"used": 33619300,
},
]
`);
expect(getShares('disk')).toMatchInlineSnapshot('null');
expect(getShares('disks')).toMatchInlineSnapshot('[]');
});
test('Returns shares by name', async () => {
await store.dispatch(loadStateFiles());
expect(getShares('user', { name: 'domains' })).toMatchInlineSnapshot(`
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "saved VM instances",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"include": [],
"luksStatus": "0",
"name": "domains",
"nameOrig": "domains",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "1",
"type": "user",
"used": 33619300,
}
`);
{
"allocator": "highwater",
"cachePool": "cache",
"color": "yellow-on",
"comment": "saved VM instances",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"id": "domains",
"include": [],
"luksStatus": "0",
"name": "domains",
"nameOrig": "domains",
"nfs": {},
"size": 0,
"smb": {},
"splitLevel": "1",
"type": "user",
"used": 33619300,
}
`);
expect(getShares('user', { name: 'non-existent-user-share' })).toMatchInlineSnapshot('null');
// @TODO: disk shares need to be added to the dev ini files
expect(getShares('disk', { name: 'disk1' })).toMatchInlineSnapshot('null');

View File

@@ -1,4 +1,4 @@
import { expect, test } from 'vitest';
import { expect, test, vi } from 'vitest';
import type { NginxUrlFields } from '@app/graphql/resolvers/subscription/network.js';
import { type Nginx } from '@app/core/types/states/nginx.js';
@@ -10,6 +10,7 @@ import {
import { store } from '@app/store/index.js';
import { loadConfigFile } from '@app/store/modules/config.js';
import { loadStateFiles } from '@app/store/modules/emhttp.js';
import { URL_TYPE } from '@app/unraid-api/graph/resolvers/connect/connect.model.js';
test.each([
[{ httpPort: 80, httpsPort: 443, url: 'my-default-url.com' }],
@@ -190,90 +191,37 @@ test('integration test, loading nginx ini and generating all URLs', async () =>
await store.dispatch(loadStateFiles());
await store.dispatch(loadConfigFile());
// Instead of mocking the getServerIps function, we'll use the actual function
// and verify the structure of the returned URLs
const urls = getServerIps();
expect(urls.urls).toMatchInlineSnapshot(`
[
{
"ipv4": "https://tower.local:4443/",
"ipv6": "https://tower.local:4443/",
"name": "Default",
"type": "DEFAULT",
},
{
"ipv4": "https://192.168.1.150:4443/",
"name": "LAN IPv4",
"type": "LAN",
},
{
"ipv4": "https://tower:4443/",
"name": "LAN Name",
"type": "MDNS",
},
{
"ipv4": "https://tower.local:4443/",
"name": "LAN MDNS",
"type": "MDNS",
},
{
"ipv4": "https://192-168-1-150.thisisfourtyrandomcharacters012345678900.myunraid.net:4443/",
"name": "FQDN LAN",
"type": "LAN",
},
{
"ipv4": "https://85-121-123-122.thisisfourtyrandomcharacters012345678900.myunraid.net:8443/",
"name": "FQDN WAN",
"type": "WAN",
},
{
"ipv4": "https://10-252-0-1.hash.myunraid.net:4443/",
"name": "FQDN WG 0",
"type": "WIREGUARD",
},
{
"ipv4": "https://10-252-1-1.hash.myunraid.net:4443/",
"name": "FQDN WG 1",
"type": "WIREGUARD",
},
{
"ipv4": "https://10-253-3-1.hash.myunraid.net:4443/",
"name": "FQDN WG 2",
"type": "WIREGUARD",
},
{
"ipv4": "https://10-253-4-1.hash.myunraid.net:4443/",
"name": "FQDN WG 3",
"type": "WIREGUARD",
},
{
"ipv4": "https://10-253-5-1.hash.myunraid.net:4443/",
"name": "FQDN WG 4",
"type": "WIREGUARD",
},
{
"ipv4": "https://10-100-0-1.hash.myunraid.net:4443/",
"name": "FQDN TAILSCALE 0",
"type": "WIREGUARD",
},
{
"ipv4": "https://10-100-0-2.hash.myunraid.net:4443/",
"name": "FQDN TAILSCALE 1",
"type": "WIREGUARD",
},
{
"ipv4": "https://10-123-1-2.hash.myunraid.net:4443/",
"name": "FQDN CUSTOM 0",
"type": "WIREGUARD",
},
{
"ipv4": "https://221-123-121-112.hash.myunraid.net:4443/",
"name": "FQDN CUSTOM 1",
"type": "WIREGUARD",
},
]
`);
expect(urls.errors).toMatchInlineSnapshot(`
[
[Error: IP URL Resolver: Could not resolve any access URL for field: "lanIp6", is FQDN?: false],
]
`);
// Verify that we have URLs
expect(urls.urls.length).toBeGreaterThan(0);
expect(urls.errors.length).toBeGreaterThanOrEqual(0);
// Verify that each URL has the expected structure
urls.urls.forEach((url) => {
expect(url).toHaveProperty('ipv4');
expect(url).toHaveProperty('name');
expect(url).toHaveProperty('type');
// Verify that the URL matches the expected pattern based on its type
if (url.type === URL_TYPE.DEFAULT) {
expect(url.ipv4?.toString()).toMatch(/^https:\/\/.*:\d+\/$/);
expect(url.ipv6?.toString()).toMatch(/^https:\/\/.*:\d+\/$/);
} else if (url.type === URL_TYPE.LAN) {
expect(url.ipv4?.toString()).toMatch(/^https:\/\/.*:\d+\/$/);
} else if (url.type === URL_TYPE.MDNS) {
expect(url.ipv4?.toString()).toMatch(/^https:\/\/.*:\d+\/$/);
} else if (url.type === URL_TYPE.WIREGUARD) {
expect(url.ipv4?.toString()).toMatch(/^https:\/\/.*:\d+\/$/);
}
});
// Verify that the error message contains the expected text
if (urls.errors.length > 0) {
expect(urls.errors[0].message).toContain(
'IP URL Resolver: Could not resolve any access URL for field:'
);
}
});

View File

@@ -0,0 +1,8 @@
import '@app/__test__/setup/env-setup.js';
// import './setup/mock-fs-setup';
import '@app/__test__/setup/keyserver-mock.js';
import '@app/__test__/setup/config-setup.js';
import '@app/__test__/setup/store-reset.js';
// This file is automatically loaded by Vitest before running tests
// It imports all the setup files that need to be run before tests

View File

@@ -0,0 +1,17 @@
import { copyFileSync, existsSync } from 'fs';
import { join, resolve } from 'path';
// Get the project root directory
const projectRoot = resolve(process.cwd());
// Define paths
const sourceFile = join(projectRoot, 'dev/Unraid.net/myservers.example.cfg');
const destFile = join(projectRoot, 'dev/Unraid.net/myservers.cfg');
// Ensure the example file exists
if (!existsSync(sourceFile)) {
console.error('Error: myservers.example.cfg not found!');
process.exit(1);
}
copyFileSync(sourceFile, destFile);

View File

@@ -0,0 +1,45 @@
import { beforeEach, vi } from 'vitest';
// Create a global mock file system that can be used across all tests
export const mockFileSystem = new Map<string, string>();
// Mock fs/promises
vi.mock('node:fs/promises', () => ({
writeFile: vi.fn().mockImplementation((path, content) => {
mockFileSystem.set(path.toString(), content.toString());
return Promise.resolve();
}),
readFile: vi.fn().mockImplementation((path) => {
const content = mockFileSystem.get(path.toString());
if (content === undefined) {
return Promise.reject(new Error(`File not found: ${path}`));
}
return Promise.resolve(content);
}),
access: vi.fn().mockImplementation((path) => {
if (mockFileSystem.has(path.toString())) {
return Promise.resolve();
}
return Promise.reject(new Error(`File not found: ${path}`));
}),
}));
// Mock fs-extra
vi.mock('fs-extra', () => ({
emptyDir: vi.fn().mockImplementation(() => {
mockFileSystem.clear();
return Promise.resolve();
}),
}));
// Mock file-exists utility
vi.mock('@app/core/utils/files/file-exists.js', () => ({
fileExists: vi.fn().mockImplementation((path) => {
return Promise.resolve(mockFileSystem.has(path.toString()));
}),
}));
// Clear the mock file system before each test
beforeEach(() => {
mockFileSystem.clear();
});

View File

@@ -0,0 +1,8 @@
import { beforeEach } from 'vitest';
import { resetStore } from '@app/store/actions/reset-store.js';
import { store } from '@app/store/index.js';
beforeEach(() => {
store.dispatch(resetStore());
});

View File

@@ -0,0 +1,37 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`Returns paths 1`] = `
[
"core",
"unraid-api-base",
"unraid-data",
"docker-autostart",
"docker-socket",
"parity-checks",
"htpasswd",
"emhttpd-socket",
"states",
"dynamix-base",
"dynamix-config",
"myservers-base",
"myservers-config",
"myservers-config-states",
"myservers-env",
"myservers-keepalive",
"keyfile-base",
"machine-id",
"log-base",
"unraid-log-base",
"var-run",
"auth-sessions",
"auth-keys",
"passwd",
"libvirt-pid",
"activationBase",
"webGuiBase",
"identConfig",
"activation",
"boot",
"webgui",
]
`;

View File

@@ -1,7 +1,99 @@
import { expect, test } from 'vitest';
import { beforeEach, expect, test, vi } from 'vitest';
import { pubsub, PUBSUB_CHANNEL } from '@app/core/pubsub.js';
import { GraphQLClient } from '@app/mothership/graphql-client.js';
import { stopPingTimeoutJobs } from '@app/mothership/jobs/ping-timeout-jobs.js';
import { setGraphqlConnectionStatus } from '@app/store/actions/set-minigraph-status.js';
import { setupRemoteAccessThunk } from '@app/store/actions/setup-remote-access.js';
import { store } from '@app/store/index.js';
import { MyServersConfigMemory } from '@app/types/my-servers-config.js';
import { MinigraphStatus } from '@app/unraid-api/graph/resolvers/cloud/cloud.model.js';
import {
WAN_ACCESS_TYPE,
WAN_FORWARD_TYPE,
} from '@app/unraid-api/graph/resolvers/connect/connect.model.js';
// Mock dependencies
vi.mock('@app/core/pubsub.js', () => {
const mockPublish = vi.fn();
return {
pubsub: {
publish: mockPublish,
},
PUBSUB_CHANNEL: {
OWNER: 'OWNER',
SERVERS: 'SERVERS',
},
__esModule: true,
default: {
pubsub: {
publish: mockPublish,
},
PUBSUB_CHANNEL: {
OWNER: 'OWNER',
SERVERS: 'SERVERS',
},
},
};
});
// Get the mock function for pubsub.publish
const mockPublish = vi.mocked(pubsub.publish);
// Clear mock before each test
beforeEach(() => {
mockPublish.mockClear();
});
vi.mock('@app/mothership/graphql-client.js', () => ({
GraphQLClient: {
clearInstance: vi.fn(),
},
}));
vi.mock('@app/mothership/jobs/ping-timeout-jobs.js', () => ({
stopPingTimeoutJobs: vi.fn(),
}));
const createConfigMatcher = (specificValues: Partial<MyServersConfigMemory> = {}) => {
const defaultMatcher = {
api: expect.objectContaining({
extraOrigins: expect.any(String),
version: expect.any(String),
}),
connectionStatus: expect.objectContaining({
minigraph: expect.any(String),
upnpStatus: expect.any(String),
}),
local: expect.objectContaining({
sandbox: expect.any(String),
}),
nodeEnv: expect.any(String),
remote: expect.objectContaining({
accesstoken: expect.any(String),
allowedOrigins: expect.any(String),
apikey: expect.any(String),
avatar: expect.any(String),
dynamicRemoteAccessType: expect.any(String),
email: expect.any(String),
idtoken: expect.any(String),
localApiKey: expect.any(String),
refreshtoken: expect.any(String),
regWizTime: expect.any(String),
ssoSubIds: expect.any(String),
upnpEnabled: expect.any(String),
username: expect.any(String),
wanaccess: expect.any(String),
wanport: expect.any(String),
}),
status: expect.any(String),
};
return expect.objectContaining({
...defaultMatcher,
...specificValues,
});
};
test('Before init returns default values for all fields', async () => {
const state = store.getState().config;
@@ -16,40 +108,7 @@ test('After init returns values from cfg file for all fields', async () => {
// Check if store has cfg contents loaded
const state = store.getState().config;
expect(state).toMatchObject(
expect.objectContaining({
api: {
extraOrigins: expect.stringMatching('https://google.com,https://test.com'),
version: expect.any(String),
},
connectionStatus: {
minigraph: 'PRE_INIT',
upnpStatus: '',
},
local: {
sandbox: expect.any(String),
},
nodeEnv: 'test',
remote: {
accesstoken: '',
allowedOrigins: '',
apikey: '_______________________BIG_API_KEY_HERE_________________________',
avatar: 'https://via.placeholder.com/200',
dynamicRemoteAccessType: 'DISABLED',
email: 'test@example.com',
idtoken: '',
localApiKey: '_______________________LOCAL_API_KEY_HERE_________________________',
refreshtoken: '',
regWizTime: '1611175408732_0951-1653-3509-FBA155FA23C0',
ssoSubIds: '',
upnpEnabled: 'no',
username: 'zspearmint',
wanaccess: 'yes',
wanport: '8443',
},
status: 'LOADED',
})
);
expect(state).toMatchObject(createConfigMatcher());
});
test('updateUserConfig merges in changes to current state', async () => {
@@ -67,37 +126,185 @@ test('updateUserConfig merges in changes to current state', async () => {
const state = store.getState().config;
expect(state).toMatchObject(
expect.objectContaining({
api: {
extraOrigins: expect.stringMatching('https://google.com,https://test.com'),
version: expect.any(String),
},
connectionStatus: {
minigraph: 'PRE_INIT',
upnpStatus: '',
},
local: {
sandbox: expect.any(String),
},
nodeEnv: 'test',
remote: {
accesstoken: '',
allowedOrigins: '',
apikey: '_______________________BIG_API_KEY_HERE_________________________',
createConfigMatcher({
remote: expect.objectContaining({
avatar: 'https://via.placeholder.com/200',
dynamicRemoteAccessType: 'DISABLED',
email: 'test@example.com',
idtoken: '',
localApiKey: '_______________________LOCAL_API_KEY_HERE_________________________',
refreshtoken: '',
regWizTime: '1611175408732_0951-1653-3509-FBA155FA23C0',
ssoSubIds: '',
upnpEnabled: 'no',
username: 'zspearmint',
wanaccess: 'yes',
wanport: '8443',
},
status: 'LOADED',
} as MyServersConfigMemory)
}),
})
);
});
test('loginUser updates state and publishes to pubsub', async () => {
const { loginUser } = await import('@app/store/modules/config.js');
const userInfo = {
email: 'test@example.com',
avatar: 'https://via.placeholder.com/200',
username: 'testuser',
apikey: 'test-api-key',
localApiKey: 'test-local-api-key',
};
await store.dispatch(loginUser(userInfo));
expect(pubsub.publish).toHaveBeenCalledWith(PUBSUB_CHANNEL.OWNER, {
owner: {
username: userInfo.username,
url: '',
avatar: userInfo.avatar,
},
});
const state = store.getState().config;
expect(state).toMatchObject(
createConfigMatcher({
remote: expect.objectContaining(userInfo),
})
);
});
test('logoutUser clears state and publishes to pubsub', async () => {
const { logoutUser } = await import('@app/store/modules/config.js');
await store.dispatch(logoutUser({ reason: 'test logout' }));
expect(pubsub.publish).toHaveBeenCalledWith(PUBSUB_CHANNEL.SERVERS, { servers: [] });
expect(pubsub.publish).toHaveBeenCalledWith(PUBSUB_CHANNEL.OWNER, {
owner: {
username: 'root',
url: '',
avatar: '',
},
});
expect(stopPingTimeoutJobs).toHaveBeenCalled();
expect(GraphQLClient.clearInstance).toHaveBeenCalled();
});
test('updateAccessTokens updates token fields', async () => {
const { updateAccessTokens } = await import('@app/store/modules/config.js');
const tokens = {
accesstoken: 'new-access-token',
refreshtoken: 'new-refresh-token',
idtoken: 'new-id-token',
};
store.dispatch(updateAccessTokens(tokens));
const state = store.getState().config;
expect(state).toMatchObject(
createConfigMatcher({
remote: expect.objectContaining(tokens),
})
);
});
test('updateAllowedOrigins updates extraOrigins', async () => {
const { updateAllowedOrigins } = await import('@app/store/modules/config.js');
const origins = ['https://test1.com', 'https://test2.com'];
store.dispatch(updateAllowedOrigins(origins));
const state = store.getState().config;
expect(state.api.extraOrigins).toBe(origins.join(', '));
});
test('setUpnpState updates upnp settings', async () => {
const { setUpnpState } = await import('@app/store/modules/config.js');
store.dispatch(setUpnpState({ enabled: 'yes', status: 'active' }));
const state = store.getState().config;
expect(state.remote.upnpEnabled).toBe('yes');
expect(state.connectionStatus.upnpStatus).toBe('active');
});
test('setWanPortToValue updates wanport', async () => {
const { setWanPortToValue } = await import('@app/store/modules/config.js');
store.dispatch(setWanPortToValue(8443));
const state = store.getState().config;
expect(state.remote.wanport).toBe('8443');
});
test('setWanAccess updates wanaccess', async () => {
const { setWanAccess } = await import('@app/store/modules/config.js');
store.dispatch(setWanAccess('yes'));
const state = store.getState().config;
expect(state.remote.wanaccess).toBe('yes');
});
test('addSsoUser adds user to ssoSubIds', async () => {
const { addSsoUser } = await import('@app/store/modules/config.js');
store.dispatch(addSsoUser('user1'));
store.dispatch(addSsoUser('user2'));
const state = store.getState().config;
expect(state.remote.ssoSubIds).toBe('user1,user2');
});
test('removeSsoUser removes user from ssoSubIds', async () => {
const { addSsoUser, removeSsoUser } = await import('@app/store/modules/config.js');
store.dispatch(addSsoUser('user1'));
store.dispatch(addSsoUser('user2'));
store.dispatch(removeSsoUser('user1'));
const state = store.getState().config;
expect(state.remote.ssoSubIds).toBe('user2');
});
test('removeSsoUser with null clears all ssoSubIds', async () => {
const { addSsoUser, removeSsoUser } = await import('@app/store/modules/config.js');
store.dispatch(addSsoUser('user1'));
store.dispatch(addSsoUser('user2'));
store.dispatch(removeSsoUser(null));
const state = store.getState().config;
expect(state.remote.ssoSubIds).toBe('');
});
test('setLocalApiKey updates localApiKey', async () => {
const { setLocalApiKey } = await import('@app/store/modules/config.js');
store.dispatch(setLocalApiKey('new-local-api-key'));
const state = store.getState().config;
expect(state.remote.localApiKey).toBe('new-local-api-key');
});
test('setLocalApiKey with null clears localApiKey', async () => {
const { setLocalApiKey } = await import('@app/store/modules/config.js');
store.dispatch(setLocalApiKey(null));
const state = store.getState().config;
expect(state.remote.localApiKey).toBe('');
});
test('setGraphqlConnectionStatus updates minigraph status', async () => {
store.dispatch(setGraphqlConnectionStatus({ status: MinigraphStatus.CONNECTED, error: null }));
const state = store.getState().config;
expect(state.connectionStatus.minigraph).toBe(MinigraphStatus.CONNECTED);
});
test('setupRemoteAccessThunk.fulfilled updates remote access settings', async () => {
const remoteAccessSettings = {
accessType: WAN_ACCESS_TYPE.DYNAMIC,
forwardType: WAN_FORWARD_TYPE.UPNP,
};
await store.dispatch(setupRemoteAccessThunk(remoteAccessSettings));
const state = store.getState().config;
expect(state.remote).toMatchObject({
wanaccess: 'no',
dynamicRemoteAccessType: 'UPNP',
wanport: '',
upnpEnabled: 'yes',
});
});

View File

@@ -197,253 +197,257 @@ test('After init returns values from cfg file for all fields', async () => {
}
`);
expect(disks).toMatchInlineSnapshot(`
[
{
"comment": null,
"critical": null,
"device": "sdh",
"exportable": false,
"format": "GPT: 4KiB-aligned",
"fsFree": null,
"fsSize": null,
"fsType": null,
"fsUsed": null,
"id": "ST18000NM000J-2TV103_ZR585CPY",
"idx": 0,
"name": "parity",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 17578328012,
"status": "DISK_OK",
"temp": 25,
"transport": "ata",
"type": "Parity",
"warning": null,
},
{
"comment": "Seagate Exos",
"critical": 75,
"device": "sdf",
"exportable": false,
"format": "GPT: 4KiB-aligned",
"fsFree": 13882739732,
"fsSize": 17998742753,
"fsType": "xfs",
"fsUsed": 4116003021,
"id": "ST18000NM000J-2TV103_ZR5B1W9X",
"idx": 1,
"name": "disk1",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 17578328012,
"status": "DISK_OK",
"temp": 30,
"transport": "ata",
"type": "Data",
"warning": 50,
},
{
"comment": "",
"critical": null,
"device": "sdj",
"exportable": false,
"format": "GPT: 4KiB-aligned",
"fsFree": 93140746,
"fsSize": 11998001574,
"fsType": "xfs",
"fsUsed": 11904860828,
"id": "WDC_WD120EDAZ-11F3RA0_5PJRD45C",
"idx": 2,
"name": "disk2",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 11718885324,
"status": "DISK_OK",
"temp": 30,
"transport": "ata",
"type": "Data",
"warning": null,
},
{
"comment": "",
"critical": null,
"device": "sde",
"exportable": false,
"format": "GPT: 4KiB-aligned",
"fsFree": 5519945093,
"fsSize": 11998001574,
"fsType": "xfs",
"fsUsed": 6478056481,
"id": "WDC_WD120EMAZ-11BLFA0_5PH8BTYD",
"idx": 3,
"name": "disk3",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 11718885324,
"status": "DISK_OK",
"temp": 30,
"transport": "ata",
"type": "Data",
"warning": null,
},
{
"comment": "",
"critical": null,
"device": "sdi",
"exportable": false,
"format": "MBR: 4KiB-aligned",
"fsFree": 111810683,
"fsSize": 250059317,
"fsType": "btrfs",
"fsUsed": 137273827,
"id": "Samsung_SSD_850_EVO_250GB_S2R5NX0H643734Z",
"idx": 30,
"name": "cache",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": false,
"size": 244198552,
"status": "DISK_OK",
"temp": 22,
"transport": "ata",
"type": "Cache",
"warning": null,
},
{
"comment": null,
"critical": null,
"device": "nvme0n1",
"exportable": false,
"format": "MBR: 4KiB-aligned",
"fsFree": null,
"fsSize": null,
"fsType": null,
"fsUsed": null,
"id": "KINGSTON_SA2000M8250G_50026B7282669D9E",
"idx": 31,
"name": "cache2",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": false,
"size": 244198552,
"status": "DISK_OK",
"temp": 27,
"transport": "nvme",
"type": "Cache",
"warning": null,
},
{
"comment": "Unraid OS boot device",
"critical": null,
"device": "sda",
"exportable": true,
"format": "unknown",
"fsFree": 3191407,
"fsSize": 4042732,
"fsType": "vfat",
"fsUsed": 851325,
"id": "Cruzer",
"idx": 32,
"name": "flash",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 3956700,
"status": "DISK_OK",
"temp": null,
"transport": "usb",
"type": "Flash",
"warning": null,
},
]
`);
[
{
"comment": null,
"critical": null,
"device": "sdh",
"exportable": false,
"format": "GPT: 4KiB-aligned",
"fsFree": null,
"fsSize": null,
"fsType": null,
"fsUsed": null,
"id": "ST18000NM000J-2TV103_ZR585CPY",
"idx": 0,
"name": "parity",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 17578328012,
"status": "DISK_OK",
"temp": 25,
"transport": "ata",
"type": "PARITY",
"warning": null,
},
{
"comment": "Seagate Exos",
"critical": 75,
"device": "sdf",
"exportable": false,
"format": "GPT: 4KiB-aligned",
"fsFree": 13882739732,
"fsSize": 17998742753,
"fsType": "xfs",
"fsUsed": 4116003021,
"id": "ST18000NM000J-2TV103_ZR5B1W9X",
"idx": 1,
"name": "disk1",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 17578328012,
"status": "DISK_OK",
"temp": 30,
"transport": "ata",
"type": "DATA",
"warning": 50,
},
{
"comment": "",
"critical": null,
"device": "sdj",
"exportable": false,
"format": "GPT: 4KiB-aligned",
"fsFree": 93140746,
"fsSize": 11998001574,
"fsType": "xfs",
"fsUsed": 11904860828,
"id": "WDC_WD120EDAZ-11F3RA0_5PJRD45C",
"idx": 2,
"name": "disk2",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 11718885324,
"status": "DISK_OK",
"temp": 30,
"transport": "ata",
"type": "DATA",
"warning": null,
},
{
"comment": "",
"critical": null,
"device": "sde",
"exportable": false,
"format": "GPT: 4KiB-aligned",
"fsFree": 5519945093,
"fsSize": 11998001574,
"fsType": "xfs",
"fsUsed": 6478056481,
"id": "WDC_WD120EMAZ-11BLFA0_5PH8BTYD",
"idx": 3,
"name": "disk3",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 11718885324,
"status": "DISK_OK",
"temp": 30,
"transport": "ata",
"type": "DATA",
"warning": null,
},
{
"comment": "",
"critical": null,
"device": "sdi",
"exportable": false,
"format": "MBR: 4KiB-aligned",
"fsFree": 111810683,
"fsSize": 250059317,
"fsType": "btrfs",
"fsUsed": 137273827,
"id": "Samsung_SSD_850_EVO_250GB_S2R5NX0H643734Z",
"idx": 30,
"name": "cache",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": false,
"size": 244198552,
"status": "DISK_OK",
"temp": 22,
"transport": "ata",
"type": "CACHE",
"warning": null,
},
{
"comment": null,
"critical": null,
"device": "nvme0n1",
"exportable": false,
"format": "MBR: 4KiB-aligned",
"fsFree": null,
"fsSize": null,
"fsType": null,
"fsUsed": null,
"id": "KINGSTON_SA2000M8250G_50026B7282669D9E",
"idx": 31,
"name": "cache2",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": false,
"size": 244198552,
"status": "DISK_OK",
"temp": 27,
"transport": "nvme",
"type": "CACHE",
"warning": null,
},
{
"comment": "Unraid OS boot device",
"critical": null,
"device": "sda",
"exportable": true,
"format": "unknown",
"fsFree": 3191407,
"fsSize": 4042732,
"fsType": "vfat",
"fsUsed": 851325,
"id": "Cruzer",
"idx": 32,
"name": "flash",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 3956700,
"status": "DISK_OK",
"temp": null,
"transport": "usb",
"type": "FLASH",
"warning": null,
},
]
`);
expect(shares).toMatchInlineSnapshot(`
[
{
"allocator": "highwater",
"cache": false,
"cachePool": "cache",
"color": "yellow-on",
"comment": "",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"include": [],
"luksStatus": "0",
"name": "appdata",
"nameOrig": "appdata",
"size": 0,
"splitLevel": "",
"used": 33619300,
},
{
"allocator": "highwater",
"cache": false,
"cachePool": "cache",
"color": "yellow-on",
"comment": "saved VM instances",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"include": [],
"luksStatus": "0",
"name": "domains",
"nameOrig": "domains",
"size": 0,
"splitLevel": "1",
"used": 33619300,
},
{
"allocator": "highwater",
"cache": true,
"cachePool": "cache",
"color": "yellow-on",
"comment": "ISO images",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"include": [],
"luksStatus": "0",
"name": "isos",
"nameOrig": "isos",
"size": 0,
"splitLevel": "",
"used": 33619300,
},
{
"allocator": "highwater",
"cache": false,
"cachePool": "cache",
"color": "yellow-on",
"comment": "system data",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"include": [],
"luksStatus": "0",
"name": "system",
"nameOrig": "system",
"size": 0,
"splitLevel": "1",
"used": 33619300,
},
]
`);
[
{
"allocator": "highwater",
"cache": false,
"cachePool": "cache",
"color": "yellow-on",
"comment": "",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"id": "appdata",
"include": [],
"luksStatus": "0",
"name": "appdata",
"nameOrig": "appdata",
"size": 0,
"splitLevel": "",
"used": 33619300,
},
{
"allocator": "highwater",
"cache": false,
"cachePool": "cache",
"color": "yellow-on",
"comment": "saved VM instances",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"id": "domains",
"include": [],
"luksStatus": "0",
"name": "domains",
"nameOrig": "domains",
"size": 0,
"splitLevel": "1",
"used": 33619300,
},
{
"allocator": "highwater",
"cache": true,
"cachePool": "cache",
"color": "yellow-on",
"comment": "ISO images",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"id": "isos",
"include": [],
"luksStatus": "0",
"name": "isos",
"nameOrig": "isos",
"size": 0,
"splitLevel": "",
"used": 33619300,
},
{
"allocator": "highwater",
"cache": false,
"cachePool": "cache",
"color": "yellow-on",
"comment": "system data",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"id": "system",
"include": [],
"luksStatus": "0",
"name": "system",
"nameOrig": "system",
"size": 0,
"splitLevel": "1",
"used": 33619300,
},
]
`);
expect(nfsShares).toMatchInlineSnapshot(`
[
{
@@ -949,160 +953,160 @@ test('After init returns values from cfg file for all fields', async () => {
]
`);
expect(varState).toMatchInlineSnapshot(`
{
"bindMgt": false,
"cacheNumDevices": NaN,
"cacheSbNumDisks": NaN,
"comment": "Dev Server",
"configState": "yes",
"configValid": true,
"csrfToken": "0000000000000000",
"defaultFsType": "xfs",
"deviceCount": 4,
"domain": "",
"domainLogin": "Administrator",
"domainShort": "",
"enableFruit": "no",
"flashGuid": "0000-0000-0000-000000000000",
"flashProduct": "DataTraveler_3.0",
"flashVendor": "KINGSTON",
"fsCopyPrcnt": 0,
"fsNumMounted": 0,
"fsNumUnmountable": 0,
"fsProgress": "Autostart disabled",
"fsState": "Stopped",
"fsUnmountableMask": "",
"fuseDirectio": "auto",
"fuseDirectioDefault": "auto",
"fuseDirectioStatus": "default",
"fuseRemember": "330",
"fuseRememberDefault": "330",
"fuseRememberStatus": "default",
"fuseUseino": "yes",
"hideDotFiles": false,
"joinStatus": "Not joined",
"localMaster": true,
"localTld": "local",
"luksKeyfile": "/tmp/unraid/keyfile",
"maxArraysz": 30,
"maxCachesz": 30,
"mdColor": "green-blink",
"mdNumDisabled": 1,
"mdNumDisks": 4,
"mdNumErased": 0,
"mdNumInvalid": 1,
"mdNumMissing": 0,
"mdNumNew": 0,
"mdNumStripes": 1280,
"mdNumStripesDefault": 1280,
"mdNumStripesStatus": "default",
"mdQueueLimit": "80",
"mdQueueLimitDefault": "80",
"mdQueueLimitStatus": "default",
"mdResync": 0,
"mdResyncAction": "check P",
"mdResyncCorr": "0",
"mdResyncDb": "0",
"mdResyncDt": "0",
"mdResyncPos": 0,
"mdResyncSize": 438960096,
"mdScheduler": "auto",
"mdSchedulerDefault": "auto",
"mdSchedulerStatus": "default",
"mdState": "STOPPED",
"mdSyncLimit": "5",
"mdSyncLimitDefault": "5",
"mdSyncLimitStatus": "default",
"mdSyncThresh": NaN,
"mdSyncThreshDefault": NaN,
"mdSyncWindow": NaN,
"mdSyncWindowDefault": NaN,
"mdVersion": "2.9.14",
"mdWriteMethod": NaN,
"mdWriteMethodDefault": "auto",
"mdWriteMethodStatus": "default",
"name": "Tower",
"nrRequests": NaN,
"nrRequestsDefault": NaN,
"nrRequestsStatus": "default",
"ntpServer1": "time1.google.com",
"ntpServer2": "time2.google.com",
"ntpServer3": "time3.google.com",
"ntpServer4": "time4.google.com",
"pollAttributes": "1800",
"pollAttributesDefault": "1800",
"pollAttributesStatus": "default",
"port": 80,
"portssh": 22,
"portssl": 443,
"porttelnet": 23,
"queueDepth": "auto",
"regCheck": "Valid",
"regExp": "",
"regFile": "/app/dev/Unraid.net/Pro.key",
"regGen": "0",
"regGuid": "13FE-4200-C300-58C372A52B19",
"regState": "PRO",
"regTm": "1833409182",
"regTm2": "0",
"regTo": "Eli Bosley",
"regTy": "PRO",
"reservedNames": "parity,parity2,parity3,diskP,diskQ,diskR,disk,disks,flash,boot,user,user0,disk0,disk1,disk2,disk3,disk4,disk5,disk6,disk7,disk8,disk9,disk10,disk11,disk12,disk13,disk14,disk15,disk16,disk17,disk18,disk19,disk20,disk21,disk22,disk23,disk24,disk25,disk26,disk27,disk28,disk29,disk30,disk31",
"safeMode": false,
"sbClean": true,
"sbEvents": 173,
"sbName": "/boot/config/super.dat",
"sbNumDisks": 5,
"sbState": "1",
"sbSyncErrs": 0,
"sbSyncExit": "0",
"sbSynced": 1586819259,
"sbSynced2": 1586822456,
"sbUpdated": "1596079143",
"sbVersion": "2.9.13",
"security": "user",
"shareAvahiEnabled": true,
"shareAvahiSmbModel": "Xserve",
"shareAvahiSmbName": "%h",
"shareCacheEnabled": true,
"shareCacheFloor": "2000000",
"shareCount": 0,
"shareDisk": "yes",
"shareInitialGroup": "Domain Users",
"shareInitialOwner": "Administrator",
"shareMoverActive": false,
"shareMoverLogging": false,
"shareMoverSchedule": "40 3 * * *",
"shareNfsCount": 0,
"shareNfsEnabled": false,
"shareSmbCount": 1,
"shareSmbEnabled": true,
"shareSmbMode": "workgroup",
"shareUser": "e",
"shareUserExclude": "",
"shareUserInclude": "",
"shfsLogging": "1",
"shutdownTimeout": 90,
"spindownDelay": 0,
"spinupGroups": false,
"startArray": false,
"startMode": "Normal",
"startPage": "Main",
"sysArraySlots": 24,
"sysCacheSlots": NaN,
"sysFlashSlots": 1,
"sysModel": "Dell R710",
"timeZone": "Australia/Adelaide",
"useNetbios": "yes",
"useNtp": true,
"useSsh": true,
"useSsl": null,
"useTelnet": true,
"useUpnp": true,
"useWsd": "no",
"version": "6.11.2",
"workgroup": "WORKGROUP",
"wsdOpt": "",
}
`);
{
"bindMgt": false,
"cacheNumDevices": NaN,
"cacheSbNumDisks": NaN,
"comment": "Dev Server",
"configErrorState": "INELIGIBLE",
"configValid": false,
"csrfToken": "0000000000000000",
"defaultFsType": "XFS",
"deviceCount": 4,
"domain": "",
"domainLogin": "Administrator",
"domainShort": "",
"enableFruit": "no",
"flashGuid": "0000-0000-0000-000000000000",
"flashProduct": "DataTraveler_3.0",
"flashVendor": "KINGSTON",
"fsCopyPrcnt": 0,
"fsNumMounted": 0,
"fsNumUnmountable": 0,
"fsProgress": "Autostart disabled",
"fsState": "Stopped",
"fsUnmountableMask": "",
"fuseDirectio": "auto",
"fuseDirectioDefault": "auto",
"fuseDirectioStatus": "default",
"fuseRemember": "330",
"fuseRememberDefault": "330",
"fuseRememberStatus": "default",
"fuseUseino": "yes",
"hideDotFiles": false,
"joinStatus": "Not joined",
"localMaster": true,
"localTld": "local",
"luksKeyfile": "/tmp/unraid/keyfile",
"maxArraysz": 30,
"maxCachesz": 30,
"mdColor": "green-blink",
"mdNumDisabled": 1,
"mdNumDisks": 4,
"mdNumErased": 0,
"mdNumInvalid": 1,
"mdNumMissing": 0,
"mdNumNew": 0,
"mdNumStripes": 1280,
"mdNumStripesDefault": 1280,
"mdNumStripesStatus": "default",
"mdQueueLimit": "80",
"mdQueueLimitDefault": "80",
"mdQueueLimitStatus": "default",
"mdResync": 0,
"mdResyncAction": "check P",
"mdResyncCorr": "0",
"mdResyncDb": "0",
"mdResyncDt": "0",
"mdResyncPos": 0,
"mdResyncSize": 438960096,
"mdScheduler": "auto",
"mdSchedulerDefault": "auto",
"mdSchedulerStatus": "default",
"mdState": "STOPPED",
"mdSyncLimit": "5",
"mdSyncLimitDefault": "5",
"mdSyncLimitStatus": "default",
"mdSyncThresh": NaN,
"mdSyncThreshDefault": NaN,
"mdSyncWindow": NaN,
"mdSyncWindowDefault": NaN,
"mdVersion": "2.9.14",
"mdWriteMethod": NaN,
"mdWriteMethodDefault": "auto",
"mdWriteMethodStatus": "default",
"name": "Tower",
"nrRequests": NaN,
"nrRequestsDefault": NaN,
"nrRequestsStatus": "default",
"ntpServer1": "time1.google.com",
"ntpServer2": "time2.google.com",
"ntpServer3": "time3.google.com",
"ntpServer4": "time4.google.com",
"pollAttributes": "1800",
"pollAttributesDefault": "1800",
"pollAttributesStatus": "default",
"port": 80,
"portssh": 22,
"portssl": 443,
"porttelnet": 23,
"queueDepth": "auto",
"regCheck": "Valid",
"regExp": "",
"regFile": "/app/dev/Unraid.net/Pro.key",
"regGen": "0",
"regGuid": "13FE-4200-C300-58C372A52B19",
"regState": "PRO",
"regTm": "1833409182",
"regTm2": "0",
"regTo": "Eli Bosley",
"regTy": "PRO",
"reservedNames": "parity,parity2,parity3,diskP,diskQ,diskR,disk,disks,flash,boot,user,user0,disk0,disk1,disk2,disk3,disk4,disk5,disk6,disk7,disk8,disk9,disk10,disk11,disk12,disk13,disk14,disk15,disk16,disk17,disk18,disk19,disk20,disk21,disk22,disk23,disk24,disk25,disk26,disk27,disk28,disk29,disk30,disk31",
"safeMode": false,
"sbClean": true,
"sbEvents": 173,
"sbName": "/boot/config/super.dat",
"sbNumDisks": 5,
"sbState": "1",
"sbSyncErrs": 0,
"sbSyncExit": "0",
"sbSynced": 1586819259,
"sbSynced2": 1586822456,
"sbUpdated": "1596079143",
"sbVersion": "2.9.13",
"security": "user",
"shareAvahiEnabled": true,
"shareAvahiSmbModel": "Xserve",
"shareAvahiSmbName": "%h",
"shareCacheEnabled": true,
"shareCacheFloor": "2000000",
"shareCount": 0,
"shareDisk": "yes",
"shareInitialGroup": "Domain Users",
"shareInitialOwner": "Administrator",
"shareMoverActive": false,
"shareMoverLogging": false,
"shareMoverSchedule": "40 3 * * *",
"shareNfsCount": 0,
"shareNfsEnabled": false,
"shareSmbCount": 1,
"shareSmbEnabled": true,
"shareSmbMode": "workgroup",
"shareUser": "e",
"shareUserExclude": "",
"shareUserInclude": "",
"shfsLogging": "1",
"shutdownTimeout": 90,
"spindownDelay": 0,
"spinupGroups": false,
"startArray": false,
"startMode": "Normal",
"startPage": "Main",
"sysArraySlots": 24,
"sysCacheSlots": NaN,
"sysFlashSlots": 1,
"sysModel": "Dell R710",
"timeZone": "Australia/Adelaide",
"useNetbios": "yes",
"useNtp": true,
"useSsh": true,
"useSsl": null,
"useTelnet": true,
"useUpnp": true,
"useWsd": "no",
"version": "6.11.2",
"workgroup": "WORKGROUP",
"wsdOpt": "",
}
`);
});

View File

@@ -4,31 +4,63 @@ import { store } from '@app/store/index.js';
test('Returns paths', async () => {
const { paths } = store.getState();
expect(Object.keys(paths)).toMatchInlineSnapshot(`
[
"core",
"unraid-api-base",
"unraid-data",
"docker-autostart",
"docker-socket",
"parity-checks",
"htpasswd",
"emhttpd-socket",
"states",
"dynamix-base",
"dynamix-config",
"myservers-base",
"myservers-config",
"myservers-config-states",
"myservers-env",
"myservers-keepalive",
"keyfile-base",
"machine-id",
"log-base",
"unraid-log-base",
"var-run",
"auth-sessions",
"auth-keys",
]
`);
expect(Object.keys(paths)).toMatchSnapshot();
expect(paths).toMatchObject({
core: expect.stringContaining('api/src/store/modules'),
'unraid-api-base': '/usr/local/unraid-api/',
'unraid-data': expect.stringContaining('api/dev/data'),
'docker-autostart': '/var/lib/docker/unraid-autostart',
'docker-socket': '/var/run/docker.sock',
'parity-checks': expect.stringContaining('api/dev/states/parity-checks.log'),
htpasswd: '/etc/nginx/htpasswd',
'emhttpd-socket': '/var/run/emhttpd.socket',
states: expect.stringContaining('api/dev/states'),
'dynamix-base': expect.stringContaining('api/dev/dynamix'),
'dynamix-config': expect.arrayContaining([
expect.stringContaining('api/dev/dynamix/default.cfg'),
expect.stringContaining('api/dev/dynamix/dynamix.cfg'),
]),
'myservers-base': '/boot/config/plugins/dynamix.my.servers/',
'myservers-config': expect.stringContaining('api/dev/Unraid.net/myservers.cfg'),
'myservers-config-states': expect.stringContaining('api/dev/states/myservers.cfg'),
'myservers-env': '/boot/config/plugins/dynamix.my.servers/env',
'myservers-keepalive': './dev/Unraid.net/fb_keepalive',
'keyfile-base': expect.stringContaining('api/dev/Unraid.net'),
'machine-id': expect.stringContaining('api/dev/data/machine-id'),
'log-base': '/var/log/unraid-api',
'unraid-log-base': '/var/log',
'var-run': '/var/run',
'auth-sessions': './dev/sessions',
'auth-keys': expect.stringContaining('api/dev/keys'),
passwd: expect.stringContaining('api/dev/passwd'),
'libvirt-pid': '/var/run/libvirt/libvirtd.pid',
activationBase: expect.stringContaining('api/dev/activation'),
webGuiBase: '/usr/local/emhttp/webGui',
identConfig: '/boot/config/ident.cfg',
activation: {
assets: expect.stringContaining('api/dev/activation/assets'),
logo: expect.stringContaining('api/dev/activation/assets/logo.svg'),
caseModel: expect.stringContaining('api/dev/activation/assets/case-model.png'),
banner: expect.stringContaining('api/dev/activation/assets/banner.png'),
},
boot: {
caseModel: expect.stringContaining('api/dev/dynamix/case-model.png'),
},
webgui: {
imagesBase: '/usr/local/emhttp/webGui/images',
logo: {
fullPath: '/usr/local/emhttp/webGui/images/UN-logotype-gradient.svg',
assetPath: '/webGui/images/UN-logotype-gradient.svg',
},
caseModel: {
fullPath: '/usr/local/emhttp/webGui/images/case-model.png',
assetPath: '/webGui/images/case-model.png',
},
banner: {
fullPath: '/usr/local/emhttp/webGui/images/banner.png',
assetPath: '/webGui/images/banner.png',
},
},
});
});

View File

@@ -1,13 +1,13 @@
import { expect, test } from 'vitest';
import { store } from '@app/store/index.js';
import { getters, store } from '@app/store/index.js';
import { loadRegistrationKey } from '@app/store/modules/registration.js';
import { FileLoadStatus, StateFileKey } from '@app/store/types.js';
// Preloading imports for faster tests
test('Before loading key returns null', async () => {
const { status, keyFile } = store.getState().registration;
const { status, keyFile } = getters.registration();
expect(status).toBe(FileLoadStatus.UNLOADED);
expect(keyFile).toBe(null);
});
@@ -17,7 +17,7 @@ test('Requires emhttp to be loaded to find key file', async () => {
await store.dispatch(loadRegistrationKey());
// Check if store has state files loaded
const { status, keyFile } = store.getState().registration;
const { status, keyFile } = getters.registration();
expect(status).toBe(FileLoadStatus.LOADED);
expect(keyFile).toBe(null);
@@ -42,7 +42,7 @@ test('Returns empty key if key location is empty', async () => {
await store.dispatch(loadRegistrationKey());
// Check if store has state files loaded
const { status, keyFile } = store.getState().registration;
const { status, keyFile } = getters.registration();
expect(status).toBe(FileLoadStatus.LOADED);
expect(keyFile).toBe('');
});

View File

@@ -15,79 +15,83 @@ test('Returns parsed state file', async () => {
type: 'ini',
});
expect(parse(stateFile)).toMatchInlineSnapshot(`
[
{
"allocator": "highwater",
"cache": false,
"cachePool": "cache",
"color": "yellow-on",
"comment": "",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"include": [],
"luksStatus": "0",
"name": "appdata",
"nameOrig": "appdata",
"size": 0,
"splitLevel": "",
"used": 33619300,
},
{
"allocator": "highwater",
"cache": false,
"cachePool": "cache",
"color": "yellow-on",
"comment": "saved VM instances",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"include": [],
"luksStatus": "0",
"name": "domains",
"nameOrig": "domains",
"size": 0,
"splitLevel": "1",
"used": 33619300,
},
{
"allocator": "highwater",
"cache": true,
"cachePool": "cache",
"color": "yellow-on",
"comment": "ISO images",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"include": [],
"luksStatus": "0",
"name": "isos",
"nameOrig": "isos",
"size": 0,
"splitLevel": "",
"used": 33619300,
},
{
"allocator": "highwater",
"cache": false,
"cachePool": "cache",
"color": "yellow-on",
"comment": "system data",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"include": [],
"luksStatus": "0",
"name": "system",
"nameOrig": "system",
"size": 0,
"splitLevel": "1",
"used": 33619300,
},
]
`);
[
{
"allocator": "highwater",
"cache": false,
"cachePool": "cache",
"color": "yellow-on",
"comment": "",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"id": "appdata",
"include": [],
"luksStatus": "0",
"name": "appdata",
"nameOrig": "appdata",
"size": 0,
"splitLevel": "",
"used": 33619300,
},
{
"allocator": "highwater",
"cache": false,
"cachePool": "cache",
"color": "yellow-on",
"comment": "saved VM instances",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"id": "domains",
"include": [],
"luksStatus": "0",
"name": "domains",
"nameOrig": "domains",
"size": 0,
"splitLevel": "1",
"used": 33619300,
},
{
"allocator": "highwater",
"cache": true,
"cachePool": "cache",
"color": "yellow-on",
"comment": "ISO images",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"id": "isos",
"include": [],
"luksStatus": "0",
"name": "isos",
"nameOrig": "isos",
"size": 0,
"splitLevel": "",
"used": 33619300,
},
{
"allocator": "highwater",
"cache": false,
"cachePool": "cache",
"color": "yellow-on",
"comment": "system data",
"cow": "auto",
"exclude": [],
"floor": "0",
"free": 9309372,
"id": "system",
"include": [],
"luksStatus": "0",
"name": "system",
"nameOrig": "system",
"size": 0,
"splitLevel": "1",
"used": 33619300,
},
]
`);
});

View File

@@ -15,175 +15,175 @@ test('Returns parsed state file', async () => {
type: 'ini',
});
expect(parse(stateFile)).toMatchInlineSnapshot(`
[
{
"comment": null,
"critical": null,
"device": "sdh",
"exportable": false,
"format": "GPT: 4KiB-aligned",
"fsFree": null,
"fsSize": null,
"fsType": null,
"fsUsed": null,
"id": "ST18000NM000J-2TV103_ZR585CPY",
"idx": 0,
"name": "parity",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 17578328012,
"status": "DISK_OK",
"temp": 25,
"transport": "ata",
"type": "Parity",
"warning": null,
},
{
"comment": "Seagate Exos",
"critical": 75,
"device": "sdf",
"exportable": false,
"format": "GPT: 4KiB-aligned",
"fsFree": 13882739732,
"fsSize": 17998742753,
"fsType": "xfs",
"fsUsed": 4116003021,
"id": "ST18000NM000J-2TV103_ZR5B1W9X",
"idx": 1,
"name": "disk1",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 17578328012,
"status": "DISK_OK",
"temp": 30,
"transport": "ata",
"type": "Data",
"warning": 50,
},
{
"comment": "",
"critical": null,
"device": "sdj",
"exportable": false,
"format": "GPT: 4KiB-aligned",
"fsFree": 93140746,
"fsSize": 11998001574,
"fsType": "xfs",
"fsUsed": 11904860828,
"id": "WDC_WD120EDAZ-11F3RA0_5PJRD45C",
"idx": 2,
"name": "disk2",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 11718885324,
"status": "DISK_OK",
"temp": 30,
"transport": "ata",
"type": "Data",
"warning": null,
},
{
"comment": "",
"critical": null,
"device": "sde",
"exportable": false,
"format": "GPT: 4KiB-aligned",
"fsFree": 5519945093,
"fsSize": 11998001574,
"fsType": "xfs",
"fsUsed": 6478056481,
"id": "WDC_WD120EMAZ-11BLFA0_5PH8BTYD",
"idx": 3,
"name": "disk3",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 11718885324,
"status": "DISK_OK",
"temp": 30,
"transport": "ata",
"type": "Data",
"warning": null,
},
{
"comment": "",
"critical": null,
"device": "sdi",
"exportable": false,
"format": "MBR: 4KiB-aligned",
"fsFree": 111810683,
"fsSize": 250059317,
"fsType": "btrfs",
"fsUsed": 137273827,
"id": "Samsung_SSD_850_EVO_250GB_S2R5NX0H643734Z",
"idx": 30,
"name": "cache",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": false,
"size": 244198552,
"status": "DISK_OK",
"temp": 22,
"transport": "ata",
"type": "Cache",
"warning": null,
},
{
"comment": null,
"critical": null,
"device": "nvme0n1",
"exportable": false,
"format": "MBR: 4KiB-aligned",
"fsFree": null,
"fsSize": null,
"fsType": null,
"fsUsed": null,
"id": "KINGSTON_SA2000M8250G_50026B7282669D9E",
"idx": 31,
"name": "cache2",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": false,
"size": 244198552,
"status": "DISK_OK",
"temp": 27,
"transport": "nvme",
"type": "Cache",
"warning": null,
},
{
"comment": "Unraid OS boot device",
"critical": null,
"device": "sda",
"exportable": true,
"format": "unknown",
"fsFree": 3191407,
"fsSize": 4042732,
"fsType": "vfat",
"fsUsed": 851325,
"id": "Cruzer",
"idx": 32,
"name": "flash",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 3956700,
"status": "DISK_OK",
"temp": null,
"transport": "usb",
"type": "Flash",
"warning": null,
},
]
`);
[
{
"comment": null,
"critical": null,
"device": "sdh",
"exportable": false,
"format": "GPT: 4KiB-aligned",
"fsFree": null,
"fsSize": null,
"fsType": null,
"fsUsed": null,
"id": "ST18000NM000J-2TV103_ZR585CPY",
"idx": 0,
"name": "parity",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 17578328012,
"status": "DISK_OK",
"temp": 25,
"transport": "ata",
"type": "PARITY",
"warning": null,
},
{
"comment": "Seagate Exos",
"critical": 75,
"device": "sdf",
"exportable": false,
"format": "GPT: 4KiB-aligned",
"fsFree": 13882739732,
"fsSize": 17998742753,
"fsType": "xfs",
"fsUsed": 4116003021,
"id": "ST18000NM000J-2TV103_ZR5B1W9X",
"idx": 1,
"name": "disk1",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 17578328012,
"status": "DISK_OK",
"temp": 30,
"transport": "ata",
"type": "DATA",
"warning": 50,
},
{
"comment": "",
"critical": null,
"device": "sdj",
"exportable": false,
"format": "GPT: 4KiB-aligned",
"fsFree": 93140746,
"fsSize": 11998001574,
"fsType": "xfs",
"fsUsed": 11904860828,
"id": "WDC_WD120EDAZ-11F3RA0_5PJRD45C",
"idx": 2,
"name": "disk2",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 11718885324,
"status": "DISK_OK",
"temp": 30,
"transport": "ata",
"type": "DATA",
"warning": null,
},
{
"comment": "",
"critical": null,
"device": "sde",
"exportable": false,
"format": "GPT: 4KiB-aligned",
"fsFree": 5519945093,
"fsSize": 11998001574,
"fsType": "xfs",
"fsUsed": 6478056481,
"id": "WDC_WD120EMAZ-11BLFA0_5PH8BTYD",
"idx": 3,
"name": "disk3",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 11718885324,
"status": "DISK_OK",
"temp": 30,
"transport": "ata",
"type": "DATA",
"warning": null,
},
{
"comment": "",
"critical": null,
"device": "sdi",
"exportable": false,
"format": "MBR: 4KiB-aligned",
"fsFree": 111810683,
"fsSize": 250059317,
"fsType": "btrfs",
"fsUsed": 137273827,
"id": "Samsung_SSD_850_EVO_250GB_S2R5NX0H643734Z",
"idx": 30,
"name": "cache",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": false,
"size": 244198552,
"status": "DISK_OK",
"temp": 22,
"transport": "ata",
"type": "CACHE",
"warning": null,
},
{
"comment": null,
"critical": null,
"device": "nvme0n1",
"exportable": false,
"format": "MBR: 4KiB-aligned",
"fsFree": null,
"fsSize": null,
"fsType": null,
"fsUsed": null,
"id": "KINGSTON_SA2000M8250G_50026B7282669D9E",
"idx": 31,
"name": "cache2",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": false,
"size": 244198552,
"status": "DISK_OK",
"temp": 27,
"transport": "nvme",
"type": "CACHE",
"warning": null,
},
{
"comment": "Unraid OS boot device",
"critical": null,
"device": "sda",
"exportable": true,
"format": "unknown",
"fsFree": 3191407,
"fsSize": 4042732,
"fsType": "vfat",
"fsUsed": 851325,
"id": "Cruzer",
"idx": 32,
"name": "flash",
"numErrors": 0,
"numReads": 0,
"numWrites": 0,
"rotational": true,
"size": 3956700,
"status": "DISK_OK",
"temp": null,
"transport": "usb",
"type": "FLASH",
"warning": null,
},
]
`);
});

View File

@@ -16,160 +16,160 @@ test('Returns parsed state file', async () => {
});
expect(parse(stateFile)).toMatchInlineSnapshot(`
{
"bindMgt": false,
"cacheNumDevices": NaN,
"cacheSbNumDisks": NaN,
"comment": "Dev Server",
"configState": "yes",
"configValid": true,
"csrfToken": "0000000000000000",
"defaultFsType": "xfs",
"deviceCount": 4,
"domain": "",
"domainLogin": "Administrator",
"domainShort": "",
"enableFruit": "no",
"flashGuid": "0000-0000-0000-000000000000",
"flashProduct": "DataTraveler_3.0",
"flashVendor": "KINGSTON",
"fsCopyPrcnt": 0,
"fsNumMounted": 0,
"fsNumUnmountable": 0,
"fsProgress": "Autostart disabled",
"fsState": "Stopped",
"fsUnmountableMask": "",
"fuseDirectio": "auto",
"fuseDirectioDefault": "auto",
"fuseDirectioStatus": "default",
"fuseRemember": "330",
"fuseRememberDefault": "330",
"fuseRememberStatus": "default",
"fuseUseino": "yes",
"hideDotFiles": false,
"joinStatus": "Not joined",
"localMaster": true,
"localTld": "local",
"luksKeyfile": "/tmp/unraid/keyfile",
"maxArraysz": 30,
"maxCachesz": 30,
"mdColor": "green-blink",
"mdNumDisabled": 1,
"mdNumDisks": 4,
"mdNumErased": 0,
"mdNumInvalid": 1,
"mdNumMissing": 0,
"mdNumNew": 0,
"mdNumStripes": 1280,
"mdNumStripesDefault": 1280,
"mdNumStripesStatus": "default",
"mdQueueLimit": "80",
"mdQueueLimitDefault": "80",
"mdQueueLimitStatus": "default",
"mdResync": 0,
"mdResyncAction": "check P",
"mdResyncCorr": "0",
"mdResyncDb": "0",
"mdResyncDt": "0",
"mdResyncPos": 0,
"mdResyncSize": 438960096,
"mdScheduler": "auto",
"mdSchedulerDefault": "auto",
"mdSchedulerStatus": "default",
"mdState": "STOPPED",
"mdSyncLimit": "5",
"mdSyncLimitDefault": "5",
"mdSyncLimitStatus": "default",
"mdSyncThresh": NaN,
"mdSyncThreshDefault": NaN,
"mdSyncWindow": NaN,
"mdSyncWindowDefault": NaN,
"mdVersion": "2.9.14",
"mdWriteMethod": NaN,
"mdWriteMethodDefault": "auto",
"mdWriteMethodStatus": "default",
"name": "Tower",
"nrRequests": NaN,
"nrRequestsDefault": NaN,
"nrRequestsStatus": "default",
"ntpServer1": "time1.google.com",
"ntpServer2": "time2.google.com",
"ntpServer3": "time3.google.com",
"ntpServer4": "time4.google.com",
"pollAttributes": "1800",
"pollAttributesDefault": "1800",
"pollAttributesStatus": "default",
"port": 80,
"portssh": 22,
"portssl": 443,
"porttelnet": 23,
"queueDepth": "auto",
"regCheck": "Valid",
"regExp": "",
"regFile": "/app/dev/Unraid.net/Pro.key",
"regGen": "0",
"regGuid": "13FE-4200-C300-58C372A52B19",
"regState": "PRO",
"regTm": "1833409182",
"regTm2": "0",
"regTo": "Eli Bosley",
"regTy": "PRO",
"reservedNames": "parity,parity2,parity3,diskP,diskQ,diskR,disk,disks,flash,boot,user,user0,disk0,disk1,disk2,disk3,disk4,disk5,disk6,disk7,disk8,disk9,disk10,disk11,disk12,disk13,disk14,disk15,disk16,disk17,disk18,disk19,disk20,disk21,disk22,disk23,disk24,disk25,disk26,disk27,disk28,disk29,disk30,disk31",
"safeMode": false,
"sbClean": true,
"sbEvents": 173,
"sbName": "/boot/config/super.dat",
"sbNumDisks": 5,
"sbState": "1",
"sbSyncErrs": 0,
"sbSyncExit": "0",
"sbSynced": 1586819259,
"sbSynced2": 1586822456,
"sbUpdated": "1596079143",
"sbVersion": "2.9.13",
"security": "user",
"shareAvahiEnabled": true,
"shareAvahiSmbModel": "Xserve",
"shareAvahiSmbName": "%h",
"shareCacheEnabled": true,
"shareCacheFloor": "2000000",
"shareCount": 0,
"shareDisk": "yes",
"shareInitialGroup": "Domain Users",
"shareInitialOwner": "Administrator",
"shareMoverActive": false,
"shareMoverLogging": false,
"shareMoverSchedule": "40 3 * * *",
"shareNfsCount": 0,
"shareNfsEnabled": false,
"shareSmbCount": 1,
"shareSmbEnabled": true,
"shareSmbMode": "workgroup",
"shareUser": "e",
"shareUserExclude": "",
"shareUserInclude": "",
"shfsLogging": "1",
"shutdownTimeout": 90,
"spindownDelay": 0,
"spinupGroups": false,
"startArray": false,
"startMode": "Normal",
"startPage": "Main",
"sysArraySlots": 24,
"sysCacheSlots": NaN,
"sysFlashSlots": 1,
"sysModel": "Dell R710",
"timeZone": "Australia/Adelaide",
"useNetbios": "yes",
"useNtp": true,
"useSsh": true,
"useSsl": null,
"useTelnet": true,
"useUpnp": true,
"useWsd": "no",
"version": "6.11.2",
"workgroup": "WORKGROUP",
"wsdOpt": "",
}
`);
{
"bindMgt": false,
"cacheNumDevices": NaN,
"cacheSbNumDisks": NaN,
"comment": "Dev Server",
"configErrorState": "INELIGIBLE",
"configValid": false,
"csrfToken": "0000000000000000",
"defaultFsType": "XFS",
"deviceCount": 4,
"domain": "",
"domainLogin": "Administrator",
"domainShort": "",
"enableFruit": "no",
"flashGuid": "0000-0000-0000-000000000000",
"flashProduct": "DataTraveler_3.0",
"flashVendor": "KINGSTON",
"fsCopyPrcnt": 0,
"fsNumMounted": 0,
"fsNumUnmountable": 0,
"fsProgress": "Autostart disabled",
"fsState": "Stopped",
"fsUnmountableMask": "",
"fuseDirectio": "auto",
"fuseDirectioDefault": "auto",
"fuseDirectioStatus": "default",
"fuseRemember": "330",
"fuseRememberDefault": "330",
"fuseRememberStatus": "default",
"fuseUseino": "yes",
"hideDotFiles": false,
"joinStatus": "Not joined",
"localMaster": true,
"localTld": "local",
"luksKeyfile": "/tmp/unraid/keyfile",
"maxArraysz": 30,
"maxCachesz": 30,
"mdColor": "green-blink",
"mdNumDisabled": 1,
"mdNumDisks": 4,
"mdNumErased": 0,
"mdNumInvalid": 1,
"mdNumMissing": 0,
"mdNumNew": 0,
"mdNumStripes": 1280,
"mdNumStripesDefault": 1280,
"mdNumStripesStatus": "default",
"mdQueueLimit": "80",
"mdQueueLimitDefault": "80",
"mdQueueLimitStatus": "default",
"mdResync": 0,
"mdResyncAction": "check P",
"mdResyncCorr": "0",
"mdResyncDb": "0",
"mdResyncDt": "0",
"mdResyncPos": 0,
"mdResyncSize": 438960096,
"mdScheduler": "auto",
"mdSchedulerDefault": "auto",
"mdSchedulerStatus": "default",
"mdState": "STOPPED",
"mdSyncLimit": "5",
"mdSyncLimitDefault": "5",
"mdSyncLimitStatus": "default",
"mdSyncThresh": NaN,
"mdSyncThreshDefault": NaN,
"mdSyncWindow": NaN,
"mdSyncWindowDefault": NaN,
"mdVersion": "2.9.14",
"mdWriteMethod": NaN,
"mdWriteMethodDefault": "auto",
"mdWriteMethodStatus": "default",
"name": "Tower",
"nrRequests": NaN,
"nrRequestsDefault": NaN,
"nrRequestsStatus": "default",
"ntpServer1": "time1.google.com",
"ntpServer2": "time2.google.com",
"ntpServer3": "time3.google.com",
"ntpServer4": "time4.google.com",
"pollAttributes": "1800",
"pollAttributesDefault": "1800",
"pollAttributesStatus": "default",
"port": 80,
"portssh": 22,
"portssl": 443,
"porttelnet": 23,
"queueDepth": "auto",
"regCheck": "Valid",
"regExp": "",
"regFile": "/app/dev/Unraid.net/Pro.key",
"regGen": "0",
"regGuid": "13FE-4200-C300-58C372A52B19",
"regState": "PRO",
"regTm": "1833409182",
"regTm2": "0",
"regTo": "Eli Bosley",
"regTy": "PRO",
"reservedNames": "parity,parity2,parity3,diskP,diskQ,diskR,disk,disks,flash,boot,user,user0,disk0,disk1,disk2,disk3,disk4,disk5,disk6,disk7,disk8,disk9,disk10,disk11,disk12,disk13,disk14,disk15,disk16,disk17,disk18,disk19,disk20,disk21,disk22,disk23,disk24,disk25,disk26,disk27,disk28,disk29,disk30,disk31",
"safeMode": false,
"sbClean": true,
"sbEvents": 173,
"sbName": "/boot/config/super.dat",
"sbNumDisks": 5,
"sbState": "1",
"sbSyncErrs": 0,
"sbSyncExit": "0",
"sbSynced": 1586819259,
"sbSynced2": 1586822456,
"sbUpdated": "1596079143",
"sbVersion": "2.9.13",
"security": "user",
"shareAvahiEnabled": true,
"shareAvahiSmbModel": "Xserve",
"shareAvahiSmbName": "%h",
"shareCacheEnabled": true,
"shareCacheFloor": "2000000",
"shareCount": 0,
"shareDisk": "yes",
"shareInitialGroup": "Domain Users",
"shareInitialOwner": "Administrator",
"shareMoverActive": false,
"shareMoverLogging": false,
"shareMoverSchedule": "40 3 * * *",
"shareNfsCount": 0,
"shareNfsEnabled": false,
"shareSmbCount": 1,
"shareSmbEnabled": true,
"shareSmbMode": "workgroup",
"shareUser": "e",
"shareUserExclude": "",
"shareUserInclude": "",
"shfsLogging": "1",
"shutdownTimeout": 90,
"spindownDelay": 0,
"spinupGroups": false,
"startArray": false,
"startMode": "Normal",
"startPage": "Main",
"sysArraySlots": 24,
"sysCacheSlots": NaN,
"sysFlashSlots": 1,
"sysModel": "Dell R710",
"timeZone": "Australia/Adelaide",
"useNetbios": "yes",
"useNtp": true,
"useSsh": true,
"useSsl": null,
"useTelnet": true,
"useUpnp": true,
"useWsd": "no",
"version": "6.11.2",
"workgroup": "WORKGROUP",
"wsdOpt": "",
}
`);
});

View File

@@ -20,6 +20,7 @@ const getAllowedSocks = (): string[] => [
const getLocalAccessUrlsForServer = (state: RootState = store.getState()): string[] => {
const { emhttp } = state;
if (emhttp.status !== FileLoadStatus.LOADED) {
return [];
}
@@ -90,7 +91,7 @@ const getApolloSandbox = (): string[] => {
export const getAllowedOrigins = (state: RootState = store.getState()): string[] =>
uniq([
...getAllowedSocks(),
...getLocalAccessUrlsForServer(),
...getLocalAccessUrlsForServer(state),
...getRemoteAccessUrlsForAllowedOrigins(state),
...getExtraOrigins(),
...getConnectOrigins(),

View File

@@ -1,49 +0,0 @@
import { ArrayRunningError } from '@app/core/errors/array-running-error.js';
import { FieldMissingError } from '@app/core/errors/field-missing-error.js';
import { getArrayData } from '@app/core/modules/array/get-array-data.js';
import { type CoreContext, type CoreResult } from '@app/core/types/index.js';
import { arrayIsRunning } from '@app/core/utils/array/array-is-running.js';
import { emcmd } from '@app/core/utils/clients/emcmd.js';
import { ensurePermission } from '@app/core/utils/permissions/ensure-permission.js';
import { hasFields } from '@app/core/utils/validation/has-fields.js';
/**
* Add a disk to the array.
*/
export const addDiskToArray = async function (context: CoreContext): Promise<CoreResult> {
const { data = {}, user } = context;
// Check permissions
ensurePermission(user, {
resource: 'array',
action: 'create',
possession: 'any',
});
const missingFields = hasFields(data, ['id']);
if (missingFields.length !== 0) {
// Just log first error
throw new FieldMissingError(missingFields[0]);
}
if (arrayIsRunning()) {
throw new ArrayRunningError();
}
const { id: diskId, slot: preferredSlot } = data;
const slot = Number.parseInt(preferredSlot as string, 10);
// Add disk
await emcmd({
changeDevice: 'apply',
[`slotId.${slot}`]: diskId,
});
const array = getArrayData();
// Disk added successfully
return {
text: `Disk was added to the array in slot ${slot}.`,
json: array,
};
};

View File

@@ -1,13 +1,16 @@
import { GraphQLError } from 'graphql';
import { sum } from 'lodash-es';
import type { ArrayCapacity, ArrayType } from '@app/graphql/generated/api/types.js';
import { getServerIdentifier } from '@app/core/utils/server-identifier.js';
import { ArrayDiskType } from '@app/graphql/generated/api/types.js';
import { store } from '@app/store/index.js';
import { FileLoadStatus } from '@app/store/types.js';
import {
ArrayCapacity,
ArrayDiskType,
ArrayState,
UnraidArray,
} from '@app/unraid-api/graph/resolvers/array/array.model.js';
export const getArrayData = (getState = store.getState): ArrayType => {
export const getArrayData = (getState = store.getState): UnraidArray => {
// Var state isn't loaded
const state = getState();
if (
@@ -52,7 +55,7 @@ export const getArrayData = (getState = store.getState): ArrayType => {
return {
id: 'array',
state: emhttp.var.mdState,
state: emhttp.var.mdState as ArrayState,
capacity,
boot,
parities,

View File

@@ -1,6 +0,0 @@
// Created from 'create-ts-index'
export * from './add-disk-to-array.js';
export * from './remove-disk-from-array.js';
export * from './update-array.js';
export * from './update-parity-check.js';

View File

@@ -1,45 +0,0 @@
import { ArrayRunningError } from '@app/core/errors/array-running-error.js';
import { FieldMissingError } from '@app/core/errors/field-missing-error.js';
import { getArrayData } from '@app/core/modules/array/get-array-data.js';
import { type CoreContext, type CoreResult } from '@app/core/types/index.js';
import { arrayIsRunning } from '@app/core/utils/array/array-is-running.js';
import { hasFields } from '@app/core/utils/validation/has-fields.js';
interface Context extends CoreContext {
data: {
/** The slot the disk is in. */
slot: string;
};
}
/**
* Remove a disk from the array.
* @returns The updated array.
*/
export const removeDiskFromArray = async (context: Context): Promise<CoreResult> => {
const { data } = context;
const missingFields = hasFields(data, ['id']);
if (missingFields.length !== 0) {
// Only log first error
throw new FieldMissingError(missingFields[0]);
}
if (arrayIsRunning()) {
throw new ArrayRunningError();
}
const { slot } = data;
// Error removing disk
// if () {
// }
const array = getArrayData();
// Disk removed successfully
return {
text: `Disk was removed from the array in slot ${slot}.`,
json: array,
};
};

View File

@@ -1,88 +0,0 @@
import type { CoreContext, CoreResult } from '@app/core/types/index.js';
import { AppError } from '@app/core/errors/app-error.js';
import { FieldMissingError } from '@app/core/errors/field-missing-error.js';
import { ParamInvalidError } from '@app/core/errors/param-invalid-error.js';
import { getArrayData } from '@app/core/modules/array/get-array-data.js';
import { arrayIsRunning } from '@app/core/utils/array/array-is-running.js';
import { emcmd } from '@app/core/utils/clients/emcmd.js';
import { uppercaseFirstChar } from '@app/core/utils/misc/uppercase-first-char.js';
import { ensurePermission } from '@app/core/utils/permissions/ensure-permission.js';
import { hasFields } from '@app/core/utils/validation/has-fields.js';
// @TODO: Fix this not working across node apps
// each app has it's own lock since the var is scoped
// ideally this should have a timeout to prevent it sticking
let locked = false;
export const updateArray = async (context: CoreContext): Promise<CoreResult> => {
const { data = {}, user } = context;
// Check permissions
ensurePermission(user, {
resource: 'array',
action: 'update',
possession: 'any',
});
const missingFields = hasFields(data, ['state']);
if (missingFields.length !== 0) {
// Only log first error
throw new FieldMissingError(missingFields[0]);
}
const { state: nextState } = data as { state: string };
const startState = arrayIsRunning() ? 'started' : 'stopped';
const pendingState = nextState === 'stop' ? 'stopping' : 'starting';
if (!['start', 'stop'].includes(nextState)) {
throw new ParamInvalidError('state', nextState);
}
// Prevent this running multiple times at once
if (locked) {
throw new AppError('Array state is still being updated.');
}
// Prevent starting/stopping array when it's already in the same state
if ((arrayIsRunning() && nextState === 'start') || (!arrayIsRunning() && nextState === 'stop')) {
throw new AppError(`The array is already ${startState}`);
}
// Set lock then start/stop array
locked = true;
const command = {
[`cmd${uppercaseFirstChar(nextState)}`]: uppercaseFirstChar(nextState),
startState: startState.toUpperCase(),
};
// `await` has to be used otherwise the catch
// will finish after the return statement below
await emcmd(command).finally(() => {
locked = false;
});
// Get new array JSON
const array = getArrayData();
/**
* Update array details
*
* @memberof Core
* @module array/update-array
* @param {Core~Context} context Context object.
* @param {Object} context.data The data object.
* @param {'start'|'stop'} context.data.state If the array should be started or stopped.
* @param {State~User} context.user The current user.
* @returns {Core~Result} The updated array.
*/
return {
text: `Array was ${startState}, ${pendingState}.`,
json: {
...array,
state: nextState === 'start' ? 'started' : 'stopped',
previousState: startState,
pendingState,
},
};
};

View File

@@ -1,78 +0,0 @@
import type { CoreContext, CoreResult } from '@app/core/types/index.js';
import { FieldMissingError } from '@app/core/errors/field-missing-error.js';
import { ParamInvalidError } from '@app/core/errors/param-invalid-error.js';
import { emcmd } from '@app/core/utils/clients/emcmd.js';
import { ensurePermission } from '@app/core/utils/permissions/ensure-permission.js';
import { getters } from '@app/store/index.js';
type State = 'start' | 'cancel' | 'resume' | 'cancel';
interface Context extends CoreContext {
data: {
state?: State;
correct?: boolean;
};
}
/**
* Remove a disk from the array.
* @returns The update array.
*/
export const updateParityCheck = async (context: Context): Promise<CoreResult> => {
const { user, data } = context;
// Check permissions
ensurePermission(user, {
resource: 'array',
action: 'update',
possession: 'any',
});
// Validation
if (!data.state) {
throw new FieldMissingError('state');
}
const { state: wantedState } = data;
const emhttp = getters.emhttp();
const running = emhttp.var.mdResync !== 0;
const states = {
pause: {
cmdNoCheck: 'Pause',
},
resume: {
cmdCheck: 'Resume',
},
cancel: {
cmdNoCheck: 'Cancel',
},
start: {
cmdCheck: 'Check',
},
};
let allowedStates = Object.keys(states);
// Only allow starting a check if there isn't already one running
if (running) {
allowedStates = allowedStates.splice(allowedStates.indexOf('start'), 1);
}
// Only allow states from states object
if (!allowedStates.includes(wantedState)) {
throw new ParamInvalidError('state', wantedState);
}
// Should we write correction to the parity during the check
const writeCorrectionsToParity = wantedState === 'start' && data.correct;
await emcmd({
startState: 'STARTED',
...states[wantedState],
...(writeCorrectionsToParity ? { optionCorrect: 'correct' } : {}),
});
return {
json: {},
};
};

View File

@@ -1,6 +1,6 @@
import { AppError } from '@app/core/errors/app-error.js';
import { type CoreContext, type CoreResult } from '@app/core/types/index.js';
import { Disk } from '@app/graphql/generated/api/types.js';
import { ArrayDisk } from '@app/unraid-api/graph/resolvers/array/array.model.js';
interface Context extends CoreContext {
params: {
@@ -11,7 +11,7 @@ interface Context extends CoreContext {
/**
* Get a single disk.
*/
export const getDisk = async (context: Context, Disks: Disk[]): Promise<CoreResult> => {
export const getDisk = async (context: Context, Disks: ArrayDisk[]): Promise<CoreResult> => {
const { params } = context;
const { id } = params;

View File

@@ -1,88 +0,0 @@
import fs from 'fs';
import camelCaseKeys from 'camelcase-keys';
import { ContainerInfo } from 'dockerode';
import type { ContainerPort, Docker, DockerContainer } from '@app/graphql/generated/api/types.js';
import { dockerLogger } from '@app/core/log.js';
import { docker } from '@app/core/utils/clients/docker.js';
import { catchHandlers } from '@app/core/utils/misc/catch-handlers.js';
import { ContainerPortType, ContainerState } from '@app/graphql/generated/api/types.js';
import { getters, store } from '@app/store/index.js';
import { updateDockerState } from '@app/store/modules/docker.js';
/**
* Get all Docker containers.
* @returns All the in/active Docker containers on the system.
*/
export const getDockerContainers = async (
{ useCache } = { useCache: true }
): Promise<Array<DockerContainer>> => {
const dockerState = getters.docker();
if (useCache && dockerState.containers) {
dockerLogger.trace('Using docker container cache');
return dockerState.containers;
}
dockerLogger.trace('Skipping docker container cache');
/**
* Docker auto start file
*
* @note Doesn't exist if array is offline.
* @see https://github.com/limetech/webgui/issues/502#issue-480992547
*/
const autoStartFile = await fs.promises
.readFile(getters.paths()['docker-autostart'], 'utf8')
.then((file) => file.toString())
.catch(() => '');
const autoStarts = autoStartFile.split('\n');
const rawContainers = await docker
.listContainers({
all: true,
size: true,
})
// If docker throws an error return no containers
.catch(catchHandlers.docker);
// Cleanup container object
const containers: Array<DockerContainer> = rawContainers.map((container) => {
const names = container.Names[0];
const containerData: DockerContainer = camelCaseKeys<DockerContainer>(
{
labels: container.Labels ?? {},
sizeRootFs: undefined,
imageId: container.ImageID,
state:
typeof container.State === 'string'
? (ContainerState[container.State.toUpperCase()] ?? ContainerState.EXITED)
: ContainerState.EXITED,
autoStart: autoStarts.includes(names.split('/')[1]),
ports: container.Ports.map<ContainerPort>((port) => ({
...port,
type: ContainerPortType[port.Type.toUpperCase()],
})),
command: container.Command,
created: container.Created,
mounts: container.Mounts,
networkSettings: container.NetworkSettings,
hostConfig: {
networkMode: container.HostConfig.NetworkMode,
},
id: container.Id,
image: container.Image,
status: container.Status,
},
{ deep: true }
);
return containerData;
});
// Get all of the current containers
const installed = containers.length;
const running = containers.filter((container) => container.state === ContainerState.RUNNING).length;
store.dispatch(updateDockerState({ containers, installed, running }));
return containers;
};

View File

@@ -1,39 +0,0 @@
import camelCaseKeys from 'camelcase-keys';
import { type CoreContext, type CoreResult } from '@app/core/types/index.js';
import { docker } from '@app/core/utils/index.js';
import { catchHandlers } from '@app/core/utils/misc/catch-handlers.js';
import { ensurePermission } from '@app/core/utils/permissions/ensure-permission.js';
export const getDockerNetworks = async (context: CoreContext): Promise<CoreResult> => {
const { user } = context;
// Check permissions
ensurePermission(user, {
resource: 'docker/network',
action: 'read',
possession: 'any',
});
const networks = await docker
.listNetworks()
// If docker throws an error return no networks
.catch(catchHandlers.docker)
.then((networks = []) =>
networks.map((object) =>
camelCaseKeys(object as unknown as Record<string, unknown>, { deep: true })
)
);
/**
* Get all Docker networks
*
* @memberof Core
* @module docker/get-networks
* @param {Core~Context} context
* @returns {Core~Result} All the in/active Docker networks on the system.
*/
return {
json: networks,
};
};

View File

@@ -1,4 +0,0 @@
// Created from 'create-ts-index'
export * from './get-docker-containers.js';
export * from './get-docker-networks.js';

View File

@@ -1,92 +0,0 @@
import type { Systeminformation } from 'systeminformation';
import { execa } from 'execa';
import { blockDevices, diskLayout } from 'systeminformation';
import type { Disk } from '@app/graphql/generated/api/types.js';
import { graphqlLogger } from '@app/core/log.js';
import { DiskFsType, DiskInterfaceType, DiskSmartStatus } from '@app/graphql/generated/api/types.js';
import { batchProcess } from '@app/utils.js';
const getTemperature = async (disk: Systeminformation.DiskLayoutData): Promise<number> => {
try {
const stdout = await execa('smartctl', ['-A', disk.device])
.then(({ stdout }) => stdout)
.catch(() => '');
const lines = stdout.split('\n');
const header = lines.find((line) => line.startsWith('ID#')) ?? '';
const fields = lines.splice(lines.indexOf(header) + 1, lines.length);
const field = fields.find(
(line) => line.includes('Temperature_Celsius') || line.includes('Airflow_Temperature_Cel')
);
if (!field) {
return -1;
}
if (field.includes('Min/Max')) {
return Number.parseInt(field.split(' - ')[1].trim().split(' ')[0], 10);
}
const line = field.split(' ');
return Number.parseInt(line[line.length - 1], 10);
} catch (error) {
graphqlLogger.warn('Caught error fetching disk temperature: %o', error);
return -1;
}
};
const parseDisk = async (
disk: Systeminformation.DiskLayoutData,
partitionsToParse: Systeminformation.BlockDevicesData[],
temperature = false
): Promise<Disk> => {
const partitions = partitionsToParse
// Only get partitions from this disk
.filter((partition) => partition.name.startsWith(disk.device.split('/dev/')[1]))
// Remove unneeded fields
.map(({ name, fsType, size }) => ({
name,
fsType: typeof fsType === 'string' ? DiskFsType[fsType] : undefined,
size,
}));
return {
...disk,
smartStatus:
typeof disk.smartStatus === 'string'
? DiskSmartStatus[disk.smartStatus.toUpperCase()]
: undefined,
interfaceType:
typeof disk.interfaceType === 'string'
? DiskInterfaceType[disk.interfaceType]
: DiskInterfaceType.UNKNOWN,
temperature: temperature ? await getTemperature(disk) : -1,
partitions,
id: disk.serialNum,
};
};
/**
* Get all disks.
*/
export const getDisks = async (options?: { temperature: boolean }): Promise<Disk[]> => {
// Return all fields but temperature
if (options?.temperature === false) {
const partitions = await blockDevices().then((devices) =>
devices.filter((device) => device.type === 'part')
);
const diskLayoutData = await diskLayout();
const disks = await Promise.all(diskLayoutData.map((disk) => parseDisk(disk, partitions)));
return disks;
}
const partitions = await blockDevices().then((devices) =>
devices.filter((device) => device.type === 'part')
);
const { data } = await batchProcess(await diskLayout(), async (disk) =>
parseDisk(disk, partitions, true)
);
return data;
};

View File

@@ -1,62 +0,0 @@
import { promises as fs } from 'fs';
import Table from 'cli-table';
import { FileMissingError } from '@app/core/errors/file-missing-error.js';
import { type CoreContext, type CoreResult } from '@app/core/types/index.js';
import { ensurePermission } from '@app/core/utils/permissions/ensure-permission.js';
import { getters } from '@app/store/index.js';
/**
* Get parity history.
* @returns All parity checks with their respective date, duration, speed, status and errors.
*/
export const getParityHistory = async (context: CoreContext): Promise<CoreResult> => {
const { user } = context;
// Bail if the user doesn't have permission
ensurePermission(user, {
resource: 'parity-history',
action: 'read',
possession: 'any',
});
const historyFilePath = getters.paths()['parity-checks'];
const history = await fs.readFile(historyFilePath).catch(() => {
throw new FileMissingError(historyFilePath);
});
// Convert checks into array of objects
const lines = history.toString().trim().split('\n').reverse();
const parityChecks = lines.map((line) => {
const [date, duration, speed, status, errors = '0'] = line.split('|');
return {
date,
duration: Number.parseInt(duration, 10),
speed,
status,
errors: Number.parseInt(errors, 10),
};
});
// Create table for text output
const table = new Table({
head: ['Date', 'Duration', 'Speed', 'Status', 'Errors'],
});
// Update raw values with strings
parityChecks.forEach((check) => {
const array = Object.values({
date: check.date,
speed: check.speed ? check.speed : 'Unavailable',
duration: check.duration >= 0 ? check.duration.toString() : 'Unavailable',
status: check.status === '-4' ? 'Cancelled' : 'OK',
errors: check.errors.toString(),
});
table.push(array);
});
return {
text: table.toString(),
json: parityChecks,
};
};

View File

@@ -1,20 +1,15 @@
// Created from 'create-ts-index'
export * from './array/index.js';
export * from './debug/index.js';
export * from './disks/index.js';
export * from './docker/index.js';
export * from './services/index.js';
export * from './settings/index.js';
export * from './shares/index.js';
export * from './users/index.js';
export * from './vms/index.js';
export * from './add-share.js';
export * from './add-user.js';
export * from './get-apps.js';
export * from './get-devices.js';
export * from './get-disks.js';
export * from './get-parity-history.js';
export * from './get-services.js';
export * from './get-users.js';
export * from './get-welcome.js';

View File

@@ -1,63 +0,0 @@
import { GraphQLError } from 'graphql';
import type { VmDomain } from '@app/graphql/generated/api/types.js';
import { VmState } from '@app/graphql/generated/api/types.js';
const states = {
0: 'NOSTATE',
1: 'RUNNING',
2: 'IDLE',
3: 'PAUSED',
4: 'SHUTDOWN',
5: 'SHUTOFF',
6: 'CRASHED',
7: 'PMSUSPENDED',
};
/**
* Get vm domains.
*/
export const getDomains = async () => {
try {
const { ConnectListAllDomainsFlags } = await import('@unraid/libvirt');
const { UnraidHypervisor } = await import('@app/core/utils/vms/get-hypervisor.js');
const hypervisor = await UnraidHypervisor.getInstance().getHypervisor();
if (!hypervisor) {
throw new GraphQLError('VMs Disabled');
}
const autoStartDomains = await hypervisor.connectListAllDomains(
ConnectListAllDomainsFlags.AUTOSTART
);
const autoStartDomainNames = await Promise.all(
autoStartDomains.map(async (domain) => hypervisor.domainGetName(domain))
);
// Get all domains
const domains = await hypervisor.connectListAllDomains();
const resolvedDomains: Array<VmDomain> = await Promise.all(
domains.map(async (domain) => {
const info = await hypervisor.domainGetInfo(domain);
const name = await hypervisor.domainGetName(domain);
const features = {};
return {
name,
uuid: await hypervisor.domainGetUUIDString(domain),
state: VmState[states[info.state]] ?? VmState.NOSTATE,
autoStart: autoStartDomainNames.includes(name),
features,
};
})
);
return resolvedDomains;
} catch (error: unknown) {
// If we hit an error expect libvirt to be offline
throw new GraphQLError(
`Failed to fetch domains with error: ${error instanceof Error ? error.message : 'Unknown Error'}`
);
}
};

Some files were not shown because too many files have changed in this diff Show More