Compare commits

...

9 Commits

Author SHA1 Message Date
Eli Bosley
eecd9b1017 fix(my.servers): improve DNS resolution robustness for backup server (#1518)
Add multiple fallback methods for DNS resolution when checking
backup.unraid.net

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

## Summary by CodeRabbit

* **Bug Fixes**
* Improved reliability of DNS resolution checks for backup services,
reducing false error reports.
* Enhanced error messages to provide clearer guidance if DNS resolution
fails, including advice to check DNS settings in network configuration.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-15 11:33:21 -04:00
Pujit Mehrotra
441e1805c1 fix: replace myservers.cfg reads in UpdateFlashBackup.php (#1517)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added a new method for verifying user sign-in status using a dedicated
configuration handler.
* Introduced a class to manage connection configuration and status
checks.

* **Refactor**
* Updated logic for checking connection and registration status to use
new configuration handling methods for improved clarity and reliability.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-15 10:30:04 -04:00
Pujit Mehrotra
29dcb7d0f0 fix: rm short-circuit in rc.unraid-api if plugin config dir is absent (#1515)
This short-circuit causes any/all `rc.unraid-api` invocations to
immediately fail on fresh 7.2 images (because
`/boot/config/dynamix.my.servers` doesn't exist).

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

* **Refactor**
* Removed initial checks and setup for a plugin directory and default
environment file in the startup script.
* Simplified environment switching with streamlined commands and
improved error handling.
* Removed deprecated environment path references and updated related
tests.
* **Documentation**
* Added descriptive comments clarifying build and environment settings.
* **Tests**
* Updated test cases by removing assertions related to deprecated
environment paths.
* **Maintenance**
  * Updated timestamp fixtures for consistency.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-15 09:48:12 -04:00
Pujit Mehrotra
1a7d35d3f6 fix: ensure no crash if emhttp state configs are missing (#1514)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added new utility functions to improve file writing reliability by
ensuring parent directories exist before writing.
* Introduced a new watch command for easier development workflow in the
shared package.

* **Bug Fixes**
* Improved startup behavior by logging warnings for missing
configuration keys instead of crashing, allowing initialization to
proceed.

* **Chores**
* Updated configuration version number and reformatted plugin list for
clarity.
* Relocated certain GraphQL schema type and enum declarations without
changing their content.
<!-- 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/1210788779106748
2025-07-15 09:48:01 -04:00
Pujit Mehrotra
af33e999a0 fix: delay nginx:reload file mod effect by 10 seconds (#1512)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Enhancements**
  * Added logging to indicate when Nginx is successfully reloaded.
* Introduced a 10-second delay with a log message before triggering
Nginx reloads in file modification effects.

* **Style**
* Removed a startup message from the Unraid API service plugin
installation process.

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

Co-authored-by: Eli Bosley <ekbosley@gmail.com>
2025-07-14 11:12:20 -04:00
renovate[bot]
85a35804c1 chore(deps): pin dependencies (#1478)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [jiti](https://redirect.github.com/unjs/jiti) | devDependencies | pin
| [`^2.4.2` ->
`2.4.2`](https://renovatebot.com/diffs/npm/jiti/2.4.2/2.4.2) |
| [node](https://redirect.github.com/actions/node-versions) | uses-with
| pin | `22` -> `22.17.0` |
| [wrangler](https://redirect.github.com/cloudflare/workers-sdk)
([source](https://redirect.github.com/cloudflare/workers-sdk/tree/HEAD/packages/wrangler))
| devDependencies | pin | [`^4.0.0` ->
`4.24.3`](https://renovatebot.com/diffs/npm/wrangler/4.24.3/4.24.3) |
| [ws](https://redirect.github.com/websockets/ws) | peerDependencies |
pin | [`^8.18.0` ->
`8.18.3`](https://renovatebot.com/diffs/npm/ws/8.18.3/8.18.3) |

Add the preset `:preserveSemverRanges` to your config if you don't want
to pin your dependencies.

---

### 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:eyJjcmVhdGVkSW5WZXIiOiI0MS4yMy4yIiwidXBkYXRlZEluVmVyIjoiNDEuMjMuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-14 11:11:46 -04:00
Eli Bosley
a35c8ff2f1 refactor(install): add debugging to install process
- Remove redundant log file handling and display errors directly to users
- Add debug information for troubleshooting installation issues

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

## Summary by CodeRabbit

* **Bug Fixes**
* Improved installation and verification scripts to display output and
error messages directly to the user, rather than writing to a log file.
* Enhanced error messages to provide clearer instructions when issues
occur during installation or verification.

* **New Features**
* Added detailed debug output during the API service startup to assist
with troubleshooting.

* **Chores**
* Updated script environments and streamlined directory creation for
improved reliability.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-14 10:59:05 -04:00
renovate[bot]
153e7a1e3a chore(deps): update dependency @vitejs/plugin-vue to v6 (#1431)
This PR contains the following updates:

| Package | Change | Age | Confidence |
|---|---|---|---|
|
[@vitejs/plugin-vue](https://redirect.github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue#readme)
([source](https://redirect.github.com/vitejs/vite-plugin-vue/tree/HEAD/packages/plugin-vue))
| [`5.2.4` ->
`6.0.0`](https://renovatebot.com/diffs/npm/@vitejs%2fplugin-vue/5.2.4/6.0.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@vitejs%2fplugin-vue/6.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@vitejs%2fplugin-vue/5.2.4/6.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>vitejs/vite-plugin-vue (@&#8203;vitejs/plugin-vue)</summary>

###
[`v6.0.0`](https://redirect.github.com/vitejs/vite-plugin-vue/blob/HEAD/packages/plugin-vue/CHANGELOG.md#600-2025-06-24)

##### Bug Fixes

- **deps:** update all non-major dependencies
([#&#8203;590](https://redirect.github.com/vitejs/vite-plugin-vue/issues/590))
([43426c8](43426c8476))
- **deps:** update all non-major dependencies
([#&#8203;600](https://redirect.github.com/vitejs/vite-plugin-vue/issues/600))
([a4c32a8](a4c32a84f3))
- **deps:** update all non-major dependencies
([#&#8203;605](https://redirect.github.com/vitejs/vite-plugin-vue/issues/605))
([67534e5](67534e5d8c))
- **deps:** update all non-major dependencies
([#&#8203;609](https://redirect.github.com/vitejs/vite-plugin-vue/issues/609))
([98c52eb](98c52eb594))

##### Miscellaneous Chores

- add `description` and `keywords` field to package.json
([#&#8203;604](https://redirect.github.com/vitejs/vite-plugin-vue/issues/604))
([67ab76b](67ab76b485))
- **deps:** update dependency rollup to ^4.41.1
([#&#8203;591](https://redirect.github.com/vitejs/vite-plugin-vue/issues/591))
([256ac31](256ac314e6))
- **deps:** update dependency rollup to ^4.43.0
([#&#8203;601](https://redirect.github.com/vitejs/vite-plugin-vue/issues/601))
([a495edf](a495edf617))
- remove Vite 7 beta from supported range
([#&#8203;598](https://redirect.github.com/vitejs/vite-plugin-vue/issues/598))
([c7ddd62](c7ddd625a7))

##### Code Refactoring

- always use `crypto.hash`
([#&#8203;606](https://redirect.github.com/vitejs/vite-plugin-vue/issues/606))
([5de85f6](5de85f6a15))

</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:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDEuMjMuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-11 15:29:14 -04:00
renovate[bot]
e73fc356cb chore(deps): update dependency wrangler to v4 (#1508)
This PR contains the following updates:

| Package | Change | Age | Confidence |
|---|---|---|---|
| [wrangler](https://redirect.github.com/cloudflare/workers-sdk)
([source](https://redirect.github.com/cloudflare/workers-sdk/tree/HEAD/packages/wrangler))
| [`^3.114.10` ->
`^4.0.0`](https://renovatebot.com/diffs/npm/wrangler/3.114.10/4.24.3) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/wrangler/4.24.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/wrangler/3.114.10/4.24.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>cloudflare/workers-sdk (wrangler)</summary>

###
[`v4.24.3`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4243)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.24.2...wrangler@4.24.3)

##### Patch Changes

-
[#&#8203;9923](https://redirect.github.com/cloudflare/workers-sdk/pull/9923)
[`c01c4ee`](c01c4ee6af)
Thanks [@&#8203;gpanders](https://redirect.github.com/gpanders)! - Fix
image name resolution when modifying a container application

-
[#&#8203;9833](https://redirect.github.com/cloudflare/workers-sdk/pull/9833)
[`3743896`](3743896120)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- fix: ensure that container builds don't disrupt dev hotkey handling

currently container builds run during local development (via `wrangler
dev` or `startWorker`) prevent the standard hotkeys not to be recognized
(most noticeably `ctrl+c`, preventing developers from existing the
process), the changes here ensure that hotkeys are instead correctly
handled as expected

- Updated dependencies \[]:
  - miniflare@4.20250709.0

###
[`v4.24.2`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4242)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.24.1...wrangler@4.24.2)

##### Patch Changes

-
[#&#8203;9917](https://redirect.github.com/cloudflare/workers-sdk/pull/9917)
[`80cc834`](80cc83403e)
Thanks [@&#8203;edmundhung](https://redirect.github.com/edmundhung)! -
fix: assets only versions upload should include tag and message

###
[`v4.24.1`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4241)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.24.0...wrangler@4.24.1)

##### Patch Changes

-
[#&#8203;9765](https://redirect.github.com/cloudflare/workers-sdk/pull/9765)
[`05adc61`](05adc615c9)
Thanks
[@&#8203;hasip-timurtas](https://redirect.github.com/hasip-timurtas)! -
Build container images without the user's account ID. This allows
containers to be built and verified in dry run mode (where we do not
necessarily have the user's account info).

When we push the image to the managed registry, we first re-tag the
image to include the user's account ID so that the image has the full
resolved image name.

- Updated dependencies
\[[`bb09e50`](bb09e50d8e),
[`25dbe54`](25dbe5480d),
[`3bdec6b`](3bdec6b768)]:
  - miniflare@4.20250709.0

###
[`v4.24.0`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4240)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.23.0...wrangler@4.24.0)

##### Minor Changes

-
[#&#8203;9796](https://redirect.github.com/cloudflare/workers-sdk/pull/9796)
[`ba69586`](ba69586d8f)
Thanks [@&#8203;simonabadoiu](https://redirect.github.com/simonabadoiu)!
- Browser Rendering local mode

-
[#&#8203;9825](https://redirect.github.com/cloudflare/workers-sdk/pull/9825)
[`49c85c5`](49c85c5306)
Thanks [@&#8203;ReppCodes](https://redirect.github.com/ReppCodes)! - Add
support for origin\_connection\_limit to Wrangler

  Configure connection limits to Hyperdrive via command line options:

- `--origin-connection-limit`: The (soft) maximum number of connections
that Hyperdrive may establish to the origin database.

-
[#&#8203;9064](https://redirect.github.com/cloudflare/workers-sdk/pull/9064)
[`a1181bf`](a1181bf804)
Thanks [@&#8203;sdnts](https://redirect.github.com/sdnts)! - Added an
`event-subscriptions` subcommand

##### Patch Changes

-
[#&#8203;9729](https://redirect.github.com/cloudflare/workers-sdk/pull/9729)
[`1b3a2b7`](1b3a2b71b7)
Thanks [@&#8203;404Wolf](https://redirect.github.com/404Wolf)! - Set
docker build context to the Dockerfile directory when
`image_build_context` is not explicitly provided

-
[#&#8203;9845](https://redirect.github.com/cloudflare/workers-sdk/pull/9845)
[`dbfa4ef`](dbfa4ef4d4)
Thanks [@&#8203;jonboulle](https://redirect.github.com/jonboulle)! -
remove extraneous double spaces from Wrangler help output

-
[#&#8203;9811](https://redirect.github.com/cloudflare/workers-sdk/pull/9811)
[`fc29c31`](fc29c31ae0)
Thanks [@&#8203;gpanders](https://redirect.github.com/gpanders)! - Fix
unauthorized errors on "containers images delete".

-
[#&#8203;9813](https://redirect.github.com/cloudflare/workers-sdk/pull/9813)
[`45497ab`](45497ab4a4)
Thanks [@&#8203;gpanders](https://redirect.github.com/gpanders)! -
Support container image names without account ID

-
[#&#8203;9821](https://redirect.github.com/cloudflare/workers-sdk/pull/9821)
[`a447d67`](a447d6722a)
Thanks
[@&#8203;WillTaylorDev](https://redirect.github.com/WillTaylorDev)! -
Preview Aliases: Force alias generation to meet stricter naming
requirements.

For cases where CI is requesting Wrangler to generate the alias based on
the branch name, we want a stricter check around the generated alias
name in order to avoid version upload failures. If a valid alias name
was not able to be generated, we warn and do not provide an alias
(avoiding a version upload failure).

-
[#&#8203;9840](https://redirect.github.com/cloudflare/workers-sdk/pull/9840)
[`7c55f9e`](7c55f9e1ea)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- fix: make sure that the experimental `remoteBindings` flag is properly
handled in `getPlatformProxy`

There are two issues related to how the experimental `remoteBindings`
flag is handled in `getPlatformProxy` that are being fixed by this
change:

- the `experimental_remote` configuration flag set on service bindings
is incorrectly always taken into account, even if `remoteBindings` is
set to `false`
- the `experimental_remote` configuration flag of all the other bindings
is never taken into account (effectively preventing the bindings to be
used in remote mode) since the `remoteBindings` flag is not being
properly propagated

-
[#&#8203;9801](https://redirect.github.com/cloudflare/workers-sdk/pull/9801)
[`0bb619a`](0bb619a929)
Thanks [@&#8203;IRCody](https://redirect.github.com/IRCody)! -
Containers: Fix issue where setting an image URI instead of dockerfile
would incorrectly not update the image

-
[#&#8203;9872](https://redirect.github.com/cloudflare/workers-sdk/pull/9872)
[`a727db3`](a727db341a)
Thanks [@&#8203;emily-shen](https://redirect.github.com/emily-shen)! -
fix: resolve Dockerfile path relative to the Wrangler config path

This fixes a bug where Wrangler would not be able to find a Dockerfile
if a Wrangler config path had been specified with the `--config` flag.

-
[#&#8203;9815](https://redirect.github.com/cloudflare/workers-sdk/pull/9815)
[`1358034`](1358034ec2)
Thanks [@&#8203;gpanders](https://redirect.github.com/gpanders)! -
Remove --json flag from containers and cloudchamber commands (except for
"images list")

-
[#&#8203;9734](https://redirect.github.com/cloudflare/workers-sdk/pull/9734)
[`1a58bc3`](1a58bc34d6)
Thanks [@&#8203;penalosa](https://redirect.github.com/penalosa)! - Make
Wrangler warn more loudly if you're missing auth scopes

-
[#&#8203;9748](https://redirect.github.com/cloudflare/workers-sdk/pull/9748)
[`7e3aa1b`](7e3aa1b774)
Thanks [@&#8203;alsuren](https://redirect.github.com/alsuren)! -
Internal-only WRANGLER\_D1\_EXTRA\_LOCATION\_CHOICES environment
variable for enabling D1's testing location hints

- Updated dependencies
\[[`ba69586`](ba69586d8f),
[`1a75f85`](1a75f85ae9),
[`395f36d`](395f36de12),
[`6f344bf`](6f344bfe31)]:
  - miniflare@4.20250705.0

###
[`v4.23.0`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4230)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.22.0...wrangler@4.23.0)

##### Minor Changes

-
[#&#8203;9535](https://redirect.github.com/cloudflare/workers-sdk/pull/9535)
[`56dc5c4`](56dc5c4946)
Thanks [@&#8203;penalosa](https://redirect.github.com/penalosa)! - In
2023 we announced [breakpoint debugging
support](https://blog.cloudflare.com/debugging-cloudflare-workers/) for
Workers, which meant that you could easily debug your Worker code in
Wrangler's built-in devtools (accessible via the `[d]` hotkey) as well
as multiple other devtools clients, [including
VSCode](https://developers.cloudflare.com/workers/observability/dev-tools/breakpoints/).
For most developers, breakpoint debugging via VSCode is the most natural
flow, but until now it's required [manually configuring a `launch.json`
file](https://developers.cloudflare.com/workers/observability/dev-tools/breakpoints/#setup-vs-code-to-use-breakpoints),
running `wrangler dev`, and connecting via VSCode's built-in debugger.

Now, using VSCode's built-in [JavaScript Debug
Terminals](https://code.visualstudio.com/docs/nodejs/nodejs-debugging#_javascript-debug-terminal),
there are just two steps: open a JS debug terminal and run `wrangler
dev` (or `vite dev`). VSCode will automatically connect to your running
Worker (even if you're running multiple Workers at once!) and start a
debugging session.

-
[#&#8203;9810](https://redirect.github.com/cloudflare/workers-sdk/pull/9810)
[`8acaf43`](8acaf432ac)
Thanks
[@&#8203;WillTaylorDev](https://redirect.github.com/WillTaylorDev)! -
WC-3626 Pull branch name from WORKERS\_CI\_BRANCH if exists.

##### Patch Changes

-
[#&#8203;9775](https://redirect.github.com/cloudflare/workers-sdk/pull/9775)
[`4309bb3`](4309bb30d2)
Thanks [@&#8203;vicb](https://redirect.github.com/vicb)! - Cap the
number of errors and warnings for bulk KV put to avoid consuming too
much memory

-
[#&#8203;9799](https://redirect.github.com/cloudflare/workers-sdk/pull/9799)
[`d11288a`](d11288aff5)
Thanks [@&#8203;penalosa](https://redirect.github.com/penalosa)! -
Better messaging for account owned tokens in `wrangler whoami`

- Updated dependencies
\[[`56dc5c4`](56dc5c4946)]:
  - miniflare@4.20250617.5

###
[`v4.22.0`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4220)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.21.2...wrangler@4.22.0)

##### Minor Changes

-
[#&#8203;7871](https://redirect.github.com/cloudflare/workers-sdk/pull/7871)
[`f2a8d4a`](f2a8d4a91e)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- add support for assets bindings to `getPlatformProxy`

this change makes sure that that `getPlatformProxy`, when the input
configuration
file contains an assets field, correctly returns the appropriate asset
binding proxy

  example:

  ```jsonc
  // wrangler.jsonc
  {
  	"name": "my-worker",
  	"assets": {
  		"directory": "./public/",
  		"binding": "ASSETS",
  	},
  }
  ```

  ```js
  import { getPlatformProxy } from "wrangler";

  const { env, dispose } = await getPlatformProxy();

const text = await (await
env.ASSETS.fetch("http://0.0.0.0/file.txt")).text();
  console.log(text); // logs the content of file.txt

  await dispose();
  ```

##### Patch Changes

-
[#&#8203;9717](https://redirect.github.com/cloudflare/workers-sdk/pull/9717)
[`d2f2f72`](d2f2f726a1)
Thanks
[@&#8203;nikitassharma](https://redirect.github.com/nikitassharma)! -
Containers should default to a "dev" instance type when no instance type
is specified in the wrangler config

-
[#&#8203;9620](https://redirect.github.com/cloudflare/workers-sdk/pull/9620)
[`1b967ea`](1b967ea0ef)
Thanks [@&#8203;gpanders](https://redirect.github.com/gpanders)! -
Simplify containers images list output format

-
[#&#8203;9684](https://redirect.github.com/cloudflare/workers-sdk/pull/9684)
[`94a340e`](94a340e121)
Thanks
[@&#8203;WillTaylorDev](https://redirect.github.com/WillTaylorDev)! -
Select only successfully deployed deployments when tailing.

###
[`v4.21.2`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4212)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.21.1...wrangler@4.21.2)

##### Patch Changes

-
[#&#8203;9731](https://redirect.github.com/cloudflare/workers-sdk/pull/9731)
[`75b75f3`](75b75f3de7)
Thanks [@&#8203;gabivlj](https://redirect.github.com/gabivlj)! -
containers: Check for container scopes before running a container
command to give a better error

-
[#&#8203;9641](https://redirect.github.com/cloudflare/workers-sdk/pull/9641)
[`fdbc9f6`](fdbc9f6048)
Thanks [@&#8203;IRCody](https://redirect.github.com/IRCody)! - Update
container builds to use a more robust method for detecting if the
currently built image already exists.

-
[#&#8203;9736](https://redirect.github.com/cloudflare/workers-sdk/pull/9736)
[`55c83a7`](55c83a7cf9)
Thanks [@&#8203;gabivlj](https://redirect.github.com/gabivlj)! -
containers: Do not check scopes if not defined

-
[#&#8203;9667](https://redirect.github.com/cloudflare/workers-sdk/pull/9667)
[`406fba5`](406fba5fa2)
Thanks [@&#8203;IRCody](https://redirect.github.com/IRCody)! - Fail
earlier in the deploy process when deploying a container worker if
docker is not detected.

###
[`v4.21.1`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4211)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.21.0...wrangler@4.21.1)

##### Patch Changes

-
[#&#8203;9626](https://redirect.github.com/cloudflare/workers-sdk/pull/9626)
[`9c938c2`](9c938c2183)
Thanks [@&#8203;penalosa](https://redirect.github.com/penalosa)! -
Support `wrangler version upload` for Python Workers

-
[#&#8203;9718](https://redirect.github.com/cloudflare/workers-sdk/pull/9718)
[`fb83341`](fb83341bed)
Thanks [@&#8203;mhart](https://redirect.github.com/mhart)! - fix error
message when docker daemon is not running

-
[#&#8203;9689](https://redirect.github.com/cloudflare/workers-sdk/pull/9689)
[`b137a6f`](b137a6f090)
Thanks [@&#8203;emily-shen](https://redirect.github.com/emily-shen)! -
fix: correctly pass container engine config to miniflare

-
[#&#8203;9722](https://redirect.github.com/cloudflare/workers-sdk/pull/9722)
[`29e911a`](29e911abbb)
Thanks [@&#8203;emily-shen](https://redirect.github.com/emily-shen)! -
Update containers config schema.

Deprecates `containers.configuration` in favour of top level fields.
Makes top level `image` required. Deprecates `instances` and
`durable_objects`. Makes `name` optional.

-
[#&#8203;9666](https://redirect.github.com/cloudflare/workers-sdk/pull/9666)
[`f3c5791`](f3c5791e3a)
Thanks [@&#8203;IRCody](https://redirect.github.com/IRCody)! - Add a
reasonable default name for containers that have no defined name.

- Updated dependencies
\[[`b137a6f`](b137a6f090)]:
  - miniflare@4.20250617.4

###
[`v4.21.0`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4210)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.20.5...wrangler@4.21.0)

##### Minor Changes

-
[#&#8203;9692](https://redirect.github.com/cloudflare/workers-sdk/pull/9692)
[`273952f`](273952ff89)
Thanks [@&#8203;dom96](https://redirect.github.com/dom96)! - Condenses
Python vendored modules in output table

-
[#&#8203;9654](https://redirect.github.com/cloudflare/workers-sdk/pull/9654)
[`2a5988c`](2a5988c50a)
Thanks [@&#8203;dom96](https://redirect.github.com/dom96)! - Python
Workers now automatically bundle .so files from vendored packages

##### Patch Changes

-
[#&#8203;9695](https://redirect.github.com/cloudflare/workers-sdk/pull/9695)
[`0e64c35`](0e64c3515f)
Thanks [@&#8203;emily-shen](https://redirect.github.com/emily-shen)! -
Move hotkey registration later in dev start up

This should have no functional change, but allows us to conditionally
render hotkeys based on config.

-
[#&#8203;9098](https://redirect.github.com/cloudflare/workers-sdk/pull/9098)
[`ef20754`](ef207546d6)
Thanks [@&#8203;jseba](https://redirect.github.com/jseba)! - Migrate
Workers Containers commands to Containers API Endpoints

The Workers Containers API was built on top of Cloudchamber, but has now
been moved to its own API
  with a reduced scoping and new token.

-
[#&#8203;9712](https://redirect.github.com/cloudflare/workers-sdk/pull/9712)
[`2a4c467`](2a4c467d83)
Thanks [@&#8203;emily-shen](https://redirect.github.com/emily-shen)! -
Make `wrangler container` commands print `open-beta` status

###
[`v4.20.5`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4205)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.20.4...wrangler@4.20.5)

##### Patch Changes

-
[#&#8203;9688](https://redirect.github.com/cloudflare/workers-sdk/pull/9688)
[`086e29d`](086e29daf4)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- add remote bindings support to `getPlatformProxy`

  Example:

  ```json
  // wrangler.jsonc
  {
  	"name": "get-platform-proxy-test",
  	"services": [
  		{
  			"binding": "MY_WORKER",
  			"service": "my-worker",
  			"experimental_remote": true
  		}
  	]
  }
  ```

  ```js
  // index.mjs
  import { getPlatformProxy } from "wrangler";

  const { env } = await getPlatformProxy({
  	experimental: {
  		remoteBindings: true,
  	},
  });

  // env.MY_WORKER.fetch() fetches from the remote my-worker service
  ```

-
[#&#8203;9558](https://redirect.github.com/cloudflare/workers-sdk/pull/9558)
[`d5edf52`](d5edf52b43)
Thanks
[@&#8203;ichernetsky-cf](https://redirect.github.com/ichernetsky-cf)! -
`wrangler containers apply` uses `observability` configuration.

-
[#&#8203;9678](https://redirect.github.com/cloudflare/workers-sdk/pull/9678)
[`24b2c66`](24b2c666cf)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- remove warnings during config validations on `experimental_remote`
fields

wrangler commands, run without the `--x-remote-bindings` flag, parsing
config files containing `experimental_remote` fields currently show
warnings stating that the field is not recognized. This is usually more
cumbersome than helpful so here we're loosening up this validation and
making wrangler always recognize the field even when no
`--x-remote-bindings` flag is provided

-
[#&#8203;9633](https://redirect.github.com/cloudflare/workers-sdk/pull/9633)
[`3f478af`](3f478af7f1)
Thanks
[@&#8203;nikitassharma](https://redirect.github.com/nikitassharma)! -
Add support for setting an instance type for containers in wrangler.
This allows users to configure memory, disk, and vCPU by setting
instance type when interacting with containers.

-
[#&#8203;9596](https://redirect.github.com/cloudflare/workers-sdk/pull/9596)
[`5162c51`](5162c51946)
Thanks
[@&#8203;CarmenPopoviciu](https://redirect.github.com/CarmenPopoviciu)!
- add ability to pull images for containers local dev

- Updated dependencies
\[[`bfb791e`](bfb791e708),
[`5162c51`](5162c51946)]:
  - miniflare@4.20250617.3

###
[`v4.20.4`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4204)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.20.3...wrangler@4.20.4)

##### Patch Changes

-
[#&#8203;9673](https://redirect.github.com/cloudflare/workers-sdk/pull/9673)
[`ffa742f`](ffa742f32f)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- fix: ensure that wrangler deploy and version upload don't override the
remote-bindings flag

-
[#&#8203;9653](https://redirect.github.com/cloudflare/workers-sdk/pull/9653)
[`8a60fe7`](8a60fe76ec)
Thanks [@&#8203;penalosa](https://redirect.github.com/penalosa)! -
Rename `WRANGLER_CONTAINERS_DOCKER_PATH` to `WRANGLER_DOCKER_BIN`

-
[#&#8203;9664](https://redirect.github.com/cloudflare/workers-sdk/pull/9664)
[`c489a44`](c489a44847)
Thanks [@&#8203;IRCody](https://redirect.github.com/IRCody)! - Remove
cloudchamber/container apply confirmation dialog when run
non-interactively.

-
[#&#8203;9653](https://redirect.github.com/cloudflare/workers-sdk/pull/9653)
[`8a60fe7`](8a60fe76ec)
Thanks [@&#8203;penalosa](https://redirect.github.com/penalosa)! - Add a
warning banner to `wrangler cloudchamber` and `wrangler containers`
commands

-
[#&#8203;9605](https://redirect.github.com/cloudflare/workers-sdk/pull/9605)
[`17d23d8`](17d23d8e5f)
Thanks [@&#8203;emily-shen](https://redirect.github.com/emily-shen)! -
Add rebuild hotkey for containers local dev, and clean up containers at
the end of a dev session.

- Updated dependencies
\[[`17d23d8`](17d23d8e5f)]:
  - miniflare@4.20250617.2

###
[`v4.20.3`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4203)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.20.2...wrangler@4.20.3)

##### Patch Changes

-
[#&#8203;9621](https://redirect.github.com/cloudflare/workers-sdk/pull/9621)
[`08be3ed`](08be3ed057)
Thanks [@&#8203;gabivlj](https://redirect.github.com/gabivlj)! -
wrangler containers: 'default' scheduling policy should be the default

-
[#&#8203;9586](https://redirect.github.com/cloudflare/workers-sdk/pull/9586)
[`d1d34fe`](d1d34fedd1)
Thanks [@&#8203;penalosa](https://redirect.github.com/penalosa)! -
Remove the Mixed Mode naming in favour of "remote bindings"/"remote
proxy"

- Updated dependencies
\[[`d1d34fe`](d1d34fedd1)]:
  - miniflare@4.20250617.1

###
[`v4.20.2`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4202)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.20.1...wrangler@4.20.2)

##### Patch Changes

-
[#&#8203;9565](https://redirect.github.com/cloudflare/workers-sdk/pull/9565)
[`b1c9139`](b1c9139524)
Thanks [@&#8203;IRCody](https://redirect.github.com/IRCody)! - Ensure
that a container applications image configuration is not updated if
there were not changes to the image.

-
[#&#8203;9628](https://redirect.github.com/cloudflare/workers-sdk/pull/9628)
[`92f12f4`](92f12f442d)
Thanks [@&#8203;gpanders](https://redirect.github.com/gpanders)! -
Remove "Cloudchamber" from user facing error messages

-
[#&#8203;9576](https://redirect.github.com/cloudflare/workers-sdk/pull/9576)
[`2671e77`](2671e77843)
Thanks [@&#8203;vicb](https://redirect.github.com/vicb)! - Add core
local dev functionality for containers.
Adds a new WRANGLER\_DOCKER\_HOST env var to customise what socket to
connect to.

- Updated dependencies
\[[`828b7df`](828b7dffad),
[`2671e77`](2671e77843)]:
  - miniflare@4.20250617.0

###
[`v4.20.1`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4201)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.20.0...wrangler@4.20.1)

##### Patch Changes

-
[#&#8203;9536](https://redirect.github.com/cloudflare/workers-sdk/pull/9536)
[`3b61c41`](3b61c41f2c)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- expose `Unstable_Binding` type

-
[#&#8203;9564](https://redirect.github.com/cloudflare/workers-sdk/pull/9564)
[`1d3293f`](1d3293f0cb)
Thanks [@&#8203;skepticfx](https://redirect.github.com/skepticfx)! -
Switch container registry to `registry.cloudflare.com` from
`registry.cloudchamber.cfdata.org`.
  Also adds the env var `CLOUDFLARE_CONTAINER_REGISTRY` to override this

-
[#&#8203;9520](https://redirect.github.com/cloudflare/workers-sdk/pull/9520)
[`04f9164`](04f9164bbc)
Thanks [@&#8203;vicb](https://redirect.github.com/vicb)! - fix the
default value for keep\_names (`true`)

-
[#&#8203;9506](https://redirect.github.com/cloudflare/workers-sdk/pull/9506)
[`36113c2`](36113c29c8)
Thanks [@&#8203;penalosa](https://redirect.github.com/penalosa)! - Strip
the `CF-Connecting-IP` header from outgoing fetches

-
[#&#8203;9592](https://redirect.github.com/cloudflare/workers-sdk/pull/9592)
[`49f5ac7`](49f5ac7ef2)
Thanks
[@&#8203;petebacondarwin](https://redirect.github.com/petebacondarwin)!
- Point to the right location for docs on telemetry

-
[#&#8203;9593](https://redirect.github.com/cloudflare/workers-sdk/pull/9593)
[`cf33417`](cf33417320)
Thanks [@&#8203;vicb](https://redirect.github.com/vicb)! - drop unused
`WRANGLER_UNENV_RESOLVE_PATHS` env var

-
[#&#8203;9566](https://redirect.github.com/cloudflare/workers-sdk/pull/9566)
[`521eeb9`](521eeb9d7d)
Thanks [@&#8203;vicb](https://redirect.github.com/vicb)! - Bump
`@cloudflare/unenv-preset` to 2.3.3

-
[#&#8203;9344](https://redirect.github.com/cloudflare/workers-sdk/pull/9344)
[`02e2c1e`](02e2c1e4de)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- add warning about env not specified to potentially risky wrangler
commands

add a warning suggesting users to specify their target environment (via
`-e` or `--env`)
when their wrangler config file contains some environments and they are
calling one
  of the following commands:

  - wrangler deploy
  - wrangler versions upload
  - wrangler versions deploy
  - wrangler versions secret bulk
  - wrangler versions secret put
  - wrangler versions secret delete
  - wrangler secret bulk
  - wrangler secret put
  - wrangler secret delete
  - wrangler triggers deploy

this is a measure we're putting in place to try to prevent developers
from accidentally applying
  changes to an incorrect (potentially even production) environment

-
[#&#8203;9344](https://redirect.github.com/cloudflare/workers-sdk/pull/9344)
[`02e2c1e`](02e2c1e4de)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- allow passing an empty string to the `-e|--env` flag to target the
top-level environment

-
[#&#8203;9536](https://redirect.github.com/cloudflare/workers-sdk/pull/9536)
[`3b61c41`](3b61c41f2c)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- performance improvement: restart a mixed mode session only if the
worker's remote bindings have changed

-
[#&#8203;9550](https://redirect.github.com/cloudflare/workers-sdk/pull/9550)
[`c117904`](c11790486f)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- allow `startWorker` to accept `false` as an `inspector` option (to
disable the inspector server)

-
[#&#8203;9473](https://redirect.github.com/cloudflare/workers-sdk/pull/9473)
[`fae8c02`](fae8c02bcf)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- expose new `experimental_maybeStartOrUpdateMixedModeSession` utility

- Updated dependencies
\[[`bd528d5`](bd528d5d53),
[`2177fb4`](2177fb44f4),
[`36113c2`](36113c29c8),
[`e16fcc7`](e16fcc747a)]:
  - miniflare@4.20250612.0

###
[`v4.20.0`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4200)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.19.2...wrangler@4.20.0)

##### Minor Changes

-
[#&#8203;9509](https://redirect.github.com/cloudflare/workers-sdk/pull/9509)
[`0b2ba45`](0b2ba4590c)
Thanks [@&#8203;emily-shen](https://redirect.github.com/emily-shen)! -
feat: add static routing options via 'run\_worker\_first' to Wrangler

Implements the proposal noted here
[https://github.com/cloudflare/workers-sdk/discussions/9143](https://redirect.github.com/cloudflare/workers-sdk/discussions/9143).

This is now usable in `wrangler dev` and in production - just specify
the routes that should hit the worker first with `run_worker_first` in
your Wrangler config. You can also omit certain paths with `!` negative
rules.

##### Patch Changes

-
[#&#8203;9507](https://redirect.github.com/cloudflare/workers-sdk/pull/9507)
[`1914b87`](1914b87e25)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- slightly improve wrangler dev bindings loggings

  improve the bindings loggings by:

- removing the unnecessary (and potentially incorrect) `[connected]`
suffix for remote bindings
- making sure that the modes presented in the bindings logs are
correctly aligned

-
[#&#8203;9475](https://redirect.github.com/cloudflare/workers-sdk/pull/9475)
[`931f467`](931f467e39)
Thanks [@&#8203;edmundhung](https://redirect.github.com/edmundhung)! -
add hello world binding that serves as as an explanatory example.

-
[#&#8203;9443](https://redirect.github.com/cloudflare/workers-sdk/pull/9443)
[`95eb47d`](95eb47d2c6)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- add workerName option to startMixedModeSession API

-
[#&#8203;9541](https://redirect.github.com/cloudflare/workers-sdk/pull/9541)
[`80b8bd9`](80b8bd93e6)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- make workers created with `startWorker` await the `ready` promise on
`dispose`

-
[#&#8203;9443](https://redirect.github.com/cloudflare/workers-sdk/pull/9443)
[`95eb47d`](95eb47d2c6)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- add mixed-mode support for mtls bindings

-
[#&#8203;9515](https://redirect.github.com/cloudflare/workers-sdk/pull/9515)
[`9e4cd16`](9e4cd16ce1)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- make sure that remote binding errors are surfaced when using mixed
(hybrid) mode

-
[#&#8203;9516](https://redirect.github.com/cloudflare/workers-sdk/pull/9516)
[`92305af`](92305af0a7)
Thanks [@&#8203;IRCody](https://redirect.github.com/IRCody)! - Reorder
deploy output when deploying a container worker so the worker url is
printed last and the worker triggers aren't deployed until the container
has been built and deployed successfully.

- Updated dependencies
\[[`931f467`](931f467e39),
[`95eb47d`](95eb47d2c6),
[`0b2ba45`](0b2ba4590c)]:
  - miniflare@4.20250604.1
-
[@&#8203;cloudflare/unenv-preset](https://redirect.github.com/cloudflare/unenv-preset)@&#8203;2.3.3

###
[`v4.19.2`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4192)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.19.1...wrangler@4.19.2)

##### Patch Changes

-
[#&#8203;9461](https://redirect.github.com/cloudflare/workers-sdk/pull/9461)
[`66edd2f`](66edd2f3bd)
Thanks [@&#8203;skepticfx](https://redirect.github.com/skepticfx)! -
Enforce disk limits on container builds

-
[#&#8203;9481](https://redirect.github.com/cloudflare/workers-sdk/pull/9481)
[`d1a1787`](d1a1787b27)
Thanks
[@&#8203;WillTaylorDev](https://redirect.github.com/WillTaylorDev)! -
Force autogenerated aliases to be fully lowercased.

-
[#&#8203;9480](https://redirect.github.com/cloudflare/workers-sdk/pull/9480)
[`1f84092`](1f84092851)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- add `experimentalMixedMode` dev option to `unstable_startWorker`

add an new `experimentalMixedMode` dev option to `unstable_startWorker`
  that allows developers to programmatically start a new mixed mode
  session using startWorker.

  Example usage:

  ```js
  // index.mjs
  import { unstable_startWorker } from "wrangler";

  await unstable_startWorker({
  	dev: {
  		experimentalMixedMode: true,
  	},
  });
  ```

  ```json
  // wrangler.jsonc
  {
  	"$schema": "node_modules/wrangler/config-schema.json",
  	"name": "programmatic-start-worker-example",
  	"main": "src/index.ts",
  	"compatibility_date": "2025-06-01",
  	"services": [
{ "binding": "REMOTE_WORKER", "service": "remote-worker", "remote": true
}
  	]
  }
  ```

- Updated dependencies
\[[`4ab5a40`](4ab5a4027d),
[`485cd08`](485cd08679),
[`e3b3ef5`](e3b3ef51cf),
[`3261957`](3261957aba)]:
  - miniflare@4.20250604.0
-
[@&#8203;cloudflare/unenv-preset](https://redirect.github.com/cloudflare/unenv-preset)@&#8203;2.3.3

###
[`v4.19.1`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4191)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.19.0...wrangler@4.19.1)

##### Patch Changes

-
[#&#8203;9456](https://redirect.github.com/cloudflare/workers-sdk/pull/9456)
[`db2cdc6`](db2cdc6b1e)
Thanks
[@&#8203;WillTaylorDev](https://redirect.github.com/WillTaylorDev)! -
Fix bug causing preview alias to always be generated.

###
[`v4.19.0`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4190)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.18.0...wrangler@4.19.0)

##### Minor Changes

-
[#&#8203;9401](https://redirect.github.com/cloudflare/workers-sdk/pull/9401)
[`03b8c1c`](03b8c1ca53)
Thanks
[@&#8203;WillTaylorDev](https://redirect.github.com/WillTaylorDev)! -
Provide ability for Wrangler to upload preview aliases during version
upload.

##### Patch Changes

-
[#&#8203;9390](https://redirect.github.com/cloudflare/workers-sdk/pull/9390)
[`80e75f4`](80e75f4a67)
Thanks [@&#8203;penalosa](https://redirect.github.com/penalosa)! -
Support additional Mixed Mode resources in Wrangler:

  - AI
  - Browser
  - Images
  - Vectorize
  - Dispatch Namespaces

-
[#&#8203;9395](https://redirect.github.com/cloudflare/workers-sdk/pull/9395)
[`b3be057`](b3be057344)
Thanks [@&#8203;Maximo-Guk](https://redirect.github.com/Maximo-Guk)! -
Add WRANGLER\_CI\_OVERRIDE\_NETWORK\_MODE\_HOST for Workers CI

-
[#&#8203;9410](https://redirect.github.com/cloudflare/workers-sdk/pull/9410)
[`87f3843`](87f38432ee)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- enable consumers of `unstable_readConfig` to silence `remote` warnings

- Updated dependencies
\[[`8c7ce77`](8c7ce7728c),
[`80e75f4`](80e75f4a67),
[`80e75f4`](80e75f4a67),
[`fac2f9d`](fac2f9dfa6),
[`92719a5`](92719a535b)]:
  - miniflare@4.20250525.1

###
[`v4.18.0`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4180)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.17.0...wrangler@4.18.0)

##### Minor Changes

-
[#&#8203;9393](https://redirect.github.com/cloudflare/workers-sdk/pull/9393)
[`34b6174`](34b61746f2)
Thanks [@&#8203;jamesopstad](https://redirect.github.com/jamesopstad)! -
Hard fail on Node.js < 20. Wrangler no longer supports Node.js 18.x as
it reached end-of-life on 2025-04-30. See
https://github.com/nodejs/release?tab=readme-ov-file#end-of-life-releases.

##### Patch Changes

-
[#&#8203;9308](https://redirect.github.com/cloudflare/workers-sdk/pull/9308)
[`d3a6eb3`](d3a6eb30e5)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- expose new utilities and types to aid consumers of the programmatic
mixed-mode API

  Specifically the exports have been added:

- `Experimental_MixedModeSession`: type representing a mixed-mode
session
- `Experimental_ConfigBindingsOptions`: type representing
config-bindings
- `experimental_pickRemoteBindings`: utility for picking only the remote
bindings from a record of start-worker bindings.
- `unstable_convertConfigBindingsToStartWorkerBindings`: utility for
converting config-bindings into start-worker bindings (that can be
passed to `startMixedModeSession`)

-
[#&#8203;9347](https://redirect.github.com/cloudflare/workers-sdk/pull/9347)
[`b8f058c`](b8f058c81e)
Thanks [@&#8203;penalosa](https://redirect.github.com/penalosa)! -
Improve binding display on narrower terminals

- Updated dependencies
\[[`d9d937a`](d9d937ab6f),
[`e39a45f`](e39a45ffa0),
[`fdae3f7`](fdae3f7665)]:
  - miniflare@4.20250525.0

###
[`v4.17.0`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4170)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.16.1...wrangler@4.17.0)

##### Minor Changes

-
[#&#8203;9321](https://redirect.github.com/cloudflare/workers-sdk/pull/9321)
[`6c03bde`](6c03bde33f)
Thanks
[@&#8203;petebacondarwin](https://redirect.github.com/petebacondarwin)!
- Add support for FedRAMP High compliance region

Now it is possible to target Wrangler at the FedRAMP High compliance
region.
  There are two ways to signal to Wrangler to run in this mode:

- set `"compliance_region": "fedramp_high"` in a Wrangler configuration
- set `CLOUDFLARE_COMPLIANCE_REGION=fedramp_high` environment variable
when running Wrangler

If both are provided and the values do not match then Wrangler will exit
with an error.

  When in this mode OAuth authentication is not supported.
It is necessary to authenticate using a Cloudflare API Token acquired
from the Cloudflare FedRAMP High dashboard.

  Most bindings and commands are supported in this mode.

- Unsupported commands may result in API requests that are not supported
- possibly 422 Unprocessable Entity responses.
- Unsupported bindings may work in local dev, as there is no local
validation, but will fail at Worker deployment time.

  Resolves DEVX-1921.

-
[#&#8203;9330](https://redirect.github.com/cloudflare/workers-sdk/pull/9330)
[`34c71ce`](34c71ce920)
Thanks [@&#8203;edmundhung](https://redirect.github.com/edmundhung)! -
Updated internal configuration to use Miniflare’s new
`defaultPersistRoot` instead of per-plugin `persist` flags

-
[#&#8203;8973](https://redirect.github.com/cloudflare/workers-sdk/pull/8973)
[`cc7fae4`](cc7fae4cb9)
Thanks
[@&#8203;Caio-Nogueira](https://redirect.github.com/Caio-Nogueira)! -
Show latest instance by default on `workflows instances describe`
command

##### Patch Changes

-
[#&#8203;9335](https://redirect.github.com/cloudflare/workers-sdk/pull/9335)
[`6479fc5`](6479fc5228)
Thanks [@&#8203;penalosa](https://redirect.github.com/penalosa)! -
Redesign `wrangler dev` to more clearly present information and have a
bit of a glow up 
![Screenshot 2025-05-22 at 01 11
43](https://redirect.github.com/user-attachments/assets/26cc6209-37a1-4ecb-8e91-daac2f79a095)

-
[#&#8203;9329](https://redirect.github.com/cloudflare/workers-sdk/pull/9329)
[`410d985`](410d985250)
Thanks [@&#8203;penalosa](https://redirect.github.com/penalosa)! - Hide
logs in the `startMixedModeSession()` API

-
[#&#8203;9325](https://redirect.github.com/cloudflare/workers-sdk/pull/9325)
[`c2678d1`](c2678d1681)
Thanks [@&#8203;edmundhung](https://redirect.github.com/edmundhung)! -
refactor: fallbacks to local image binding from miniflare when local
mode is enabled

- Updated dependencies
\[[`34c71ce`](34c71ce920),
[`f7c82a4`](f7c82a4a9f),
[`7ddd865`](7ddd865fa6),
[`6479fc5`](6479fc5228),
[`e5ae13a`](e5ae13adeb)]:
  - miniflare@4.20250523.0

###
[`v4.16.1`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4161)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.16.0...wrangler@4.16.1)

##### Patch Changes

-
[#&#8203;9268](https://redirect.github.com/cloudflare/workers-sdk/pull/9268)
[`7344344`](734434418f)
Thanks [@&#8203;gabivlj](https://redirect.github.com/gabivlj)! -
`wrangler containers delete` handles API errors correctly

###
[`v4.16.0`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4160)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.15.2...wrangler@4.16.0)

##### Minor Changes

-
[#&#8203;9288](https://redirect.github.com/cloudflare/workers-sdk/pull/9288)
[`3b8f7f1`](3b8f7f18be)
Thanks
[@&#8203;petebacondarwin](https://redirect.github.com/petebacondarwin)!
- allow --name and --env args on wrangler deploy

Previously it was not possible to provide a Worker name as a command
line argument at the same time as setting the Wrangler environment.
Now specifying `--name` is supported and will override any names set in
the Wrangler config:

  **wrangler.json**

  ```json
  {
  	"name": "config-worker"
  	"env": {
  		"staging": { "name": "config-worker-env" }
  	}
  }
  ```

| Command | Previous (Worker name) | Proposed (Worker name) | Comment |
| ------------------------------------------------ |
---------------------- | ---------------------- |
------------------------------------- |
| wrangler deploy --name=args-worker | "args-worker" | "args-worker" |
CLI arg used |
| wrangler deploy --name=args-worker --env=staging | *Error* |
"args-worker" | CLI arg used |
| wrangler deploy --name=args-worker --env=prod | *Error* |
"args-worker" | CLI arg used |
| wrangler deploy | "config-worker" | "config-worker" | Top-level config
used |
| wrangler deploy --env=staging | "config-worker-env" |
"config-worker-env" | Named env config used |
| wrangler deploy --env=prod | "config-worker-prod" |
"config-worker-prod" | CLI arg and top-level config combined |

-
[#&#8203;9265](https://redirect.github.com/cloudflare/workers-sdk/pull/9265)
[`16de0d5`](16de0d5227)
Thanks [@&#8203;edmundhung](https://redirect.github.com/edmundhung)! -
docs: add documentation links to individual config properties in the
JSON schema of the Wrangler config file

##### Patch Changes

-
[#&#8203;9234](https://redirect.github.com/cloudflare/workers-sdk/pull/9234)
[`2fe6219`](2fe62198d7)
Thanks [@&#8203;emily-shen](https://redirect.github.com/emily-shen)! -
fix: add no-op `props` to `ctx` in `getPlatformProxy` to fix type
mismatch

-
[#&#8203;9269](https://redirect.github.com/cloudflare/workers-sdk/pull/9269)
[`66d975e`](66d975e905)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- Wire up mixed-mode remote bindings for multi-worker `wrangler dev`

Under the `--x-mixed-mode` flag, make sure that bindings configurations
with `remote: true` actually generate bindings to remote resources
during a multi-worker `wrangler dev` session, currently the bindings
included in this are: services, kv\_namespaces, r2\_buckets,
d1\_databases, queues and workflows.

Also include the ai binding since the bindings is already remote by
default anyways.

-
[#&#8203;9151](https://redirect.github.com/cloudflare/workers-sdk/pull/9151)
[`5ab035d`](5ab035d8a1)
Thanks [@&#8203;gabivlj](https://redirect.github.com/gabivlj)! -
wrangler containers can be configured with the kind of application
rollout on `apply`

-
[#&#8203;9231](https://redirect.github.com/cloudflare/workers-sdk/pull/9231)
[`02d40ed`](02d40ed3bb)
Thanks
[@&#8203;dario-piotrowicz](https://redirect.github.com/dario-piotrowicz)!
- Wire up mixed-mode remote bindings for (single-worker) `wrangler dev`

Under the `--x-mixed-mode` flag, make sure that bindings configurations
with `remote: true` actually generate bindings to remote resources
during a single-worker `wrangler dev` session, currently the bindings
included in this are: services, kv\_namespaces, r2\_buckets,
d1\_databases, queues and workflows.

Also include the ai binding since the bindings is already remote by
default anyways.

-
[#&#8203;9221](https://redirect.github.com/cloudflare/workers-sdk/pull/9221)
[`2ef31a9`](2ef31a9459)
Thanks [@&#8203;vicb](https://redirect.github.com/vicb)! - bump
`@cloudflare/unenv-preset`

-
[#&#8203;9277](https://redirect.github.com/cloudflare/workers-sdk/pull/9277)
[`db5ea8f`](db5ea8f1f6)
Thanks [@&#8203;penalosa](https://redirect.github.com/penalosa)! -
Support Mixed Mode for more binding types

-
[#&#8203;9266](https://redirect.github.com/cloudflare/workers-sdk/pull/9266)
[`f2a16f1`](f2a16f1126)
Thanks
[@&#8203;petebacondarwin](https://redirect.github.com/petebacondarwin)!
- fix: setting triggers.crons:\[] in Wrangler config should delete
deployed cron schedules

-
[#&#8203;9245](https://redirect.github.com/cloudflare/workers-sdk/pull/9245)
[`b87b472`](b87b472a1a)
Thanks [@&#8203;penalosa](https://redirect.github.com/penalosa)! -
Support Mixed Mode Dispatch Namespaces

- Updated dependencies
\[[`db5ea8f`](db5ea8f1f6),
[`b87b472`](b87b472a1a)]:
  - miniflare@4.20250508.3

###
[`v4.15.2`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4152)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.15.1...wrangler@4.15.2)

##### Patch Changes

-
[#&#8203;9257](https://redirect.github.com/cloudflare/workers-sdk/pull/9257)
[`33daa09`](33daa0961f)
Thanks [@&#8203;penalosa](https://redirect.github.com/penalosa)! - Relax
R2 bucket validation for `pages dev` commands

-
[#&#8203;9256](https://redirect.github.com/cloudflare/workers-sdk/pull/9256)
[`3b384e2`](3b384e28c7)
Thanks [@&#8203;penalosa](https://redirect.github.com/penalosa)! - Move
the Analytics Engine simulator implementation from JSRPC to a Wrapped
binding. This fixes a regression introduced in
[https://github.com/cloudflare/workers-sdk/pull/8935](https://redirect.github.com/cloudflare/workers-sdk/pull/8935)
that preventing Analytics Engine bindings working in local dev for
Workers with a compatibility date prior to JSRPC being enabled.

- Updated dependencies
\[[`3b384e2`](3b384e28c7)]:
  - miniflare@4.20250508.2
-
[@&#8203;cloudflare/unenv-preset](https://redirect.github.com/cloudflare/unenv-preset)@&#8203;2.3.2

###
[`v4.15.1`](https://redirect.github.com/cloudflare/workers-sdk/blob/HEAD/packages/wrangler/CHANGELOG.md#4151)

[Compare
Source](https://redirect.github.com/cloudflare/workers-sdk/compare/wrangler@4.15.0...wrangler@4.15.1)

##### Patch Changes

-
[#&#8203;9248](https://redirect.github.com/cloudflare/workers-sdk/pull/9248)
[`07f4010`](07f4010e6d)

</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:eyJjcmVhdGVkSW5WZXIiOiI0MS4yMy4yIiwidXBkYXRlZEluVmVyIjoiNDEuMjMuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-11 15:27:20 -04:00
29 changed files with 891 additions and 808 deletions

View File

@@ -25,7 +25,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
node-version: '22.17.0'
- uses: pnpm/action-setup@v4
name: Install pnpm

View File

@@ -1,10 +1,12 @@
{
"version": "4.8.0",
"version": "4.9.5",
"extraOrigins": [
"https://google.com",
"https://test.com"
],
"sandbox": true,
"ssoSubIds": [],
"plugins": ["unraid-api-plugin-connect"]
"plugins": [
"unraid-api-plugin-connect"
]
}

View File

@@ -247,347 +247,6 @@ A field whose value conforms to the standard URL format as specified in RFC3986:
"""
scalar URL
type DiskPartition {
"""The name of the partition"""
name: String!
"""The filesystem type of the partition"""
fsType: DiskFsType!
"""The size of the partition in bytes"""
size: Float!
}
"""The type of filesystem on the disk partition"""
enum DiskFsType {
XFS
BTRFS
VFAT
ZFS
EXT4
NTFS
}
type Disk implements Node {
id: PrefixedID!
"""The device path of the disk (e.g. /dev/sdb)"""
device: String!
"""The type of disk (e.g. SSD, HDD)"""
type: String!
"""The model name of the disk"""
name: String!
"""The manufacturer of the disk"""
vendor: String!
"""The total size of the disk in bytes"""
size: Float!
"""The number of bytes per sector"""
bytesPerSector: Float!
"""The total number of cylinders on the disk"""
totalCylinders: Float!
"""The total number of heads on the disk"""
totalHeads: Float!
"""The total number of sectors on the disk"""
totalSectors: Float!
"""The total number of tracks on the disk"""
totalTracks: Float!
"""The number of tracks per cylinder"""
tracksPerCylinder: Float!
"""The number of sectors per track"""
sectorsPerTrack: Float!
"""The firmware revision of the disk"""
firmwareRevision: String!
"""The serial number of the disk"""
serialNum: String!
"""The interface type of the disk"""
interfaceType: DiskInterfaceType!
"""The SMART status of the disk"""
smartStatus: DiskSmartStatus!
"""The current temperature of the disk in Celsius"""
temperature: Float
"""The partitions on the disk"""
partitions: [DiskPartition!]!
}
"""The type of interface the disk uses to connect to the system"""
enum DiskInterfaceType {
SAS
SATA
USB
PCIE
UNKNOWN
}
"""
The SMART (Self-Monitoring, Analysis and Reporting Technology) status of the disk
"""
enum DiskSmartStatus {
OK
UNKNOWN
}
type KeyFile {
location: String
contents: String
}
type Registration implements Node {
id: PrefixedID!
type: registrationType
keyFile: KeyFile
state: RegistrationState
expiration: String
updateExpiration: String
}
enum registrationType {
BASIC
PLUS
PRO
STARTER
UNLEASHED
LIFETIME
INVALID
TRIAL
}
enum RegistrationState {
TRIAL
BASIC
PLUS
PRO
STARTER
UNLEASHED
LIFETIME
EEXPIRED
EGUID
EGUID1
ETRIAL
ENOKEYFILE
ENOKEYFILE1
ENOKEYFILE2
ENOFLASH
ENOFLASH1
ENOFLASH2
ENOFLASH3
ENOFLASH4
ENOFLASH5
ENOFLASH6
ENOFLASH7
EBLACKLISTED
EBLACKLISTED1
EBLACKLISTED2
ENOCONN
}
type Vars implements Node {
id: PrefixedID!
"""Unraid version"""
version: String
maxArraysz: Int
maxCachesz: Int
"""Machine hostname"""
name: String
timeZone: String
comment: String
security: String
workgroup: String
domain: String
domainShort: String
hideDotFiles: Boolean
localMaster: Boolean
enableFruit: String
"""Should a NTP server be used for time sync?"""
useNtp: Boolean
"""NTP Server 1"""
ntpServer1: String
"""NTP Server 2"""
ntpServer2: String
"""NTP Server 3"""
ntpServer3: String
"""NTP Server 4"""
ntpServer4: String
domainLogin: String
sysModel: String
sysArraySlots: Int
sysCacheSlots: Int
sysFlashSlots: Int
useSsl: Boolean
"""Port for the webui via HTTP"""
port: Int
"""Port for the webui via HTTPS"""
portssl: Int
localTld: String
bindMgt: Boolean
"""Should telnet be enabled?"""
useTelnet: Boolean
porttelnet: Int
useSsh: Boolean
portssh: Int
startPage: String
startArray: Boolean
spindownDelay: String
queueDepth: String
spinupGroups: Boolean
defaultFormat: String
defaultFsType: String
shutdownTimeout: Int
luksKeyfile: String
pollAttributes: String
pollAttributesDefault: String
pollAttributesStatus: String
nrRequests: Int
nrRequestsDefault: Int
nrRequestsStatus: String
mdNumStripes: Int
mdNumStripesDefault: Int
mdNumStripesStatus: String
mdSyncWindow: Int
mdSyncWindowDefault: Int
mdSyncWindowStatus: String
mdSyncThresh: Int
mdSyncThreshDefault: Int
mdSyncThreshStatus: String
mdWriteMethod: Int
mdWriteMethodDefault: String
mdWriteMethodStatus: String
shareDisk: String
shareUser: String
shareUserInclude: String
shareUserExclude: String
shareSmbEnabled: Boolean
shareNfsEnabled: Boolean
shareAfpEnabled: Boolean
shareInitialOwner: String
shareInitialGroup: String
shareCacheEnabled: Boolean
shareCacheFloor: String
shareMoverSchedule: String
shareMoverLogging: Boolean
fuseRemember: String
fuseRememberDefault: String
fuseRememberStatus: String
fuseDirectio: String
fuseDirectioDefault: String
fuseDirectioStatus: String
shareAvahiEnabled: Boolean
shareAvahiSmbName: String
shareAvahiSmbModel: String
shareAvahiAfpName: String
shareAvahiAfpModel: String
safeMode: Boolean
startMode: String
configValid: Boolean
configError: ConfigErrorState
joinStatus: String
deviceCount: Int
flashGuid: String
flashProduct: String
flashVendor: String
regCheck: String
regFile: String
regGuid: String
regTy: registrationType
regState: RegistrationState
"""Registration owner"""
regTo: String
regTm: String
regTm2: String
regGen: String
sbName: String
sbVersion: String
sbUpdated: String
sbEvents: Int
sbState: String
sbClean: Boolean
sbSynced: Int
sbSyncErrs: Int
sbSynced2: Int
sbSyncExit: String
sbNumDisks: Int
mdColor: String
mdNumDisks: Int
mdNumDisabled: Int
mdNumInvalid: Int
mdNumMissing: Int
mdNumNew: Int
mdNumErased: Int
mdResync: Int
mdResyncCorr: String
mdResyncPos: String
mdResyncDb: String
mdResyncDt: String
mdResyncAction: String
mdResyncSize: Int
mdState: String
mdVersion: String
cacheNumDevices: Int
cacheSbNumDisks: Int
fsState: String
"""Human friendly string of array events happening"""
fsProgress: String
"""
Percentage from 0 - 100 while upgrading a disk or swapping parity drives
"""
fsCopyPrcnt: Int
fsNumMounted: Int
fsNumUnmountable: Int
fsUnmountableMask: String
"""Total amount of user shares"""
shareCount: Int
"""Total amount shares with SMB enabled"""
shareSmbCount: Int
"""Total amount shares with NFS enabled"""
shareNfsCount: Int
"""Total amount shares with AFP enabled"""
shareAfpCount: Int
shareMoverActive: Boolean
csrfToken: String
}
"""Possible error states for configuration"""
enum ConfigErrorState {
UNKNOWN_ERROR
INELIGIBLE
INVALID
NO_KEY_SERVER
WITHDRAWN
}
type Permission {
resource: Resource!
actions: [String!]!
@@ -961,6 +620,102 @@ enum ThemeName {
white
}
type DiskPartition {
"""The name of the partition"""
name: String!
"""The filesystem type of the partition"""
fsType: DiskFsType!
"""The size of the partition in bytes"""
size: Float!
}
"""The type of filesystem on the disk partition"""
enum DiskFsType {
XFS
BTRFS
VFAT
ZFS
EXT4
NTFS
}
type Disk implements Node {
id: PrefixedID!
"""The device path of the disk (e.g. /dev/sdb)"""
device: String!
"""The type of disk (e.g. SSD, HDD)"""
type: String!
"""The model name of the disk"""
name: String!
"""The manufacturer of the disk"""
vendor: String!
"""The total size of the disk in bytes"""
size: Float!
"""The number of bytes per sector"""
bytesPerSector: Float!
"""The total number of cylinders on the disk"""
totalCylinders: Float!
"""The total number of heads on the disk"""
totalHeads: Float!
"""The total number of sectors on the disk"""
totalSectors: Float!
"""The total number of tracks on the disk"""
totalTracks: Float!
"""The number of tracks per cylinder"""
tracksPerCylinder: Float!
"""The number of sectors per track"""
sectorsPerTrack: Float!
"""The firmware revision of the disk"""
firmwareRevision: String!
"""The serial number of the disk"""
serialNum: String!
"""The interface type of the disk"""
interfaceType: DiskInterfaceType!
"""The SMART status of the disk"""
smartStatus: DiskSmartStatus!
"""The current temperature of the disk in Celsius"""
temperature: Float
"""The partitions on the disk"""
partitions: [DiskPartition!]!
}
"""The type of interface the disk uses to connect to the system"""
enum DiskInterfaceType {
SAS
SATA
USB
PCIE
UNKNOWN
}
"""
The SMART (Self-Monitoring, Analysis and Reporting Technology) status of the disk
"""
enum DiskSmartStatus {
OK
UNKNOWN
}
type InfoApps implements Node {
id: PrefixedID!
@@ -1351,6 +1106,60 @@ type Owner {
avatar: String!
}
type KeyFile {
location: String
contents: String
}
type Registration implements Node {
id: PrefixedID!
type: registrationType
keyFile: KeyFile
state: RegistrationState
expiration: String
updateExpiration: String
}
enum registrationType {
BASIC
PLUS
PRO
STARTER
UNLEASHED
LIFETIME
INVALID
TRIAL
}
enum RegistrationState {
TRIAL
BASIC
PLUS
PRO
STARTER
UNLEASHED
LIFETIME
EEXPIRED
EGUID
EGUID1
ETRIAL
ENOKEYFILE
ENOKEYFILE1
ENOKEYFILE2
ENOFLASH
ENOFLASH1
ENOFLASH2
ENOFLASH3
ENOFLASH4
ENOFLASH5
ENOFLASH6
ENOFLASH7
EBLACKLISTED
EBLACKLISTED1
EBLACKLISTED2
ENOCONN
}
type ProfileModel implements Node {
id: PrefixedID!
username: String!
@@ -1416,6 +1225,197 @@ type Settings implements Node {
api: ApiConfig!
}
type Vars implements Node {
id: PrefixedID!
"""Unraid version"""
version: String
maxArraysz: Int
maxCachesz: Int
"""Machine hostname"""
name: String
timeZone: String
comment: String
security: String
workgroup: String
domain: String
domainShort: String
hideDotFiles: Boolean
localMaster: Boolean
enableFruit: String
"""Should a NTP server be used for time sync?"""
useNtp: Boolean
"""NTP Server 1"""
ntpServer1: String
"""NTP Server 2"""
ntpServer2: String
"""NTP Server 3"""
ntpServer3: String
"""NTP Server 4"""
ntpServer4: String
domainLogin: String
sysModel: String
sysArraySlots: Int
sysCacheSlots: Int
sysFlashSlots: Int
useSsl: Boolean
"""Port for the webui via HTTP"""
port: Int
"""Port for the webui via HTTPS"""
portssl: Int
localTld: String
bindMgt: Boolean
"""Should telnet be enabled?"""
useTelnet: Boolean
porttelnet: Int
useSsh: Boolean
portssh: Int
startPage: String
startArray: Boolean
spindownDelay: String
queueDepth: String
spinupGroups: Boolean
defaultFormat: String
defaultFsType: String
shutdownTimeout: Int
luksKeyfile: String
pollAttributes: String
pollAttributesDefault: String
pollAttributesStatus: String
nrRequests: Int
nrRequestsDefault: Int
nrRequestsStatus: String
mdNumStripes: Int
mdNumStripesDefault: Int
mdNumStripesStatus: String
mdSyncWindow: Int
mdSyncWindowDefault: Int
mdSyncWindowStatus: String
mdSyncThresh: Int
mdSyncThreshDefault: Int
mdSyncThreshStatus: String
mdWriteMethod: Int
mdWriteMethodDefault: String
mdWriteMethodStatus: String
shareDisk: String
shareUser: String
shareUserInclude: String
shareUserExclude: String
shareSmbEnabled: Boolean
shareNfsEnabled: Boolean
shareAfpEnabled: Boolean
shareInitialOwner: String
shareInitialGroup: String
shareCacheEnabled: Boolean
shareCacheFloor: String
shareMoverSchedule: String
shareMoverLogging: Boolean
fuseRemember: String
fuseRememberDefault: String
fuseRememberStatus: String
fuseDirectio: String
fuseDirectioDefault: String
fuseDirectioStatus: String
shareAvahiEnabled: Boolean
shareAvahiSmbName: String
shareAvahiSmbModel: String
shareAvahiAfpName: String
shareAvahiAfpModel: String
safeMode: Boolean
startMode: String
configValid: Boolean
configError: ConfigErrorState
joinStatus: String
deviceCount: Int
flashGuid: String
flashProduct: String
flashVendor: String
regCheck: String
regFile: String
regGuid: String
regTy: registrationType
regState: RegistrationState
"""Registration owner"""
regTo: String
regTm: String
regTm2: String
regGen: String
sbName: String
sbVersion: String
sbUpdated: String
sbEvents: Int
sbState: String
sbClean: Boolean
sbSynced: Int
sbSyncErrs: Int
sbSynced2: Int
sbSyncExit: String
sbNumDisks: Int
mdColor: String
mdNumDisks: Int
mdNumDisabled: Int
mdNumInvalid: Int
mdNumMissing: Int
mdNumNew: Int
mdNumErased: Int
mdResync: Int
mdResyncCorr: String
mdResyncPos: String
mdResyncDb: String
mdResyncDt: String
mdResyncAction: String
mdResyncSize: Int
mdState: String
mdVersion: String
cacheNumDevices: Int
cacheSbNumDisks: Int
fsState: String
"""Human friendly string of array events happening"""
fsProgress: String
"""
Percentage from 0 - 100 while upgrading a disk or swapping parity drives
"""
fsCopyPrcnt: Int
fsNumMounted: Int
fsNumUnmountable: Int
fsUnmountableMask: String
"""Total amount of user shares"""
shareCount: Int
"""Total amount shares with SMB enabled"""
shareSmbCount: Int
"""Total amount shares with NFS enabled"""
shareNfsCount: Int
"""Total amount shares with AFP enabled"""
shareAfpCount: Int
shareMoverActive: Boolean
csrfToken: String
}
"""Possible error states for configuration"""
enum ConfigErrorState {
UNKNOWN_ERROR
INELIGIBLE
INVALID
NO_KEY_SERVER
WITHDRAWN
}
type VmDomain implements Node {
"""The unique identifier for the vm (uuid)"""
id: PrefixedID!

View File

@@ -17,7 +17,6 @@ exports[`Returns paths 1`] = `
"myservers-base",
"myservers-config",
"myservers-config-states",
"myservers-env",
"myservers-keepalive",
"keyfile-base",
"machine-id",

View File

@@ -24,7 +24,6 @@ test('Returns paths', async () => {
'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'),

View File

@@ -67,6 +67,7 @@ export const getPackageJsonDependencies = (): string[] | undefined => {
export const API_VERSION = process.env.npm_package_version ?? getPackageJson().version;
/** Controls how the app is built/run (i.e. in terms of optimization) */
export const NODE_ENV =
(process.env.NODE_ENV as 'development' | 'test' | 'staging' | 'production') ?? 'production';
export const environment = {
@@ -76,6 +77,7 @@ export const CHOKIDAR_USEPOLLING = process.env.CHOKIDAR_USEPOLLING === 'true';
export const IS_DOCKER = process.env.IS_DOCKER === 'true';
export const DEBUG = process.env.DEBUG === 'true';
export const INTROSPECTION = process.env.INTROSPECTION === 'true';
/** Determines the app-level & business logic environment (i.e. what data & infrastructure is used) */
export const ENVIRONMENT = process.env.ENVIRONMENT
? (process.env.ENVIRONMENT as 'production' | 'staging' | 'development')
: 'production';

View File

@@ -49,7 +49,6 @@ const initialState = {
resolvePath(process.env.PATHS_STATES ?? ('/usr/local/emhttp/state/' as const)),
'myservers.cfg' as const
),
'myservers-env': '/boot/config/plugins/dynamix.my.servers/env' as const,
'myservers-keepalive':
process.env.PATHS_MY_SERVERS_FB ??
('/boot/config/plugins/dynamix.my.servers/fb_keepalive' as const),

View File

@@ -1,6 +1,6 @@
import { writeFileSync } from 'fs';
import { join } from 'path';
import { ensureWriteSync } from '@unraid/shared/util/file.js';
import { isEqual } from 'lodash-es';
import type { RootState } from '@app/store/index.js';
@@ -27,8 +27,11 @@ export const startStoreSync = async () => {
!isEqual(state, lastState) &&
state.paths['myservers-config-states']
) {
writeFileSync(join(state.paths.states, 'config.log'), JSON.stringify(state.config, null, 2));
writeFileSync(
ensureWriteSync(
join(state.paths.states, 'config.log'),
JSON.stringify(state.config, null, 2)
);
ensureWriteSync(
join(state.paths.states, 'graphql.log'),
JSON.stringify(state.minigraph, null, 2)
);

View File

@@ -1,13 +1,13 @@
import { copyFile, readFile, writeFile } from 'fs/promises';
import { copyFile } from 'fs/promises';
import { join } from 'path';
import { Command, CommandRunner, Option } from 'nest-commander';
import { cliLogger } from '@app/core/log.js';
import { fileExistsSync } from '@app/core/utils/files/file-exists.js';
import { ENVIRONMENT } from '@app/environment.js';
import { getters } from '@app/store/index.js';
import { LogService } from '@app/unraid-api/cli/log.service.js';
import { StartCommand } from '@app/unraid-api/cli/start.command.js';
import { StopCommand } from '@app/unraid-api/cli/stop.command.js';
import { RestartCommand } from '@app/unraid-api/cli/restart.command.js';
interface SwitchEnvOptions {
environment?: 'staging' | 'production';
@@ -31,60 +31,43 @@ export class SwitchEnvCommand extends CommandRunner {
constructor(
private readonly logger: LogService,
private readonly stopCommand: StopCommand,
private readonly startCommand: StartCommand
private readonly restartCommand: RestartCommand
) {
super();
}
private async getEnvironmentFromFile(path: string): Promise<'production' | 'staging'> {
const envFile = await readFile(path, 'utf-8').catch(() => '');
this.logger.debug(`Checking ${path} for current ENV, found ${envFile}`);
// Match the env file env="production" which would be [0] = env="production", [1] = env and [2] = production
const matchArray = /([a-zA-Z]+)=["]*([a-zA-Z]+)["]*/.exec(envFile);
// Get item from index 2 of the regex match or return production
const [, , currentEnvInFile] = matchArray && matchArray.length === 3 ? matchArray : [];
return this.parseStringToEnv(currentEnvInFile);
}
private switchToOtherEnv(environment: 'production' | 'staging'): 'production' | 'staging' {
if (environment === 'production') {
return 'staging';
}
return 'production';
}
async run(_, options: SwitchEnvOptions): Promise<void> {
const paths = getters.paths();
const basePath = paths['unraid-api-base'];
const envFlashFilePath = paths['myservers-env'];
const currentEnvPath = join(basePath, '.env');
this.logger.warn('Stopping the Unraid API');
try {
await this.stopCommand.run([], { delete: false });
} catch (err) {
this.logger.warn('Failed to stop the Unraid API (maybe already stopped?)');
// Determine target environment
const currentEnv = ENVIRONMENT;
const targetEnv = options.environment ?? 'production';
this.logger.info(`Switching environment from ${currentEnv} to ${targetEnv}`);
// Check if target environment file exists
const sourceEnvPath = join(basePath, `.env.${targetEnv}`);
if (!fileExistsSync(sourceEnvPath)) {
this.logger.error(
`Environment file ${sourceEnvPath} does not exist. Cannot switch to ${targetEnv} environment.`
);
process.exit(1);
}
const newEnv =
options.environment ??
this.switchToOtherEnv(await this.getEnvironmentFromFile(envFlashFilePath));
this.logger.info(`Setting environment to ${newEnv}`);
// Copy the target environment file to .env
this.logger.debug(`Copying ${sourceEnvPath} to ${currentEnvPath}`);
try {
await copyFile(sourceEnvPath, currentEnvPath);
this.logger.info(`Successfully switched to ${targetEnv} environment`);
} catch (error) {
this.logger.error(`Failed to copy environment file: ${error}`);
process.exit(1);
}
// Write new env to flash
const newEnvLine = `env="${newEnv}"`;
this.logger.debug('Writing %s to %s', newEnvLine, envFlashFilePath);
await writeFile(envFlashFilePath, newEnvLine);
// Copy the new env over to live location before restarting
const source = join(basePath, `.env.${newEnv}`);
const destination = join(basePath, '.env');
cliLogger.debug('Copying %s to %s', source, destination);
await copyFile(source, destination);
cliLogger.info('Now using %s', newEnv);
await this.startCommand.run([], {});
// Restart the API to pick up the new environment
this.logger.info('Restarting Unraid API to apply environment changes...');
await this.restartCommand.run();
}
}

View File

@@ -10,6 +10,7 @@ export class NginxService {
async reload() {
try {
await execa('/etc/rc.d/rc.nginx', ['reload']);
this.logger.log('Nginx reloaded');
return true;
} catch (err: unknown) {
this.logger.warn('Failed to reload Nginx with error: ', err);

View File

@@ -1,14 +1,18 @@
import { Injectable } from '@nestjs/common';
import { Injectable, Logger } from '@nestjs/common';
import { ONE_SECOND_MS } from '@app/consts.js';
import { NginxService } from '@app/unraid-api/nginx/nginx.service.js';
import { ModificationEffect } from '@app/unraid-api/unraid-file-modifier/file-modification.js';
@Injectable()
export class FileModificationEffectService {
private readonly logger = new Logger(FileModificationEffectService.name);
constructor(private readonly nginxService: NginxService) {}
async runEffect(effect: ModificationEffect): Promise<void> {
switch (effect) {
case 'nginx:reload':
this.logger.log('Reloading Nginx in 10 seconds...');
await new Promise((resolve) => setTimeout(resolve, 10 * ONE_SECOND_MS));
await this.nginxService.reload();
break;
}

View File

@@ -97,7 +97,7 @@
"lodash-es": "4.17.21",
"nest-authz": "2.17.0",
"rxjs": "7.8.2",
"ws": "^8.18.0",
"ws": "8.18.3",
"zen-observable-ts": "1.1.0"
}
}

View File

@@ -130,11 +130,19 @@ export class MothershipConnectionService implements OnModuleInit, OnModuleDestro
}
async onModuleInit() {
// Crash on startup if these config values are not set initially
// Warn on startup if these config values are not set initially
const { unraidVersion, flashGuid, apiVersion } = this.configKeys;
const warnings: string[] = [];
[unraidVersion, flashGuid, apiVersion].forEach((key) => {
this.configService.getOrThrow(key);
try {
this.configService.getOrThrow(key);
} catch (error) {
warnings.push(`${key} is not set`);
}
});
if (warnings.length > 0) {
this.logger.warn('Missing config values: %s', warnings.join(', '));
}
// Setup IDENTITY_CHANGED & METADATA_CHANGED events
this.setupIdentitySubscription();
this.setupMetadataChangedEvent();

View File

@@ -0,0 +1,9 @@
# Justfile for unraid-shared
# Default recipe to run when just is called without arguments
default:
@just --list
# Watch for changes in src files and run clean + build
watch:
watchexec -r -e ts,tsx -w src -- pnpm build

View File

@@ -1,11 +1,24 @@
import { accessSync } from 'fs';
import { access } from 'fs/promises';
import { access, mkdir, writeFile } from 'fs/promises';
import { mkdirSync, writeFileSync } from 'fs';
import { F_OK } from 'node:constants';
import { dirname } from 'path';
/**
* Checks if a file exists asynchronously.
* @param path - The file path to check
* @returns Promise that resolves to true if file exists, false otherwise
*/
export const fileExists = async (path: string) =>
access(path, F_OK)
.then(() => true)
.catch(() => false);
/**
* Checks if a file exists synchronously.
* @param path - The file path to check
* @returns true if file exists, false otherwise
*/
export const fileExistsSync = (path: string) => {
try {
accessSync(path, F_OK);
@@ -14,3 +27,44 @@ export const fileExistsSync = (path: string) => {
return false;
}
};
/**
* Writes data to a file, creating parent directories if they don't exist.
*
* This function ensures the directory structure exists before writing the file,
* equivalent to `mkdir -p` followed by file writing.
*
* @param path - The file path to write to
* @param data - The data to write (string or Buffer)
* @throws {Error} If path is invalid (null, empty, or not a string)
* @throws {Error} For any file system errors (EACCES, EPERM, ENOSPC, EISDIR, etc.)
*/
export const ensureWrite = async (path: string, data: string | Buffer) => {
if (!path || typeof path !== 'string') {
throw new Error(`Invalid path provided: ${path}`);
}
await mkdir(dirname(path), { recursive: true });
return await writeFile(path, data);
};
/**
* Writes data to a file synchronously, creating parent directories if they don't exist.
*
* This function ensures the directory structure exists before writing the file,
* equivalent to `mkdir -p` followed by file writing.
*
* @param path - The file path to write to
* @param data - The data to write (string or Buffer)
* @throws {Error} If path is invalid (null, empty, or not a string)
* @throws {Error} For any file system errors (EACCES, EPERM, ENOSPC, EISDIR, etc.)
*/
export const ensureWriteSync = (path: string, data: string | Buffer) => {
if (!path || typeof path !== 'string') {
throw new Error(`Invalid path provided: ${path}`);
}
mkdirSync(dirname(path), { recursive: true });
return writeFileSync(path, data);
};

View File

@@ -331,8 +331,7 @@ exit 0
<![CDATA[
SCRIPTS_DIR="/usr/local/share/dynamix.unraid.net/install/scripts"
# Log file for debugging
LOGFILE="/var/log/unraid-api/dynamix-unraid-install.log"
mkdir -p "$(dirname "$LOGFILE")"
mkdir -p "/var/log/unraid-api"
echo "Starting Unraid Connect installation..."
@@ -344,26 +343,26 @@ CFG_NEW=/boot/config/plugins/dynamix.my.servers
# Setup the API (but don't start it yet)
if [ -x "$SCRIPTS_DIR/setup_api.sh" ]; then
echo "Setting up Unraid API..."
echo "Running setup_api.sh" >> "$LOGFILE"
# Capture output and add to log file
setup_output=$("$SCRIPTS_DIR/setup_api.sh")
echo "$setup_output" >> "$LOGFILE"
echo "Running setup_api.sh"
# Run and show output to user
"$SCRIPTS_DIR/setup_api.sh"
else
echo "ERROR: setup_api.sh not found or not executable" >> "$LOGFILE"
echo "ERROR: setup_api.sh not found or not executable"
echo "ERROR: setup_api.sh not found or not executable"
fi
# Run post-installation verification
if [ -x "$SCRIPTS_DIR/verify_install.sh" ]; then
echo "Running post-installation verification..."
echo "Running verify_install.sh" >> "$LOGFILE"
# Capture output and add to log file
verify_output=$("$SCRIPTS_DIR/verify_install.sh")
echo "$verify_output" >> "$LOGFILE"
echo "Running verify_install.sh"
# Run and show output to user
"$SCRIPTS_DIR/verify_install.sh"
else
echo "ERROR: verify_install.sh not found or not executable" >> "$LOGFILE"
echo "ERROR: verify_install.sh not found or not executable"
echo "ERROR: verify_install.sh not found or not executable"
fi
echo "Installation completed at $(date)" >> "$LOGFILE"
echo "Installation completed at $(date)"
]]>
</INLINE>
</FILE>
@@ -379,6 +378,18 @@ echo "Installation completed at $(date)" >> "$LOGFILE"
/etc/rc.d/rc.unraid-api cleanup-dependencies
echo "Starting Unraid API service"
echo "DEBUG: Checking PATH: $PATH"
echo "DEBUG: Checking if unraid-api files exist:"
ls -la /usr/local/unraid-api/dist/
echo "DEBUG: Checking symlink:"
ls -la /usr/local/bin/unraid-api
echo "DEBUG: Checking Node.js version:"
node --version
echo "DEBUG: Checking if cli.js is executable:"
ls -la /usr/local/unraid-api/dist/cli.js
echo "DEBUG: Attempting to run unraid-api directly:"
/usr/local/unraid-api/dist/cli.js version || echo "Direct execution failed"
echo "If no additional messages appear within 30 seconds, it is safe to refresh the page."
/etc/rc.d/rc.unraid-api plugins add unraid-api-plugin-connect -b --no-restart
/etc/rc.d/rc.unraid-api start

View File

@@ -166,22 +166,23 @@ _enabled() {
return 1
}
_connected() {
CFG=$API_CONFIG_HOME/connect.json
[[ ! -f "${CFG}" ]] && return 1
local connect_config username status_cfg connection_status
connect_config=$API_CONFIG_HOME/connect.json
[[ ! -f "${connect_config}" ]] && return 1
username=$(jq -r '.username // empty' "${CFG}" 2>/dev/null)
# is the user signed in?
username=$(jq -r '.username // empty' "${connect_config}" 2>/dev/null)
if [ -z "${username}" ]; then
return 1
fi
# the minigraph status is no longer synced to the connect config file
# to avoid a false negative, we'll omit this check for now.
#
# shellcheck disable=SC1090
# source <(sed -nr '/\[connectionStatus\]/,/\[/{/minigraph/p}' "${CFG}" 2>/dev/null)
# # ensure connected
# if [[ -z "${minigraph}" || "${minigraph}" != "CONNECTED" ]]; then
# return 1
# fi
# are we connected to mothership?
status_cfg="/var/local/emhttp/connectStatus.json"
[[ ! -f "${status_cfg}" ]] && return 1
connection_status=$(jq -r '.connectionStatus // empty' "${status_cfg}" 2>/dev/null)
if [[ "${connection_status}" != "CONNECTED" ]]; then
return 1
fi
return 0
}
_haserror() {

View File

@@ -4,9 +4,6 @@
# shellcheck source=/dev/null
source /etc/profile
flash="/boot/config/plugins/dynamix.my.servers"
[[ ! -d "${flash}" ]] && echo "Please reinstall the Unraid Connect plugin" && exit 1
[[ ! -f "${flash}/env" ]] && echo 'env=production' >"${flash}/env"
unraid_binary_path="/usr/local/bin/unraid-api"
api_base_dir="/usr/local/unraid-api"
scripts_dir="/usr/local/share/dynamix.unraid.net/scripts"

View File

@@ -18,10 +18,9 @@ $cli = php_sapi_name()=='cli';
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
require_once "$docroot/webGui/include/Wrappers.php";
require_once "$docroot/plugins/dynamix.my.servers/include/connect-config.php";
$myservers_flash_cfg_path='/boot/config/plugins/dynamix.my.servers/myservers.cfg';
$myservers = file_exists($myservers_flash_cfg_path) ? @parse_ini_file($myservers_flash_cfg_path,true) : [];
$isRegistered = !empty($myservers['remote']['username']);
$isRegistered = ConnectConfig::isUserSignedIn();
// Read connection status from the new API status file
$statusFilePath = '/var/local/emhttp/connectStatus.json';
@@ -595,9 +594,31 @@ set_git_config('user.email', 'gitbot@unraid.net');
set_git_config('user.name', 'gitbot');
// ensure dns can resolve backup.unraid.net
if (! checkdnsrr("backup.unraid.net","A") ) {
$dnsResolved = false;
// Try multiple DNS resolution methods
if (function_exists('dns_get_record')) {
$dnsRecords = dns_get_record("backup.unraid.net", DNS_A);
$dnsResolved = !empty($dnsRecords);
}
// Fallback to gethostbyname if dns_get_record fails
if (!$dnsResolved) {
$ip = gethostbyname("backup.unraid.net");
$dnsResolved = ($ip !== "backup.unraid.net");
}
// Final fallback to system nslookup
if (!$dnsResolved) {
$output = [];
$return_var = 0;
exec('nslookup backup.unraid.net 2>/dev/null', $output, $return_var);
$dnsResolved = ($return_var === 0 && !empty($output));
}
if (!$dnsResolved) {
$arrState['loading'] = '';
$arrState['error'] = 'DNS is unable to resolve backup.unraid.net';
$arrState['error'] = 'DNS resolution failed for backup.unraid.net - PHP DNS functions (checkdnsrr, dns_get_record, gethostbyname) and system nslookup all failed to resolve the hostname. This indicates a DNS configuration issue on your Unraid server. Check your DNS settings in Settings > Network Settings.';
response_complete(406, array('error' => $arrState['error']));
}

View File

@@ -0,0 +1,26 @@
<?php
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
require_once "$docroot/plugins/dynamix.my.servers/include/api-config.php";
/**
* Wrapper around the API's connect.json configuration file.
*/
class ConnectConfig
{
public const CONFIG_PATH = ApiConfig::CONFIG_DIR . '/connect.json';
public static function getConfig()
{
try {
return json_decode(file_get_contents(self::CONFIG_PATH), true) ?? [];
} catch (Throwable $e) {
return [];
}
}
public static function isUserSignedIn()
{
$config = self::getConfig();
return ApiConfig::isConnectPluginEnabled() && !empty($config['username'] ?? '');
}
}

View File

@@ -1,10 +1,7 @@
#!/bin/sh
#!/bin/bash
# Unraid API Installation Verification Script
# Checks that critical files are installed correctly
# Exit on errors
set -e
echo "Performing comprehensive installation verification..."
# Define critical files to check (POSIX-compliant, no arrays)
@@ -171,7 +168,7 @@ if [ $TOTAL_ERRORS -eq 0 ]; then
else
printf 'Found %d total errors.\n' "$TOTAL_ERRORS"
echo "Installation verification completed with issues."
echo "See log file for details: /var/log/unraid-api/dynamix-unraid-install.log"
echo "Please review the errors above and contact support if needed."
# We don't exit with error as this is just a verification script
exit 0
fi

683
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -79,7 +79,7 @@
"@types/testing-library__vue": "5.3.0",
"@typescript-eslint/eslint-plugin": "8.36.0",
"@unraid/tailwind-rem-to-rem": "1.1.0",
"@vitejs/plugin-vue": "5.2.4",
"@vitejs/plugin-vue": "6.0.0",
"@vitest/coverage-v8": "3.2.4",
"@vitest/ui": "3.2.4",
"@vue/test-utils": "2.4.6",
@@ -94,7 +94,7 @@
"eslint-plugin-storybook": "9.0.16",
"eslint-plugin-vue": "10.3.0",
"happy-dom": "18.0.1",
"jiti": "^2.4.2",
"jiti": "2.4.2",
"postcss": "8.5.6",
"postcss-import": "16.1.1",
"prettier": "3.6.2",
@@ -112,7 +112,7 @@
"vitest": "3.2.4",
"vue": "3.5.17",
"vue-tsc": "3.0.1",
"wrangler": "^3.114.10"
"wrangler": "4.24.3"
},
"optionalDependencies": {
"@rollup/rollup-linux-x64-gnu": "4.44.2"

View File

@@ -57,7 +57,7 @@
"@types/semver": "7.7.0",
"@typescript-eslint/eslint-plugin": "8.36.0",
"@unraid/tailwind-rem-to-rem": "1.1.0",
"@vitejs/plugin-vue": "5.2.4",
"@vitejs/plugin-vue": "6.0.0",
"@vitest/coverage-v8": "3.2.4",
"@vue/apollo-util": "4.2.2",
"@vue/test-utils": "2.4.6",