From ae47866724fca47ae52b97233eebfcfb579d5c7d Mon Sep 17 00:00:00 2001 From: Eli Bosley Date: Tue, 25 Feb 2025 14:14:14 -0500 Subject: [PATCH] chore: pure ESM (#1202) --- .github/workflows/main.yml | 1 - .npmrc | 1 + CONTRIBUTING.md | 11 + api/.eslintrc.ts | 23 +- api/codegen.ts | 192 +-- api/commitlint.config.js | 1 + api/fix-array-type.cjs | 18 + api/package.json | 20 +- api/scripts/build.ts | 9 +- api/scripts/get-deployment-version.ts | 8 +- .../__test__/common/allowed-origins.test.ts | 8 +- .../core/modules/array/get-array-data.test.ts | 10 +- .../__test__/core/notifiers/console.test.ts | 4 +- .../core/notifiers/unraid-local.test.ts | 4 +- .../core/utils/array/array-is-running.test.ts | 8 +- .../files/config-file-normalizer.test.ts | 4 +- .../utils/files/safe-ini-serializer.test.ts | 2 +- .../utils/images/image-file-helpers.test.ts | 9 +- .../core/utils/misc/clean-stdout.test.ts | 2 +- .../core/utils/misc/get-key-file.test.ts | 46 +- .../core/utils/misc/parse-config.test.ts | 4 +- .../core/utils/shares/get-shares.test.ts | 6 +- .../resolvers/query/cloud/check-dns.test.ts | 34 - .../check-mothership-authentication.test.ts | 7 +- .../resolvers/subscription/network.test.ts | 28 +- api/src/__test__/mothership/index.test.ts | 6 +- api/src/__test__/setup/keyserver-mock.ts | 2 +- api/src/__test__/store/modules/config.test.ts | 8 +- api/src/__test__/store/modules/emhttp.test.ts | 8 +- api/src/__test__/store/modules/paths.test.ts | 2 +- .../store/modules/registration.test.ts | 28 +- .../store/state-parsers/devices.test.ts | 8 +- .../store/state-parsers/network.test.ts | 8 +- .../__test__/store/state-parsers/nfs.test.ts | 8 +- .../store/state-parsers/nginx.test.ts | 8 +- .../store/state-parsers/shares.test.ts | 8 +- .../store/state-parsers/slots.test.ts | 8 +- .../__test__/store/state-parsers/smb.test.ts | 8 +- .../store/state-parsers/users.test.ts | 8 +- .../__test__/store/state-parsers/var.test.ts | 8 +- .../store/sync/registration-sync.test.ts | 16 +- api/src/__test__/upnp/helpers.test.ts | 2 +- api/src/__test__/utils.test.ts | 2 +- api/src/cli.ts | 10 +- api/src/common/allowed-origins.ts | 12 +- .../common/dashboard/get-unraid-version.ts | 4 +- api/src/common/unraid-version-compare.ts | 2 +- api/src/consts.ts | 2 +- api/src/core/errors/api-key-error.ts | 2 +- api/src/core/errors/array-running-error.ts | 2 +- api/src/core/errors/atomic-write-error.ts | 2 +- api/src/core/errors/em-cmd-error.ts | 2 +- api/src/core/errors/fatal-error.ts | 2 +- api/src/core/errors/field-missing-error.ts | 2 +- api/src/core/errors/file-missing-error.ts | 2 +- api/src/core/errors/not-implemented-error.ts | 2 +- api/src/core/errors/param-invalid-error.ts | 2 +- api/src/core/errors/param-missing-error.ts | 2 +- api/src/core/errors/permission-error.ts | 2 +- api/src/core/errors/php-error.ts | 2 +- api/src/core/index.ts | 10 +- api/src/core/log.ts | 2 +- api/src/core/modules/add-share.ts | 12 +- api/src/core/modules/add-user.ts | 21 +- .../core/modules/array/add-disk-to-array.ts | 16 +- api/src/core/modules/array/get-array-data.ts | 12 +- api/src/core/modules/array/index.ts | 6 + .../modules/array/remove-disk-from-array.ts | 23 +- api/src/core/modules/array/update-array.ts | 24 +- .../core/modules/array/update-parity-check.ts | 12 +- api/src/core/modules/debug/get-context.ts | 2 +- api/src/core/modules/debug/index.ts | 3 + api/src/core/modules/disks/id/get-disk.ts | 19 +- api/src/core/modules/disks/id/index.ts | 3 + api/src/core/modules/disks/index.ts | 3 + .../modules/docker/get-docker-containers.ts | 63 +- .../modules/docker/get-docker-networks.ts | 15 +- api/src/core/modules/docker/index.ts | 4 + api/src/core/modules/get-apps.ts | 2 +- api/src/core/modules/get-devices.ts | 4 +- api/src/core/modules/get-disks.ts | 9 +- api/src/core/modules/get-parity-history.ts | 13 +- api/src/core/modules/get-services.ts | 10 +- api/src/core/modules/get-users.ts | 18 +- api/src/core/modules/get-welcome.ts | 6 +- api/src/core/modules/index.ts | 36 +- api/src/core/modules/services/get-emhttpd.ts | 7 +- .../core/modules/services/get-unraid-api.ts | 7 +- api/src/core/modules/services/index.ts | 4 + api/src/core/modules/services/nginx.ts | 2 +- api/src/core/modules/services/update-dns.ts | 2 +- api/src/core/modules/settings/index.ts | 3 + api/src/core/modules/settings/update-disk.ts | 21 +- api/src/core/modules/shares/index.ts | 3 + api/src/core/modules/shares/name/get-share.ts | 10 +- api/src/core/modules/shares/name/index.ts | 3 + api/src/core/modules/users/id/add-role.ts | 21 +- api/src/core/modules/users/id/delete-user.ts | 19 +- api/src/core/modules/users/id/get-user.ts | 10 +- api/src/core/modules/users/id/index.ts | 5 + api/src/core/modules/users/index.ts | 3 + api/src/core/modules/vms/get-domains.ts | 6 +- api/src/core/modules/vms/index.ts | 2 +- api/src/core/notifiers/console.ts | 10 +- api/src/core/notifiers/http.ts | 4 +- api/src/core/notifiers/index.ts | 5 + api/src/core/notifiers/notifier.ts | 4 +- api/src/core/notifiers/unraid-local.ts | 6 +- api/src/core/types/global.ts | 2 +- api/src/core/types/index.ts | 5 + api/src/core/types/states/sec.ts | 2 +- api/src/core/types/states/var.ts | 4 +- api/src/core/utils/array/array-is-running.ts | 4 +- api/src/core/utils/array/index.ts | 3 + api/src/core/utils/clients/emcmd.ts | 10 +- api/src/core/utils/clients/index.ts | 4 + .../utils/files/config-file-normalizer.ts | 6 +- .../core/utils/files/load-file-from-path.ts | 2 +- .../core/utils/images/image-file-helpers.ts | 4 +- api/src/core/utils/index.ts | 14 +- api/src/core/utils/misc/catch-handlers.ts | 4 +- api/src/core/utils/misc/exit-app.ts | 4 +- api/src/core/utils/misc/get-key-file.ts | 4 +- api/src/core/utils/misc/get-machine-id.ts | 4 +- .../core/utils/misc/global-error-handler.ts | 2 +- api/src/core/utils/misc/load-state.ts | 4 +- api/src/core/utils/misc/parse-config.ts | 4 +- .../core/utils/misc/send-form-to-keyserver.ts | 4 +- .../utils/permissions/check-permission.ts | 2 +- .../utils/permissions/ensure-permission.ts | 4 +- api/src/core/utils/plugins/index.ts | 3 + api/src/core/utils/plugins/php-loader.ts | 6 +- api/src/core/utils/server-identifier.ts | 2 +- api/src/core/utils/shares/get-shares.ts | 8 +- api/src/core/utils/shares/index.ts | 4 + api/src/core/utils/shares/process-share.ts | 6 +- .../utils/validation/context/ensure-data.ts | 4 +- .../validation/context/ensure-parameter.ts | 4 +- .../utils/validation/context/ensure-query.ts | 4 +- .../core/utils/validation/context/index.ts | 5 + api/src/core/utils/validation/has-fields.ts | 2 +- api/src/core/utils/validation/index.ts | 5 + api/src/core/utils/vms/domain/index.ts | 5 + api/src/core/utils/vms/get-hypervisor.ts | 2 +- api/src/core/utils/vms/get-pci-devices.ts | 4 +- api/src/core/utils/vms/index.ts | 8 + api/src/core/utils/vms/parse-domain.ts | 4 +- api/src/core/utils/vms/parse-domains.ts | 6 +- api/src/core/utils/write-to-boot.ts | 4 +- api/src/environment.ts | 20 +- api/src/graphql/client/api/get-api-client.ts | 6 +- api/src/graphql/generated/api/operations.ts | 31 +- api/src/graphql/generated/api/types.ts | 7 +- api/src/graphql/generated/client/graphql.ts | 2 +- .../graphql/generated/client/validators.ts | 6 +- api/src/graphql/index.ts | 4 +- api/src/graphql/mothership/mutations.ts | 2 +- api/src/graphql/mothership/subscriptions.ts | 2 +- .../mutation/connect/connect-sign-in.ts | 10 +- .../resolvers/query/cloud/check-api.ts | 4 +- .../resolvers/query/cloud/check-cloud.ts | 20 +- .../resolvers/query/cloud/check-dns.ts | 12 +- .../query/cloud/check-minigraphql.ts | 6 +- .../cloud/check-mothership-authentication.ts | 8 +- api/src/graphql/resolvers/query/info.ts | 69 +- .../graphql/resolvers/subscription/network.ts | 21 +- .../remote-graphql/remote-query.ts | 16 +- .../remote-graphql/remote-subscription.ts | 6 +- api/src/graphql/schema.ts | 11 - api/src/graphql/schema/loadTypesDefs.ts | 2 +- .../graphql/schema/types/disks/disk.graphql | 1 + api/src/graphql/schema/utils.ts | 18 +- api/src/index.ts | 38 +- api/src/mothership/graphql-client.ts | 20 +- api/src/mothership/jobs/ping-timeout-jobs.ts | 16 +- api/src/mothership/subscribe-to-mothership.ts | 22 +- api/src/mothership/utils/delay-function.ts | 2 +- .../utils/get-mothership-websocket-headers.ts | 10 +- .../handlers/remote-access-interface.ts | 4 +- .../handlers/static-remote-access.ts | 14 +- .../handlers/upnp-remote-access.ts | 16 +- .../remoteAccess/remote-access-controller.ts | 20 +- api/src/run.ts | 10 +- .../store/actions/add-remote-subscription.ts | 20 +- .../actions/handle-remote-graphql-event.ts | 14 +- .../store/actions/load-dynamix-config-file.ts | 10 +- .../actions/reload-nginx-and-update-dns.ts | 8 +- api/src/store/actions/set-minigraph-status.ts | 2 +- .../actions/set-wan-access-with-reload.ts | 6 +- api/src/store/actions/setup-remote-access.ts | 8 +- api/src/store/actions/shutdown-api-event.ts | 14 +- api/src/store/getters/index.ts | 8 +- api/src/store/index.ts | 26 +- .../store/listeners/array-event-listener.ts | 12 +- api/src/store/listeners/config-listener.ts | 12 +- .../dynamic-remote-access-listener.ts | 14 +- .../store/listeners/listener-middleware.ts | 18 +- .../mothership-subscription-listener.ts | 12 +- .../listeners/notification-path-listener.ts | 8 +- .../store/listeners/server-state-listener.ts | 12 +- api/src/store/listeners/stop-listeners.ts | 4 +- api/src/store/listeners/upnp-listener.ts | 16 +- api/src/store/listeners/version-listener.ts | 10 +- .../listeners/wan-access-change-listener.ts | 8 +- api/src/store/middleware.ts | 13 - api/src/store/modules/cache.ts | 8 +- api/src/store/modules/config.ts | 34 +- api/src/store/modules/docker.ts | 4 +- .../store/modules/dynamic-remote-access.ts | 18 +- api/src/store/modules/dynamix.ts | 8 +- api/src/store/modules/emhttp.ts | 46 +- api/src/store/modules/minigraph.ts | 10 +- api/src/store/modules/notifications.ts | 16 +- api/src/store/modules/registration.ts | 8 +- api/src/store/modules/remote-graphql.ts | 12 +- api/src/store/modules/upnp.ts | 17 +- api/src/store/state-parsers/devices.ts | 2 +- api/src/store/state-parsers/network.ts | 10 +- api/src/store/state-parsers/nfs.ts | 4 +- api/src/store/state-parsers/nginx.ts | 8 +- api/src/store/state-parsers/shares.ts | 6 +- api/src/store/state-parsers/slots.ts | 10 +- api/src/store/state-parsers/smb.ts | 6 +- api/src/store/state-parsers/users.ts | 4 +- api/src/store/state-parsers/var.ts | 17 +- api/src/store/store-sync.ts | 14 +- api/src/store/sync/config-disk-sync.ts | 12 +- api/src/store/sync/info-apps-sync.ts | 10 +- api/src/store/sync/registration-sync.ts | 10 +- api/src/store/types.ts | 40 +- api/src/store/watch/config-watch.ts | 12 +- api/src/store/watch/docker-watch.ts | 12 +- api/src/store/watch/dynamix-config-watch.ts | 4 +- api/src/store/watch/registration-watch.ts | 6 +- api/src/store/watch/state-watch.ts | 16 +- api/src/store/watch/var-run-watch.ts | 8 +- api/src/types/my-servers-config.ts | 2 +- api/src/unraid-api/app/app.module.ts | 16 +- api/src/unraid-api/app/cors.ts | 12 +- .../unraid-api/auth/api-key.service.spec.ts | 32 +- api/src/unraid-api/auth/api-key.service.ts | 12 +- api/src/unraid-api/auth/auth.guard.ts | 10 +- api/src/unraid-api/auth/auth.module.ts | 18 +- api/src/unraid-api/auth/auth.service.spec.ts | 12 +- api/src/unraid-api/auth/auth.service.ts | 12 +- .../unraid-api/auth/casbin/casbin.module.ts | 2 +- .../unraid-api/auth/casbin/casbin.service.ts | 2 +- api/src/unraid-api/auth/casbin/index.ts | 4 +- api/src/unraid-api/auth/casbin/policy.ts | 2 +- .../unraid-api/auth/cookie.service.spec.ts | 2 +- api/src/unraid-api/auth/cookie.service.ts | 6 +- api/src/unraid-api/auth/cookie.strategy.ts | 4 +- api/src/unraid-api/auth/header.strategy.ts | 4 +- api/src/unraid-api/auth/user.decorator.ts | 4 +- .../cli/apikey/add-api-key.questions.ts | 6 +- .../unraid-api/cli/apikey/api-key.command.ts | 8 +- api/src/unraid-api/cli/cli.module.ts | 46 +- api/src/unraid-api/cli/config.command.ts | 4 +- .../cli/developer/developer.command.ts | 12 +- api/src/unraid-api/cli/log.service.ts | 4 +- api/src/unraid-api/cli/logs.command.ts | 2 +- api/src/unraid-api/cli/pm2.service.ts | 6 +- api/src/unraid-api/cli/report.command.ts | 10 +- api/src/unraid-api/cli/restart.command.ts | 6 +- .../cli/sso/add-sso-user.command.ts | 12 +- .../cli/sso/list-sso-user.command.ts | 6 +- .../cli/sso/remove-sso-user.command.ts | 10 +- .../cli/sso/remove-sso-user.questions.ts | 4 +- api/src/unraid-api/cli/sso/sso.command.ts | 10 +- .../cli/sso/validate-token.command.ts | 8 +- api/src/unraid-api/cli/start.command.ts | 10 +- api/src/unraid-api/cli/status.command.ts | 2 +- api/src/unraid-api/cli/stop.command.ts | 4 +- api/src/unraid-api/cli/switch-env.command.ts | 12 +- api/src/unraid-api/cli/version.command.ts | 4 +- api/src/unraid-api/cron/cron.module.ts | 4 +- .../cron/write-flash-file.service.ts | 8 +- .../unraid-api/cron/write-flash-file.spec.ts | 20 +- .../graph/connect/connect.resolver.spec.ts | 4 +- .../graph/connect/connect.resolver.ts | 14 +- .../graph/connect/connect.service.spec.ts | 4 +- api/src/unraid-api/graph/graph.module.ts | 75 +- api/src/unraid-api/graph/id-prefix-plugin.ts | 4 +- .../graph/network/network.resolver.spec.ts | 4 +- .../graph/network/network.resolver.ts | 4 +- .../api-key/api-key.resolver.spec.ts | 12 +- .../resolvers/api-key/api-key.resolver.ts | 10 +- .../resolvers/array/array.resolver.spec.ts | 4 +- .../graph/resolvers/array/array.resolver.ts | 8 +- .../resolvers/cloud/cloud.resolver.spec.ts | 4 +- .../graph/resolvers/cloud/cloud.resolver.ts | 20 +- .../resolvers/config/config.resolver.spec.ts | 4 +- .../graph/resolvers/config/config.resolver.ts | 10 +- .../resolvers/disks/disks.resolver.spec.ts | 4 +- .../graph/resolvers/disks/disks.resolver.ts | 4 +- .../display/display.resolver.spec.ts | 4 +- .../resolvers/display/display.resolver.ts | 8 +- .../resolvers/docker/docker.resolver.spec.ts | 4 +- .../graph/resolvers/docker/docker.resolver.ts | 6 +- .../resolvers/flash/flash.resolver.spec.ts | 4 +- .../graph/resolvers/flash/flash.resolver.ts | 4 +- .../resolvers/info/info.resolver.spec.ts | 4 +- .../graph/resolvers/info/info.resolver.ts | 8 +- .../graph/resolvers/me/me.resolver.spec.ts | 4 +- .../graph/resolvers/me/me.resolver.ts | 6 +- .../notifications/notifications.resolver.ts | 12 +- .../notifications.service.spec.ts | 13 +- .../notifications/notifications.service.ts | 24 +- .../resolvers/online/online.resolver.spec.ts | 4 +- .../graph/resolvers/online/online.resolver.ts | 2 +- .../resolvers/owner/owner.resolver.spec.ts | 4 +- .../graph/resolvers/owner/owner.resolver.ts | 6 +- .../registration.resolver.spec.ts | 4 +- .../registration/registration.resolver.ts | 12 +- .../graph/resolvers/resolvers.module.ts | 38 +- .../resolvers/servers/server.resolver.spec.ts | 4 +- .../resolvers/servers/server.resolver.ts | 8 +- .../resolvers/vars/vars.resolver.spec.ts | 4 +- .../graph/resolvers/vars/vars.resolver.ts | 4 +- .../graph/resolvers/vms/vms.resolver.spec.ts | 4 +- .../graph/resolvers/vms/vms.resolver.ts | 10 +- api/src/unraid-api/graph/sandbox-plugin.ts | 2 +- .../graph/services/services.resolver.spec.ts | 4 +- .../graph/services/services.resolver.ts | 8 +- .../graph/shares/shares.resolver.spec.ts | 4 +- .../graph/shares/shares.resolver.ts | 4 +- api/src/unraid-api/main.ts | 14 +- .../unraid-api/observers/shutdown.observer.ts | 2 +- api/src/unraid-api/rest/rest.controller.ts | 8 +- api/src/unraid-api/rest/rest.module.ts | 4 +- api/src/unraid-api/rest/rest.service.spec.ts | 4 +- api/src/unraid-api/rest/rest.service.ts | 11 +- api/src/unraid-api/types/request.ts | 2 +- .../__test__/generic-modification.spec.ts | 37 +- .../auth-request.modification.ts | 2 +- .../default-page-layout.modification.ts | 2 +- .../modifications/log-rotate.modification.ts | 4 +- .../notifications-page.modification.ts | 2 +- .../modifications/sso.modification.ts | 4 +- .../unraid-file-modifier.module.ts | 2 +- .../unraid-file-modifier.service.ts | 12 +- .../unraid-file-modifier.spec.ts | 17 +- api/src/upnp/helpers.ts | 14 +- api/src/upnp/jobs.ts | 6 +- api/src/utils.ts | 4 +- api/tsconfig.json | 12 +- api/vite.config.ts | 1 + package.json | 1 + pnpm-lock.yaml | 1102 ++++++++++++----- .../ConnectSettings/AllowedOrigins.vue | 3 +- 350 files changed, 2587 insertions(+), 1923 deletions(-) create mode 100644 .npmrc create mode 100644 api/commitlint.config.js create mode 100644 api/fix-array-type.cjs delete mode 100644 api/src/__test__/graphql/resolvers/query/cloud/check-dns.test.ts create mode 100644 api/src/core/modules/array/index.ts create mode 100644 api/src/core/modules/debug/index.ts create mode 100644 api/src/core/modules/disks/id/index.ts create mode 100644 api/src/core/modules/disks/index.ts create mode 100644 api/src/core/modules/docker/index.ts create mode 100644 api/src/core/modules/services/index.ts create mode 100644 api/src/core/modules/settings/index.ts create mode 100644 api/src/core/modules/shares/index.ts create mode 100644 api/src/core/modules/shares/name/index.ts create mode 100644 api/src/core/modules/users/id/index.ts create mode 100644 api/src/core/modules/users/index.ts create mode 100644 api/src/core/notifiers/index.ts create mode 100644 api/src/core/types/index.ts create mode 100644 api/src/core/utils/array/index.ts create mode 100644 api/src/core/utils/clients/index.ts create mode 100644 api/src/core/utils/plugins/index.ts create mode 100644 api/src/core/utils/shares/index.ts create mode 100644 api/src/core/utils/validation/context/index.ts create mode 100644 api/src/core/utils/validation/index.ts create mode 100644 api/src/core/utils/vms/domain/index.ts create mode 100644 api/src/core/utils/vms/index.ts delete mode 100644 api/src/graphql/schema.ts delete mode 100644 api/src/store/middleware.ts diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 527123a28..5d35186a3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -122,7 +122,6 @@ jobs: - name: Type Check run: pnpm run type-check - continue-on-error: true - name: Build run: pnpm run build diff --git a/.npmrc b/.npmrc new file mode 100644 index 000000000..0519ecba6 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 477fb8ca1..41d35f297 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,6 +7,17 @@ Thank you for your interest in contributing to Unraid Connect! We want to make c - Submitting a fix - Proposing new features +## TypeScript Import Extensions in the API Directory + +When working with the API directory, you'll notice that TypeScript files are imported with `.js` extensions (e.g., `import { something } from './file.js'`) even though the actual files have `.ts` extensions. This is because: + +1. We use ECMAScript modules (ESM) in our TypeScript configuration +2. When TypeScript compiles `.ts` files to `.js`, the import paths in the compiled code need to reference `.js` files +3. TypeScript doesn't automatically change the extensions in import statements during compilation +4. Using `.js` extensions in imports ensures that both TypeScript during development and Node.js in production can resolve the modules correctly + +This approach follows the [official TypeScript ESM recommendation](https://www.typescriptlang.org/docs/handbook/esm-node.html) and ensures compatibility across development and production environments. + ## Development Process We use GitHub to host code, to track issues and feature requests, as well as accept pull requests. diff --git a/api/.eslintrc.ts b/api/.eslintrc.ts index a2930a323..881f777bb 100644 --- a/api/.eslintrc.ts +++ b/api/.eslintrc.ts @@ -1,4 +1,5 @@ import eslint from '@eslint/js'; +import importPlugin from 'eslint-plugin-import'; import noRelativeImportPaths from 'eslint-plugin-no-relative-import-paths'; import prettier from 'eslint-plugin-prettier'; import tseslint from 'typescript-eslint'; @@ -7,6 +8,7 @@ export default tseslint.config(eslint.configs.recommended, ...tseslint.configs.r plugins: { 'no-relative-import-paths': noRelativeImportPaths, prettier: prettier, + import: importPlugin, }, rules: { '@typescript-eslint/no-redundant-type-constituents': 'off', @@ -22,7 +24,6 @@ export default tseslint.config(eslint.configs.recommended, ...tseslint.configs.r '@typescript-eslint/no-unused-vars': 'off', '@typescript-eslint/no-unused-expressions': 'off', 'import/no-unresolved': 'off', - 'import/extensions': 'off', 'import/no-absolute-path': 'off', 'import/prefer-default-export': 'off', 'no-relative-import-paths/no-relative-import-paths': [ @@ -30,6 +31,26 @@ export default tseslint.config(eslint.configs.recommended, ...tseslint.configs.r { allowSameFolder: false, rootDir: 'src', prefix: '@app' }, ], 'prettier/prettier': 'error', + 'import/extensions': [ + 'error', + 'ignorePackages', + { + js: 'always', + ts: 'always', + }, + ], + 'no-restricted-globals': [ + 'error', + { + name: '__dirname', + message: 'Use import.meta.url instead of __dirname in ESM', + }, + { + name: '__filename', + message: 'Use import.meta.url instead of __filename in ESM', + }, + ], }, + ignores: ['src/graphql/generated/client/**/*'], }); diff --git a/api/codegen.ts b/api/codegen.ts index 62cdc2d72..195c46d83 100644 --- a/api/codegen.ts +++ b/api/codegen.ts @@ -1,105 +1,105 @@ 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', - useTypeImports: true, - }, - scalars: { - DateTime: 'string', - Long: 'number', - JSON: '{ [key: string]: any }', - URL: 'URL', - Port: 'number', - UUID: 'string', - }, - }, - generates: { - 'src/graphql/generated/client/': { - documents: './src/graphql/mothership/*.ts', - schema: { - [process.env.MOTHERSHIP_GRAPHQL_LINK as string]: { - headers: { - origin: 'https://forums.unraid.net', - }, + overwrite: true, + emitLegacyCommonJSImports: false, + verbose: true, + config: { + namingConvention: { + typeNames: './fix-array-type.cjs', + enumValues: 'change-case#upperCase', + useTypeImports: true, }, - }, - preset: 'client', - presetConfig: { - gqlTagName: 'graphql', - }, - config: { - useTypeImports: true, - withObjectType: true, - }, - 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 */' } }, - ], - config: { - contextType: '@app/graphql/schema/utils#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', - }, - plugins: [ - 'typescript-validation-schema', - 'typescript-operations', - 'typed-document-node', - { add: { content: '/* eslint-disable */' } }, - ], - config: { - importFrom: '@app/graphql/generated/api/types', - strictScalars: false, - schema: 'zod', - withObjectType: true, - }, - }, - 'src/graphql/generated/client/validators.ts': { - schema: { - [process.env.MOTHERSHIP_GRAPHQL_LINK as string]: { - headers: { - origin: 'https://forums.unraid.net', - }, + scalars: { + DateTime: 'string', + Long: 'number', + JSON: 'Record', + URL: 'URL', + Port: 'number', + UUID: 'string', + }, + scalarSchemas: { + URL: 'z.instanceof(URL)', + Long: 'z.number()', + JSON: 'z.record(z.string(), z.any())', + Port: 'z.number()', + UUID: 'z.string()', + }, + }, + generates: { + 'src/graphql/generated/client/': { + documents: './src/graphql/mothership/*.ts', + schema: { + [process.env.MOTHERSHIP_GRAPHQL_LINK as string]: { + headers: { + origin: 'https://forums.unraid.net', + }, + }, + }, + preset: 'client', + presetConfig: { + gqlTagName: 'graphql', + }, + config: { + useTypeImports: true, + withObjectType: true, + }, + 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]: { + headers: { + origin: 'https://forums.unraid.net', + }, + }, + }, + plugins: ['typescript-validation-schema', { add: { content: '/* eslint-disable */' } }], + config: { + importFrom: '@app/graphql/generated/client/graphql.js', + strictScalars: false, + schema: 'zod', + }, }, - }, - plugins: [ - 'typescript-validation-schema', - { add: { content: '/* eslint-disable */' } }, - ], - config: { - importFrom: '@app/graphql/generated/client/graphql', - strictScalars: false, - schema: 'zod', - }, }, - }, }; export default config; \ No newline at end of file diff --git a/api/commitlint.config.js b/api/commitlint.config.js new file mode 100644 index 000000000..422b19445 --- /dev/null +++ b/api/commitlint.config.js @@ -0,0 +1 @@ +module.exports = { extends: ['@commitlint/config-conventional'] }; diff --git a/api/fix-array-type.cjs b/api/fix-array-type.cjs new file mode 100644 index 000000000..a5e8ef2df --- /dev/null +++ b/api/fix-array-type.cjs @@ -0,0 +1,18 @@ +/** + * 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; diff --git a/api/package.json b/api/package.json index e6065b4d4..aa66625d4 100644 --- a/api/package.json +++ b/api/package.json @@ -17,28 +17,23 @@ "start": "node dist/main.js", "dev": "vite", "command": "pnpm run build && clear && ./dist/cli.js", - "// Build": "", "build": "vite build --mode=production", "postbuild": "chmod +x dist/main.js && chmod +x dist/cli.js", "build:docker": "./scripts/dc.sh run --rm builder", "build-and-pack": "tsx ./scripts/build.ts", - "// GraphQL Codegen": "", "codegen": "MOTHERSHIP_GRAPHQL_LINK='https://staging.mothership.unraid.net/ws' graphql-codegen --config codegen.ts -r dotenv/config './.env.staging'", "codegen:watch": "DOTENV_CONFIG_PATH='./.env.staging' graphql-codegen --config codegen.ts --watch -r dotenv/config", "codegen:local": "NODE_TLS_REJECT_UNAUTHORIZED=0 MOTHERSHIP_GRAPHQL_LINK='https://mothership.localhost/ws' graphql-codegen --config codegen.ts --watch", - "// Code Quality": "", "lint": "eslint --config .eslintrc.ts src/", "lint:fix": "eslint --fix --config .eslintrc.ts src/", "type-check": "tsc --noEmit", - "// Testing": "", "test": "NODE_ENV=test vitest run", "test:watch": "NODE_ENV=test vitest --ui", "coverage": "NODE_ENV=test vitest run --coverage", - "// Docker": "", "container:build": "./scripts/dc.sh build dev", "container:start": "pnpm run container:stop && ./scripts/dc.sh run --rm --service-ports dev", @@ -81,7 +76,7 @@ "chokidar": "^4.0.1", "cli-table": "^0.3.11", "command-exists": "^1.2.9", - "convert": "^5.5.1", + "convert": "^5.8.0", "cookie": "^1.0.2", "cron": "3.5.0", "cross-fetch": "^4.0.0", @@ -91,11 +86,12 @@ "dotenv": "^16.4.5", "execa": "^9.5.1", "exit-hook": "^4.0.0", + "fastify": "^4.28.1", "filenamify": "^6.0.0", "fs-extra": "^11.2.0", "glob": "^11.0.1", "global-agent": "^3.0.0", - "got": "^14.4.4", + "got": "^14.4.6", "graphql": "^16.9.0", "graphql-fields": "^2.0.3", "graphql-scalars": "^1.23.0", @@ -125,14 +121,17 @@ "pm2": "^5.4.2", "reflect-metadata": "^0.1.14", "request": "^2.88.2", + "rxjs": "^7.8.2", "semver": "^7.6.3", "strftime": "^0.10.3", "systeminformation": "^5.25.11", "uuid": "^11.0.2", "ws": "^8.18.0", + "zen-observable-ts": "^1.1.0", "zod": "^3.23.8" }, "devDependencies": { + "@eslint/js": "^9.21.0", "@graphql-codegen/add": "^5.0.3", "@graphql-codegen/cli": "^5.0.3", "@graphql-codegen/fragment-matcher": "^5.0.2", @@ -159,7 +158,7 @@ "@types/ip": "^1.1.3", "@types/lodash": "^4.17.13", "@types/mustache": "^4.2.5", - "@types/node": "^22.9.0", + "@types/node": "^22.13.4", "@types/pify": "^5.0.4", "@types/semver": "^7.5.8", "@types/sendmail": "^1.4.7", @@ -171,12 +170,15 @@ "@vitest/coverage-v8": "^3.0.5", "@vitest/ui": "^3.0.5", "cz-conventional-changelog": "3.3.0", - "eslint": "^9.14.0", + "eslint": "^9.20.1", + "eslint-plugin-import": "^2.31.0", "eslint-plugin-no-relative-import-paths": "^1.6.1", + "eslint-plugin-node": "^11.1.0", "eslint-plugin-prettier": "^5.2.3", "graphql-codegen-typescript-validation-schema": "^0.17.0", "jiti": "^2.4.0", "nodemon": "^3.1.7", + "prettier": "^3.5.2", "rollup-plugin-node-externals": "^8.0.0", "standard-version": "^9.5.0", "tsx": "^4.19.2", diff --git a/api/scripts/build.ts b/api/scripts/build.ts index c53c91b46..c371e8766 100755 --- a/api/scripts/build.ts +++ b/api/scripts/build.ts @@ -30,14 +30,14 @@ try { // Create a temporary directory for packaging await mkdir('./deploy/pack/', { recursive: true }); - + await writeFile('./deploy/pack/package.json', JSON.stringify(parsedPackageJson, null, 4)); // Copy necessary files to the pack directory await $`cp -r dist README.md .env.* ecosystem.config.json ./deploy/pack/`; - + // Change to the pack directory and install dependencies cd('./deploy/pack'); - + console.log('Installing production dependencies...'); $.verbose = true; await $`pnpm install --prod --ignore-workspace --node-linker hoisted`; @@ -48,10 +48,9 @@ try { // Create the tarball await $`tar -czf ../release/unraid-api.tgz ./`; - + // Clean up cd('..'); - } catch (error) { // Error with a command if (Object.keys(error).includes('stderr')) { diff --git a/api/scripts/get-deployment-version.ts b/api/scripts/get-deployment-version.ts index bb99d6e2a..e3550f94c 100644 --- a/api/scripts/get-deployment-version.ts +++ b/api/scripts/get-deployment-version.ts @@ -19,10 +19,12 @@ export const getDeploymentVersion = async (env = process.env, packageVersion: st return env.IS_TAGGED ? packageVersion : `${packageVersion}+${env.GIT_SHA}`; } else { const gitShortSHA = await runCommand('git', ['rev-parse', '--short', 'HEAD']); - const isCommitTagged = await runCommand('git', ['describe', '--tags', '--abbrev=0', '--exact-match']) !== undefined; - + const isCommitTagged = + (await runCommand('git', ['describe', '--tags', '--abbrev=0', '--exact-match'])) !== + undefined; + console.log('gitShortSHA', gitShortSHA, 'isCommitTagged', isCommitTagged); - + if (!gitShortSHA) { console.error('Failed to get git short SHA'); process.exit(1); diff --git a/api/src/__test__/common/allowed-origins.test.ts b/api/src/__test__/common/allowed-origins.test.ts index 5c1274926..f14842766 100644 --- a/api/src/__test__/common/allowed-origins.test.ts +++ b/api/src/__test__/common/allowed-origins.test.ts @@ -1,7 +1,7 @@ -import { getAllowedOrigins } from '@app/common/allowed-origins'; -import { store } from '@app/store/index'; -import { loadConfigFile } from '@app/store/modules/config'; -import { loadStateFiles } from '@app/store/modules/emhttp'; +import { getAllowedOrigins } from '@app/common/allowed-origins.js'; +import { store } from '@app/store/index.js'; +import { loadConfigFile } from '@app/store/modules/config.js'; +import { loadStateFiles } from '@app/store/modules/emhttp.js'; import 'reflect-metadata'; diff --git a/api/src/__test__/core/modules/array/get-array-data.test.ts b/api/src/__test__/core/modules/array/get-array-data.test.ts index 38361ff11..4431fba85 100644 --- a/api/src/__test__/core/modules/array/get-array-data.test.ts +++ b/api/src/__test__/core/modules/array/get-array-data.test.ts @@ -1,11 +1,11 @@ import { expect, test, vi } from 'vitest'; -import { getArrayData } from '@app/core/modules/array/get-array-data'; -import { store } from '@app/store'; -import { loadConfigFile } from '@app/store/modules/config'; -import { loadStateFiles } from '@app/store/modules/emhttp'; +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', () => ({ +vi.mock('@app/core/pubsub.js', () => ({ pubsub: { publish: vi.fn() }, })); diff --git a/api/src/__test__/core/notifiers/console.test.ts b/api/src/__test__/core/notifiers/console.test.ts index 7f60cbb4e..1a559a899 100644 --- a/api/src/__test__/core/notifiers/console.test.ts +++ b/api/src/__test__/core/notifiers/console.test.ts @@ -1,8 +1,8 @@ import { expect, test, vi } from 'vitest'; -import { ConsoleNotifier } from '@app/core/notifiers/console'; +import { ConsoleNotifier } from '@app/core/notifiers/console.js'; -vi.mock('@app/core/log', () => ({ +vi.mock('@app/core/log.js', () => ({ logger: { info: vi.fn(), error: vi.fn(), diff --git a/api/src/__test__/core/notifiers/unraid-local.test.ts b/api/src/__test__/core/notifiers/unraid-local.test.ts index 19307adfa..196b0180a 100644 --- a/api/src/__test__/core/notifiers/unraid-local.test.ts +++ b/api/src/__test__/core/notifiers/unraid-local.test.ts @@ -1,8 +1,8 @@ import { expect, test, vi } from 'vitest'; -import { UnraidLocalNotifier } from '@app/core/notifiers/unraid-local'; +import { UnraidLocalNotifier } from '@app/core/notifiers/unraid-local.js'; -vi.mock('@app/core/log', () => ({ +vi.mock('@app/core/log.js', () => ({ logger: { info: vi.fn(), error: vi.fn(), diff --git a/api/src/__test__/core/utils/array/array-is-running.test.ts b/api/src/__test__/core/utils/array/array-is-running.test.ts index b78ee0bce..dfc17a8fd 100644 --- a/api/src/__test__/core/utils/array/array-is-running.test.ts +++ b/api/src/__test__/core/utils/array/array-is-running.test.ts @@ -1,14 +1,14 @@ import { expect, test, vi } from 'vitest'; -import type { SliceState } from '@app/store/modules/emhttp'; -import { getters } from '@app/store'; +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'); + const { arrayIsRunning } = await import('@app/core/utils/array/array-is-running.js'); expect(arrayIsRunning()).toBe(true); vi.spyOn(getters, 'emhttp').mockReset(); }); @@ -17,7 +17,7 @@ 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'); + const { arrayIsRunning } = await import('@app/core/utils/array/array-is-running.js'); expect(arrayIsRunning()).toBe(false); vi.spyOn(getters, 'emhttp').mockReset(); }); diff --git a/api/src/__test__/core/utils/files/config-file-normalizer.test.ts b/api/src/__test__/core/utils/files/config-file-normalizer.test.ts index 0f168b2f3..93f94d614 100644 --- a/api/src/__test__/core/utils/files/config-file-normalizer.test.ts +++ b/api/src/__test__/core/utils/files/config-file-normalizer.test.ts @@ -3,8 +3,8 @@ import 'reflect-metadata'; import { cloneDeep } from 'lodash-es'; import { expect, test } from 'vitest'; -import { getWriteableConfig } from '@app/core/utils/files/config-file-normalizer'; -import { initialState } from '@app/store/modules/config'; +import { getWriteableConfig } from '@app/core/utils/files/config-file-normalizer.js'; +import { initialState } from '@app/store/modules/config.js'; test('it creates a FLASH config with NO OPTIONAL values', () => { const basicConfig = initialState; diff --git a/api/src/__test__/core/utils/files/safe-ini-serializer.test.ts b/api/src/__test__/core/utils/files/safe-ini-serializer.test.ts index af2c0a4ba..7332ab591 100644 --- a/api/src/__test__/core/utils/files/safe-ini-serializer.test.ts +++ b/api/src/__test__/core/utils/files/safe-ini-serializer.test.ts @@ -2,7 +2,7 @@ import { parse } from 'ini'; import { Serializer } from 'multi-ini'; import { expect, test } from 'vitest'; -import { safelySerializeObjectToIni } from '@app/core/utils/files/safe-ini-serializer'; +import { safelySerializeObjectToIni } from '@app/core/utils/files/safe-ini-serializer.js'; test('MultiIni breaks when serializing an object with a boolean inside', async () => { const objectToSerialize = { diff --git a/api/src/__test__/core/utils/images/image-file-helpers.test.ts b/api/src/__test__/core/utils/images/image-file-helpers.test.ts index 34076bf28..3b6920ccf 100644 --- a/api/src/__test__/core/utils/images/image-file-helpers.test.ts +++ b/api/src/__test__/core/utils/images/image-file-helpers.test.ts @@ -1,8 +1,11 @@ import { expect, test } from 'vitest'; -import { getBannerPathIfPresent, getCasePathIfPresent } from '@app/core/utils/images/image-file-helpers'; -import { loadDynamixConfigFile } from '@app/store/actions/load-dynamix-config-file'; -import { store } from '@app/store/index'; +import { + getBannerPathIfPresent, + getCasePathIfPresent, +} from '@app/core/utils/images/image-file-helpers.js'; +import { loadDynamixConfigFile } from '@app/store/actions/load-dynamix-config-file.js'; +import { store } from '@app/store/index.js'; test('get case path returns expected result', async () => { await expect(getCasePathIfPresent()).resolves.toContain('/dev/dynamix/case-model.png'); diff --git a/api/src/__test__/core/utils/misc/clean-stdout.test.ts b/api/src/__test__/core/utils/misc/clean-stdout.test.ts index af372d398..44773c841 100644 --- a/api/src/__test__/core/utils/misc/clean-stdout.test.ts +++ b/api/src/__test__/core/utils/misc/clean-stdout.test.ts @@ -1,6 +1,6 @@ import { expect, test } from 'vitest'; -import { cleanStdout } from '@app/core/utils/misc/clean-stdout'; +import { cleanStdout } from '@app/core/utils/misc/clean-stdout.js'; test('Returns trimmed stdout from execa command', () => { expect(cleanStdout({ stdout: 'test' })).toBe('test'); diff --git a/api/src/__test__/core/utils/misc/get-key-file.test.ts b/api/src/__test__/core/utils/misc/get-key-file.test.ts index 9790c19da..c44300287 100644 --- a/api/src/__test__/core/utils/misc/get-key-file.test.ts +++ b/api/src/__test__/core/utils/misc/get-key-file.test.ts @@ -1,13 +1,13 @@ import { expect, test } from 'vitest'; -import { store } from '@app/store'; -import { FileLoadStatus, StateFileKey } from '@app/store/types'; +import { store } from '@app/store/index.js'; +import { FileLoadStatus, StateFileKey } from '@app/store/types.js'; -import '@app/core/utils/misc/get-key-file'; -import '@app/store/modules/emhttp'; +import '@app/core/utils/misc/get-key-file.js'; +import '@app/store/modules/emhttp.js'; test('Before loading key returns null', async () => { - const { getKeyFile } = await import('@app/core/utils/misc/get-key-file'); + const { getKeyFile } = await import('@app/core/utils/misc/get-key-file.js'); const { status } = store.getState().registration; expect(status).toBe(FileLoadStatus.UNLOADED); @@ -15,8 +15,8 @@ test('Before loading key returns null', async () => { }); test('Requires emhttp to be loaded to find key file', async () => { - const { getKeyFile } = await import('@app/core/utils/misc/get-key-file'); - const { loadRegistrationKey } = await import('@app/store/modules/registration'); + const { getKeyFile } = await import('@app/core/utils/misc/get-key-file.js'); + const { loadRegistrationKey } = await import('@app/store/modules/registration.js'); // Load registration key into store await store.dispatch(loadRegistrationKey()); @@ -28,8 +28,8 @@ test('Requires emhttp to be loaded to find key file', async () => { }); test('Returns empty key if key location is empty', async () => { - const { getKeyFile } = await import('@app/core/utils/misc/get-key-file'); - const { updateEmhttpState } = await import('@app/store/modules/emhttp'); + const { getKeyFile } = await import('@app/core/utils/misc/get-key-file.js'); + const { updateEmhttpState } = await import('@app/store/modules/emhttp.js'); // Set key file location as empty // This should only happen if the user doesn't have a key file @@ -48,17 +48,21 @@ test('Returns empty key if key location is empty', async () => { await expect(getKeyFile()).resolves.toBe(''); }); -test('Returns decoded key file if key location exists', async () => { - const { getKeyFile } = await import('@app/core/utils/misc/get-key-file'); - const { loadStateFiles } = await import('@app/store/modules/emhttp'); +test( + 'Returns decoded key file if key location exists', + async () => { + const { getKeyFile } = await import('@app/core/utils/misc/get-key-file.js'); + const { loadStateFiles } = await import('@app/store/modules/emhttp.js'); - // Load state files into store - await store.dispatch(loadStateFiles()); + // Load state files into store + await store.dispatch(loadStateFiles()); - // Check if store has state files loaded - const { status } = store.getState().registration; - expect(status).toBe(FileLoadStatus.LOADED); - await expect(getKeyFile()).resolves.toMatchInlineSnapshot( - '"hVs1tLjvC9FiiQsIwIQ7G1KszAcexf0IneThhnmf22SB0dGs5WzRkqMiSMmt2DtR5HOXFUD32YyxuzGeUXmky3zKpSu6xhZNKVg5atGM1OfvkzHBMldI3SeBLuUFSgejLbpNUMdTrbk64JJdbzle4O8wiQgkIpAMIGxeYLwLBD4zHBcfyzq40QnxG--HcX6j25eE0xqa2zWj-j0b0rCAXahJV2a3ySCbPzr1MvfPRTVb0rr7KJ-25R592hYrz4H7Sc1B3p0lr6QUxHE6o7bcYrWKDRtIVoZ8SMPpd1_0gzYIcl5GsDFzFumTXUh8NEnl0Q8hwW1YE-tRc6Y_rrvd7w"' - ); -}); + // Check if store has state files loaded + const { status } = store.getState().registration; + expect(status).toBe(FileLoadStatus.LOADED); + await expect(getKeyFile()).resolves.toMatchInlineSnapshot( + '"hVs1tLjvC9FiiQsIwIQ7G1KszAcexf0IneThhnmf22SB0dGs5WzRkqMiSMmt2DtR5HOXFUD32YyxuzGeUXmky3zKpSu6xhZNKVg5atGM1OfvkzHBMldI3SeBLuUFSgejLbpNUMdTrbk64JJdbzle4O8wiQgkIpAMIGxeYLwLBD4zHBcfyzq40QnxG--HcX6j25eE0xqa2zWj-j0b0rCAXahJV2a3ySCbPzr1MvfPRTVb0rr7KJ-25R592hYrz4H7Sc1B3p0lr6QUxHE6o7bcYrWKDRtIVoZ8SMPpd1_0gzYIcl5GsDFzFumTXUh8NEnl0Q8hwW1YE-tRc6Y_rrvd7w"' + ); + }, + { timeout: 10000 } +); diff --git a/api/src/__test__/core/utils/misc/parse-config.test.ts b/api/src/__test__/core/utils/misc/parse-config.test.ts index 8e152d508..0eb9274ba 100644 --- a/api/src/__test__/core/utils/misc/parse-config.test.ts +++ b/api/src/__test__/core/utils/misc/parse-config.test.ts @@ -4,8 +4,8 @@ import { parse } from 'ini'; import { Parser as MultiIniParser } from 'multi-ini'; import { expect, test } from 'vitest'; -import { safelySerializeObjectToIni } from '@app/core/utils/files/safe-ini-serializer'; -import { parseConfig } from '@app/core/utils/misc/parse-config'; +import { safelySerializeObjectToIni } from '@app/core/utils/files/safe-ini-serializer.js'; +import { parseConfig } from '@app/core/utils/misc/parse-config.js'; const iniTestData = `["root"] idx="0" diff --git a/api/src/__test__/core/utils/shares/get-shares.test.ts b/api/src/__test__/core/utils/shares/get-shares.test.ts index cb5e7eac0..b3e75bb46 100644 --- a/api/src/__test__/core/utils/shares/get-shares.test.ts +++ b/api/src/__test__/core/utils/shares/get-shares.test.ts @@ -1,8 +1,8 @@ import { expect, test } from 'vitest'; -import { getShares } from '@app/core/utils/shares/get-shares'; -import { store } from '@app/store'; -import { loadStateFiles } from '@app/store/modules/emhttp'; +import { getShares } from '@app/core/utils/shares/get-shares.js'; +import { store } from '@app/store/index.js'; +import { loadStateFiles } from '@app/store/modules/emhttp.js'; test('Returns both disk and user shares', async () => { await store.dispatch(loadStateFiles()); diff --git a/api/src/__test__/graphql/resolvers/query/cloud/check-dns.test.ts b/api/src/__test__/graphql/resolvers/query/cloud/check-dns.test.ts deleted file mode 100644 index a73d072a8..000000000 --- a/api/src/__test__/graphql/resolvers/query/cloud/check-dns.test.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { afterEach, expect, test, vi } from 'vitest'; - -import { checkDNS } from '@app/graphql/resolvers/query/cloud/check-dns'; -import { store } from '@app/store'; -import { clearKey } from '@app/store/modules/cache'; -import { CacheKeys } from '@app/store/types'; - -afterEach(() => { - store.dispatch(clearKey(CacheKeys.checkDns)); -}); - -test('it resolves dns successfully', async () => { - // @TODO - const dns = await checkDNS('example.com'); - expect(dns.cloudIp).not.toBeNull(); -}, 25_000); - -test('testing twice results in a cache hit', async () => { - // Hit mothership - const getters = await import('@app/store/getters'); - const dnsSpy = vi.spyOn(getters, 'getDnsCache'); - const dns = await checkDNS(); - expect(dns.cloudIp).toBeTypeOf('string'); - expect(dnsSpy.mock.results[0]).toMatchInlineSnapshot(` - { - "type": "return", - "value": undefined, - } - `); - const dnslookup2 = await checkDNS(); - expect(dnslookup2.cloudIp).toEqual(dns.cloudIp); - expect(dnsSpy.mock.results[1].value.cloudIp).toEqual(dns.cloudIp); - expect(store.getState().cache.nodeCache.getTtl(CacheKeys.checkDns)).toBeGreaterThan(500); -}); diff --git a/api/src/__test__/graphql/resolvers/query/cloud/check-mothership-authentication.test.ts b/api/src/__test__/graphql/resolvers/query/cloud/check-mothership-authentication.test.ts index 8fc04b271..560bf3172 100644 --- a/api/src/__test__/graphql/resolvers/query/cloud/check-mothership-authentication.test.ts +++ b/api/src/__test__/graphql/resolvers/query/cloud/check-mothership-authentication.test.ts @@ -1,12 +1,15 @@ import 'reflect-metadata'; +import { readFileSync } from 'fs'; +import { join } from 'path'; + import { expect, test } from 'vitest'; -import packageJson from '@app/../package.json'; -import { checkMothershipAuthentication } from '@app/graphql/resolvers/query/cloud/check-mothership-authentication'; +import { checkMothershipAuthentication } from '@app/graphql/resolvers/query/cloud/check-mothership-authentication.js'; test('It fails to authenticate with mothership with no credentials', async () => { try { + const packageJson = JSON.parse(readFileSync(join(process.cwd(), 'package.json'), 'utf-8')); await expect( checkMothershipAuthentication('BAD', 'BAD') ).rejects.toThrowErrorMatchingInlineSnapshot( diff --git a/api/src/__test__/graphql/resolvers/subscription/network.test.ts b/api/src/__test__/graphql/resolvers/subscription/network.test.ts index 3cd763f9e..d71123279 100644 --- a/api/src/__test__/graphql/resolvers/subscription/network.test.ts +++ b/api/src/__test__/graphql/resolvers/subscription/network.test.ts @@ -1,15 +1,15 @@ import { expect, test } from 'vitest'; -import type { NginxUrlFields } from '@app/graphql/resolvers/subscription/network'; -import { type Nginx } from '@app/core/types/states/nginx'; +import type { NginxUrlFields } from '@app/graphql/resolvers/subscription/network.js'; +import { type Nginx } from '@app/core/types/states/nginx.js'; import { getServerIps, getUrlForField, getUrlForServer, -} from '@app/graphql/resolvers/subscription/network'; -import { store } from '@app/store'; -import { loadConfigFile } from '@app/store/modules/config'; -import { loadStateFiles } from '@app/store/modules/emhttp'; +} from '@app/graphql/resolvers/subscription/network.js'; +import { store } from '@app/store/index.js'; +import { loadConfigFile } from '@app/store/modules/config.js'; +import { loadStateFiles } from '@app/store/modules/emhttp.js'; test.each([ [{ httpPort: 80, httpsPort: 443, url: 'my-default-url.com' }], @@ -117,16 +117,16 @@ test('getUrlForServer - field does not exist, ssl disabled', async () => { test('getUrlForServer - FQDN - field exists, port non-empty', () => { const result = getUrlForServer({ - nginx: { lanFqdn: 'my-fqdn.unraid.net', httpsPort: 445 } as const as Nginx, - field: 'lanFqdn', + nginx: { lanFqdn: 'my-fqdn.unraid.net', httpsPort: 445 } as unknown as Nginx, + field: 'lanFqdn' as NginxUrlFields, }); expect(result).toMatchInlineSnapshot('"https://my-fqdn.unraid.net:445/"'); }); test('getUrlForServer - FQDN - field exists, port empty', () => { const result = getUrlForServer({ - nginx: { lanFqdn: 'my-fqdn.unraid.net', httpPort: 80, httpsPort: 443 } as const as Nginx, - field: 'lanFqdn', + nginx: { lanFqdn: 'my-fqdn.unraid.net', httpPort: 80, httpsPort: 443 } as unknown as Nginx, + field: 'lanFqdn' as NginxUrlFields, }); expect(result).toMatchInlineSnapshot('"https://my-fqdn.unraid.net/"'); }); @@ -140,7 +140,7 @@ test.each([ sslMode: 'no', httpPort: 80, httpsPort: 443, - } as const as Nginx, + } as unknown as Nginx, field: 'lanFqdn' as NginxUrlFields, }, ], @@ -152,7 +152,7 @@ test.each([ sslMode: 'yes', httpPort: 80, httpsPort: 443, - } as const as Nginx, + } as unknown as Nginx, field: 'wanFqdn' as NginxUrlFields, }, ], @@ -164,7 +164,7 @@ test.each([ sslMode: 'auto', httpPort: 80, httpsPort: 443, - } as const as Nginx, + } as unknown as Nginx, field: 'wanFqdn6' as NginxUrlFields, }, ], @@ -176,7 +176,7 @@ test.each([ test('getUrlForServer - field does not exist, ssl disabled', async () => { const getResult = async () => getUrlForServer({ - nginx: { lanFqdn: 'my-fqdn.unraid.net' } as const as Nginx, + nginx: { lanFqdn: 'my-fqdn.unraid.net' } as unknown as Nginx, ports: { portSsl: '', port: '', defaultUrl: new URL('https://my-default-url.unraid.net') }, // @ts-expect-error Field doesn't exist field: 'idontexist', diff --git a/api/src/__test__/mothership/index.test.ts b/api/src/__test__/mothership/index.test.ts index b9144b482..283244d6d 100644 --- a/api/src/__test__/mothership/index.test.ts +++ b/api/src/__test__/mothership/index.test.ts @@ -1,7 +1,7 @@ import { beforeEach, expect, test, vi } from 'vitest'; // Preloading imports for faster tests -import '@app/mothership/utils/convert-to-fuzzy-time'; +import '@app/mothership/utils/convert-to-fuzzy-time.js'; vi.mock('fs', () => ({ default: { @@ -17,7 +17,7 @@ vi.mock('@graphql-tools/schema', () => ({ makeExecutableSchema: vi.fn(), })); -vi.mock('@app/core/log', () => ({ +vi.mock('@app/core/log.js', () => ({ default: { relayLogger: { trace: vi.fn() } }, relayLogger: { trace: vi.fn() }, logger: { trace: vi.fn() }, @@ -40,7 +40,7 @@ const generateTestCases = () => { }; test.each(generateTestCases())('Successfully converts to fuzzy time %o', async ({ min, max }) => { - const { convertToFuzzyTime } = await import('@app/mothership/utils/convert-to-fuzzy-time'); + const { convertToFuzzyTime } = await import('@app/mothership/utils/convert-to-fuzzy-time.js'); const res = convertToFuzzyTime(min, max); expect(res).toBeGreaterThanOrEqual(min); diff --git a/api/src/__test__/setup/keyserver-mock.ts b/api/src/__test__/setup/keyserver-mock.ts index c70865521..d3e1354fa 100644 --- a/api/src/__test__/setup/keyserver-mock.ts +++ b/api/src/__test__/setup/keyserver-mock.ts @@ -1,6 +1,6 @@ import { vi } from 'vitest'; -vi.mock('@app/core/utils/misc/send-form-to-keyserver', () => { +vi.mock('@app/core/utils/misc/send-form-to-keyserver.js', () => { const sendFormToKeyServer = vi.fn().mockResolvedValue({ body: JSON.stringify({ valid: true }) }); return { sendFormToKeyServer }; }); diff --git a/api/src/__test__/store/modules/config.test.ts b/api/src/__test__/store/modules/config.test.ts index 7a51a4d77..e735bb057 100644 --- a/api/src/__test__/store/modules/config.test.ts +++ b/api/src/__test__/store/modules/config.test.ts @@ -1,7 +1,7 @@ import { expect, test } from 'vitest'; -import { store } from '@app/store'; -import { MyServersConfigMemory } from '@app/types/my-servers-config'; +import { store } from '@app/store/index.js'; +import { MyServersConfigMemory } from '@app/types/my-servers-config.js'; test('Before init returns default values for all fields', async () => { const state = store.getState().config; @@ -9,7 +9,7 @@ test('Before init returns default values for all fields', async () => { }, 10_000); test('After init returns values from cfg file for all fields', async () => { - const { loadConfigFile } = await import('@app/store/modules/config'); + const { loadConfigFile } = await import('@app/store/modules/config.js'); // Load cfg into store await store.dispatch(loadConfigFile()); @@ -53,7 +53,7 @@ test('After init returns values from cfg file for all fields', async () => { }); test('updateUserConfig merges in changes to current state', async () => { - const { loadConfigFile, updateUserConfig } = await import('@app/store/modules/config'); + const { loadConfigFile, updateUserConfig } = await import('@app/store/modules/config.js'); // Load cfg into store await store.dispatch(loadConfigFile()); diff --git a/api/src/__test__/store/modules/emhttp.test.ts b/api/src/__test__/store/modules/emhttp.test.ts index da6b1e5cb..aed7e0d74 100644 --- a/api/src/__test__/store/modules/emhttp.test.ts +++ b/api/src/__test__/store/modules/emhttp.test.ts @@ -1,10 +1,10 @@ import { expect, test } from 'vitest'; -import { store } from '@app/store'; -import { FileLoadStatus } from '@app/store/types'; +import { store } from '@app/store/index.js'; +import { FileLoadStatus } from '@app/store/types.js'; // Preloading imports for faster tests -import '@app/store/modules/emhttp'; +import '@app/store/modules/emhttp.js'; test('Before init returns default values for all fields', async () => { const { status, ...state } = store.getState().emhttp; @@ -25,7 +25,7 @@ test('Before init returns default values for all fields', async () => { }); test('After init returns values from cfg file for all fields', async () => { - const { loadStateFiles } = await import('@app/store/modules/emhttp'); + const { loadStateFiles } = await import('@app/store/modules/emhttp.js'); // Load state files into store await store.dispatch(loadStateFiles()); diff --git a/api/src/__test__/store/modules/paths.test.ts b/api/src/__test__/store/modules/paths.test.ts index 1b01a1bcd..b1d21ce30 100644 --- a/api/src/__test__/store/modules/paths.test.ts +++ b/api/src/__test__/store/modules/paths.test.ts @@ -1,6 +1,6 @@ import { expect, test } from 'vitest'; -import { store } from '@app/store'; +import { store } from '@app/store/index.js'; test('Returns paths', async () => { const { paths } = store.getState(); diff --git a/api/src/__test__/store/modules/registration.test.ts b/api/src/__test__/store/modules/registration.test.ts index 33c8b2d98..cb3358836 100644 --- a/api/src/__test__/store/modules/registration.test.ts +++ b/api/src/__test__/store/modules/registration.test.ts @@ -1,8 +1,8 @@ import { expect, test } from 'vitest'; -import { store } from '@app/store'; -import { loadRegistrationKey } from '@app/store/modules/registration'; -import { FileLoadStatus, StateFileKey } from '@app/store/types'; +import { 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 @@ -24,8 +24,8 @@ test('Requires emhttp to be loaded to find key file', async () => { }); test('Returns empty key if key location is empty', async () => { - const { updateEmhttpState } = await import('@app/store/modules/emhttp'); - const { loadRegistrationKey } = await import('@app/store/modules/registration'); + const { updateEmhttpState } = await import('@app/store/modules/emhttp.js'); + const { loadRegistrationKey } = await import('@app/store/modules/registration.js'); // Set key file location as empty // This should only happen if the user doesn't have a key file @@ -46,21 +46,3 @@ test('Returns empty key if key location is empty', async () => { expect(status).toBe(FileLoadStatus.LOADED); expect(keyFile).toBe(''); }); - -test('Returns decoded key file if key location exists', async () => { - const { loadRegistrationKey } = await import('@app/store/modules/registration'); - const { loadStateFiles } = await import('@app/store/modules/emhttp'); - - // Load state files into store - await store.dispatch(loadStateFiles()); - - // Load registration key into store - await store.dispatch(loadRegistrationKey()); - - // Check if store has state files loaded - const { status, keyFile } = store.getState().registration; - expect(status).toBe(FileLoadStatus.LOADED); - expect(keyFile).toMatchInlineSnapshot( - '"hVs1tLjvC9FiiQsIwIQ7G1KszAcexf0IneThhnmf22SB0dGs5WzRkqMiSMmt2DtR5HOXFUD32YyxuzGeUXmky3zKpSu6xhZNKVg5atGM1OfvkzHBMldI3SeBLuUFSgejLbpNUMdTrbk64JJdbzle4O8wiQgkIpAMIGxeYLwLBD4zHBcfyzq40QnxG--HcX6j25eE0xqa2zWj-j0b0rCAXahJV2a3ySCbPzr1MvfPRTVb0rr7KJ-25R592hYrz4H7Sc1B3p0lr6QUxHE6o7bcYrWKDRtIVoZ8SMPpd1_0gzYIcl5GsDFzFumTXUh8NEnl0Q8hwW1YE-tRc6Y_rrvd7w"' - ); -}); diff --git a/api/src/__test__/store/state-parsers/devices.test.ts b/api/src/__test__/store/state-parsers/devices.test.ts index cf98fce71..2c65aff87 100644 --- a/api/src/__test__/store/state-parsers/devices.test.ts +++ b/api/src/__test__/store/state-parsers/devices.test.ts @@ -2,12 +2,12 @@ import { join } from 'path'; import { expect, test } from 'vitest'; -import type { DevicesIni } from '@app/store/state-parsers/devices'; -import { store } from '@app/store'; +import type { DevicesIni } from '@app/store/state-parsers/devices.js'; +import { store } from '@app/store/index.js'; test('Returns parsed state file', async () => { - const { parse } = await import('@app/store/state-parsers/devices'); - const { parseConfig } = await import('@app/core/utils/misc/parse-config'); + const { parse } = await import('@app/store/state-parsers/devices.js'); + const { parseConfig } = await import('@app/core/utils/misc/parse-config.js'); const { paths } = store.getState(); const filePath = join(paths.states, 'devs.ini'); const stateFile = parseConfig({ diff --git a/api/src/__test__/store/state-parsers/network.test.ts b/api/src/__test__/store/state-parsers/network.test.ts index 63ca1979a..2427a4bac 100644 --- a/api/src/__test__/store/state-parsers/network.test.ts +++ b/api/src/__test__/store/state-parsers/network.test.ts @@ -2,12 +2,12 @@ import { join } from 'path'; import { expect, test } from 'vitest'; -import type { NetworkIni } from '@app/store/state-parsers/network'; -import { store } from '@app/store'; +import type { NetworkIni } from '@app/store/state-parsers/network.js'; +import { store } from '@app/store/index.js'; test('Returns parsed state file', async () => { - const { parse } = await import('@app/store/state-parsers/network'); - const { parseConfig } = await import('@app/core/utils/misc/parse-config'); + const { parse } = await import('@app/store/state-parsers/network.js'); + const { parseConfig } = await import('@app/core/utils/misc/parse-config.js'); const { paths } = store.getState(); const filePath = join(paths.states, 'network.ini'); const stateFile = parseConfig({ diff --git a/api/src/__test__/store/state-parsers/nfs.test.ts b/api/src/__test__/store/state-parsers/nfs.test.ts index 3fc0dfb85..541d286fc 100644 --- a/api/src/__test__/store/state-parsers/nfs.test.ts +++ b/api/src/__test__/store/state-parsers/nfs.test.ts @@ -2,12 +2,12 @@ import { join } from 'path'; import { expect, test } from 'vitest'; -import type { NfsSharesIni } from '@app/store/state-parsers/nfs'; -import { store } from '@app/store'; +import type { NfsSharesIni } from '@app/store/state-parsers/nfs.js'; +import { store } from '@app/store/index.js'; test('Returns parsed state file', async () => { - const { parse } = await import('@app/store/state-parsers/nfs'); - const { parseConfig } = await import('@app/core/utils/misc/parse-config'); + const { parse } = await import('@app/store/state-parsers/nfs.js'); + const { parseConfig } = await import('@app/core/utils/misc/parse-config.js'); const { paths } = store.getState(); const filePath = join(paths.states, 'sec_nfs.ini'); const stateFile = parseConfig({ diff --git a/api/src/__test__/store/state-parsers/nginx.test.ts b/api/src/__test__/store/state-parsers/nginx.test.ts index 6c93ff1ef..2f0f8cf1f 100644 --- a/api/src/__test__/store/state-parsers/nginx.test.ts +++ b/api/src/__test__/store/state-parsers/nginx.test.ts @@ -2,12 +2,12 @@ import { join } from 'path'; import { expect, test } from 'vitest'; -import type { NginxIni } from '@app/store/state-parsers/nginx'; -import { store } from '@app/store'; +import type { NginxIni } from '@app/store/state-parsers/nginx.js'; +import { store } from '@app/store/index.js'; test('Returns parsed state file', async () => { - const { parse } = await import('@app/store/state-parsers/nginx'); - const { parseConfig } = await import('@app/core/utils/misc/parse-config'); + const { parse } = await import('@app/store/state-parsers/nginx.js'); + const { parseConfig } = await import('@app/core/utils/misc/parse-config.js'); const { paths } = store.getState(); const filePath = join(paths.states, 'nginx.ini'); const stateFile = parseConfig({ diff --git a/api/src/__test__/store/state-parsers/shares.test.ts b/api/src/__test__/store/state-parsers/shares.test.ts index c51e6e646..a0769dc14 100644 --- a/api/src/__test__/store/state-parsers/shares.test.ts +++ b/api/src/__test__/store/state-parsers/shares.test.ts @@ -2,12 +2,12 @@ import { join } from 'path'; import { expect, test } from 'vitest'; -import type { SharesIni } from '@app/store/state-parsers/shares'; -import { store } from '@app/store'; +import type { SharesIni } from '@app/store/state-parsers/shares.js'; +import { store } from '@app/store/index.js'; test('Returns parsed state file', async () => { - const { parse } = await import('@app/store/state-parsers/shares'); - const { parseConfig } = await import('@app/core/utils/misc/parse-config'); + const { parse } = await import('@app/store/state-parsers/shares.js'); + const { parseConfig } = await import('@app/core/utils/misc/parse-config.js'); const { paths } = store.getState(); const filePath = join(paths.states, 'shares.ini'); const stateFile = parseConfig({ diff --git a/api/src/__test__/store/state-parsers/slots.test.ts b/api/src/__test__/store/state-parsers/slots.test.ts index ab0c91fc9..3c1e1064d 100644 --- a/api/src/__test__/store/state-parsers/slots.test.ts +++ b/api/src/__test__/store/state-parsers/slots.test.ts @@ -2,12 +2,12 @@ import { join } from 'path'; import { expect, test } from 'vitest'; -import type { SlotsIni } from '@app/store/state-parsers/slots'; -import { store } from '@app/store'; +import type { SlotsIni } from '@app/store/state-parsers/slots.js'; +import { store } from '@app/store/index.js'; test('Returns parsed state file', async () => { - const { parse } = await import('@app/store/state-parsers/slots'); - const { parseConfig } = await import('@app/core/utils/misc/parse-config'); + const { parse } = await import('@app/store/state-parsers/slots.js'); + const { parseConfig } = await import('@app/core/utils/misc/parse-config.js'); const { paths } = store.getState(); const filePath = join(paths.states, 'disks.ini'); const stateFile = parseConfig({ diff --git a/api/src/__test__/store/state-parsers/smb.test.ts b/api/src/__test__/store/state-parsers/smb.test.ts index 035d8e715..a6dc37666 100644 --- a/api/src/__test__/store/state-parsers/smb.test.ts +++ b/api/src/__test__/store/state-parsers/smb.test.ts @@ -2,12 +2,12 @@ import { join } from 'path'; import { expect, test } from 'vitest'; -import type { SmbIni } from '@app/store/state-parsers/smb'; -import { store } from '@app/store'; +import type { SmbIni } from '@app/store/state-parsers/smb.js'; +import { store } from '@app/store/index.js'; test('Returns parsed state file', async () => { - const { parse } = await import('@app/store/state-parsers/smb'); - const { parseConfig } = await import('@app/core/utils/misc/parse-config'); + const { parse } = await import('@app/store/state-parsers/smb.js'); + const { parseConfig } = await import('@app/core/utils/misc/parse-config.js'); const { paths } = store.getState(); const filePath = join(paths.states, 'sec.ini'); const stateFile = parseConfig({ diff --git a/api/src/__test__/store/state-parsers/users.test.ts b/api/src/__test__/store/state-parsers/users.test.ts index 823ed75e6..d69394bcf 100644 --- a/api/src/__test__/store/state-parsers/users.test.ts +++ b/api/src/__test__/store/state-parsers/users.test.ts @@ -2,12 +2,12 @@ import { join } from 'path'; import { expect, test } from 'vitest'; -import type { UsersIni } from '@app/store/state-parsers/users'; -import { store } from '@app/store'; +import type { UsersIni } from '@app/store/state-parsers/users.js'; +import { store } from '@app/store/index.js'; test('Returns parsed state file', async () => { - const { parse } = await import('@app/store/state-parsers/users'); - const { parseConfig } = await import('@app/core/utils/misc/parse-config'); + const { parse } = await import('@app/store/state-parsers/users.js'); + const { parseConfig } = await import('@app/core/utils/misc/parse-config.js'); const { paths } = store.getState(); const filePath = join(paths.states, 'users.ini'); const stateFile = parseConfig({ diff --git a/api/src/__test__/store/state-parsers/var.test.ts b/api/src/__test__/store/state-parsers/var.test.ts index f74779047..e4df766a5 100644 --- a/api/src/__test__/store/state-parsers/var.test.ts +++ b/api/src/__test__/store/state-parsers/var.test.ts @@ -2,12 +2,12 @@ import { join } from 'path'; import { expect, test } from 'vitest'; -import type { VarIni } from '@app/store/state-parsers/var'; -import { store } from '@app/store'; +import type { VarIni } from '@app/store/state-parsers/var.js'; +import { store } from '@app/store/index.js'; test('Returns parsed state file', async () => { - const { parse } = await import('@app/store/state-parsers/var'); - const { parseConfig } = await import('@app/core/utils/misc/parse-config'); + const { parse } = await import('@app/store/state-parsers/var.js'); + const { parseConfig } = await import('@app/core/utils/misc/parse-config.js'); const { paths } = store.getState(); const filePath = join(paths.states, 'var.ini'); const stateFile = parseConfig({ diff --git a/api/src/__test__/store/sync/registration-sync.test.ts b/api/src/__test__/store/sync/registration-sync.test.ts index 02d40fe2f..92a5c0a14 100644 --- a/api/src/__test__/store/sync/registration-sync.test.ts +++ b/api/src/__test__/store/sync/registration-sync.test.ts @@ -1,16 +1,20 @@ import { expect, test, vi } from 'vitest'; +import { store } from '@app/store/index.js'; +import { loadStateFiles } from '@app/store/modules/emhttp.js'; +import { loadRegistrationKey } from '@app/store/modules/registration.js'; +import { createRegistrationEvent } from '@app/store/sync/registration-sync.js'; + vi.mock('@app/core/pubsub', () => ({ pubsub: { publish: vi.fn() }, })); test('Creates a registration event', async () => { - const { createRegistrationEvent } = await import('@app/store/sync/registration-sync'); - const { store } = await import('@app/store'); - const { loadStateFiles } = await import('@app/store/modules/emhttp'); - // Load state files into store - await store.dispatch(loadStateFiles()); + + const config = await store.dispatch(loadStateFiles()).unwrap(); + await store.dispatch(loadRegistrationKey()); + expect(config.var.regFile).toBe('/app/dev/Unraid.net/Pro.key'); const state = store.getState(); const registrationEvent = createRegistrationEvent(state); @@ -19,7 +23,7 @@ test('Creates a registration event', async () => { "registration": { "guid": "13FE-4200-C300-58C372A52B19", "keyFile": { - "contents": null, + "contents": "hVs1tLjvC9FiiQsIwIQ7G1KszAcexf0IneThhnmf22SB0dGs5WzRkqMiSMmt2DtR5HOXFUD32YyxuzGeUXmky3zKpSu6xhZNKVg5atGM1OfvkzHBMldI3SeBLuUFSgejLbpNUMdTrbk64JJdbzle4O8wiQgkIpAMIGxeYLwLBD4zHBcfyzq40QnxG--HcX6j25eE0xqa2zWj-j0b0rCAXahJV2a3ySCbPzr1MvfPRTVb0rr7KJ-25R592hYrz4H7Sc1B3p0lr6QUxHE6o7bcYrWKDRtIVoZ8SMPpd1_0gzYIcl5GsDFzFumTXUh8NEnl0Q8hwW1YE-tRc6Y_rrvd7w", "location": "/app/dev/Unraid.net/Pro.key", }, "state": "PRO", diff --git a/api/src/__test__/upnp/helpers.test.ts b/api/src/__test__/upnp/helpers.test.ts index 48b382e93..f8a0f4dfd 100644 --- a/api/src/__test__/upnp/helpers.test.ts +++ b/api/src/__test__/upnp/helpers.test.ts @@ -1,7 +1,7 @@ import { type Mapping } from '@runonflux/nat-upnp'; import { expect, test, vi } from 'vitest'; -import { getWanPortForUpnp } from '@app/upnp/helpers'; +import { getWanPortForUpnp } from '@app/upnp/helpers.js'; test('it successfully gets a wan port given no exclusions', () => { const port = getWanPortForUpnp(null, 36_000, 38_000); diff --git a/api/src/__test__/utils.test.ts b/api/src/__test__/utils.test.ts index c0ddff43e..0a8d3481f 100644 --- a/api/src/__test__/utils.test.ts +++ b/api/src/__test__/utils.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { formatDatetime } from '@app/utils'; +import { formatDatetime } from '@app/utils.js'; describe('formatDatetime', () => { const testDate = new Date('2024-02-14T12:34:56'); diff --git a/api/src/cli.ts b/api/src/cli.ts index 0a7605780..0833faa11 100644 --- a/api/src/cli.ts +++ b/api/src/cli.ts @@ -1,14 +1,14 @@ #!/usr/bin/env node -import '@app/dotenv'; +import '@app/dotenv.js'; import { execa } from 'execa'; import { CommandFactory } from 'nest-commander'; -import { internalLogger, logger } from '@app/core/log'; -import { LOG_LEVEL } from '@app/environment'; -import { CliModule } from '@app/unraid-api/cli/cli.module'; -import { LogService } from '@app/unraid-api/cli/log.service'; +import { internalLogger, logger } from '@app/core/log.js'; +import { LOG_LEVEL } from '@app/environment.js'; +import { CliModule } from '@app/unraid-api/cli/cli.module.js'; +import { LogService } from '@app/unraid-api/cli/log.service.js'; const getUnraidApiLocation = async () => { try { diff --git a/api/src/common/allowed-origins.ts b/api/src/common/allowed-origins.ts index bf841c909..16049d2b0 100644 --- a/api/src/common/allowed-origins.ts +++ b/api/src/common/allowed-origins.ts @@ -1,11 +1,11 @@ import { uniq } from 'lodash-es'; -import type { RootState } from '@app/store'; -import { logger } from '@app/core'; -import { GRAPHQL_INTROSPECTION } from '@app/environment'; -import { getServerIps, getUrlForField } from '@app/graphql/resolvers/subscription/network'; -import { getters, store } from '@app/store'; -import { FileLoadStatus } from '@app/store/types'; +import type { RootState } from '@app/store/index.js'; +import { logger } from '@app/core/log.js'; +import { GRAPHQL_INTROSPECTION } from '@app/environment.js'; +import { getServerIps, getUrlForField } from '@app/graphql/resolvers/subscription/network.js'; +import { getters, store } from '@app/store/index.js'; +import { FileLoadStatus } from '@app/store/types.js'; const getAllowedSocks = (): string[] => [ // Notifier bridge diff --git a/api/src/common/dashboard/get-unraid-version.ts b/api/src/common/dashboard/get-unraid-version.ts index 5c15300d5..de785f7ec 100644 --- a/api/src/common/dashboard/get-unraid-version.ts +++ b/api/src/common/dashboard/get-unraid-version.ts @@ -1,5 +1,5 @@ -import { getters } from '@app/store'; -import { FileLoadStatus } from '@app/store/types'; +import { getters } from '@app/store/index.js'; +import { FileLoadStatus } from '@app/store/types.js'; /** * Unraid version string. diff --git a/api/src/common/unraid-version-compare.ts b/api/src/common/unraid-version-compare.ts index c07da315b..5508250d8 100644 --- a/api/src/common/unraid-version-compare.ts +++ b/api/src/common/unraid-version-compare.ts @@ -1,6 +1,6 @@ import { satisfies } from 'semver'; -import { getters } from '@app/store'; +import { getters } from '@app/store/index.js'; /** * Compare version against the current unraid version. diff --git a/api/src/consts.ts b/api/src/consts.ts index 8f59081c6..4979b9765 100644 --- a/api/src/consts.ts +++ b/api/src/consts.ts @@ -2,7 +2,7 @@ import { join } from 'path'; import type { JSONWebKeySet } from 'jose'; -import { PORT } from '@app/environment'; +import { PORT } from '@app/environment.js'; export const getInternalApiAddress = (isHttp = true, nginxPort = 80) => { const envPort = PORT; diff --git a/api/src/core/errors/api-key-error.ts b/api/src/core/errors/api-key-error.ts index 61f40a95e..02ec9e650 100644 --- a/api/src/core/errors/api-key-error.ts +++ b/api/src/core/errors/api-key-error.ts @@ -1,4 +1,4 @@ -import { AppError } from '@app/core/errors/app-error'; +import { AppError } from '@app/core/errors/app-error.js'; /** * API key error. diff --git a/api/src/core/errors/array-running-error.ts b/api/src/core/errors/array-running-error.ts index a912b7234..be8e05bc0 100644 --- a/api/src/core/errors/array-running-error.ts +++ b/api/src/core/errors/array-running-error.ts @@ -1,4 +1,4 @@ -import { AppError } from '@app/core/errors/app-error'; +import { AppError } from '@app/core/errors/app-error.js'; /** * The attempted operation can only be processed while the array is stopped. diff --git a/api/src/core/errors/atomic-write-error.ts b/api/src/core/errors/atomic-write-error.ts index 89076037f..8c0376c79 100644 --- a/api/src/core/errors/atomic-write-error.ts +++ b/api/src/core/errors/atomic-write-error.ts @@ -1,4 +1,4 @@ -import { FatalAppError } from '@app/core/errors/fatal-error'; +import { FatalAppError } from '@app/core/errors/fatal-error.js'; /** * Atomic write error diff --git a/api/src/core/errors/em-cmd-error.ts b/api/src/core/errors/em-cmd-error.ts index 716850871..8f4e74157 100644 --- a/api/src/core/errors/em-cmd-error.ts +++ b/api/src/core/errors/em-cmd-error.ts @@ -1,4 +1,4 @@ -import { FatalAppError } from '@app/core/errors/fatal-error'; +import { FatalAppError } from '@app/core/errors/fatal-error.js'; /** * Em cmd client error. diff --git a/api/src/core/errors/fatal-error.ts b/api/src/core/errors/fatal-error.ts index 5a30694bf..f0857dd4d 100644 --- a/api/src/core/errors/fatal-error.ts +++ b/api/src/core/errors/fatal-error.ts @@ -1,4 +1,4 @@ -import { AppError } from '@app/core/errors/app-error'; +import { AppError } from '@app/core/errors/app-error.js'; /** * Fatal application error. diff --git a/api/src/core/errors/field-missing-error.ts b/api/src/core/errors/field-missing-error.ts index 65364118a..7314e2d89 100644 --- a/api/src/core/errors/field-missing-error.ts +++ b/api/src/core/errors/field-missing-error.ts @@ -1,4 +1,4 @@ -import { AppError } from '@app/core/errors/app-error'; +import { AppError } from '@app/core/errors/app-error.js'; /** * Module is missing a needed field diff --git a/api/src/core/errors/file-missing-error.ts b/api/src/core/errors/file-missing-error.ts index 00d5ce0a9..1c837db46 100644 --- a/api/src/core/errors/file-missing-error.ts +++ b/api/src/core/errors/file-missing-error.ts @@ -1,4 +1,4 @@ -import { AppError } from '@app/core/errors/app-error'; +import { AppError } from '@app/core/errors/app-error.js'; /** * The provided file is missing diff --git a/api/src/core/errors/not-implemented-error.ts b/api/src/core/errors/not-implemented-error.ts index 9036c160d..4848c1811 100644 --- a/api/src/core/errors/not-implemented-error.ts +++ b/api/src/core/errors/not-implemented-error.ts @@ -1,4 +1,4 @@ -import { AppError } from '@app/core/errors/app-error'; +import { AppError } from '@app/core/errors/app-error.js'; /** * Whatever this is attached to isn't yet implemented. diff --git a/api/src/core/errors/param-invalid-error.ts b/api/src/core/errors/param-invalid-error.ts index 22f9c5429..62c38b82b 100644 --- a/api/src/core/errors/param-invalid-error.ts +++ b/api/src/core/errors/param-invalid-error.ts @@ -1,6 +1,6 @@ import { format } from 'util'; -import { AppError } from '@app/core/errors/app-error'; +import { AppError } from '@app/core/errors/app-error.js'; /** * Invalid param provided to module diff --git a/api/src/core/errors/param-missing-error.ts b/api/src/core/errors/param-missing-error.ts index 6ef4ef2f2..71653e420 100644 --- a/api/src/core/errors/param-missing-error.ts +++ b/api/src/core/errors/param-missing-error.ts @@ -1,4 +1,4 @@ -import { AppError } from '@app/core/errors/app-error'; +import { AppError } from '@app/core/errors/app-error.js'; /** * Required param is missing diff --git a/api/src/core/errors/permission-error.ts b/api/src/core/errors/permission-error.ts index 66c93b2ec..ffca951f8 100644 --- a/api/src/core/errors/permission-error.ts +++ b/api/src/core/errors/permission-error.ts @@ -1,4 +1,4 @@ -import { AppError } from '@app/core/errors/app-error'; +import { AppError } from '@app/core/errors/app-error.js'; /** * Non fatal permission error diff --git a/api/src/core/errors/php-error.ts b/api/src/core/errors/php-error.ts index 04934514e..e2bf454bd 100644 --- a/api/src/core/errors/php-error.ts +++ b/api/src/core/errors/php-error.ts @@ -1,4 +1,4 @@ -import { AppError } from '@app/core/errors/app-error'; +import { AppError } from '@app/core/errors/app-error.js'; /** * Error bubbled up from a PHP script. diff --git a/api/src/core/index.ts b/api/src/core/index.ts index 06f051042..8055152b0 100644 --- a/api/src/core/index.ts +++ b/api/src/core/index.ts @@ -1,5 +1,5 @@ -export * as modules from '@app/core/modules'; -export * as notifiers from '@app/core/notifiers'; -export * as utils from '@app/core/utils'; -export * from '@app/core/log'; -export * from '@app/core/pubsub'; +export * as modules from '@app/core/modules/index.js'; +export * as notifiers from '@app/core/notifiers/index.js'; +export * as utils from '@app/core/utils/index.js'; +export * from '@app/core/log.js'; +export * from '@app/core/pubsub.js'; diff --git a/api/src/core/log.ts b/api/src/core/log.ts index 4d7398fb9..cf0a40c20 100644 --- a/api/src/core/log.ts +++ b/api/src/core/log.ts @@ -1,7 +1,7 @@ import { pino } from 'pino'; import pretty from 'pino-pretty'; -import { LOG_TYPE } from '@app/environment'; +import { LOG_TYPE } from '@app/environment.js'; export const levels = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'] as const; diff --git a/api/src/core/modules/add-share.ts b/api/src/core/modules/add-share.ts index 11172f726..0a39ff7f1 100644 --- a/api/src/core/modules/add-share.ts +++ b/api/src/core/modules/add-share.ts @@ -1,8 +1,8 @@ -import type { CoreContext, CoreResult } from '@app/core/types'; -import { AppError } from '@app/core/errors/app-error'; -import { NotImplementedError } from '@app/core/errors/not-implemented-error'; -import { ensurePermission } from '@app/core/utils/permissions/ensure-permission'; -import { getters } from '@app/store'; +import type { CoreContext, CoreResult } from '@app/core/types/index.js'; +import { AppError } from '@app/core/errors/app-error.js'; +import { NotImplementedError } from '@app/core/errors/not-implemented-error.js'; +import { ensurePermission } from '@app/core/utils/permissions/ensure-permission.js'; +import { getters } from '@app/store/index.js'; export const addShare = async (context: CoreContext): Promise => { const { user, data } = context; @@ -24,7 +24,7 @@ export const addShare = async (context: CoreContext): const userShares = shares.map(({ name }) => name); const diskShares = disks .filter((slot) => slot.exportable) - .filter(({ name }) => name.startsWith('disk')) + .filter(({ name }) => name?.startsWith('disk')) .map(({ name }) => name); // Existing share names diff --git a/api/src/core/modules/add-user.ts b/api/src/core/modules/add-user.ts index 04ee513ee..5d59252f0 100644 --- a/api/src/core/modules/add-user.ts +++ b/api/src/core/modules/add-user.ts @@ -1,11 +1,11 @@ -import type { CoreContext, CoreResult } from '@app/core/types'; -import { AppError } from '@app/core/errors/app-error'; -import { FieldMissingError } from '@app/core/errors/field-missing-error'; -import { pubsub } from '@app/core/pubsub'; -import { emcmd } from '@app/core/utils/clients/emcmd'; -import { ensurePermission } from '@app/core/utils/permissions/ensure-permission'; -import { hasFields } from '@app/core/utils/validation/has-fields'; -import { getters } from '@app/store'; +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 { pubsub } from '@app/core/pubsub.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'; +import { getters } from '@app/store/index.js'; interface Context extends CoreContext { readonly data: { @@ -24,11 +24,6 @@ interface Context extends CoreContext { export const addUser = async (context: Context): Promise => { const { data } = context; // Check permissions - ensurePermission(context.user, { - resource: 'user', - action: 'create', - possession: 'any', - }); // Validation const { name, description = '', password } = data; diff --git a/api/src/core/modules/array/add-disk-to-array.ts b/api/src/core/modules/array/add-disk-to-array.ts index f4810113c..8760c5e0d 100644 --- a/api/src/core/modules/array/add-disk-to-array.ts +++ b/api/src/core/modules/array/add-disk-to-array.ts @@ -1,11 +1,11 @@ -import { ArrayRunningError } from '@app/core/errors/array-running-error'; -import { FieldMissingError } from '@app/core/errors/field-missing-error'; -import { getArrayData } from '@app/core/modules/array/get-array-data'; -import { type CoreContext, type CoreResult } from '@app/core/types'; -import { arrayIsRunning } from '@app/core/utils/array/array-is-running'; -import { emcmd } from '@app/core/utils/clients/emcmd'; -import { ensurePermission } from '@app/core/utils/permissions/ensure-permission'; -import { hasFields } from '@app/core/utils/validation/has-fields'; +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. diff --git a/api/src/core/modules/array/get-array-data.ts b/api/src/core/modules/array/get-array-data.ts index dd6cd4de6..39bad51c8 100644 --- a/api/src/core/modules/array/get-array-data.ts +++ b/api/src/core/modules/array/get-array-data.ts @@ -1,11 +1,11 @@ import { GraphQLError } from 'graphql'; import { sum } from 'lodash-es'; -import type { ArrayCapacity, ArrayType } from '@app/graphql/generated/api/types'; -import { getServerIdentifier } from '@app/core/utils/server-identifier'; -import { ArrayDiskType } from '@app/graphql/generated/api/types'; -import { store } from '@app/store/index'; -import { FileLoadStatus } from '@app/store/types'; +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'; export const getArrayData = (getState = store.getState): ArrayType => { // Var state isn't loaded @@ -51,7 +51,7 @@ export const getArrayData = (getState = store.getState): ArrayType => { }; return { - id: getServerIdentifier('array'), + id: 'array', state: emhttp.var.mdState, capacity, boot, diff --git a/api/src/core/modules/array/index.ts b/api/src/core/modules/array/index.ts new file mode 100644 index 000000000..fc4540420 --- /dev/null +++ b/api/src/core/modules/array/index.ts @@ -0,0 +1,6 @@ +// 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'; diff --git a/api/src/core/modules/array/remove-disk-from-array.ts b/api/src/core/modules/array/remove-disk-from-array.ts index 70ad5d3ee..895a5b7aa 100644 --- a/api/src/core/modules/array/remove-disk-from-array.ts +++ b/api/src/core/modules/array/remove-disk-from-array.ts @@ -1,10 +1,9 @@ -import { ArrayRunningError } from '@app/core/errors/array-running-error'; -import { FieldMissingError } from '@app/core/errors/field-missing-error'; -import { getArrayData } from '@app/core/modules/array/get-array-data'; -import { type CoreContext, type CoreResult } from '@app/core/types'; -import { arrayIsRunning } from '@app/core/utils/array/array-is-running'; -import { ensurePermission } from '@app/core/utils/permissions/ensure-permission'; -import { hasFields } from '@app/core/utils/validation/has-fields'; +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: { @@ -18,15 +17,7 @@ interface Context extends CoreContext { * @returns The updated array. */ export const removeDiskFromArray = async (context: Context): Promise => { - const { data, user } = context; - - // Check permissions - ensurePermission(user, { - resource: 'array', - action: 'create', - possession: 'any', - }); - + const { data } = context; const missingFields = hasFields(data, ['id']); if (missingFields.length !== 0) { diff --git a/api/src/core/modules/array/update-array.ts b/api/src/core/modules/array/update-array.ts index e9040307a..baf87af19 100644 --- a/api/src/core/modules/array/update-array.ts +++ b/api/src/core/modules/array/update-array.ts @@ -1,13 +1,13 @@ -import type { CoreContext, CoreResult } from '@app/core/types'; -import { AppError } from '@app/core/errors/app-error'; -import { FieldMissingError } from '@app/core/errors/field-missing-error'; -import { ParamInvalidError } from '@app/core/errors/param-invalid-error'; -import { getArrayData } from '@app/core/modules/array/get-array-data'; -import { arrayIsRunning } from '@app/core/utils/array/array-is-running'; -import { emcmd } from '@app/core/utils/clients/emcmd'; -import { uppercaseFirstChar } from '@app/core/utils/misc/uppercase-first-char'; -import { ensurePermission } from '@app/core/utils/permissions/ensure-permission'; -import { hasFields } from '@app/core/utils/validation/has-fields'; +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 @@ -31,7 +31,7 @@ export const updateArray = async (context: CoreContext): Promise => throw new FieldMissingError(missingFields[0]); } - const { state: nextState } = data; + const { state: nextState } = data as { state: string }; const startState = arrayIsRunning() ? 'started' : 'stopped'; const pendingState = nextState === 'stop' ? 'stopping' : 'starting'; @@ -79,7 +79,7 @@ export const updateArray = async (context: CoreContext): Promise => return { text: `Array was ${startState}, ${pendingState}.`, json: { - ...array.json, + ...array, state: nextState === 'start' ? 'started' : 'stopped', previousState: startState, pendingState, diff --git a/api/src/core/modules/array/update-parity-check.ts b/api/src/core/modules/array/update-parity-check.ts index 6e35c7105..6885e7d75 100644 --- a/api/src/core/modules/array/update-parity-check.ts +++ b/api/src/core/modules/array/update-parity-check.ts @@ -1,9 +1,9 @@ -import type { CoreContext, CoreResult } from '@app/core/types'; -import { FieldMissingError } from '@app/core/errors/field-missing-error'; -import { ParamInvalidError } from '@app/core/errors/param-invalid-error'; -import { emcmd } from '@app/core/utils/clients/emcmd'; -import { ensurePermission } from '@app/core/utils/permissions/ensure-permission'; -import { getters } from '@app/store'; +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'; diff --git a/api/src/core/modules/debug/get-context.ts b/api/src/core/modules/debug/get-context.ts index 73e4939d3..3ebb3cfb1 100644 --- a/api/src/core/modules/debug/get-context.ts +++ b/api/src/core/modules/debug/get-context.ts @@ -1,4 +1,4 @@ -import { type CoreContext, type CoreResult } from '@app/core/types'; +import { type CoreContext, type CoreResult } from '@app/core/types/index.js'; /** * Get internal context object. diff --git a/api/src/core/modules/debug/index.ts b/api/src/core/modules/debug/index.ts new file mode 100644 index 000000000..f6544f705 --- /dev/null +++ b/api/src/core/modules/debug/index.ts @@ -0,0 +1,3 @@ +// Created from 'create-ts-index' + +export * from './get-context.js'; diff --git a/api/src/core/modules/disks/id/get-disk.ts b/api/src/core/modules/disks/id/get-disk.ts index 1d1b6e906..f8802847c 100644 --- a/api/src/core/modules/disks/id/get-disk.ts +++ b/api/src/core/modules/disks/id/get-disk.ts @@ -1,6 +1,6 @@ -import { AppError } from '@app/core/errors/app-error'; -import { type CoreContext, type CoreResult } from '@app/core/types'; -import { ensurePermission } from '@app/core/utils/permissions/ensure-permission'; +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'; interface Context extends CoreContext { params: { @@ -11,18 +11,11 @@ interface Context extends CoreContext { /** * Get a single disk. */ -export const getDisk = async (context: Context, Disks): Promise => { - const { params, user } = context; - - // Check permissions - ensurePermission(user, { - resource: 'disk', - action: 'read', - possession: 'any', - }); +export const getDisk = async (context: Context, Disks: Disk[]): Promise => { + const { params } = context; const { id } = params; - const disk = await Disks.findOne({ id }); + const disk = Disks.find((disk) => disk.id === id); if (!disk) { throw new AppError(`No disk found matching ${id}`, 404); diff --git a/api/src/core/modules/disks/id/index.ts b/api/src/core/modules/disks/id/index.ts new file mode 100644 index 000000000..803268a68 --- /dev/null +++ b/api/src/core/modules/disks/id/index.ts @@ -0,0 +1,3 @@ +// Created from 'create-ts-index' + +export * from './get-disk.js'; diff --git a/api/src/core/modules/disks/index.ts b/api/src/core/modules/disks/index.ts new file mode 100644 index 000000000..5ce7ec989 --- /dev/null +++ b/api/src/core/modules/disks/index.ts @@ -0,0 +1,3 @@ +// Created from 'create-ts-index' + +export * from './id/index.js'; diff --git a/api/src/core/modules/docker/get-docker-containers.ts b/api/src/core/modules/docker/get-docker-containers.ts index 490223446..a5d4c5245 100644 --- a/api/src/core/modules/docker/get-docker-containers.ts +++ b/api/src/core/modules/docker/get-docker-containers.ts @@ -1,14 +1,15 @@ import fs from 'fs'; import camelCaseKeys from 'camelcase-keys'; +import { ContainerInfo } from 'dockerode'; -import type { ContainerPort, DockerContainer } from '@app/graphql/generated/api/types'; -import { dockerLogger } from '@app/core/log'; -import { docker } from '@app/core/utils/clients/docker'; -import { catchHandlers } from '@app/core/utils/misc/catch-handlers'; -import { ContainerPortType, ContainerState } from '@app/graphql/generated/api/types'; -import { getters, store } from '@app/store'; -import { updateDockerState } from '@app/store/modules/docker'; +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. @@ -42,29 +43,39 @@ export const getDockerContainers = async ( all: true, size: true, }) - .then((containers) => containers.map((object) => camelCaseKeys(object, { deep: true }))) // If docker throws an error return no containers .catch(catchHandlers.docker); // Cleanup container object - const containers: Array = rawContainers.map((container) => { - const names = container.names[0]; - const containerData: DockerContainer = { - ...container, - labels: container.labels, - // @ts-expect-error sizeRootFs is not on the dockerode type, but is fetched when size: true is set - sizeRootFs: container.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((port) => ({ - ...port, - type: ContainerPortType[port.type.toUpperCase()], - })), - }; + const containers: Array = rawContainers.map((container) => { + const names = container.Names[0]; + const containerData: DockerContainer = camelCaseKeys( + { + 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((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; }); diff --git a/api/src/core/modules/docker/get-docker-networks.ts b/api/src/core/modules/docker/get-docker-networks.ts index 7245dcbfd..f2beae1fa 100644 --- a/api/src/core/modules/docker/get-docker-networks.ts +++ b/api/src/core/modules/docker/get-docker-networks.ts @@ -1,9 +1,9 @@ import camelCaseKeys from 'camelcase-keys'; -import { type CoreContext, type CoreResult } from '@app/core/types'; -import { docker } from '@app/core/utils'; -import { catchHandlers } from '@app/core/utils/misc/catch-handlers'; -import { ensurePermission } from '@app/core/utils/permissions/ensure-permission'; +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 => { const { user } = context; @@ -19,7 +19,11 @@ export const getDockerNetworks = async (context: CoreContext): Promise networks.map((object) => camelCaseKeys(object, { deep: true }))); + .then((networks = []) => + networks.map((object) => + camelCaseKeys(object as unknown as Record, { deep: true }) + ) + ); /** * Get all Docker networks @@ -30,7 +34,6 @@ export const getDockerNetworks = async (context: CoreContext): Promise => { try { @@ -62,6 +62,7 @@ const parseDisk = async ( : DiskInterfaceType.UNKNOWN, temperature: temperature ? await getTemperature(disk) : -1, partitions, + id: disk.serialNum, }; }; diff --git a/api/src/core/modules/get-parity-history.ts b/api/src/core/modules/get-parity-history.ts index 6e448806a..e83306ee6 100644 --- a/api/src/core/modules/get-parity-history.ts +++ b/api/src/core/modules/get-parity-history.ts @@ -2,10 +2,10 @@ import { promises as fs } from 'fs'; import Table from 'cli-table'; -import { FileMissingError } from '@app/core/errors/file-missing-error'; -import { type CoreContext, type CoreResult } from '@app/core/types'; -import { ensurePermission } from '@app/core/utils/permissions/ensure-permission'; -import { getters } from '@app/store'; +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. @@ -46,10 +46,11 @@ export const getParityHistory = async (context: CoreContext): Promise { const array = Object.values({ - ...check, + date: check.date, speed: check.speed ? check.speed : 'Unavailable', - duration: check.duration >= 0 ? check.duration : 'Unavailable', + duration: check.duration >= 0 ? check.duration.toString() : 'Unavailable', status: check.status === '-4' ? 'Cancelled' : 'OK', + errors: check.errors.toString(), }); table.push(array); }); diff --git a/api/src/core/modules/get-services.ts b/api/src/core/modules/get-services.ts index 1d33325b0..d8741a242 100644 --- a/api/src/core/modules/get-services.ts +++ b/api/src/core/modules/get-services.ts @@ -1,8 +1,7 @@ -import type { CoreContext, CoreResult } from '@app/core/types'; -import { logger } from '@app/core/log'; -import { getEmhttpdService } from '@app/core/modules/services/get-emhttpd'; -import { getUnraidApiService } from '@app/core/modules/services/get-unraid-api'; -import { NODE_ENV } from '@app/environment'; +import type { CoreContext, CoreResult } from '@app/core/types/index.js'; +import { logger } from '@app/core/log.js'; +import { getEmhttpdService } from '@app/core/modules/services/get-emhttpd.js'; +import { getUnraidApiService } from '@app/core/modules/services/get-unraid-api.js'; const devNames = ['emhttpd', 'rest-api']; @@ -61,7 +60,6 @@ export const getServices = async (context: CoreContext): Promise => { ]; return { - text: `Services: ${JSON.stringify(result, null, 2)}`, json: result, }; }; diff --git a/api/src/core/modules/get-users.ts b/api/src/core/modules/get-users.ts index 6085138f1..cfafc64ad 100644 --- a/api/src/core/modules/get-users.ts +++ b/api/src/core/modules/get-users.ts @@ -1,8 +1,7 @@ -import type { CoreContext, CoreResult } from '@app/core/types'; -import { AppError } from '@app/core/errors/app-error'; -import { type User } from '@app/core/types/states/user'; -import { ensurePermission } from '@app/core/utils/permissions/ensure-permission'; -import { getters } from '@app/store'; +import type { CoreContext, CoreResult } from '@app/core/types/index.js'; +import { AppError } from '@app/core/errors/app-error.js'; +import { type User } from '@app/core/types/states/user.js'; +import { getters } from '@app/store/index.js'; interface Context extends CoreContext { query: { @@ -15,14 +14,7 @@ interface Context extends CoreContext { * Get all users. */ export const getUsers = async (context: Context): Promise => { - const { query, user } = context; - - // Check permissions - ensurePermission(user, { - resource: 'user', - action: 'read', - possession: 'any', - }); + const { query } = context; // Default to only showing limited fields const { slim = 'true' } = query; diff --git a/api/src/core/modules/get-welcome.ts b/api/src/core/modules/get-welcome.ts index b718c63e9..318cf20b7 100644 --- a/api/src/core/modules/get-welcome.ts +++ b/api/src/core/modules/get-welcome.ts @@ -1,6 +1,6 @@ -import type { CoreContext, CoreResult } from '@app/core/types'; -import { getUnraidVersion } from '@app/common/dashboard/get-unraid-version'; -import { ensurePermission } from '@app/core/utils/permissions/ensure-permission'; +import type { CoreContext, CoreResult } from '@app/core/types/index.js'; +import { getUnraidVersion } from '@app/common/dashboard/get-unraid-version.js'; +import { ensurePermission } from '@app/core/utils/permissions/ensure-permission.js'; /** * Get welcome message. diff --git a/api/src/core/modules/index.ts b/api/src/core/modules/index.ts index 8f2e205e2..a08e81bfd 100644 --- a/api/src/core/modules/index.ts +++ b/api/src/core/modules/index.ts @@ -1,20 +1,20 @@ // Created from 'create-ts-index' -export * from './array'; -export * from './debug'; -export * from './disks'; -export * from './docker'; -export * from './services'; -export * from './settings'; -export * from './shares'; -export * from './users'; -export * from './vms'; -export * from './add-share'; -export * from './add-user'; -export * from './get-apps'; -export * from './get-devices'; -export * from './get-disks'; -export * from './get-parity-history'; -export * from './get-services'; -export * from './get-users'; -export * from './get-welcome'; +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'; diff --git a/api/src/core/modules/services/get-emhttpd.ts b/api/src/core/modules/services/get-emhttpd.ts index 567fdc2d0..82899dc53 100644 --- a/api/src/core/modules/services/get-emhttpd.ts +++ b/api/src/core/modules/services/get-emhttpd.ts @@ -1,8 +1,8 @@ import { execa } from 'execa'; -import { type CoreContext, type CoreResult } from '@app/core/types'; -import { cleanStdout } from '@app/core/utils/misc/clean-stdout'; -import { ensurePermission } from '@app/core/utils/permissions/ensure-permission'; +import { type CoreContext, type CoreResult } from '@app/core/types/index.js'; +import { cleanStdout } from '@app/core/utils/misc/clean-stdout.js'; +import { ensurePermission } from '@app/core/utils/permissions/ensure-permission.js'; interface Result extends CoreResult { json: { @@ -33,7 +33,6 @@ export const getEmhttpdService = async (context: CoreContext): Promise = const online = uptime >= 1; return { - text: `Online: ${online}\n Uptime: ${uptime}`, json: { online, uptime, diff --git a/api/src/core/modules/services/get-unraid-api.ts b/api/src/core/modules/services/get-unraid-api.ts index bbf7ceccb..1114a36b9 100644 --- a/api/src/core/modules/services/get-unraid-api.ts +++ b/api/src/core/modules/services/get-unraid-api.ts @@ -1,6 +1,6 @@ -import type { CoreContext, CoreResult } from '@app/core/types'; -import { ensurePermission } from '@app/core/utils/permissions/ensure-permission'; -import { API_VERSION } from '@app/environment'; +import type { CoreContext, CoreResult } from '@app/core/types/index.js'; +import { ensurePermission } from '@app/core/utils/permissions/ensure-permission.js'; +import { API_VERSION } from '@app/environment.js'; interface Result extends CoreResult { json: { @@ -42,7 +42,6 @@ export const getUnraidApiService = async (context: CoreContext): Promise }; return { - text: `Service: ${JSON.stringify(service, null, 2)}`, json: service, }; }; diff --git a/api/src/core/modules/services/index.ts b/api/src/core/modules/services/index.ts new file mode 100644 index 000000000..4f18db8f8 --- /dev/null +++ b/api/src/core/modules/services/index.ts @@ -0,0 +1,4 @@ +// Created from 'create-ts-index' + +export * from './get-emhttpd.js'; +export * from './get-unraid-api.js'; diff --git a/api/src/core/modules/services/nginx.ts b/api/src/core/modules/services/nginx.ts index 1749ff88a..090d41c3b 100644 --- a/api/src/core/modules/services/nginx.ts +++ b/api/src/core/modules/services/nginx.ts @@ -1,6 +1,6 @@ import { execa } from 'execa'; -import { logger } from '@app/core/log'; +import { logger } from '@app/core/log.js'; export class NginxManager { public reloadNginx = async () => { diff --git a/api/src/core/modules/services/update-dns.ts b/api/src/core/modules/services/update-dns.ts index 0fef7aa12..53fccdb73 100644 --- a/api/src/core/modules/services/update-dns.ts +++ b/api/src/core/modules/services/update-dns.ts @@ -1,6 +1,6 @@ import { execa } from 'execa'; -import { logger } from '@app/core/log'; +import { logger } from '@app/core/log.js'; export class UpdateDNSManager { public updateDNS = async () => { diff --git a/api/src/core/modules/settings/index.ts b/api/src/core/modules/settings/index.ts new file mode 100644 index 000000000..825c688c9 --- /dev/null +++ b/api/src/core/modules/settings/index.ts @@ -0,0 +1,3 @@ +// Created from 'create-ts-index' + +export * from './update-disk.js'; diff --git a/api/src/core/modules/settings/update-disk.ts b/api/src/core/modules/settings/update-disk.ts index b3b2aced0..bee930df0 100644 --- a/api/src/core/modules/settings/update-disk.ts +++ b/api/src/core/modules/settings/update-disk.ts @@ -1,9 +1,9 @@ -import { EmCmdError } from '@app/core/errors/em-cmd-error'; -import { type CoreContext, type CoreResult } from '@app/core/types'; -import { type Var } from '@app/core/types/states/var'; -import { emcmd } from '@app/core/utils/clients/emcmd'; -import { ensurePermission } from '@app/core/utils/permissions/ensure-permission'; -import { getters } from '@app/store'; +import { EmCmdError } from '@app/core/errors/em-cmd-error.js'; +import { type CoreContext, type CoreResult } from '@app/core/types/index.js'; +import { type Var } from '@app/core/types/states/var.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'; interface Context extends CoreContext { data: Var; @@ -23,14 +23,7 @@ interface Result extends CoreResult { * Update disk settings. */ export const updateDisk = async (context: Context): Promise => { - const { data, user } = context; - - // Check permissions - ensurePermission(user, { - resource: 'disk/settings', - action: 'update', - possession: 'any', - }); + const { data } = context; /** * Check context.data[property] is using an allowed value. diff --git a/api/src/core/modules/shares/index.ts b/api/src/core/modules/shares/index.ts new file mode 100644 index 000000000..b8917760e --- /dev/null +++ b/api/src/core/modules/shares/index.ts @@ -0,0 +1,3 @@ +// Created from 'create-ts-index' + +export * from './name/index.js'; diff --git a/api/src/core/modules/shares/name/get-share.ts b/api/src/core/modules/shares/name/get-share.ts index a53b9cbe7..29b81aaa8 100644 --- a/api/src/core/modules/shares/name/get-share.ts +++ b/api/src/core/modules/shares/name/get-share.ts @@ -1,8 +1,8 @@ -import type { CoreContext, CoreResult } from '@app/core/types/global'; -import type { DiskShare, UserShare } from '@app/core/types/states/share'; -import { AppError } from '@app/core/errors/app-error'; -import { getShares } from '@app/core/utils'; -import { ensurePermission } from '@app/core/utils/permissions/ensure-permission'; +import type { CoreContext, CoreResult } from '@app/core/types/global.js'; +import type { DiskShare, UserShare } from '@app/core/types/states/share.js'; +import { AppError } from '@app/core/errors/app-error.js'; +import { ensurePermission } from '@app/core/utils/permissions/ensure-permission.js'; +import { getShares } from '@app/core/utils/shares/get-shares.js'; interface Context extends CoreContext { params: { diff --git a/api/src/core/modules/shares/name/index.ts b/api/src/core/modules/shares/name/index.ts new file mode 100644 index 000000000..d803164ad --- /dev/null +++ b/api/src/core/modules/shares/name/index.ts @@ -0,0 +1,3 @@ +// Created from 'create-ts-index' + +export * from './get-share.js'; diff --git a/api/src/core/modules/users/id/add-role.ts b/api/src/core/modules/users/id/add-role.ts index 9ca1ee0e1..4a241104c 100644 --- a/api/src/core/modules/users/id/add-role.ts +++ b/api/src/core/modules/users/id/add-role.ts @@ -1,9 +1,9 @@ -import { AppError } from '@app/core/errors/app-error'; -import { FieldMissingError } from '@app/core/errors/field-missing-error'; -import { type CoreContext, type CoreResult } from '@app/core/types'; -import { ensurePermission } from '@app/core/utils/permissions/ensure-permission'; -import { hasFields } from '@app/core/utils/validation/has-fields'; -import { getters } from '@app/store'; +import { AppError } from '@app/core/errors/app-error.js'; +import { FieldMissingError } from '@app/core/errors/field-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 { hasFields } from '@app/core/utils/validation/has-fields.js'; +import { getters } from '@app/store/index.js'; interface Context extends CoreContext { params: { @@ -16,14 +16,7 @@ interface Context extends CoreContext { * Add role to user. */ export const addRole = async (context: Context): Promise => { - const { user, params } = context; - - // Check permissions - ensurePermission(user, { - resource: 'user', - action: 'update', - possession: 'any', - }); + const { params } = context; // Validation const { name } = params; diff --git a/api/src/core/modules/users/id/delete-user.ts b/api/src/core/modules/users/id/delete-user.ts index 890854b05..ffabe3ee4 100644 --- a/api/src/core/modules/users/id/delete-user.ts +++ b/api/src/core/modules/users/id/delete-user.ts @@ -1,10 +1,10 @@ -import type { CoreContext, CoreResult } from '@app/core/types'; -import { AppError } from '@app/core/errors/app-error'; -import { FieldMissingError } from '@app/core/errors/field-missing-error'; -import { emcmd } from '@app/core/utils/clients/emcmd'; -import { ensurePermission } from '@app/core/utils/permissions/ensure-permission'; -import { hasFields } from '@app/core/utils/validation/has-fields'; -import { getters } from '@app/store'; +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 { 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'; +import { getters } from '@app/store/index.js'; interface Context extends CoreContext { params: { @@ -18,11 +18,6 @@ interface Context extends CoreContext { */ export const deleteUser = async (context: Context): Promise => { // Check permissions - ensurePermission(context.user, { - resource: 'user', - action: 'delete', - possession: 'any', - }); const { params } = context; const { name } = params; diff --git a/api/src/core/modules/users/id/get-user.ts b/api/src/core/modules/users/id/get-user.ts index 9aca19b78..bfdff7f23 100644 --- a/api/src/core/modules/users/id/get-user.ts +++ b/api/src/core/modules/users/id/get-user.ts @@ -1,8 +1,8 @@ -import type { CoreContext, CoreResult } from '@app/core/types'; -import { AppError } from '@app/core/errors/app-error'; -import { ensurePermission } from '@app/core/utils/permissions/ensure-permission'; -import { ensureParameter } from '@app/core/utils/validation/context'; -import { getters } from '@app/store'; +import type { CoreContext, CoreResult } from '@app/core/types/index.js'; +import { AppError } from '@app/core/errors/app-error.js'; +import { ensurePermission } from '@app/core/utils/permissions/ensure-permission.js'; +import { ensureParameter } from '@app/core/utils/validation/context/ensure-parameter.js'; +import { getters } from '@app/store/index.js'; interface Context extends CoreContext { params: { diff --git a/api/src/core/modules/users/id/index.ts b/api/src/core/modules/users/id/index.ts new file mode 100644 index 000000000..91aa082b8 --- /dev/null +++ b/api/src/core/modules/users/id/index.ts @@ -0,0 +1,5 @@ +// Created from 'create-ts-index' + +export * from './add-role.js'; +export * from './delete-user.js'; +export * from './get-user.js'; diff --git a/api/src/core/modules/users/index.ts b/api/src/core/modules/users/index.ts new file mode 100644 index 000000000..5ce7ec989 --- /dev/null +++ b/api/src/core/modules/users/index.ts @@ -0,0 +1,3 @@ +// Created from 'create-ts-index' + +export * from './id/index.js'; diff --git a/api/src/core/modules/vms/get-domains.ts b/api/src/core/modules/vms/get-domains.ts index 0d5accff0..bac467fbc 100644 --- a/api/src/core/modules/vms/get-domains.ts +++ b/api/src/core/modules/vms/get-domains.ts @@ -1,7 +1,7 @@ import { GraphQLError } from 'graphql'; -import type { VmDomain } from '@app/graphql/generated/api/types'; -import { VmState } from '@app/graphql/generated/api/types'; +import type { VmDomain } from '@app/graphql/generated/api/types.js'; +import { VmState } from '@app/graphql/generated/api/types.js'; const states = { 0: 'NOSTATE', @@ -20,7 +20,7 @@ const states = { export const getDomains = async () => { try { const { ConnectListAllDomainsFlags } = await import('@unraid/libvirt'); - const { UnraidHypervisor } = await import('@app/core/utils/vms/get-hypervisor'); + const { UnraidHypervisor } = await import('@app/core/utils/vms/get-hypervisor.js'); const hypervisor = await UnraidHypervisor.getInstance().getHypervisor(); if (!hypervisor) { diff --git a/api/src/core/modules/vms/index.ts b/api/src/core/modules/vms/index.ts index b69f3d784..50b2361bc 100644 --- a/api/src/core/modules/vms/index.ts +++ b/api/src/core/modules/vms/index.ts @@ -1,2 +1,2 @@ // Created from 'create-ts-index' -export * from './get-domains'; +export * from './get-domains.js'; diff --git a/api/src/core/notifiers/console.ts b/api/src/core/notifiers/console.ts index 3f610f8c9..3384fc506 100644 --- a/api/src/core/notifiers/console.ts +++ b/api/src/core/notifiers/console.ts @@ -1,6 +1,6 @@ -import type { NotifierOptions, NotifierSendOptions } from '@app/core/notifiers/notifier'; -import { logger } from '@app/core/log'; -import { Notifier } from '@app/core/notifiers/notifier'; +import type { NotifierOptions, NotifierSendOptions } from '@app/core/notifiers/notifier.js'; +import { logger } from '@app/core/log.js'; +import { Notifier } from '@app/core/notifiers/notifier.js'; /** * Console notifier. @@ -22,9 +22,9 @@ export class ConsoleNotifier extends Notifier { */ send(options: NotifierSendOptions) { const { title, data } = options; - const { level, helpers } = this; + const { level } = this; // Render template - const template = this.render({ ...data }, helpers); + const template = this.render({ ...data }); this.log[level](title, template); } diff --git a/api/src/core/notifiers/http.ts b/api/src/core/notifiers/http.ts index 1d114e2e8..24a1cf48c 100644 --- a/api/src/core/notifiers/http.ts +++ b/api/src/core/notifiers/http.ts @@ -1,7 +1,7 @@ import { got } from 'got'; -import type { NotifierOptions } from '@app/core/notifiers/notifier'; -import { Notifier } from '@app/core/notifiers/notifier'; +import type { NotifierOptions } from '@app/core/notifiers/notifier.js'; +import { Notifier } from '@app/core/notifiers/notifier.js'; export type Options = NotifierOptions; diff --git a/api/src/core/notifiers/index.ts b/api/src/core/notifiers/index.ts new file mode 100644 index 000000000..c43f3f537 --- /dev/null +++ b/api/src/core/notifiers/index.ts @@ -0,0 +1,5 @@ +// Created from 'create-ts-index' + +export * from './console.js'; +export * from './http.js'; +export * from './notifier.js'; diff --git a/api/src/core/notifiers/notifier.ts b/api/src/core/notifiers/notifier.ts index 54f53e154..18124609d 100644 --- a/api/src/core/notifiers/notifier.ts +++ b/api/src/core/notifiers/notifier.ts @@ -1,7 +1,7 @@ import Mustache from 'mustache'; -import { type LooseObject } from '@app/core/types'; -import { type NotificationIni } from '@app/core/types/states/notification'; +import { type LooseObject } from '@app/core/types/index.js'; +import { type NotificationIni } from '@app/core/types/states/notification.js'; export type NotifierLevel = 'info' | 'warn' | 'error'; diff --git a/api/src/core/notifiers/unraid-local.ts b/api/src/core/notifiers/unraid-local.ts index 2b92aa146..732691292 100644 --- a/api/src/core/notifiers/unraid-local.ts +++ b/api/src/core/notifiers/unraid-local.ts @@ -1,8 +1,8 @@ import { execa } from 'execa'; -import type { NotifierOptions, NotifierSendOptions } from '@app/core/notifiers/notifier'; -import { logger } from '@app/core/log'; -import { Notifier } from '@app/core/notifiers/notifier'; +import type { NotifierOptions, NotifierSendOptions } from '@app/core/notifiers/notifier.js'; +import { logger } from '@app/core/log.js'; +import { Notifier } from '@app/core/notifiers/notifier.js'; type ValidLocalLevels = 'alert' | 'warning' | 'normal'; diff --git a/api/src/core/types/global.ts b/api/src/core/types/global.ts index b6023f2b5..0cf1e802c 100644 --- a/api/src/core/types/global.ts +++ b/api/src/core/types/global.ts @@ -1,4 +1,4 @@ -import { type User } from '@app/core/types/states/user'; +import { type User } from '@app/core/types/states/user.js'; /** * Example: 1, 2, 3 or 1,2,3 diff --git a/api/src/core/types/index.ts b/api/src/core/types/index.ts new file mode 100644 index 000000000..c82bce579 --- /dev/null +++ b/api/src/core/types/index.ts @@ -0,0 +1,5 @@ +// Created from 'create-ts-index' + +export * from './domain.js'; +export * from './global.js'; +export * from './pci-device.js'; diff --git a/api/src/core/types/states/sec.ts b/api/src/core/types/states/sec.ts index bc0f473c3..b2ff458b0 100644 --- a/api/src/core/types/states/sec.ts +++ b/api/src/core/types/states/sec.ts @@ -1,4 +1,4 @@ -import { type IniEnabled } from '@app/core/types/ini'; +import { type IniEnabled } from '@app/core/types/ini.js'; export interface SecIni { export: IniEnabled; diff --git a/api/src/core/types/states/var.ts b/api/src/core/types/states/var.ts index 5a99005e1..961422561 100644 --- a/api/src/core/types/states/var.ts +++ b/api/src/core/types/states/var.ts @@ -3,7 +3,7 @@ import { type DiskFsType, type RegistrationState, type registrationType, -} from '@app/graphql/generated/api/types'; +} from '@app/graphql/generated/api/types.js'; /** * Global vars @@ -22,7 +22,7 @@ export type Var = { csrfToken: string; defaultFormat: string; /** Default file system for data disks. */ - defaultFsType: DiskFsType.XFS; + defaultFsType: DiskFsType; /** Amount of connected drives (license device count). */ deviceCount: number; domain: string; diff --git a/api/src/core/utils/array/array-is-running.ts b/api/src/core/utils/array/array-is-running.ts index 4b41a716b..f94835dd5 100644 --- a/api/src/core/utils/array/array-is-running.ts +++ b/api/src/core/utils/array/array-is-running.ts @@ -1,5 +1,5 @@ -import { ArrayState } from '@app/graphql/generated/api/types'; -import { getters } from '@app/store'; +import { ArrayState } from '@app/graphql/generated/api/types.js'; +import { getters } from '@app/store/index.js'; /** * Is the array running? diff --git a/api/src/core/utils/array/index.ts b/api/src/core/utils/array/index.ts new file mode 100644 index 000000000..dd7c0b9ae --- /dev/null +++ b/api/src/core/utils/array/index.ts @@ -0,0 +1,3 @@ +// Created from 'create-ts-index' + +export * from './array-is-running.js'; diff --git a/api/src/core/utils/clients/emcmd.ts b/api/src/core/utils/clients/emcmd.ts index e0b750f79..8c8d65914 100644 --- a/api/src/core/utils/clients/emcmd.ts +++ b/api/src/core/utils/clients/emcmd.ts @@ -1,10 +1,10 @@ import { got } from 'got'; -import { logger } from '@app/core/log'; -import { type LooseObject } from '@app/core/types'; -import { catchHandlers } from '@app/core/utils/misc/catch-handlers'; -import { DRY_RUN } from '@app/environment'; -import { getters } from '@app/store'; +import { logger } from '@app/core/log.js'; +import { type LooseObject } from '@app/core/types/index.js'; +import { catchHandlers } from '@app/core/utils/misc/catch-handlers.js'; +import { DRY_RUN } from '@app/environment.js'; +import { getters } from '@app/store/index.js'; /** * Run a command with emcmd. diff --git a/api/src/core/utils/clients/index.ts b/api/src/core/utils/clients/index.ts new file mode 100644 index 000000000..7130a16b2 --- /dev/null +++ b/api/src/core/utils/clients/index.ts @@ -0,0 +1,4 @@ +// Created from 'create-ts-index' + +export * from './docker.js'; +export * from './emcmd.js'; diff --git a/api/src/core/utils/files/config-file-normalizer.ts b/api/src/core/utils/files/config-file-normalizer.ts index b5f45ab5f..cc4d538a7 100644 --- a/api/src/core/utils/files/config-file-normalizer.ts +++ b/api/src/core/utils/files/config-file-normalizer.ts @@ -1,13 +1,13 @@ import { isEqual, merge } from 'lodash-es'; -import { getAllowedOrigins } from '@app/common/allowed-origins'; -import { initialState } from '@app/store/modules/config'; +import { getAllowedOrigins } from '@app/common/allowed-origins.js'; +import { initialState } from '@app/store/modules/config.js'; import { MyServersConfig, MyServersConfigMemory, MyServersConfigMemorySchema, MyServersConfigSchema, -} from '@app/types/my-servers-config'; +} from '@app/types/my-servers-config.js'; // Define ConfigType and ConfigObject export type ConfigType = 'flash' | 'memory'; diff --git a/api/src/core/utils/files/load-file-from-path.ts b/api/src/core/utils/files/load-file-from-path.ts index 093ab4497..be9f406e8 100644 --- a/api/src/core/utils/files/load-file-from-path.ts +++ b/api/src/core/utils/files/load-file-from-path.ts @@ -2,7 +2,7 @@ import { readFileSync } from 'fs'; import { readFile } from 'fs/promises'; import { extname } from 'path'; -import { fileExists, fileExistsSync } from '@app/core/utils/files/file-exists'; +import { fileExists, fileExistsSync } from '@app/core/utils/files/file-exists.js'; export const loadFileFromPath = async ( filePath: string diff --git a/api/src/core/utils/images/image-file-helpers.ts b/api/src/core/utils/images/image-file-helpers.ts index 22de74936..f326877b3 100644 --- a/api/src/core/utils/images/image-file-helpers.ts +++ b/api/src/core/utils/images/image-file-helpers.ts @@ -1,8 +1,8 @@ import { readFile, stat } from 'node:fs/promises'; import { join } from 'node:path'; -import { getters } from '@app/store/index'; -import { FileLoadStatus } from '@app/store/types'; +import { getters } from '@app/store/index.js'; +import { FileLoadStatus } from '@app/store/types.js'; const isImageFile = async (path: string): Promise => { try { diff --git a/api/src/core/utils/index.ts b/api/src/core/utils/index.ts index 456fe2c9e..78908be91 100644 --- a/api/src/core/utils/index.ts +++ b/api/src/core/utils/index.ts @@ -1,9 +1,9 @@ // Created from 'create-ts-index' -export * from './array'; -export * from './clients'; -export * from './plugins'; -export * from './shares'; -export * from './validation'; -export * from './vms'; -export * from './casting'; +export * from './array/index.js'; +export * from './clients/index.js'; +export * from './plugins/index.js'; +export * from './shares/index.js'; +export * from './validation/index.js'; +export * from './vms/index.js'; +export * from './casting.js'; diff --git a/api/src/core/utils/misc/catch-handlers.ts b/api/src/core/utils/misc/catch-handlers.ts index 10b4f12ce..48b334113 100644 --- a/api/src/core/utils/misc/catch-handlers.ts +++ b/api/src/core/utils/misc/catch-handlers.ts @@ -1,5 +1,5 @@ -import { AppError } from '@app/core/errors/app-error'; -import { getters } from '@app/store'; +import { AppError } from '@app/core/errors/app-error.js'; +import { getters } from '@app/store/index.js'; interface DockerError extends NodeJS.ErrnoException { address: string; diff --git a/api/src/core/utils/misc/exit-app.ts b/api/src/core/utils/misc/exit-app.ts index b43720bf0..fb21f72f6 100644 --- a/api/src/core/utils/misc/exit-app.ts +++ b/api/src/core/utils/misc/exit-app.ts @@ -1,5 +1,5 @@ -import { AppError } from '@app/core/errors/app-error'; -import { logger } from '@app/core/log'; +import { AppError } from '@app/core/errors/app-error.js'; +import { logger } from '@app/core/log.js'; /** * Exit application. diff --git a/api/src/core/utils/misc/get-key-file.ts b/api/src/core/utils/misc/get-key-file.ts index e7e51af9c..55cd139c9 100644 --- a/api/src/core/utils/misc/get-key-file.ts +++ b/api/src/core/utils/misc/get-key-file.ts @@ -1,8 +1,8 @@ import { readFile } from 'fs/promises'; import { basename, join } from 'path'; -import type { RootState } from '@app/store'; -import { store } from '@app/store'; +import type { RootState } from '@app/store/index.js'; +import { store } from '@app/store/index.js'; // Get key file export const getKeyFile = async function (appStore: RootState = store.getState()) { diff --git a/api/src/core/utils/misc/get-machine-id.ts b/api/src/core/utils/misc/get-machine-id.ts index 3b83da7aa..e1bb1237f 100644 --- a/api/src/core/utils/misc/get-machine-id.ts +++ b/api/src/core/utils/misc/get-machine-id.ts @@ -1,7 +1,7 @@ import { readFile } from 'fs/promises'; -import { FileMissingError } from '@app/core/errors/file-missing-error'; -import { getters } from '@app/store'; +import { FileMissingError } from '@app/core/errors/file-missing-error.js'; +import { getters } from '@app/store/index.js'; let machineId: string | null = null; diff --git a/api/src/core/utils/misc/global-error-handler.ts b/api/src/core/utils/misc/global-error-handler.ts index f773fffc3..b72a7fbf0 100644 --- a/api/src/core/utils/misc/global-error-handler.ts +++ b/api/src/core/utils/misc/global-error-handler.ts @@ -1,4 +1,4 @@ -import { exitApp } from '@app/core/utils/misc/exit-app'; +import { exitApp } from '@app/core/utils/misc/exit-app.js'; /** * Handles all global, bubbled and uncaught errors. diff --git a/api/src/core/utils/misc/load-state.ts b/api/src/core/utils/misc/load-state.ts index 37782dcad..23f98bd65 100644 --- a/api/src/core/utils/misc/load-state.ts +++ b/api/src/core/utils/misc/load-state.ts @@ -1,7 +1,7 @@ import camelCaseKeys from 'camelcase-keys'; -import { logger } from '@app/core/log'; -import { parseConfig } from '@app/core/utils/misc/parse-config'; +import { logger } from '@app/core/log.js'; +import { parseConfig } from '@app/core/utils/misc/parse-config.js'; /** * Loads state from path. diff --git a/api/src/core/utils/misc/parse-config.ts b/api/src/core/utils/misc/parse-config.ts index a76e6b8fc..8ce1a7658 100644 --- a/api/src/core/utils/misc/parse-config.ts +++ b/api/src/core/utils/misc/parse-config.ts @@ -6,8 +6,8 @@ import { extname } from 'path'; import camelCaseKeys from 'camelcase-keys'; import { parse as parseIni } from 'ini'; -import { AppError } from '@app/core/errors/app-error'; -import { fileExistsSync } from '@app/core/utils/files/file-exists'; +import { AppError } from '@app/core/errors/app-error.js'; +import { fileExistsSync } from '@app/core/utils/files/file-exists.js'; type ConfigType = 'ini' | 'cfg'; diff --git a/api/src/core/utils/misc/send-form-to-keyserver.ts b/api/src/core/utils/misc/send-form-to-keyserver.ts index 317f46390..1983035c1 100644 --- a/api/src/core/utils/misc/send-form-to-keyserver.ts +++ b/api/src/core/utils/misc/send-form-to-keyserver.ts @@ -1,8 +1,8 @@ import type { CancelableRequest, Response } from 'got'; import { got } from 'got'; -import { AppError } from '@app/core/errors/app-error'; -import { logger } from '@app/core/log'; +import { AppError } from '@app/core/errors/app-error.js'; +import { logger } from '@app/core/log.js'; export const sendFormToKeyServer = async ( url: string, diff --git a/api/src/core/utils/permissions/check-permission.ts b/api/src/core/utils/permissions/check-permission.ts index e755524db..bf751a28a 100644 --- a/api/src/core/utils/permissions/check-permission.ts +++ b/api/src/core/utils/permissions/check-permission.ts @@ -1,4 +1,4 @@ -import { type User } from '@app/core/types/states/user'; +import { type User } from '@app/core/types/states/user.js'; /** * Check if the user has the correct permissions. diff --git a/api/src/core/utils/permissions/ensure-permission.ts b/api/src/core/utils/permissions/ensure-permission.ts index 6e934daa0..bb3b1f67b 100644 --- a/api/src/core/utils/permissions/ensure-permission.ts +++ b/api/src/core/utils/permissions/ensure-permission.ts @@ -1,6 +1,6 @@ -import { type User } from '@app/core/types/states/user'; +import { type User } from '@app/core/types/states/user.js'; -import '@app/core/utils/permissions/check-permission'; +import '@app/core/utils/permissions/check-permission.js'; /** * @deprecated Use casbin auth in nest instead diff --git a/api/src/core/utils/plugins/index.ts b/api/src/core/utils/plugins/index.ts new file mode 100644 index 000000000..f202d7201 --- /dev/null +++ b/api/src/core/utils/plugins/index.ts @@ -0,0 +1,3 @@ +// Created from 'create-ts-index' + +export * from './php-loader.js'; diff --git a/api/src/core/utils/plugins/php-loader.ts b/api/src/core/utils/plugins/php-loader.ts index 0a85ffcb1..7b3800334 100644 --- a/api/src/core/utils/plugins/php-loader.ts +++ b/api/src/core/utils/plugins/php-loader.ts @@ -2,9 +2,9 @@ import path from 'path'; import { execa } from 'execa'; -import { FileMissingError } from '@app/core/errors/file-missing-error'; -import { PhpError } from '@app/core/errors/php-error'; -import { type LooseObject, type LooseStringObject } from '@app/core/types'; +import { FileMissingError } from '@app/core/errors/file-missing-error.js'; +import { PhpError } from '@app/core/errors/php-error.js'; +import { type LooseObject, type LooseStringObject } from '@app/core/types/index.js'; /** * Encode GET/POST params. diff --git a/api/src/core/utils/server-identifier.ts b/api/src/core/utils/server-identifier.ts index 8bdd59f07..a81cb94ab 100644 --- a/api/src/core/utils/server-identifier.ts +++ b/api/src/core/utils/server-identifier.ts @@ -1,7 +1,7 @@ import crypto from 'crypto'; import { hostname } from 'os'; -import { getters } from '@app/store/index'; +import { getters } from '@app/store/index.js'; export const getServerIdentifier = (): string => { const flashGuid = getters.emhttp()?.var?.flashGuid ?? 'FLASH_GUID_NOT_FOUND'; diff --git a/api/src/core/utils/shares/get-shares.ts b/api/src/core/utils/shares/get-shares.ts index c7af9e928..fa5efa99d 100644 --- a/api/src/core/utils/shares/get-shares.ts +++ b/api/src/core/utils/shares/get-shares.ts @@ -1,7 +1,7 @@ -import { AppError } from '@app/core/errors/app-error'; -import { type DiskShare, type UserShare } from '@app/core/types/states/share'; -import { processShare } from '@app/core/utils/shares/process-share'; -import { getters } from '@app/store'; +import { AppError } from '@app/core/errors/app-error.js'; +import { type DiskShare, type UserShare } from '@app/core/types/states/share.js'; +import { processShare } from '@app/core/utils/shares/process-share.js'; +import { getters } from '@app/store/index.js'; interface Filter { name: string; diff --git a/api/src/core/utils/shares/index.ts b/api/src/core/utils/shares/index.ts new file mode 100644 index 000000000..cf6591edb --- /dev/null +++ b/api/src/core/utils/shares/index.ts @@ -0,0 +1,4 @@ +// Created from 'create-ts-index' + +export * from './get-shares.js'; +export * from './process-share.js'; diff --git a/api/src/core/utils/shares/process-share.ts b/api/src/core/utils/shares/process-share.ts index d38e9b2cf..f3596d1f8 100644 --- a/api/src/core/utils/shares/process-share.ts +++ b/api/src/core/utils/shares/process-share.ts @@ -1,6 +1,6 @@ -import type { DiskShare, Share, UserShare } from '@app/core/types/states/share'; -import type { ArrayDisk } from '@app/graphql/generated/api/types'; -import { getters } from '@app/store'; +import type { DiskShare, Share, UserShare } from '@app/core/types/states/share.js'; +import type { ArrayDisk } from '@app/graphql/generated/api/types.js'; +import { getters } from '@app/store/index.js'; const processors = { user(share: Share) { diff --git a/api/src/core/utils/validation/context/ensure-data.ts b/api/src/core/utils/validation/context/ensure-data.ts index 2f9587015..19a986c14 100644 --- a/api/src/core/utils/validation/context/ensure-data.ts +++ b/api/src/core/utils/validation/context/ensure-data.ts @@ -1,5 +1,5 @@ -import { FieldMissingError } from '@app/core/errors/field-missing-error'; -import { type CoreContext } from '@app/core/types'; +import { FieldMissingError } from '@app/core/errors/field-missing-error.js'; +import { type CoreContext } from '@app/core/types/index.js'; export const ensureData = (context: CoreContext, field: string) => { const hasData = context.data && Object.keys(context.data).includes(field); diff --git a/api/src/core/utils/validation/context/ensure-parameter.ts b/api/src/core/utils/validation/context/ensure-parameter.ts index 69e03c8e3..83b8a5ed3 100644 --- a/api/src/core/utils/validation/context/ensure-parameter.ts +++ b/api/src/core/utils/validation/context/ensure-parameter.ts @@ -1,5 +1,5 @@ -import { FieldMissingError } from '@app/core/errors/field-missing-error'; -import { type CoreContext } from '@app/core/types'; +import { FieldMissingError } from '@app/core/errors/field-missing-error.js'; +import { type CoreContext } from '@app/core/types/index.js'; export const ensureParameter = (context: CoreContext, field: string) => { const hasParameter = context.params && Object.keys(context.params).includes(field); diff --git a/api/src/core/utils/validation/context/ensure-query.ts b/api/src/core/utils/validation/context/ensure-query.ts index dd116f009..0ac088dd8 100644 --- a/api/src/core/utils/validation/context/ensure-query.ts +++ b/api/src/core/utils/validation/context/ensure-query.ts @@ -1,5 +1,5 @@ -import { FieldMissingError } from '@app/core/errors/field-missing-error'; -import { type CoreContext } from '@app/core/types'; +import { FieldMissingError } from '@app/core/errors/field-missing-error.js'; +import { type CoreContext } from '@app/core/types/index.js'; export const ensureQuery = (context: CoreContext, field: string) => { const hasQuery = context.query && Object.keys(context.query).includes(field); diff --git a/api/src/core/utils/validation/context/index.ts b/api/src/core/utils/validation/context/index.ts new file mode 100644 index 000000000..a81d659a8 --- /dev/null +++ b/api/src/core/utils/validation/context/index.ts @@ -0,0 +1,5 @@ +// Created from 'create-ts-index' + +export * from './ensure-data.js'; +export * from './ensure-parameter.js'; +export * from './ensure-query.js'; diff --git a/api/src/core/utils/validation/has-fields.ts b/api/src/core/utils/validation/has-fields.ts index 368455f08..e81e6748a 100644 --- a/api/src/core/utils/validation/has-fields.ts +++ b/api/src/core/utils/validation/has-fields.ts @@ -1,4 +1,4 @@ -import { type LooseObject } from '@app/core/types'; +import { type LooseObject } from '@app/core/types/index.js'; /** * Check if object has fields. diff --git a/api/src/core/utils/validation/index.ts b/api/src/core/utils/validation/index.ts new file mode 100644 index 000000000..93589a2e5 --- /dev/null +++ b/api/src/core/utils/validation/index.ts @@ -0,0 +1,5 @@ +// Created from 'create-ts-index' + +export * from './context/index.js'; +export * from './has-fields.js'; +export * from './is-node-error.js'; diff --git a/api/src/core/utils/vms/domain/index.ts b/api/src/core/utils/vms/domain/index.ts new file mode 100644 index 000000000..47709c838 --- /dev/null +++ b/api/src/core/utils/vms/domain/index.ts @@ -0,0 +1,5 @@ +// Created from 'create-ts-index' + +export * from './sanitize-product.js'; +export * from './sanitize-vendor.js'; +export * from './vm-regexps.js'; diff --git a/api/src/core/utils/vms/get-hypervisor.ts b/api/src/core/utils/vms/get-hypervisor.ts index 713aa86b7..d6620263f 100644 --- a/api/src/core/utils/vms/get-hypervisor.ts +++ b/api/src/core/utils/vms/get-hypervisor.ts @@ -3,7 +3,7 @@ import { access } from 'fs/promises'; import { type Hypervisor as HypervisorType } from '@unraid/libvirt'; -import { libvirtLogger } from '@app/core/log'; +import { libvirtLogger } from '@app/core/log.js'; const uri = process.env.LIBVIRT_URI ?? 'qemu:///system'; diff --git a/api/src/core/utils/vms/get-pci-devices.ts b/api/src/core/utils/vms/get-pci-devices.ts index 397dea075..6a87d1cc5 100644 --- a/api/src/core/utils/vms/get-pci-devices.ts +++ b/api/src/core/utils/vms/get-pci-devices.ts @@ -1,7 +1,7 @@ import { execa } from 'execa'; -import { type PciDevice } from '@app/core/types'; -import { cleanStdout } from '@app/core/utils/misc/clean-stdout'; +import { type PciDevice } from '@app/core/types/index.js'; +import { cleanStdout } from '@app/core/utils/misc/clean-stdout.js'; const regex = new RegExp( /^(?\S+) "(?[^"]+) \[(?[a-f\d]{4})]" "(?[^"]+) \[(?[a-f\d]{4})]" "(?[^"]+) \[(?[a-f\d]{4})]"/ diff --git a/api/src/core/utils/vms/index.ts b/api/src/core/utils/vms/index.ts new file mode 100644 index 000000000..b042d2841 --- /dev/null +++ b/api/src/core/utils/vms/index.ts @@ -0,0 +1,8 @@ +// Created from 'create-ts-index' + +export * from './filter-devices.js'; +export * from './get-hypervisor.js'; +export * from './get-pci-devices.js'; +export * from './parse-domain.js'; +export * from './parse-domains.js'; +export * from './system-network-interfaces.js'; diff --git a/api/src/core/utils/vms/parse-domain.ts b/api/src/core/utils/vms/parse-domain.ts index 858a74af0..23364b55e 100644 --- a/api/src/core/utils/vms/parse-domain.ts +++ b/api/src/core/utils/vms/parse-domain.ts @@ -1,4 +1,4 @@ -import { type Domain } from '@app/core/types'; +import { type Domain } from '@app/core/types/index.js'; export type DomainLookupType = 'id' | 'uuid' | 'name'; @@ -20,7 +20,7 @@ export const parseDomain = async (type: DomainLookupType, id: string): Promise { logger.debug(`Writing ${convert(fileContents.length, 'bytes').to('kilobytes')} to ${filePath}`); diff --git a/api/src/environment.ts b/api/src/environment.ts index e71bed908..9b4b8a9b9 100644 --- a/api/src/environment.ts +++ b/api/src/environment.ts @@ -1,10 +1,24 @@ +import { readFileSync } from 'node:fs'; import { homedir } from 'node:os'; -import { join } from 'node:path'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; -import { version } from 'package.json'; +const getPackageJsonVersion = () => { + try { + // Use import.meta.resolve to get the URL of package.json + const packageJsonUrl = import.meta.resolve('../package.json'); + const packageJsonPath = fileURLToPath(packageJsonUrl); + const packageJson = readFileSync(packageJsonPath, 'utf-8'); + const packageJsonObject = JSON.parse(packageJson); + return packageJsonObject.version; + } catch (error) { + console.error('Failed to load package.json:', error); + return undefined; + } +}; export const API_VERSION = - process.env.npm_package_version ?? version ?? new Error('API_VERSION not set'); + process.env.npm_package_version ?? getPackageJsonVersion() ?? new Error('API_VERSION not set'); export const NODE_ENV = (process.env.NODE_ENV as 'development' | 'test' | 'staging' | 'production') ?? 'production'; diff --git a/api/src/graphql/client/api/get-api-client.ts b/api/src/graphql/client/api/get-api-client.ts index be92192a2..6158d4803 100644 --- a/api/src/graphql/client/api/get-api-client.ts +++ b/api/src/graphql/client/api/get-api-client.ts @@ -6,9 +6,9 @@ import { fetch } from 'cross-fetch'; import { createClient } from 'graphql-ws'; import WebSocket from 'ws'; -import { getInternalApiAddress } from '@app/consts'; -import { graphqlLogger } from '@app/core/log'; -import { getters } from '@app/store/index'; +import { getInternalApiAddress } from '@app/consts.js'; +import { graphqlLogger } from '@app/core/log.js'; +import { getters } from '@app/store/index.js'; const getWebsocketWithHeaders = () => { return class WebsocketWithOriginHeader extends WebSocket { diff --git a/api/src/graphql/generated/api/operations.ts b/api/src/graphql/generated/api/operations.ts index 751621237..bb5d20ffc 100755 --- a/api/src/graphql/generated/api/operations.ts +++ b/api/src/graphql/generated/api/operations.ts @@ -1,8 +1,8 @@ /* eslint-disable */ -import * as Types from '@app/graphql/generated/api/types'; +import * as Types from '@app/graphql/generated/api/types.js'; import { z } from 'zod' -import { AccessUrl, AccessUrlInput, AddPermissionInput, AddRoleForApiKeyInput, AddRoleForUserInput, AllowedOriginInput, ApiKey, ApiKeyResponse, ApiKeyWithSecret, ArrayType, ArrayCapacity, ArrayDisk, ArrayDiskFsColor, ArrayDiskStatus, ArrayDiskType, ArrayPendingState, ArrayState, Baseboard, Capacity, Case, Cloud, CloudResponse, Config, ConfigErrorState, Connect, ConnectSignInInput, ConnectUserInfoInput, ContainerHostConfig, ContainerMount, ContainerPort, ContainerPortType, ContainerState, CreateApiKeyInput, Devices, Disk, DiskFsType, DiskInterfaceType, DiskPartition, DiskSmartStatus, Display, Docker, DockerContainer, DockerNetwork, DynamicRemoteAccessStatus, DynamicRemoteAccessType, EnableDynamicRemoteAccessInput, Flash, Gpu, Importance, Info, InfoApps, InfoCpu, InfoMemory, KeyFile, Me, MemoryFormFactor, MemoryLayout, MemoryType, MinigraphStatus, MinigraphqlResponse, Mount, Network, Node, Notification, NotificationCounts, NotificationData, NotificationFilter, NotificationOverview, NotificationType, Notifications, NotificationslistArgs, Os, Owner, ParityCheck, Partition, Pci, Permission, ProfileModel, Registration, RegistrationState, RelayResponse, RemoteAccess, RemoveRoleFromApiKeyInput, Resource, Role, Server, ServerStatus, Service, SetupRemoteAccessInput, Share, System, Temperature, Theme, URL_TYPE, UnassignedDevice, Uptime, Usb, User, UserAccount, Vars, Versions, VmDomain, VmState, Vms, WAN_ACCESS_TYPE, WAN_FORWARD_TYPE, Welcome, addUserInput, arrayDiskInput, deleteUserInput, mdState, registrationType, usersInput } from '@app/graphql/generated/api/types' +import { AccessUrl, AccessUrlInput, AddPermissionInput, AddRoleForApiKeyInput, AddRoleForUserInput, AllowedOriginInput, ApiKey, ApiKeyResponse, ApiKeyWithSecret, ArrayType, ArrayCapacity, ArrayDisk, ArrayDiskFsColor, ArrayDiskStatus, ArrayDiskType, ArrayPendingState, ArrayState, Baseboard, Capacity, Case, Cloud, CloudResponse, Config, ConfigErrorState, Connect, ConnectSignInInput, ConnectUserInfoInput, ContainerHostConfig, ContainerMount, ContainerPort, ContainerPortType, ContainerState, CreateApiKeyInput, Devices, Disk, DiskFsType, DiskInterfaceType, DiskPartition, DiskSmartStatus, Display, Docker, DockerContainer, DockerNetwork, DynamicRemoteAccessStatus, DynamicRemoteAccessType, EnableDynamicRemoteAccessInput, Flash, Gpu, Importance, Info, InfoApps, InfoCpu, InfoMemory, KeyFile, Me, MemoryFormFactor, MemoryLayout, MemoryType, MinigraphStatus, MinigraphqlResponse, Mount, Network, Node, Notification, NotificationCounts, NotificationData, NotificationFilter, NotificationOverview, NotificationType, Notifications, NotificationslistArgs, Os, Owner, ParityCheck, Partition, Pci, Permission, ProfileModel, Registration, RegistrationState, RelayResponse, RemoteAccess, RemoveRoleFromApiKeyInput, Resource, Role, Server, ServerStatus, Service, SetupRemoteAccessInput, Share, System, Temperature, Theme, URL_TYPE, UnassignedDevice, Uptime, Usb, User, UserAccount, Vars, Versions, VmDomain, VmState, Vms, WAN_ACCESS_TYPE, WAN_FORWARD_TYPE, Welcome, addUserInput, arrayDiskInput, deleteUserInput, mdState, registrationType, usersInput } from '@app/graphql/generated/api/types.js' import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; type Properties = Required<{ @@ -76,8 +76,8 @@ export const registrationTypeSchema = z.nativeEnum(registrationType); export function AccessUrlSchema(): z.ZodObject> { return z.object({ __typename: z.literal('AccessUrl').optional(), - ipv4: definedNonNullAnySchema.nullish(), - ipv6: definedNonNullAnySchema.nullish(), + ipv4: z.instanceof(URL).nullish(), + ipv6: z.instanceof(URL).nullish(), name: z.string().nullish(), type: URL_TYPESchema }) @@ -85,8 +85,8 @@ export function AccessUrlSchema(): z.ZodObject> { export function AccessUrlInputSchema(): z.ZodObject> { return z.object({ - ipv4: definedNonNullAnySchema.nullish(), - ipv6: definedNonNullAnySchema.nullish(), + ipv4: z.instanceof(URL).nullish(), + ipv6: z.instanceof(URL).nullish(), name: z.string().nullish(), type: URL_TYPESchema }) @@ -346,6 +346,7 @@ export function DiskSchema(): z.ZodObject> { bytesPerSector: z.number(), device: z.string(), firmwareRevision: z.string(), + id: z.string(), interfaceType: DiskInterfaceTypeSchema, name: z.string(), partitions: z.array(DiskPartitionSchema()).nullish(), @@ -419,10 +420,10 @@ export function DockerContainerSchema(): z.ZodObject id: z.string(), image: z.string(), imageId: z.string(), - labels: definedNonNullAnySchema.nullish(), - mounts: z.array(definedNonNullAnySchema.nullable()).nullish(), + labels: z.record(z.string(), z.any()).nullish(), + mounts: z.array(z.record(z.string(), z.any()).nullable()).nullish(), names: z.array(z.string()).nullish(), - networkSettings: definedNonNullAnySchema.nullish(), + networkSettings: z.record(z.string(), z.any()).nullish(), ports: z.array(ContainerPortSchema()), sizeRootFs: z.number().nullish(), state: ContainerStateSchema, @@ -434,19 +435,19 @@ export function DockerNetworkSchema(): z.ZodObject> { return z.object({ __typename: z.literal('DockerNetwork').optional(), attachable: z.boolean(), - configFrom: definedNonNullAnySchema.nullish(), + configFrom: z.record(z.string(), z.any()).nullish(), configOnly: z.boolean(), - containers: definedNonNullAnySchema.nullish(), + containers: z.record(z.string(), z.any()).nullish(), created: z.string().nullish(), driver: z.string().nullish(), enableIPv6: z.boolean(), id: z.string().nullish(), ingress: z.boolean(), internal: z.boolean(), - ipam: definedNonNullAnySchema.nullish(), - labels: definedNonNullAnySchema.nullish(), + ipam: z.record(z.string(), z.any()).nullish(), + labels: z.record(z.string(), z.any()).nullish(), name: z.string().nullish(), - options: definedNonNullAnySchema.nullish(), + options: z.record(z.string(), z.any()).nullish(), scope: z.string().nullish() }) } @@ -519,7 +520,7 @@ export function InfoCpuSchema(): z.ZodObject> { return z.object({ __typename: z.literal('InfoCpu').optional(), brand: z.string(), - cache: definedNonNullAnySchema, + cache: z.record(z.string(), z.any()), cores: z.number(), family: z.string(), flags: z.array(z.string()).nullish(), diff --git a/api/src/graphql/generated/api/types.ts b/api/src/graphql/generated/api/types.ts index faaf57df1..698942881 100644 --- a/api/src/graphql/generated/api/types.ts +++ b/api/src/graphql/generated/api/types.ts @@ -1,6 +1,7 @@ /* eslint-disable */ +/* @ts-nocheck */ import { GraphQLResolveInfo, GraphQLScalarType, GraphQLScalarTypeConfig } from 'graphql'; -import { Context } from '@app/graphql/schema/utils'; +import { Context } from '@app/graphql/schema/utils.js'; export type Maybe = T | null; export type InputMaybe = Maybe; export type Exact = { [K in keyof T]: T[K] }; @@ -17,7 +18,7 @@ export type Scalars = { Int: { input: number; output: number; } Float: { input: number; output: number; } DateTime: { input: string; output: string; } - JSON: { input: { [key: string]: any }; output: { [key: string]: any }; } + JSON: { input: Record; output: Record; } Long: { input: number; output: number; } Port: { input: number; output: number; } URL: { input: URL; output: URL; } @@ -367,6 +368,7 @@ export type Disk = { bytesPerSector: Scalars['Long']['output']; device: Scalars['String']['output']; firmwareRevision: Scalars['String']['output']; + id: Scalars['ID']['output']; interfaceType: DiskInterfaceType; name: Scalars['String']['output']; partitions?: Maybe>; @@ -2220,6 +2222,7 @@ export type DiskResolvers; device?: Resolver; firmwareRevision?: Resolver; + id?: Resolver; interfaceType?: Resolver; name?: Resolver; partitions?: Resolver>, ParentType, ContextType>; diff --git a/api/src/graphql/generated/client/graphql.ts b/api/src/graphql/generated/client/graphql.ts index 81b99a682..c7adc0682 100644 --- a/api/src/graphql/generated/client/graphql.ts +++ b/api/src/graphql/generated/client/graphql.ts @@ -21,7 +21,7 @@ export type Scalars = { /** A field whose value is a IPv6 address: https://en.wikipedia.org/wiki/IPv6. */ IPv6: { input: any; output: any; } /** The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). */ - JSON: { input: { [key: string]: any }; output: { [key: string]: any }; } + JSON: { input: Record; output: Record; } /** The `Long` scalar type represents 52-bit integers */ Long: { input: number; output: number; } /** A field whose value is a valid TCP port within the range of 0 to 65535: https://en.wikipedia.org/wiki/Transmission_Control_Protocol#TCP_ports */ diff --git a/api/src/graphql/generated/client/validators.ts b/api/src/graphql/generated/client/validators.ts index 4bb0c65ba..3be98611a 100644 --- a/api/src/graphql/generated/client/validators.ts +++ b/api/src/graphql/generated/client/validators.ts @@ -1,6 +1,6 @@ /* eslint-disable */ import { z } from 'zod' -import { AccessUrlInput, ArrayCapacityBytesInput, ArrayCapacityInput, ClientType, ConfigErrorState, DashboardAppsInput, DashboardArrayInput, DashboardCaseInput, DashboardConfigInput, DashboardDisplayInput, DashboardInput, DashboardOsInput, DashboardServiceInput, DashboardServiceUptimeInput, DashboardTwoFactorInput, DashboardTwoFactorLocalInput, DashboardTwoFactorRemoteInput, DashboardVarsInput, DashboardVersionsInput, DashboardVmsInput, EventType, Importance, NetworkInput, NotificationInput, NotificationStatus, PingEventSource, RegistrationState, RemoteAccessEventActionType, RemoteAccessInput, RemoteGraphQLClientInput, RemoteGraphQLEventType, RemoteGraphQLServerInput, ServerStatus, URL_TYPE, UpdateType } from '@app/graphql/generated/client/graphql' +import { AccessUrlInput, ArrayCapacityBytesInput, ArrayCapacityInput, ClientType, ConfigErrorState, DashboardAppsInput, DashboardArrayInput, DashboardCaseInput, DashboardConfigInput, DashboardDisplayInput, DashboardInput, DashboardOsInput, DashboardServiceInput, DashboardServiceUptimeInput, DashboardTwoFactorInput, DashboardTwoFactorLocalInput, DashboardTwoFactorRemoteInput, DashboardVarsInput, DashboardVersionsInput, DashboardVmsInput, EventType, Importance, NetworkInput, NotificationInput, NotificationStatus, PingEventSource, RegistrationState, RemoteAccessEventActionType, RemoteAccessInput, RemoteGraphQLClientInput, RemoteGraphQLEventType, RemoteGraphQLServerInput, ServerStatus, URL_TYPE, UpdateType } from '@app/graphql/generated/client/graphql.js' type Properties = Required<{ [K in keyof T]: z.ZodType; @@ -38,8 +38,8 @@ export const UpdateTypeSchema = z.nativeEnum(UpdateType); export function AccessUrlInputSchema(): z.ZodObject> { return z.object({ - ipv4: definedNonNullAnySchema.nullish(), - ipv6: definedNonNullAnySchema.nullish(), + ipv4: z.instanceof(URL).nullish(), + ipv6: z.instanceof(URL).nullish(), name: z.string().nullish(), type: URL_TYPESchema }) diff --git a/api/src/graphql/index.ts b/api/src/graphql/index.ts index c0b2ac181..9c2c4d75e 100644 --- a/api/src/graphql/index.ts +++ b/api/src/graphql/index.ts @@ -1,5 +1,5 @@ -import { modules } from '@app/core'; -import { FatalAppError } from '@app/core/errors/fatal-error'; +import { FatalAppError } from '@app/core/errors/fatal-error.js'; +import { modules } from '@app/core/index.js'; export const getCoreModule = (moduleName: string) => { if (!Object.keys(modules).includes(moduleName)) { diff --git a/api/src/graphql/mothership/mutations.ts b/api/src/graphql/mothership/mutations.ts index 0a31f0a4f..91a23ab63 100644 --- a/api/src/graphql/mothership/mutations.ts +++ b/api/src/graphql/mothership/mutations.ts @@ -1,4 +1,4 @@ -import { graphql } from '@app/graphql/generated/client/gql'; +import { graphql } from '@app/graphql/generated/client/gql.js'; export const SEND_REMOTE_QUERY_RESPONSE = graphql(/* GraphQL */ ` mutation sendRemoteGraphQLResponse($input: RemoteGraphQLServerInput!) { diff --git a/api/src/graphql/mothership/subscriptions.ts b/api/src/graphql/mothership/subscriptions.ts index 30835295a..bec490bd6 100644 --- a/api/src/graphql/mothership/subscriptions.ts +++ b/api/src/graphql/mothership/subscriptions.ts @@ -1,4 +1,4 @@ -import { graphql } from '@app/graphql/generated/client/gql'; +import { graphql } from '@app/graphql/generated/client/gql.js'; export const RemoteGraphQL_Fragment = graphql(/* GraphQL */ ` fragment RemoteGraphQLEventFragment on RemoteGraphQLEvent { diff --git a/api/src/graphql/resolvers/mutation/connect/connect-sign-in.ts b/api/src/graphql/resolvers/mutation/connect/connect-sign-in.ts index 9e7155cbe..2c06d76f8 100644 --- a/api/src/graphql/resolvers/mutation/connect/connect-sign-in.ts +++ b/api/src/graphql/resolvers/mutation/connect/connect-sign-in.ts @@ -1,10 +1,10 @@ import { decodeJwt } from 'jose'; -import type { ConnectSignInInput } from '@app/graphql/generated/api/types'; -import { getters, store } from '@app/store/index'; -import { loginUser } from '@app/store/modules/config'; -import { FileLoadStatus } from '@app/store/types'; -import { ApiKeyService } from '@app/unraid-api/auth/api-key.service'; +import type { ConnectSignInInput } from '@app/graphql/generated/api/types.js'; +import { getters, store } from '@app/store/index.js'; +import { loginUser } from '@app/store/modules/config.js'; +import { FileLoadStatus } from '@app/store/types.js'; +import { ApiKeyService } from '@app/unraid-api/auth/api-key.service.js'; export const connectSignIn = async (input: ConnectSignInInput): Promise => { if (getters.emhttp().status === FileLoadStatus.LOADED) { diff --git a/api/src/graphql/resolvers/query/cloud/check-api.ts b/api/src/graphql/resolvers/query/cloud/check-api.ts index f5dedd150..05633a42b 100644 --- a/api/src/graphql/resolvers/query/cloud/check-api.ts +++ b/api/src/graphql/resolvers/query/cloud/check-api.ts @@ -1,5 +1,5 @@ -import { logger } from '@app/core/log'; -import { type ApiKeyResponse } from '@app/graphql/generated/api/types'; +import { logger } from '@app/core/log.js'; +import { type ApiKeyResponse } from '@app/graphql/generated/api/types.js'; export const checkApi = async (): Promise => { logger.trace('Cloud endpoint: Checking API'); diff --git a/api/src/graphql/resolvers/query/cloud/check-cloud.ts b/api/src/graphql/resolvers/query/cloud/check-cloud.ts index 2776a1782..9c6aa4b3d 100644 --- a/api/src/graphql/resolvers/query/cloud/check-cloud.ts +++ b/api/src/graphql/resolvers/query/cloud/check-cloud.ts @@ -1,15 +1,15 @@ import { got } from 'got'; -import type { CloudResponse } from '@app/graphql/generated/api/types'; -import { FIVE_DAYS_SECS, ONE_DAY_SECS } from '@app/consts'; -import { logger } from '@app/core/log'; -import { API_VERSION, MOTHERSHIP_GRAPHQL_LINK } from '@app/environment'; -import { MinigraphStatus } from '@app/graphql/generated/api/types'; -import { checkDNS } from '@app/graphql/resolvers/query/cloud/check-dns'; -import { checkMothershipAuthentication } from '@app/graphql/resolvers/query/cloud/check-mothership-authentication'; -import { getters, store } from '@app/store'; -import { getCloudCache, getDnsCache } from '@app/store/getters'; -import { setCloudCheck, setDNSCheck } from '@app/store/modules/cache'; +import type { CloudResponse } from '@app/graphql/generated/api/types.js'; +import { FIVE_DAYS_SECS, ONE_DAY_SECS } from '@app/consts.js'; +import { logger } from '@app/core/log.js'; +import { API_VERSION, MOTHERSHIP_GRAPHQL_LINK } from '@app/environment.js'; +import { MinigraphStatus } from '@app/graphql/generated/api/types.js'; +import { checkDNS } from '@app/graphql/resolvers/query/cloud/check-dns.js'; +import { checkMothershipAuthentication } from '@app/graphql/resolvers/query/cloud/check-mothership-authentication.js'; +import { getCloudCache, getDnsCache } from '@app/store/getters/index.js'; +import { getters, store } from '@app/store/index.js'; +import { setCloudCheck, setDNSCheck } from '@app/store/modules/cache.js'; const mothershipBaseUrl = new URL(MOTHERSHIP_GRAPHQL_LINK).origin; diff --git a/api/src/graphql/resolvers/query/cloud/check-dns.ts b/api/src/graphql/resolvers/query/cloud/check-dns.ts index 6a3f15123..e348bb436 100644 --- a/api/src/graphql/resolvers/query/cloud/check-dns.ts +++ b/api/src/graphql/resolvers/query/cloud/check-dns.ts @@ -3,10 +3,10 @@ import { promisify } from 'util'; import ip from 'ip'; -import { MOTHERSHIP_GRAPHQL_LINK } from '@app/environment'; -import { store } from '@app/store'; -import { getDnsCache } from '@app/store/getters'; -import { setDNSCheck } from '@app/store/modules/cache'; +import { MOTHERSHIP_GRAPHQL_LINK } from '@app/environment.js'; +import { getDnsCache } from '@app/store/getters/index.js'; +import { store } from '@app/store/index.js'; +import { setDNSCheck } from '@app/store/modules/cache.js'; const msHostname = new URL(MOTHERSHIP_GRAPHQL_LINK).host; @@ -41,7 +41,9 @@ export const checkDNS = async (hostname = msHostname): Promise<{ cloudIp: string // The user's server and the DNS server they're using are returning different results if (!local.includes(network)) throw new Error( - `Local and network resolvers showing different IP for "${hostname}". [local="${local ?? 'NOT FOUND'}"] [network="${network ?? 'NOT FOUND'}"]` + `Local and network resolvers showing different IP for "${hostname}". [local="${ + local ?? 'NOT FOUND' + }"] [network="${network ?? 'NOT FOUND'}"]` ); // The user likely has a PI-hole or something similar running. diff --git a/api/src/graphql/resolvers/query/cloud/check-minigraphql.ts b/api/src/graphql/resolvers/query/cloud/check-minigraphql.ts index 6b1ff6e26..890514249 100644 --- a/api/src/graphql/resolvers/query/cloud/check-minigraphql.ts +++ b/api/src/graphql/resolvers/query/cloud/check-minigraphql.ts @@ -1,6 +1,6 @@ -import { logger } from '@app/core/log'; -import { type MinigraphqlResponse } from '@app/graphql/generated/api/types'; -import { getters } from '@app/store'; +import { logger } from '@app/core/log.js'; +import { type MinigraphqlResponse } from '@app/graphql/generated/api/types.js'; +import { getters } from '@app/store/index.js'; export const checkMinigraphql = (): MinigraphqlResponse => { logger.trace('Cloud endpoint: Checking mini-graphql'); diff --git a/api/src/graphql/resolvers/query/cloud/check-mothership-authentication.ts b/api/src/graphql/resolvers/query/cloud/check-mothership-authentication.ts index 1679daf8b..82d1655b2 100644 --- a/api/src/graphql/resolvers/query/cloud/check-mothership-authentication.ts +++ b/api/src/graphql/resolvers/query/cloud/check-mothership-authentication.ts @@ -1,7 +1,7 @@ import { got, HTTPError, TimeoutError } from 'got'; -import { logger } from '@app/core'; -import { MOTHERSHIP_GRAPHQL_LINK } from '@app/environment'; +import { logger } from '@app/core/log.js'; +import { MOTHERSHIP_GRAPHQL_LINK } from '@app/environment.js'; const createGotOptions = (apiVersion: string, apiKey: string) => ({ timeout: { @@ -15,6 +15,8 @@ const createGotOptions = (apiVersion: string, apiKey: string) => ({ }, }); +const isHttpError = (error: unknown): error is HTTPError => error instanceof HTTPError; + // Check if we're rate limited, etc. export const checkMothershipAuthentication = async (apiVersion: string, apiKey: string) => { const msURL = new URL(MOTHERSHIP_GRAPHQL_LINK); @@ -27,7 +29,7 @@ export const checkMothershipAuthentication = async (apiVersion: string, apiKey: await got.head(url, options); } catch (error: unknown) { // HTTP errors - if (error instanceof HTTPError) { + if (isHttpError(error)) { switch (error.response.statusCode) { case 429: { const retryAfter = error.response.headers['retry-after']; diff --git a/api/src/graphql/resolvers/query/info.ts b/api/src/graphql/resolvers/query/info.ts index 651b07a72..412077463 100644 --- a/api/src/graphql/resolvers/query/info.ts +++ b/api/src/graphql/resolvers/query/info.ts @@ -5,20 +5,20 @@ import { execa, execaCommandSync } from 'execa'; import { isSymlink } from 'path-type'; import { cpu, cpuFlags, mem, memLayout, osInfo, versions } from 'systeminformation'; -import type { PciDevice } from '@app/core/types'; -import { bootTimestamp } from '@app/common/dashboard/boot-timestamp'; -import { getUnraidVersion } from '@app/common/dashboard/get-unraid-version'; -import { AppError } from '@app/core/errors/app-error'; -import { type DynamixConfig } from '@app/core/types/ini'; -import { toBoolean } from '@app/core/utils/casting'; -import { docker } from '@app/core/utils/clients/docker'; -import { cleanStdout } from '@app/core/utils/misc/clean-stdout'; -import { loadState } from '@app/core/utils/misc/load-state'; -import { sanitizeProduct } from '@app/core/utils/vms/domain/sanitize-product'; -import { sanitizeVendor } from '@app/core/utils/vms/domain/sanitize-vendor'; -import { vmRegExps } from '@app/core/utils/vms/domain/vm-regexps'; -import { filterDevices } from '@app/core/utils/vms/filter-devices'; -import { getPciDevices } from '@app/core/utils/vms/get-pci-devices'; +import type { PciDevice } from '@app/core/types/index.js'; +import { bootTimestamp } from '@app/common/dashboard/boot-timestamp.js'; +import { getUnraidVersion } from '@app/common/dashboard/get-unraid-version.js'; +import { AppError } from '@app/core/errors/app-error.js'; +import { type DynamixConfig } from '@app/core/types/ini.js'; +import { toBoolean } from '@app/core/utils/casting.js'; +import { docker } from '@app/core/utils/clients/docker.js'; +import { cleanStdout } from '@app/core/utils/misc/clean-stdout.js'; +import { loadState } from '@app/core/utils/misc/load-state.js'; +import { sanitizeProduct } from '@app/core/utils/vms/domain/sanitize-product.js'; +import { sanitizeVendor } from '@app/core/utils/vms/domain/sanitize-vendor.js'; +import { vmRegExps } from '@app/core/utils/vms/domain/vm-regexps.js'; +import { filterDevices } from '@app/core/utils/vms/filter-devices.js'; +import { getPciDevices } from '@app/core/utils/vms/get-pci-devices.js'; import { type Devices, type Display, @@ -31,8 +31,8 @@ import { type Temperature, type Theme, type Versions, -} from '@app/graphql/generated/api/types'; -import { getters } from '@app/store'; +} from '@app/graphql/generated/api/types.js'; +import { getters } from '@app/store/index.js'; export const generateApps = async (): Promise => { const installed = await docker @@ -75,14 +75,27 @@ export const generateCpu = async (): Promise => { }; export const generateDisplay = async (): Promise => { - const filePath = getters.paths()['dynamix-config']; - const state = loadState(filePath); - if (!state) { - return {}; + const filePaths = getters.paths()['dynamix-config']; + + const state = filePaths.reduce>( + (acc, filePath) => { + const state = loadState(filePath); + return state ? { ...acc, ...state } : acc; + }, + { + id: 'dynamix-config/display', + } + ); + + if (!state.display) { + return { + id: 'dynamix-config/display', + }; } const { theme, unit, ...display } = state.display; return { ...display, + id: 'dynamix-config/display', theme: theme as Theme, unit: unit as Temperature, scale: toBoolean(display.scale), @@ -138,12 +151,13 @@ export const generateMemory = async (): Promise => { const end = lines.indexOf(nextHeaders); const fields = lines.slice(start, end); - max = toBytes( - fields - ?.find((line) => line.trim().startsWith('Maximum Capacity')) - ?.trim() - ?.split(': ')[1] ?? '0' - ); + max = + toBytes( + fields + ?.find((line) => line.trim().startsWith('Maximum Capacity')) + ?.trim() + ?.split(': ')[1] ?? '0' + ) ?? 0; } } } catch { @@ -223,8 +237,7 @@ export const generateDevices = async (): Promise => { const processedDevices = await filterDevices(filteredDevices).then(async (devices) => Promise.all( devices - // @ts-expect-error - Device is not PciDevice - .map((device) => addDeviceClass(device)) + .map((device) => addDeviceClass(device as PciDevice)) .map(async (device) => { // Attempt to get the current kernel-bound driver for this pci device await isSymlink(`${basePath}${device.id}/driver`).then((symlink) => { diff --git a/api/src/graphql/resolvers/subscription/network.ts b/api/src/graphql/resolvers/subscription/network.ts index 2163985c8..bb8623d19 100644 --- a/api/src/graphql/resolvers/subscription/network.ts +++ b/api/src/graphql/resolvers/subscription/network.ts @@ -1,11 +1,11 @@ -import type { AccessUrlInput } from '@app/graphql/generated/client/graphql'; -import type { RootState } from '@app/store'; -import { logger } from '@app/core'; -import { type Nginx } from '@app/core/types/states/nginx'; -import { type AccessUrl } from '@app/graphql/generated/api/types'; -import { URL_TYPE } from '@app/graphql/generated/client/graphql'; -import { AccessUrlInputSchema } from '@app/graphql/generated/client/validators'; -import { store } from '@app/store'; +import type { AccessUrlInput } from '@app/graphql/generated/client/graphql.js'; +import type { RootState } from '@app/store/index.js'; +import { logger } from '@app/core/log.js'; +import { type Nginx } from '@app/core/types/states/nginx.js'; +import { type AccessUrl } from '@app/graphql/generated/api/types.js'; +import { URL_TYPE } from '@app/graphql/generated/client/graphql.js'; +import { AccessUrlInputSchema } from '@app/graphql/generated/client/validators.js'; +import { store } from '@app/store/index.js'; interface UrlForFieldInput { url: string; @@ -55,7 +55,10 @@ export const getUrlForField = ({ const fieldIsFqdn = (field: keyof Nginx) => field?.toLowerCase().includes('fqdn'); -export type NginxUrlFields = Extract; +export type NginxUrlFields = Extract< + keyof Nginx, + 'lanIp' | 'lanIp6' | 'lanName' | 'lanMdns' | 'lanFqdn' | 'wanFqdn' | 'wanFqdn6' +>; /** * diff --git a/api/src/graphql/resolvers/subscription/remote-graphql/remote-query.ts b/api/src/graphql/resolvers/subscription/remote-graphql/remote-query.ts index c89b37a2c..8e72f17de 100644 --- a/api/src/graphql/resolvers/subscription/remote-graphql/remote-query.ts +++ b/api/src/graphql/resolvers/subscription/remote-graphql/remote-query.ts @@ -1,11 +1,11 @@ -import type { RemoteGraphQLEventFragmentFragment } from '@app/graphql/generated/client/graphql'; -import { remoteQueryLogger } from '@app/core/log'; -import { getApiApolloClient } from '@app/graphql/client/api/get-api-client'; -import { RemoteGraphQLEventType } from '@app/graphql/generated/client/graphql'; -import { SEND_REMOTE_QUERY_RESPONSE } from '@app/graphql/mothership/mutations'; -import { parseGraphQLQuery } from '@app/graphql/resolvers/subscription/remote-graphql/remote-graphql-helpers'; -import { GraphQLClient } from '@app/mothership/graphql-client'; -import { getters } from '@app/store/index'; +import type { RemoteGraphQLEventFragmentFragment } from '@app/graphql/generated/client/graphql.js'; +import { remoteQueryLogger } from '@app/core/log.js'; +import { getApiApolloClient } from '@app/graphql/client/api/get-api-client.js'; +import { RemoteGraphQLEventType } from '@app/graphql/generated/client/graphql.js'; +import { SEND_REMOTE_QUERY_RESPONSE } from '@app/graphql/mothership/mutations.js'; +import { parseGraphQLQuery } from '@app/graphql/resolvers/subscription/remote-graphql/remote-graphql-helpers.js'; +import { GraphQLClient } from '@app/mothership/graphql-client.js'; +import { getters } from '@app/store/index.js'; export const executeRemoteGraphQLQuery = async ( data: RemoteGraphQLEventFragmentFragment['remoteGraphQLEventData'] diff --git a/api/src/graphql/resolvers/subscription/remote-graphql/remote-subscription.ts b/api/src/graphql/resolvers/subscription/remote-graphql/remote-subscription.ts index a30422142..9fd6a2c44 100644 --- a/api/src/graphql/resolvers/subscription/remote-graphql/remote-subscription.ts +++ b/api/src/graphql/resolvers/subscription/remote-graphql/remote-subscription.ts @@ -1,6 +1,6 @@ -import { type RemoteGraphQLEventFragmentFragment } from '@app/graphql/generated/client/graphql'; -import { addRemoteSubscription } from '@app/store/actions/add-remote-subscription'; -import { store } from '@app/store/index'; +import { type RemoteGraphQLEventFragmentFragment } from '@app/graphql/generated/client/graphql.js'; +import { addRemoteSubscription } from '@app/store/actions/add-remote-subscription.js'; +import { store } from '@app/store/index.js'; export const createRemoteSubscription = async ( data: RemoteGraphQLEventFragmentFragment['remoteGraphQLEventData'] diff --git a/api/src/graphql/schema.ts b/api/src/graphql/schema.ts deleted file mode 100644 index 972398e68..000000000 --- a/api/src/graphql/schema.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { makeExecutableSchema } from '@graphql-tools/schema'; - -import { resolvers } from '@app/graphql/resolvers/resolvers'; -import { typeDefs } from '@app/graphql/schema/index'; - -const baseSchema = makeExecutableSchema({ - typeDefs: typeDefs, - resolvers, -}); - -export const schema = baseSchema; diff --git a/api/src/graphql/schema/loadTypesDefs.ts b/api/src/graphql/schema/loadTypesDefs.ts index 040b6e6af..80b87d7cd 100644 --- a/api/src/graphql/schema/loadTypesDefs.ts +++ b/api/src/graphql/schema/loadTypesDefs.ts @@ -1,6 +1,6 @@ import { mergeTypeDefs } from '@graphql-tools/merge'; -import { logger } from '@app/core/log'; +import { logger } from '@app/core/log.js'; export const loadTypeDefs = async () => { // TypeScript now knows this returns Record Promise> diff --git a/api/src/graphql/schema/types/disks/disk.graphql b/api/src/graphql/schema/types/disks/disk.graphql index 0332b9535..b40857816 100644 --- a/api/src/graphql/schema/types/disks/disk.graphql +++ b/api/src/graphql/schema/types/disks/disk.graphql @@ -5,6 +5,7 @@ type Query { disks: [Disk]! } type Disk { + id: ID! # /dev/sdb device: String! # SSD diff --git a/api/src/graphql/schema/utils.ts b/api/src/graphql/schema/utils.ts index 340967eef..cc86c874a 100644 --- a/api/src/graphql/schema/utils.ts +++ b/api/src/graphql/schema/utils.ts @@ -1,12 +1,12 @@ -import type { Server } from '@app/graphql/generated/client/graphql'; -import { AppError } from '@app/core/errors/app-error'; -import { graphqlLogger } from '@app/core/log'; -import { pubsub } from '@app/core/pubsub'; -import { type User } from '@app/core/types/states/user'; -import { ensurePermission } from '@app/core/utils/permissions/ensure-permission'; -import { MinigraphStatus } from '@app/graphql/generated/api/types'; -import { ServerStatus } from '@app/graphql/generated/client/graphql'; -import { store } from '@app/store'; +import type { Server } from '@app/graphql/generated/client/graphql.js'; +import { AppError } from '@app/core/errors/app-error.js'; +import { graphqlLogger } from '@app/core/log.js'; +import { pubsub } from '@app/core/pubsub.js'; +import { type User } from '@app/core/types/states/user.js'; +import { ensurePermission } from '@app/core/utils/permissions/ensure-permission.js'; +import { MinigraphStatus } from '@app/graphql/generated/api/types.js'; +import { ServerStatus } from '@app/graphql/generated/client/graphql.js'; +import { store } from '@app/store/index.js'; export interface Context { user?: User; diff --git a/api/src/index.ts b/api/src/index.ts index 61f5677c0..7d937ebcf 100644 --- a/api/src/index.ts +++ b/api/src/index.ts @@ -1,6 +1,6 @@ import 'reflect-metadata'; import 'global-agent/bootstrap.js'; -import '@app/dotenv'; +import '@app/dotenv.js'; import { type NestFastifyApplication } from '@nestjs/platform-fastify'; import { unlinkSync } from 'fs'; @@ -12,23 +12,23 @@ import CacheableLookup from 'cacheable-lookup'; import { asyncExitHook, gracefulExit } from 'exit-hook'; import { WebSocket } from 'ws'; -import { logger } from '@app/core/log'; -import { fileExistsSync } from '@app/core/utils/files/file-exists'; -import { environment, PORT } from '@app/environment'; -import * as envVars from '@app/environment'; -import { setupNewMothershipSubscription } from '@app/mothership/subscribe-to-mothership'; -import { store } from '@app/store'; -import { loadDynamixConfigFile } from '@app/store/actions/load-dynamix-config-file'; -import { shutdownApiEvent } from '@app/store/actions/shutdown-api-event'; -import { startMiddlewareListeners } from '@app/store/listeners/listener-middleware'; -import { loadConfigFile } from '@app/store/modules/config'; -import { loadStateFiles } from '@app/store/modules/emhttp'; -import { loadRegistrationKey } from '@app/store/modules/registration'; -import { startStoreSync } from '@app/store/store-sync'; -import { setupDynamixConfigWatch } from '@app/store/watch/dynamix-config-watch'; -import { setupRegistrationKeyWatch } from '@app/store/watch/registration-watch'; -import { StateManager } from '@app/store/watch/state-watch'; -import { setupVarRunWatch } from '@app/store/watch/var-run-watch'; +import { logger } from '@app/core/log.js'; +import { fileExistsSync } from '@app/core/utils/files/file-exists.js'; +import { environment, PORT } from '@app/environment.js'; +import * as envVars from '@app/environment.js'; +import { setupNewMothershipSubscription } from '@app/mothership/subscribe-to-mothership.js'; +import { loadDynamixConfigFile } from '@app/store/actions/load-dynamix-config-file.js'; +import { shutdownApiEvent } from '@app/store/actions/shutdown-api-event.js'; +import { store } from '@app/store/index.js'; +import { startMiddlewareListeners } from '@app/store/listeners/listener-middleware.js'; +import { loadConfigFile } from '@app/store/modules/config.js'; +import { loadStateFiles } from '@app/store/modules/emhttp.js'; +import { loadRegistrationKey } from '@app/store/modules/registration.js'; +import { startStoreSync } from '@app/store/store-sync.js'; +import { setupDynamixConfigWatch } from '@app/store/watch/dynamix-config-watch.js'; +import { setupRegistrationKeyWatch } from '@app/store/watch/registration-watch.js'; +import { StateManager } from '@app/store/watch/state-watch.js'; +import { setupVarRunWatch } from '@app/store/watch/var-run-watch.js'; let server: NestFastifyApplication | null = null; @@ -88,7 +88,7 @@ export const viteNodeApp = async () => { startMiddlewareListeners(); // Start webserver - const { bootstrapNestServer } = await import('@app/unraid-api/main'); + const { bootstrapNestServer } = await import('@app/unraid-api/main.js'); server = await bootstrapNestServer(); diff --git a/api/src/mothership/graphql-client.ts b/api/src/mothership/graphql-client.ts index 9ac14538e..5b81a1fee 100644 --- a/api/src/mothership/graphql-client.ts +++ b/api/src/mothership/graphql-client.ts @@ -7,19 +7,19 @@ import { GraphQLWsLink } from '@apollo/client/link/subscriptions/index.js'; import { createClient } from 'graphql-ws'; import { WebSocket } from 'ws'; -import { FIVE_MINUTES_MS } from '@app/consts'; -import { minigraphLogger } from '@app/core/log'; -import { API_VERSION, MOTHERSHIP_GRAPHQL_LINK } from '@app/environment'; -import { MinigraphStatus } from '@app/graphql/generated/api/types'; -import { buildDelayFunction } from '@app/mothership/utils/delay-function'; +import { FIVE_MINUTES_MS } from '@app/consts.js'; +import { minigraphLogger } from '@app/core/log.js'; +import { API_VERSION, MOTHERSHIP_GRAPHQL_LINK } from '@app/environment.js'; +import { MinigraphStatus } from '@app/graphql/generated/api/types.js'; +import { buildDelayFunction } from '@app/mothership/utils/delay-function.js'; import { getMothershipConnectionParams, getMothershipWebsocketHeaders, -} from '@app/mothership/utils/get-mothership-websocket-headers'; -import { getters, store } from '@app/store'; -import { setGraphqlConnectionStatus } from '@app/store/actions/set-minigraph-status'; -import { logoutUser } from '@app/store/modules/config'; -import { receivedMothershipPing, setMothershipTimeout } from '@app/store/modules/minigraph'; +} from '@app/mothership/utils/get-mothership-websocket-headers.js'; +import { setGraphqlConnectionStatus } from '@app/store/actions/set-minigraph-status.js'; +import { getters, store } from '@app/store/index.js'; +import { logoutUser } from '@app/store/modules/config.js'; +import { receivedMothershipPing, setMothershipTimeout } from '@app/store/modules/minigraph.js'; const getWebsocketWithMothershipHeaders = () => { return class WebsocketWithMothershipHeaders extends WebSocket { diff --git a/api/src/mothership/jobs/ping-timeout-jobs.ts b/api/src/mothership/jobs/ping-timeout-jobs.ts index ec48af478..8d7761097 100644 --- a/api/src/mothership/jobs/ping-timeout-jobs.ts +++ b/api/src/mothership/jobs/ping-timeout-jobs.ts @@ -1,13 +1,13 @@ import { CronJob } from 'cron'; -import { KEEP_ALIVE_INTERVAL_MS, ONE_MINUTE_MS } from '@app/consts'; -import { minigraphLogger, mothershipLogger, remoteAccessLogger } from '@app/core/log'; -import { DynamicRemoteAccessType, MinigraphStatus } from '@app/graphql/generated/api/types'; -import { isAPIStateDataFullyLoaded } from '@app/mothership/graphql-client'; -import { setGraphqlConnectionStatus } from '@app/store/actions/set-minigraph-status'; -import { store } from '@app/store/index'; -import { setRemoteAccessRunningType } from '@app/store/modules/dynamic-remote-access'; -import { clearSubscription } from '@app/store/modules/remote-graphql'; +import { KEEP_ALIVE_INTERVAL_MS, ONE_MINUTE_MS } from '@app/consts.js'; +import { minigraphLogger, mothershipLogger, remoteAccessLogger } from '@app/core/log.js'; +import { DynamicRemoteAccessType, MinigraphStatus } from '@app/graphql/generated/api/types.js'; +import { isAPIStateDataFullyLoaded } from '@app/mothership/graphql-client.js'; +import { setGraphqlConnectionStatus } from '@app/store/actions/set-minigraph-status.js'; +import { store } from '@app/store/index.js'; +import { setRemoteAccessRunningType } from '@app/store/modules/dynamic-remote-access.js'; +import { clearSubscription } from '@app/store/modules/remote-graphql.js'; class PingTimeoutJobs { private cronJob: CronJob; diff --git a/api/src/mothership/subscribe-to-mothership.ts b/api/src/mothership/subscribe-to-mothership.ts index 2a5d33a7e..eb051065b 100644 --- a/api/src/mothership/subscribe-to-mothership.ts +++ b/api/src/mothership/subscribe-to-mothership.ts @@ -1,14 +1,14 @@ -import { minigraphLogger, mothershipLogger } from '@app/core/log'; -import { useFragment } from '@app/graphql/generated/client/fragment-masking'; -import { ClientType } from '@app/graphql/generated/client/graphql'; -import { EVENTS_SUBSCRIPTION, RemoteGraphQL_Fragment } from '@app/graphql/mothership/subscriptions'; -import { GraphQLClient } from '@app/mothership/graphql-client'; -import { initPingTimeoutJobs, PingTimeoutJobs } from '@app/mothership/jobs/ping-timeout-jobs'; -import { getMothershipConnectionParams } from '@app/mothership/utils/get-mothership-websocket-headers'; -import { store } from '@app/store'; -import { handleRemoteGraphQLEvent } from '@app/store/actions/handle-remote-graphql-event'; -import { setSelfDisconnected, setSelfReconnected } from '@app/store/modules/minigraph'; -import { notNull } from '@app/utils'; +import { minigraphLogger, mothershipLogger } from '@app/core/log.js'; +import { useFragment } from '@app/graphql/generated/client/fragment-masking.js'; +import { ClientType } from '@app/graphql/generated/client/graphql.js'; +import { EVENTS_SUBSCRIPTION, RemoteGraphQL_Fragment } from '@app/graphql/mothership/subscriptions.js'; +import { GraphQLClient } from '@app/mothership/graphql-client.js'; +import { initPingTimeoutJobs } from '@app/mothership/jobs/ping-timeout-jobs.js'; +import { getMothershipConnectionParams } from '@app/mothership/utils/get-mothership-websocket-headers.js'; +import { handleRemoteGraphQLEvent } from '@app/store/actions/handle-remote-graphql-event.js'; +import { store } from '@app/store/index.js'; +import { setSelfDisconnected, setSelfReconnected } from '@app/store/modules/minigraph.js'; +import { notNull } from '@app/utils.js'; export const subscribeToEvents = async (apiKey: string) => { minigraphLogger.info('Subscribing to Events'); diff --git a/api/src/mothership/utils/delay-function.ts b/api/src/mothership/utils/delay-function.ts index 4fab7a591..facaa28b7 100644 --- a/api/src/mothership/utils/delay-function.ts +++ b/api/src/mothership/utils/delay-function.ts @@ -1,4 +1,4 @@ -import { type DelayFunctionOptions } from '@apollo/client/link/retry/delayFunction'; +import { type DelayFunctionOptions } from '@apollo/client/link/retry/delayFunction.js'; export function buildDelayFunction(delayOptions?: DelayFunctionOptions): (count: number) => number { const { initial = 10_000, jitter = true, max = Infinity } = delayOptions ?? {}; diff --git a/api/src/mothership/utils/get-mothership-websocket-headers.ts b/api/src/mothership/utils/get-mothership-websocket-headers.ts index 5f916aec2..53614550f 100644 --- a/api/src/mothership/utils/get-mothership-websocket-headers.ts +++ b/api/src/mothership/utils/get-mothership-websocket-headers.ts @@ -1,10 +1,10 @@ import { type OutgoingHttpHeaders } from 'node:http2'; -import { logger } from '@app/core/log'; -import { API_VERSION } from '@app/environment'; -import { ClientType } from '@app/graphql/generated/client/graphql'; -import { isAPIStateDataFullyLoaded } from '@app/mothership/graphql-client'; -import { store } from '@app/store'; +import { logger } from '@app/core/log.js'; +import { API_VERSION } from '@app/environment.js'; +import { ClientType } from '@app/graphql/generated/client/graphql.js'; +import { isAPIStateDataFullyLoaded } from '@app/mothership/graphql-client.js'; +import { store } from '@app/store/index.js'; interface MothershipWebsocketHeaders extends OutgoingHttpHeaders { 'x-api-key': string; diff --git a/api/src/remoteAccess/handlers/remote-access-interface.ts b/api/src/remoteAccess/handlers/remote-access-interface.ts index 3a6a34219..93fe95a4b 100644 --- a/api/src/remoteAccess/handlers/remote-access-interface.ts +++ b/api/src/remoteAccess/handlers/remote-access-interface.ts @@ -1,5 +1,5 @@ -import { type AccessUrl } from '@app/graphql/generated/api/types'; -import { type AppDispatch, type RootState } from '@app/store/index'; +import { type AccessUrl } from '@app/graphql/generated/api/types.js'; +import { type AppDispatch, type RootState } from '@app/store/index.js'; export interface GenericRemoteAccess { beginRemoteAccess({ diff --git a/api/src/remoteAccess/handlers/static-remote-access.ts b/api/src/remoteAccess/handlers/static-remote-access.ts index bb60e0d2c..419dd53e9 100644 --- a/api/src/remoteAccess/handlers/static-remote-access.ts +++ b/api/src/remoteAccess/handlers/static-remote-access.ts @@ -1,10 +1,10 @@ -import type { AccessUrl } from '@app/graphql/generated/api/types'; -import { remoteAccessLogger } from '@app/core/log'; -import { DynamicRemoteAccessType, URL_TYPE } from '@app/graphql/generated/api/types'; -import { getServerIps } from '@app/graphql/resolvers/subscription/network'; -import { type GenericRemoteAccess } from '@app/remoteAccess/handlers/remote-access-interface'; -import { setWanAccessAndReloadNginx } from '@app/store/actions/set-wan-access-with-reload'; -import { type AppDispatch, type RootState } from '@app/store/index'; +import type { AccessUrl } from '@app/graphql/generated/api/types.js'; +import { remoteAccessLogger } from '@app/core/log.js'; +import { DynamicRemoteAccessType, URL_TYPE } from '@app/graphql/generated/api/types.js'; +import { getServerIps } from '@app/graphql/resolvers/subscription/network.js'; +import { type GenericRemoteAccess } from '@app/remoteAccess/handlers/remote-access-interface.js'; +import { setWanAccessAndReloadNginx } from '@app/store/actions/set-wan-access-with-reload.js'; +import { type AppDispatch, type RootState } from '@app/store/index.js'; export class StaticRemoteAccess implements GenericRemoteAccess { public getRemoteAccessUrl({ getState }: { getState: () => RootState }): AccessUrl | null { diff --git a/api/src/remoteAccess/handlers/upnp-remote-access.ts b/api/src/remoteAccess/handlers/upnp-remote-access.ts index 42ae07918..33e7490bf 100644 --- a/api/src/remoteAccess/handlers/upnp-remote-access.ts +++ b/api/src/remoteAccess/handlers/upnp-remote-access.ts @@ -1,11 +1,11 @@ -import type { AccessUrl } from '@app/graphql/generated/api/types'; -import { remoteAccessLogger } from '@app/core/log'; -import { DynamicRemoteAccessType, URL_TYPE } from '@app/graphql/generated/api/types'; -import { getServerIps } from '@app/graphql/resolvers/subscription/network'; -import { type GenericRemoteAccess } from '@app/remoteAccess/handlers/remote-access-interface'; -import { setWanAccessAndReloadNginx } from '@app/store/actions/set-wan-access-with-reload'; -import { type AppDispatch, type RootState } from '@app/store/index'; -import { disableUpnp, enableUpnp } from '@app/store/modules/upnp'; +import type { AccessUrl } from '@app/graphql/generated/api/types.js'; +import { remoteAccessLogger } from '@app/core/log.js'; +import { DynamicRemoteAccessType, URL_TYPE } from '@app/graphql/generated/api/types.js'; +import { getServerIps } from '@app/graphql/resolvers/subscription/network.js'; +import { type GenericRemoteAccess } from '@app/remoteAccess/handlers/remote-access-interface.js'; +import { setWanAccessAndReloadNginx } from '@app/store/actions/set-wan-access-with-reload.js'; +import { type AppDispatch, type RootState } from '@app/store/index.js'; +import { disableUpnp, enableUpnp } from '@app/store/modules/upnp.js'; export class UpnpRemoteAccess implements GenericRemoteAccess { async stopRemoteAccess({ dispatch }: { getState: () => RootState; dispatch: AppDispatch }) { diff --git a/api/src/remoteAccess/remote-access-controller.ts b/api/src/remoteAccess/remote-access-controller.ts index c547237b9..c9a9b48de 100644 --- a/api/src/remoteAccess/remote-access-controller.ts +++ b/api/src/remoteAccess/remote-access-controller.ts @@ -1,18 +1,18 @@ -import type { AccessUrl } from '@app/graphql/generated/api/types'; -import type { AppDispatch, RootState } from '@app/store/index'; -import { remoteAccessLogger } from '@app/core/log'; -import { UnraidLocalNotifier } from '@app/core/notifiers/unraid-local'; -import { DynamicRemoteAccessType } from '@app/graphql/generated/api/types'; -import { type IRemoteAccessController } from '@app/remoteAccess/handlers/remote-access-interface'; -import { StaticRemoteAccess } from '@app/remoteAccess/handlers/static-remote-access'; -import { UpnpRemoteAccess } from '@app/remoteAccess/handlers/upnp-remote-access'; -import { getters } from '@app/store/index'; +import type { AccessUrl } from '@app/graphql/generated/api/types.js'; +import type { AppDispatch, RootState } from '@app/store/index.js'; +import { remoteAccessLogger } from '@app/core/log.js'; +import { UnraidLocalNotifier } from '@app/core/notifiers/unraid-local.js'; +import { DynamicRemoteAccessType } from '@app/graphql/generated/api/types.js'; +import { type IRemoteAccessController } from '@app/remoteAccess/handlers/remote-access-interface.js'; +import { StaticRemoteAccess } from '@app/remoteAccess/handlers/static-remote-access.js'; +import { UpnpRemoteAccess } from '@app/remoteAccess/handlers/upnp-remote-access.js'; +import { getters } from '@app/store/index.js'; import { clearPing, receivedPing, setDynamicRemoteAccessError, setRemoteAccessRunningType, -} from '@app/store/modules/dynamic-remote-access'; +} from '@app/store/modules/dynamic-remote-access.js'; export class RemoteAccessController implements IRemoteAccessController { static _instance: RemoteAccessController | null = null; diff --git a/api/src/run.ts b/api/src/run.ts index 6baf29d28..00018a5c5 100644 --- a/api/src/run.ts +++ b/api/src/run.ts @@ -1,8 +1,8 @@ -import type { CoreContext, CoreResult } from '@app/core/types'; -import { logger, pubsub } from '@app/core'; -import { AppError } from '@app/core/errors/app-error'; -import { isNodeError } from '@app/core/utils'; -import { sleep } from '@app/core/utils/misc/sleep'; +import { AppError } from '@app/core/errors/app-error.js'; +import { logger, pubsub } from '@app/core/index.js'; +import { CoreContext, CoreResult } from '@app/core/types/global.js'; +import { sleep } from '@app/core/utils/misc/sleep.js'; +import { isNodeError } from '@app/core/utils/validation/is-node-error.js'; /** * Publish update to topic channel. diff --git a/api/src/store/actions/add-remote-subscription.ts b/api/src/store/actions/add-remote-subscription.ts index eadac206f..0e08e5e55 100644 --- a/api/src/store/actions/add-remote-subscription.ts +++ b/api/src/store/actions/add-remote-subscription.ts @@ -1,15 +1,15 @@ import { createAsyncThunk } from '@reduxjs/toolkit'; -import type { RemoteGraphQLEventFragmentFragment } from '@app/graphql/generated/client/graphql'; -import { remoteQueryLogger } from '@app/core/log'; -import { getApiApolloClient } from '@app/graphql/client/api/get-api-client'; -import { RemoteGraphQLEventType } from '@app/graphql/generated/client/graphql'; -import { SEND_REMOTE_QUERY_RESPONSE } from '@app/graphql/mothership/mutations'; -import { parseGraphQLQuery } from '@app/graphql/resolvers/subscription/remote-graphql/remote-graphql-helpers'; -import { GraphQLClient } from '@app/mothership/graphql-client'; -import { hasRemoteSubscription } from '@app/store/getters/index'; -import { type AppDispatch, type RootState } from '@app/store/index'; -import { type SubscriptionWithSha256 } from '@app/store/types'; +import type { RemoteGraphQLEventFragmentFragment } from '@app/graphql/generated/client/graphql.js'; +import { remoteQueryLogger } from '@app/core/log.js'; +import { getApiApolloClient } from '@app/graphql/client/api/get-api-client.js'; +import { RemoteGraphQLEventType } from '@app/graphql/generated/client/graphql.js'; +import { SEND_REMOTE_QUERY_RESPONSE } from '@app/graphql/mothership/mutations.js'; +import { parseGraphQLQuery } from '@app/graphql/resolvers/subscription/remote-graphql/remote-graphql-helpers.js'; +import { GraphQLClient } from '@app/mothership/graphql-client.js'; +import { hasRemoteSubscription } from '@app/store/getters/index.js'; +import { type AppDispatch, type RootState } from '@app/store/index.js'; +import { type SubscriptionWithSha256 } from '@app/store/types.js'; export const addRemoteSubscription = createAsyncThunk< SubscriptionWithSha256, diff --git a/api/src/store/actions/handle-remote-graphql-event.ts b/api/src/store/actions/handle-remote-graphql-event.ts index 66fdab13f..9a8e3e1f9 100644 --- a/api/src/store/actions/handle-remote-graphql-event.ts +++ b/api/src/store/actions/handle-remote-graphql-event.ts @@ -1,12 +1,12 @@ import { createAsyncThunk } from '@reduxjs/toolkit'; -import type { RemoteGraphQLEventFragmentFragment } from '@app/graphql/generated/client/graphql'; -import { remoteQueryLogger } from '@app/core/log'; -import { RemoteGraphQLEventType } from '@app/graphql/generated/client/graphql'; -import { executeRemoteGraphQLQuery } from '@app/graphql/resolvers/subscription/remote-graphql/remote-query'; -import { createRemoteSubscription } from '@app/graphql/resolvers/subscription/remote-graphql/remote-subscription'; -import { type AppDispatch, type RootState } from '@app/store/index'; -import { renewRemoteSubscription } from '@app/store/modules/remote-graphql'; +import type { RemoteGraphQLEventFragmentFragment } from '@app/graphql/generated/client/graphql.js'; +import { remoteQueryLogger } from '@app/core/log.js'; +import { RemoteGraphQLEventType } from '@app/graphql/generated/client/graphql.js'; +import { executeRemoteGraphQLQuery } from '@app/graphql/resolvers/subscription/remote-graphql/remote-query.js'; +import { createRemoteSubscription } from '@app/graphql/resolvers/subscription/remote-graphql/remote-subscription.js'; +import { type AppDispatch, type RootState } from '@app/store/index.js'; +import { renewRemoteSubscription } from '@app/store/modules/remote-graphql.js'; export const handleRemoteGraphQLEvent = createAsyncThunk< void, diff --git a/api/src/store/actions/load-dynamix-config-file.ts b/api/src/store/actions/load-dynamix-config-file.ts index d39bc573e..ebae78c18 100644 --- a/api/src/store/actions/load-dynamix-config-file.ts +++ b/api/src/store/actions/load-dynamix-config-file.ts @@ -3,10 +3,10 @@ import { access } from 'fs/promises'; import { createAsyncThunk } from '@reduxjs/toolkit'; -import { type DynamixConfig } from '@app/core/types/ini'; -import { parseConfig } from '@app/core/utils/misc/parse-config'; -import { type RecursiveNullable, type RecursivePartial } from '@app/types'; -import { batchProcess } from '@app/utils'; +import { type DynamixConfig } from '@app/core/types/ini.js'; +import { parseConfig } from '@app/core/utils/misc/parse-config.js'; +import { type RecursiveNullable, type RecursivePartial } from '@app/types/index.js'; +import { batchProcess } from '@app/utils.js'; /** * Loads a configuration file from disk, parses it to a RecursivePartial of the provided type, and returns it. @@ -40,7 +40,7 @@ export const loadDynamixConfigFile = createAsyncThunk< if (filePath) { return loadConfigFile(filePath); } - const store = await import('@app/store'); + const store = await import('@app/store/index.js'); const paths = store.getters.paths()['dynamix-config']; const { data: configs } = await batchProcess(paths, (path) => loadConfigFile(path)); const [defaultConfig = {}, customConfig = {}] = configs; diff --git a/api/src/store/actions/reload-nginx-and-update-dns.ts b/api/src/store/actions/reload-nginx-and-update-dns.ts index 082aeb371..76500e1b1 100644 --- a/api/src/store/actions/reload-nginx-and-update-dns.ts +++ b/api/src/store/actions/reload-nginx-and-update-dns.ts @@ -1,9 +1,9 @@ import { createAsyncThunk } from '@reduxjs/toolkit'; -import { remoteAccessLogger } from '@app/core/log'; -import { NginxManager } from '@app/core/modules/services/nginx'; -import { UpdateDNSManager } from '@app/core/modules/services/update-dns'; -import { type AppDispatch, type RootState } from '@app/store/index'; +import { remoteAccessLogger } from '@app/core/log.js'; +import { NginxManager } from '@app/core/modules/services/nginx.js'; +import { UpdateDNSManager } from '@app/core/modules/services/update-dns.js'; +import { type AppDispatch, type RootState } from '@app/store/index.js'; export const reloadNginxAndUpdateDNS = createAsyncThunk< void, diff --git a/api/src/store/actions/set-minigraph-status.ts b/api/src/store/actions/set-minigraph-status.ts index 2bb4d7b97..d7b78faf6 100644 --- a/api/src/store/actions/set-minigraph-status.ts +++ b/api/src/store/actions/set-minigraph-status.ts @@ -1,6 +1,6 @@ import { createAction } from '@reduxjs/toolkit'; -import { type MinigraphStatus } from '@app/graphql/generated/api/types'; +import { type MinigraphStatus } from '@app/graphql/generated/api/types.js'; export const setGraphqlConnectionStatus = createAction<{ status: MinigraphStatus; diff --git a/api/src/store/actions/set-wan-access-with-reload.ts b/api/src/store/actions/set-wan-access-with-reload.ts index 531ac99d7..0b99dafe1 100644 --- a/api/src/store/actions/set-wan-access-with-reload.ts +++ b/api/src/store/actions/set-wan-access-with-reload.ts @@ -1,8 +1,8 @@ import { createAsyncThunk } from '@reduxjs/toolkit'; -import { reloadNginxAndUpdateDNS } from '@app/store/actions/reload-nginx-and-update-dns'; -import { type AppDispatch, type RootState } from '@app/store/index'; -import { setWanAccess } from '@app/store/modules/config'; +import { reloadNginxAndUpdateDNS } from '@app/store/actions/reload-nginx-and-update-dns.js'; +import { type AppDispatch, type RootState } from '@app/store/index.js'; +import { setWanAccess } from '@app/store/modules/config.js'; type EnableWanAccessArgs = Parameters[0]; export const setWanAccessAndReloadNginx = createAsyncThunk< diff --git a/api/src/store/actions/setup-remote-access.ts b/api/src/store/actions/setup-remote-access.ts index 250bcaee7..c0066ad85 100644 --- a/api/src/store/actions/setup-remote-access.ts +++ b/api/src/store/actions/setup-remote-access.ts @@ -1,13 +1,13 @@ import { createAsyncThunk } from '@reduxjs/toolkit'; -import type { SetupRemoteAccessInput } from '@app/graphql/generated/api/types'; +import type { SetupRemoteAccessInput } from '@app/graphql/generated/api/types.js'; import { DynamicRemoteAccessType, WAN_ACCESS_TYPE, WAN_FORWARD_TYPE, -} from '@app/graphql/generated/api/types'; -import { type AppDispatch, type RootState } from '@app/store/index'; -import { type MyServersConfig } from '@app/types/my-servers-config'; +} from '@app/graphql/generated/api/types.js'; +import { type AppDispatch, type RootState } from '@app/store/index.js'; +import { type MyServersConfig } from '@app/types/my-servers-config.js'; const getDynamicRemoteAccessType = ( accessType: WAN_ACCESS_TYPE, diff --git a/api/src/store/actions/shutdown-api-event.ts b/api/src/store/actions/shutdown-api-event.ts index 410a014ac..81ba4b83f 100644 --- a/api/src/store/actions/shutdown-api-event.ts +++ b/api/src/store/actions/shutdown-api-event.ts @@ -1,10 +1,10 @@ -import { logDestination, logger } from '@app/core/log'; -import { DynamicRemoteAccessType, MinigraphStatus } from '@app/graphql/generated/api/types'; -import { setGraphqlConnectionStatus } from '@app/store/actions/set-minigraph-status'; -import { store } from '@app/store/index'; -import { stopListeners } from '@app/store/listeners/stop-listeners'; -import { setWanAccess } from '@app/store/modules/config'; -import { writeConfigSync } from '@app/store/sync/config-disk-sync'; +import { logDestination, logger } from '@app/core/log.js'; +import { DynamicRemoteAccessType, MinigraphStatus } from '@app/graphql/generated/api/types.js'; +import { setGraphqlConnectionStatus } from '@app/store/actions/set-minigraph-status.js'; +import { store } from '@app/store/index.js'; +import { stopListeners } from '@app/store/listeners/stop-listeners.js'; +import { setWanAccess } from '@app/store/modules/config.js'; +import { writeConfigSync } from '@app/store/sync/config-disk-sync.js'; export const shutdownApiEvent = () => { logger.debug('Running shutdown'); diff --git a/api/src/store/getters/index.ts b/api/src/store/getters/index.ts index a25a768e2..42a24295c 100644 --- a/api/src/store/getters/index.ts +++ b/api/src/store/getters/index.ts @@ -1,7 +1,7 @@ -import type { DNSCheck } from '@app/store/types'; -import { type CloudResponse } from '@app/graphql/generated/api/types'; -import { getters, store } from '@app/store'; -import { CacheKeys } from '@app/store/types'; +import type { DNSCheck } from '@app/store/types.js'; +import { type CloudResponse } from '@app/graphql/generated/api/types.js'; +import { getters, store } from '@app/store/index.js'; +import { CacheKeys } from '@app/store/types.js'; export const getCloudCache = (): CloudResponse | undefined => { const { nodeCache } = getters.cache(); diff --git a/api/src/store/index.ts b/api/src/store/index.ts index fa72dd67a..a38893c94 100644 --- a/api/src/store/index.ts +++ b/api/src/store/index.ts @@ -1,18 +1,18 @@ import { configureStore } from '@reduxjs/toolkit'; -import { listenerMiddleware } from '@app/store/listeners/listener-middleware'; -import { cache } from '@app/store/modules/cache'; -import { configReducer } from '@app/store/modules/config'; -import { docker } from '@app/store/modules/docker'; -import { dynamicRemoteAccessReducer } from '@app/store/modules/dynamic-remote-access'; -import { dynamix } from '@app/store/modules/dynamix'; -import { emhttp } from '@app/store/modules/emhttp'; -import { mothership } from '@app/store/modules/minigraph'; -import { notificationReducer } from '@app/store/modules/notifications'; -import { paths } from '@app/store/modules/paths'; -import { registration } from '@app/store/modules/registration'; -import { remoteGraphQLReducer } from '@app/store/modules/remote-graphql'; -import { upnp } from '@app/store/modules/upnp'; +import { listenerMiddleware } from '@app/store/listeners/listener-middleware.js'; +import { cache } from '@app/store/modules/cache.js'; +import { configReducer } from '@app/store/modules/config.js'; +import { docker } from '@app/store/modules/docker.js'; +import { dynamicRemoteAccessReducer } from '@app/store/modules/dynamic-remote-access.js'; +import { dynamix } from '@app/store/modules/dynamix.js'; +import { emhttp } from '@app/store/modules/emhttp.js'; +import { mothership } from '@app/store/modules/minigraph.js'; +import { notificationReducer } from '@app/store/modules/notifications.js'; +import { paths } from '@app/store/modules/paths.js'; +import { registration } from '@app/store/modules/registration.js'; +import { remoteGraphQLReducer } from '@app/store/modules/remote-graphql.js'; +import { upnp } from '@app/store/modules/upnp.js'; export const store = configureStore({ reducer: { diff --git a/api/src/store/listeners/array-event-listener.ts b/api/src/store/listeners/array-event-listener.ts index 8eefb138d..6291a0919 100644 --- a/api/src/store/listeners/array-event-listener.ts +++ b/api/src/store/listeners/array-event-listener.ts @@ -1,12 +1,12 @@ import { isAnyOf } from '@reduxjs/toolkit'; import { isEqual } from 'lodash-es'; -import { logger } from '@app/core/log'; -import { getArrayData } from '@app/core/modules/array/get-array-data'; -import { pubsub, PUBSUB_CHANNEL } from '@app/core/pubsub'; -import { startAppListening } from '@app/store/listeners/listener-middleware'; -import { loadSingleStateFile } from '@app/store/modules/emhttp'; -import { StateFileKey } from '@app/store/types'; +import { logger } from '@app/core/log.js'; +import { getArrayData } from '@app/core/modules/array/get-array-data.js'; +import { pubsub, PUBSUB_CHANNEL } from '@app/core/pubsub.js'; +import { startAppListening } from '@app/store/listeners/listener-middleware.js'; +import { loadSingleStateFile } from '@app/store/modules/emhttp.js'; +import { StateFileKey } from '@app/store/types.js'; export const enableArrayEventListener = () => startAppListening({ diff --git a/api/src/store/listeners/config-listener.ts b/api/src/store/listeners/config-listener.ts index 49c36cb71..ddf6c63cc 100644 --- a/api/src/store/listeners/config-listener.ts +++ b/api/src/store/listeners/config-listener.ts @@ -1,11 +1,11 @@ import { writeFileSync } from 'fs'; -import type { ConfigType } from '@app/core/utils/files/config-file-normalizer'; -import { logger } from '@app/core/log'; -import { getWriteableConfig } from '@app/core/utils/files/config-file-normalizer'; -import { safelySerializeObjectToIni } from '@app/core/utils/files/safe-ini-serializer'; -import { startAppListening } from '@app/store/listeners/listener-middleware'; -import { configUpdateActionsFlash, configUpdateActionsMemory } from '@app/store/modules/config'; +import type { ConfigType } from '@app/core/utils/files/config-file-normalizer.js'; +import { logger } from '@app/core/log.js'; +import { getWriteableConfig } from '@app/core/utils/files/config-file-normalizer.js'; +import { safelySerializeObjectToIni } from '@app/core/utils/files/safe-ini-serializer.js'; +import { startAppListening } from '@app/store/listeners/listener-middleware.js'; +import { configUpdateActionsFlash, configUpdateActionsMemory } from '@app/store/modules/config.js'; export const enableConfigFileListener = (mode: ConfigType) => () => startAppListening({ diff --git a/api/src/store/listeners/dynamic-remote-access-listener.ts b/api/src/store/listeners/dynamic-remote-access-listener.ts index 5fc087f26..da2047eac 100644 --- a/api/src/store/listeners/dynamic-remote-access-listener.ts +++ b/api/src/store/listeners/dynamic-remote-access-listener.ts @@ -1,12 +1,12 @@ import { isAnyOf } from '@reduxjs/toolkit'; -import { remoteAccessLogger } from '@app/core/log'; -import { DynamicRemoteAccessType } from '@app/graphql/generated/api/types'; -import { RemoteAccessController } from '@app/remoteAccess/remote-access-controller'; -import { type RootState } from '@app/store'; -import { startAppListening } from '@app/store/listeners/listener-middleware'; -import { loadConfigFile } from '@app/store/modules/config'; -import { FileLoadStatus } from '@app/store/types'; +import { remoteAccessLogger } from '@app/core/log.js'; +import { DynamicRemoteAccessType } from '@app/graphql/generated/api/types.js'; +import { RemoteAccessController } from '@app/remoteAccess/remote-access-controller.js'; +import { type RootState } from '@app/store/index.js'; +import { startAppListening } from '@app/store/listeners/listener-middleware.js'; +import { loadConfigFile } from '@app/store/modules/config.js'; +import { FileLoadStatus } from '@app/store/types.js'; const shouldDynamicRemoteAccessBeEnabled = (state: RootState | null): boolean => { if ( diff --git a/api/src/store/listeners/listener-middleware.ts b/api/src/store/listeners/listener-middleware.ts index 8ec94bcd4..7ec07c42c 100644 --- a/api/src/store/listeners/listener-middleware.ts +++ b/api/src/store/listeners/listener-middleware.ts @@ -3,15 +3,15 @@ import 'reflect-metadata'; import type { TypedAddListener, TypedStartListening } from '@reduxjs/toolkit'; import { addListener, createListenerMiddleware } from '@reduxjs/toolkit'; -import { type AppDispatch, type RootState } from '@app/store'; -import { enableArrayEventListener } from '@app/store/listeners/array-event-listener'; -import { enableConfigFileListener } from '@app/store/listeners/config-listener'; -import { enableDynamicRemoteAccessListener } from '@app/store/listeners/dynamic-remote-access-listener'; -import { enableMothershipJobsListener } from '@app/store/listeners/mothership-subscription-listener'; -import { enableServerStateListener } from '@app/store/listeners/server-state-listener'; -import { enableUpnpListener } from '@app/store/listeners/upnp-listener'; -import { enableVersionListener } from '@app/store/listeners/version-listener'; -import { enableWanAccessChangeListener } from '@app/store/listeners/wan-access-change-listener'; +import { type AppDispatch, type RootState } from '@app/store/index.js'; +import { enableArrayEventListener } from '@app/store/listeners/array-event-listener.js'; +import { enableConfigFileListener } from '@app/store/listeners/config-listener.js'; +import { enableDynamicRemoteAccessListener } from '@app/store/listeners/dynamic-remote-access-listener.js'; +import { enableMothershipJobsListener } from '@app/store/listeners/mothership-subscription-listener.js'; +import { enableServerStateListener } from '@app/store/listeners/server-state-listener.js'; +import { enableUpnpListener } from '@app/store/listeners/upnp-listener.js'; +import { enableVersionListener } from '@app/store/listeners/version-listener.js'; +import { enableWanAccessChangeListener } from '@app/store/listeners/wan-access-change-listener.js'; export const listenerMiddleware = createListenerMiddleware(); diff --git a/api/src/store/listeners/mothership-subscription-listener.ts b/api/src/store/listeners/mothership-subscription-listener.ts index 6da91a446..8a79b080e 100644 --- a/api/src/store/listeners/mothership-subscription-listener.ts +++ b/api/src/store/listeners/mothership-subscription-listener.ts @@ -1,11 +1,11 @@ import { isEqual } from 'lodash-es'; -import { minigraphLogger } from '@app/core/log'; -import { MinigraphStatus } from '@app/graphql/generated/api/types'; -import { setupNewMothershipSubscription } from '@app/mothership/subscribe-to-mothership'; -import { getMothershipConnectionParams } from '@app/mothership/utils/get-mothership-websocket-headers'; -import { setGraphqlConnectionStatus } from '@app/store/actions/set-minigraph-status'; -import { startAppListening } from '@app/store/listeners/listener-middleware'; +import { minigraphLogger } from '@app/core/log.js'; +import { MinigraphStatus } from '@app/graphql/generated/api/types.js'; +import { setupNewMothershipSubscription } from '@app/mothership/subscribe-to-mothership.js'; +import { getMothershipConnectionParams } from '@app/mothership/utils/get-mothership-websocket-headers.js'; +import { setGraphqlConnectionStatus } from '@app/store/actions/set-minigraph-status.js'; +import { startAppListening } from '@app/store/listeners/listener-middleware.js'; export const enableMothershipJobsListener = () => startAppListening({ diff --git a/api/src/store/listeners/notification-path-listener.ts b/api/src/store/listeners/notification-path-listener.ts index eddd89760..89436b0f4 100644 --- a/api/src/store/listeners/notification-path-listener.ts +++ b/api/src/store/listeners/notification-path-listener.ts @@ -1,7 +1,6 @@ -import { logger } from '@app/core/log'; -import { setupNotificationWatch } from '@app/core/modules/notifications/setup-notification-watch'; -import { startAppListening } from '@app/store/listeners/listener-middleware'; -import { clearAllNotifications } from '@app/store/modules/notifications'; +import { logger } from '@app/core/log.js'; +import { startAppListening } from '@app/store/listeners/listener-middleware.js'; +import { clearAllNotifications } from '@app/store/modules/notifications.js'; export const enableNotificationPathListener = () => startAppListening({ @@ -18,6 +17,5 @@ export const enableNotificationPathListener = () => async effect(_, { dispatch }) { logger.debug('Notification Path Changed or Loaded, Recreating Watcher'); dispatch(clearAllNotifications()); - await setupNotificationWatch(); }, }); diff --git a/api/src/store/listeners/server-state-listener.ts b/api/src/store/listeners/server-state-listener.ts index 167cef043..69d495a59 100644 --- a/api/src/store/listeners/server-state-listener.ts +++ b/api/src/store/listeners/server-state-listener.ts @@ -1,11 +1,11 @@ import { isEqual } from 'lodash-es'; -import { mothershipLogger } from '@app/core/log'; -import { pubsub, PUBSUB_CHANNEL } from '@app/core/pubsub'; -import { getServers } from '@app/graphql/schema/utils'; -import { isAPIStateDataFullyLoaded } from '@app/mothership/graphql-client'; -import { startAppListening } from '@app/store/listeners/listener-middleware'; -import { FileLoadStatus } from '@app/store/types'; +import { mothershipLogger } from '@app/core/log.js'; +import { pubsub, PUBSUB_CHANNEL } from '@app/core/pubsub.js'; +import { getServers } from '@app/graphql/schema/utils.js'; +import { isAPIStateDataFullyLoaded } from '@app/mothership/graphql-client.js'; +import { startAppListening } from '@app/store/listeners/listener-middleware.js'; +import { FileLoadStatus } from '@app/store/types.js'; export const enableServerStateListener = () => startAppListening({ diff --git a/api/src/store/listeners/stop-listeners.ts b/api/src/store/listeners/stop-listeners.ts index eed09cdc8..19874d4ab 100644 --- a/api/src/store/listeners/stop-listeners.ts +++ b/api/src/store/listeners/stop-listeners.ts @@ -1,5 +1,5 @@ -import { logger } from '@app/core/log'; -import { listenerMiddleware } from '@app/store/listeners/listener-middleware'; +import { logger } from '@app/core/log.js'; +import { listenerMiddleware } from '@app/store/listeners/listener-middleware.js'; export const stopListeners = () => { logger.debug('Stopping app listeners'); diff --git a/api/src/store/listeners/upnp-listener.ts b/api/src/store/listeners/upnp-listener.ts index 40bb044a5..5b7bb9627 100644 --- a/api/src/store/listeners/upnp-listener.ts +++ b/api/src/store/listeners/upnp-listener.ts @@ -1,13 +1,13 @@ import { isAnyOf } from '@reduxjs/toolkit'; -import { upnpLogger } from '@app/core/log'; -import { type RootState } from '@app/store'; -import { setupRemoteAccessThunk } from '@app/store/actions/setup-remote-access'; -import { startAppListening } from '@app/store/listeners/listener-middleware'; -import { loadConfigFile } from '@app/store/modules/config'; -import { loadSingleStateFile, loadStateFiles } from '@app/store/modules/emhttp'; -import { disableUpnp, enableUpnp } from '@app/store/modules/upnp'; -import { FileLoadStatus } from '@app/store/types'; +import { upnpLogger } from '@app/core/log.js'; +import { setupRemoteAccessThunk } from '@app/store/actions/setup-remote-access.js'; +import { type RootState } from '@app/store/index.js'; +import { startAppListening } from '@app/store/listeners/listener-middleware.js'; +import { loadConfigFile } from '@app/store/modules/config.js'; +import { loadSingleStateFile, loadStateFiles } from '@app/store/modules/emhttp.js'; +import { disableUpnp, enableUpnp } from '@app/store/modules/upnp.js'; +import { FileLoadStatus } from '@app/store/types.js'; const shouldUpnpBeEnabled = (state: RootState | null): boolean => { if ( diff --git a/api/src/store/listeners/version-listener.ts b/api/src/store/listeners/version-listener.ts index a8d684c63..f15c0e3c4 100644 --- a/api/src/store/listeners/version-listener.ts +++ b/api/src/store/listeners/version-listener.ts @@ -1,8 +1,8 @@ -import { logger } from '@app/core/log'; -import { API_VERSION } from '@app/environment'; -import { startAppListening } from '@app/store/listeners/listener-middleware'; -import { updateUserConfig } from '@app/store/modules/config'; -import { FileLoadStatus } from '@app/store/types'; +import { logger } from '@app/core/log.js'; +import { API_VERSION } from '@app/environment.js'; +import { startAppListening } from '@app/store/listeners/listener-middleware.js'; +import { updateUserConfig } from '@app/store/modules/config.js'; +import { FileLoadStatus } from '@app/store/types.js'; export const enableVersionListener = () => startAppListening({ diff --git a/api/src/store/listeners/wan-access-change-listener.ts b/api/src/store/listeners/wan-access-change-listener.ts index e1246f2d2..a8384ce5b 100644 --- a/api/src/store/listeners/wan-access-change-listener.ts +++ b/api/src/store/listeners/wan-access-change-listener.ts @@ -1,7 +1,7 @@ -import { remoteAccessLogger } from '@app/core/log'; -import { reloadNginxAndUpdateDNS } from '@app/store/actions/reload-nginx-and-update-dns'; -import { startAppListening } from '@app/store/listeners/listener-middleware'; -import { loadConfigFile } from '@app/store/modules/config'; +import { remoteAccessLogger } from '@app/core/log.js'; +import { reloadNginxAndUpdateDNS } from '@app/store/actions/reload-nginx-and-update-dns.js'; +import { startAppListening } from '@app/store/listeners/listener-middleware.js'; +import { loadConfigFile } from '@app/store/modules/config.js'; export const enableWanAccessChangeListener = () => startAppListening({ diff --git a/api/src/store/middleware.ts b/api/src/store/middleware.ts deleted file mode 100644 index 68f1d4bea..000000000 --- a/api/src/store/middleware.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { type CurriedGetDefaultMiddleware } from '@reduxjs/toolkit/dist/getDefaultMiddleware'; - -export const defaultAppMiddleware = (getDefaultMiddleware: CurriedGetDefaultMiddleware) => - getDefaultMiddleware({ - serializableCheck: { - ignoredPaths: ['minigraph.client', 'minigraph.subscriptions', 'dashboard.publishJob'], - ignoredActions: [ - 'minigraph/addSubscription', - 'minigraph/createNewClient/fulfilled', - 'minigraph/setClient', - ], - }, - }); diff --git a/api/src/store/modules/cache.ts b/api/src/store/modules/cache.ts index 3219a6027..d1e461094 100644 --- a/api/src/store/modules/cache.ts +++ b/api/src/store/modules/cache.ts @@ -2,10 +2,10 @@ import type { PayloadAction } from '@reduxjs/toolkit'; import { createSlice } from '@reduxjs/toolkit'; import NodeCache from 'node-cache'; -import type { DNSCheck } from '@app/store/types'; -import { ONE_HOUR_SECS } from '@app/consts'; -import { type CloudResponse } from '@app/graphql/generated/api/types'; -import { CacheKeys } from '@app/store/types'; +import type { DNSCheck } from '@app/store/types.js'; +import { ONE_HOUR_SECS } from '@app/consts.js'; +import { type CloudResponse } from '@app/graphql/generated/api/types.js'; +import { CacheKeys } from '@app/store/types.js'; const initialState: { nodeCache: NodeCache; diff --git a/api/src/store/modules/config.ts b/api/src/store/modules/config.ts index 1387b9f1c..38ae1b5e7 100644 --- a/api/src/store/modules/config.ts +++ b/api/src/store/modules/config.ts @@ -6,22 +6,22 @@ import type { PayloadAction } from '@reduxjs/toolkit'; import { createAsyncThunk, createSlice, isAnyOf } from '@reduxjs/toolkit'; import { isEqual, merge } from 'lodash-es'; -import type { Owner } from '@app/graphql/generated/api/types'; -import { logger } from '@app/core/log'; -import { pubsub, PUBSUB_CHANNEL } from '@app/core/pubsub'; -import { getWriteableConfig } from '@app/core/utils/files/config-file-normalizer'; -import { safelySerializeObjectToIni } from '@app/core/utils/files/safe-ini-serializer'; -import { parseConfig } from '@app/core/utils/misc/parse-config'; -import { NODE_ENV } from '@app/environment'; -import { DynamicRemoteAccessType, MinigraphStatus } from '@app/graphql/generated/api/types'; -import { GraphQLClient } from '@app/mothership/graphql-client'; -import { stopPingTimeoutJobs } from '@app/mothership/jobs/ping-timeout-jobs'; -import { type RootState } from '@app/store'; -import { setGraphqlConnectionStatus } from '@app/store/actions/set-minigraph-status'; -import { setupRemoteAccessThunk } from '@app/store/actions/setup-remote-access'; -import { FileLoadStatus } from '@app/store/types'; -import { type RecursivePartial } from '@app/types'; -import { type MyServersConfig, type MyServersConfigMemory } from '@app/types/my-servers-config'; +import type { Owner } from '@app/graphql/generated/api/types.js'; +import { logger } from '@app/core/log.js'; +import { pubsub, PUBSUB_CHANNEL } from '@app/core/pubsub.js'; +import { getWriteableConfig } from '@app/core/utils/files/config-file-normalizer.js'; +import { safelySerializeObjectToIni } from '@app/core/utils/files/safe-ini-serializer.js'; +import { parseConfig } from '@app/core/utils/misc/parse-config.js'; +import { NODE_ENV } from '@app/environment.js'; +import { DynamicRemoteAccessType, MinigraphStatus } from '@app/graphql/generated/api/types.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 { type RootState } from '@app/store/index.js'; +import { FileLoadStatus } from '@app/store/types.js'; +import { RecursivePartial } from '@app/types/index.js'; +import { type MyServersConfig, type MyServersConfigMemory } from '@app/types/my-servers-config.js'; export type SliceState = { status: FileLoadStatus; @@ -79,7 +79,7 @@ export const logoutUser = createAsyncThunk { logger.info('Logging out user: %s', reason ?? 'No reason provided'); - const { pubsub } = await import('@app/core/pubsub'); + const { pubsub } = await import('@app/core/pubsub.js'); // Publish to servers endpoint await pubsub.publish(PUBSUB_CHANNEL.SERVERS, { diff --git a/api/src/store/modules/docker.ts b/api/src/store/modules/docker.ts index 99f557ce7..37696cfe9 100644 --- a/api/src/store/modules/docker.ts +++ b/api/src/store/modules/docker.ts @@ -1,8 +1,8 @@ import type { PayloadAction } from '@reduxjs/toolkit'; import { createSlice } from '@reduxjs/toolkit'; -import { type DockerContainer } from '@app/graphql/generated/api/types'; -import { DaemonConnectionStatus } from '@app/store/types'; +import { type DockerContainer } from '@app/graphql/generated/api/types.js'; +import { DaemonConnectionStatus } from '@app/store/types.js'; type DockerState = { status: DaemonConnectionStatus; diff --git a/api/src/store/modules/dynamic-remote-access.ts b/api/src/store/modules/dynamic-remote-access.ts index 3fe16ac9d..2e8a00078 100644 --- a/api/src/store/modules/dynamic-remote-access.ts +++ b/api/src/store/modules/dynamic-remote-access.ts @@ -1,15 +1,20 @@ import type { PayloadAction } from '@reduxjs/toolkit'; import { createSlice } from '@reduxjs/toolkit'; -import type { AccessUrl, AccessUrlInput } from '@app/graphql/generated/api/types'; -import { remoteAccessLogger } from '@app/core/log'; -import { DynamicRemoteAccessType, URL_TYPE } from '@app/graphql/generated/api/types'; +import type { AccessUrlInput } from '@app/graphql/generated/api/types.js'; +import { remoteAccessLogger } from '@app/core/log.js'; +import { DynamicRemoteAccessType, URL_TYPE } from '@app/graphql/generated/api/types.js'; interface DynamicRemoteAccessState { runningType: DynamicRemoteAccessType; // Is Dynamic Remote Access actively running - shows type of access currently running error: string | null; lastPing: number | null; - allowedUrl: AccessUrl | null; // Not used yet, will be used to facilitate allowlisting clients + allowedUrl: { + ipv4: string | null | undefined; + ipv6: string | null | undefined; + type: URL_TYPE; + name: string | null | undefined; + } | null; } const initialState: DynamicRemoteAccessState = { @@ -45,10 +50,9 @@ const dynamicRemoteAccess = createSlice({ }, setAllowedRemoteAccessUrl(state, action: PayloadAction) { if (action.payload) { - console.log(action.payload); state.allowedUrl = { - ipv4: action.payload.ipv4, - ipv6: action.payload.ipv6, + ipv4: action.payload.ipv4?.toString(), + ipv6: action.payload.ipv6?.toString(), type: action.payload.type ?? URL_TYPE.WAN, name: action.payload.name, }; diff --git a/api/src/store/modules/dynamix.ts b/api/src/store/modules/dynamix.ts index f903449c6..e78070577 100644 --- a/api/src/store/modules/dynamix.ts +++ b/api/src/store/modules/dynamix.ts @@ -2,10 +2,10 @@ import type { PayloadAction } from '@reduxjs/toolkit'; import { createSlice } from '@reduxjs/toolkit'; import { merge } from 'lodash-es'; -import { type DynamixConfig } from '@app/core/types/ini'; -import { loadDynamixConfigFile } from '@app/store/actions/load-dynamix-config-file'; -import { FileLoadStatus } from '@app/store/types'; -import { type RecursivePartial } from '@app/types'; +import { type DynamixConfig } from '@app/core/types/ini.js'; +import { loadDynamixConfigFile } from '@app/store/actions/load-dynamix-config-file.js'; +import { FileLoadStatus } from '@app/store/types.js'; +import { RecursivePartial } from '@app/types/index.js'; export type SliceState = { status: FileLoadStatus; diff --git a/api/src/store/modules/emhttp.ts b/api/src/store/modules/emhttp.ts index 905d5804c..35af546ba 100644 --- a/api/src/store/modules/emhttp.ts +++ b/api/src/store/modules/emhttp.ts @@ -4,20 +4,20 @@ import type { PayloadAction } from '@reduxjs/toolkit'; import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; import { merge } from 'lodash-es'; -import type { RootState } from '@app/store'; -import type { StateFileToIniParserMap } from '@app/store/types'; -import { emhttpLogger } from '@app/core/log'; -import { type Devices } from '@app/core/types/states/devices'; -import { type Networks } from '@app/core/types/states/network'; -import { type NfsShares } from '@app/core/types/states/nfs'; -import { type Nginx } from '@app/core/types/states/nginx'; -import { type Shares } from '@app/core/types/states/share'; -import { type SmbShares } from '@app/core/types/states/smb'; -import { type Users } from '@app/core/types/states/user'; -import { type Var } from '@app/core/types/states/var'; -import { parseConfig } from '@app/core/utils/misc/parse-config'; -import { type ArrayDisk } from '@app/graphql/generated/api/types'; -import { FileLoadStatus, StateFileKey } from '@app/store/types'; +import type { RootState } from '@app/store/index.js'; +import type { StateFileToIniParserMap } from '@app/store/types.js'; +import { emhttpLogger } from '@app/core/log.js'; +import { type Devices } from '@app/core/types/states/devices.js'; +import { type Networks } from '@app/core/types/states/network.js'; +import { type NfsShares } from '@app/core/types/states/nfs.js'; +import { type Nginx } from '@app/core/types/states/nginx.js'; +import { type Shares } from '@app/core/types/states/share.js'; +import { type SmbShares } from '@app/core/types/states/smb.js'; +import { type Users } from '@app/core/types/states/user.js'; +import { type Var } from '@app/core/types/states/var.js'; +import { parseConfig } from '@app/core/utils/misc/parse-config.js'; +import { type ArrayDisk } from '@app/graphql/generated/api/types.js'; +import { FileLoadStatus, StateFileKey } from '@app/store/types.js'; export type SliceState = { status: FileLoadStatus; @@ -48,15 +48,15 @@ const initialState: SliceState = { export const parsers: { [K in StateFileKey]: () => Promise; } = { - [StateFileKey.var]: async () => (await import('@app/store/state-parsers/var')).parse, - [StateFileKey.devs]: async () => (await import('@app/store/state-parsers/devices')).parse, - [StateFileKey.network]: async () => (await import('@app/store/state-parsers/network')).parse, - [StateFileKey.nginx]: async () => (await import('@app/store/state-parsers/nginx')).parse, - [StateFileKey.shares]: async () => (await import('@app/store/state-parsers/shares')).parse, - [StateFileKey.disks]: async () => (await import('@app/store/state-parsers/slots')).parse, - [StateFileKey.users]: async () => (await import('@app/store/state-parsers/users')).parse, - [StateFileKey.sec]: async () => (await import('@app/store/state-parsers/smb')).parse, - [StateFileKey.sec_nfs]: async () => (await import('@app/store/state-parsers/nfs')).parse, + [StateFileKey.var]: async () => (await import('@app/store/state-parsers/var.js')).parse, + [StateFileKey.devs]: async () => (await import('@app/store/state-parsers/devices.js')).parse, + [StateFileKey.network]: async () => (await import('@app/store/state-parsers/network.js')).parse, + [StateFileKey.nginx]: async () => (await import('@app/store/state-parsers/nginx.js')).parse, + [StateFileKey.shares]: async () => (await import('@app/store/state-parsers/shares.js')).parse, + [StateFileKey.disks]: async () => (await import('@app/store/state-parsers/slots.js')).parse, + [StateFileKey.users]: async () => (await import('@app/store/state-parsers/users.js')).parse, + [StateFileKey.sec]: async () => (await import('@app/store/state-parsers/smb.js')).parse, + [StateFileKey.sec_nfs]: async () => (await import('@app/store/state-parsers/nfs.js')).parse, }; const getParserFunction = async (parser: StateFileKey): Promise => diff --git a/api/src/store/modules/minigraph.ts b/api/src/store/modules/minigraph.ts index 3a08f112a..222f9e25d 100644 --- a/api/src/store/modules/minigraph.ts +++ b/api/src/store/modules/minigraph.ts @@ -1,11 +1,11 @@ import type { PayloadAction } from '@reduxjs/toolkit'; import { createSlice } from '@reduxjs/toolkit'; -import { KEEP_ALIVE_INTERVAL_MS } from '@app/consts'; -import { minigraphLogger } from '@app/core/log'; -import { MinigraphStatus } from '@app/graphql/generated/api/types'; -import { setGraphqlConnectionStatus } from '@app/store/actions/set-minigraph-status'; -import { loginUser, logoutUser } from '@app/store/modules/config'; +import { KEEP_ALIVE_INTERVAL_MS } from '@app/consts.js'; +import { minigraphLogger } from '@app/core/log.js'; +import { MinigraphStatus } from '@app/graphql/generated/api/types.js'; +import { setGraphqlConnectionStatus } from '@app/store/actions/set-minigraph-status.js'; +import { loginUser, logoutUser } from '@app/store/modules/config.js'; export type MinigraphClientState = { status: MinigraphStatus; diff --git a/api/src/store/modules/notifications.ts b/api/src/store/modules/notifications.ts index 09d22926c..4aeb794fe 100644 --- a/api/src/store/modules/notifications.ts +++ b/api/src/store/modules/notifications.ts @@ -1,14 +1,14 @@ import type { PayloadAction } from '@reduxjs/toolkit'; import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; -import type { Notification } from '@app/graphql/generated/api/types'; -import { logger } from '@app/core/log'; -import { pubsub, PUBSUB_CHANNEL } from '@app/core/pubsub'; -import { type NotificationIni } from '@app/core/types/states/notification'; -import { parseConfig } from '@app/core/utils/misc/parse-config'; -import { NotificationSchema } from '@app/graphql/generated/api/operations'; -import { Importance, NotificationType } from '@app/graphql/generated/api/types'; -import { type AppDispatch, type RootState } from '@app/store/index'; +import type { Notification } from '@app/graphql/generated/api/types.js'; +import { logger } from '@app/core/log.js'; +import { pubsub, PUBSUB_CHANNEL } from '@app/core/pubsub.js'; +import { type NotificationIni } from '@app/core/types/states/notification.js'; +import { parseConfig } from '@app/core/utils/misc/parse-config.js'; +import { NotificationSchema } from '@app/graphql/generated/api/operations.js'; +import { Importance, NotificationType } from '@app/graphql/generated/api/types.js'; +import { type AppDispatch, type RootState } from '@app/store/index.js'; interface NotificationState { notifications: Record; diff --git a/api/src/store/modules/registration.ts b/api/src/store/modules/registration.ts index 0e8ab46be..dff1d68fb 100644 --- a/api/src/store/modules/registration.ts +++ b/api/src/store/modules/registration.ts @@ -4,10 +4,10 @@ import type { PayloadAction } from '@reduxjs/toolkit'; import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; import { merge } from 'lodash-es'; -import type { RootState } from '@app/store'; -import { logger } from '@app/core/log'; -import { getKeyFile } from '@app/core/utils/misc/get-key-file'; -import { FileLoadStatus } from '@app/store/types'; +import type { RootState } from '@app/store/index.js'; +import { logger } from '@app/core/log.js'; +import { getKeyFile } from '@app/core/utils/misc/get-key-file.js'; +import { FileLoadStatus } from '@app/store/types.js'; export type SliceState = { status: FileLoadStatus; diff --git a/api/src/store/modules/remote-graphql.ts b/api/src/store/modules/remote-graphql.ts index 5a72ac328..e732175b1 100644 --- a/api/src/store/modules/remote-graphql.ts +++ b/api/src/store/modules/remote-graphql.ts @@ -1,12 +1,12 @@ import type { PayloadAction } from '@reduxjs/toolkit'; import { createSlice, isAnyOf } from '@reduxjs/toolkit'; -import type { SubscriptionWithLastPing } from '@app/store/types'; -import { remoteAccessLogger } from '@app/core/log'; -import { addRemoteSubscription } from '@app/store/actions/add-remote-subscription'; -import { setGraphqlConnectionStatus } from '@app/store/actions/set-minigraph-status'; -import { logoutUser } from '@app/store/modules/config'; -import { MOTHERSHIP_CRITICAL_STATUSES } from '@app/store/types'; +import type { SubscriptionWithLastPing } from '@app/store/types.js'; +import { remoteAccessLogger } from '@app/core/log.js'; +import { addRemoteSubscription } from '@app/store/actions/add-remote-subscription.js'; +import { setGraphqlConnectionStatus } from '@app/store/actions/set-minigraph-status.js'; +import { logoutUser } from '@app/store/modules/config.js'; +import { MOTHERSHIP_CRITICAL_STATUSES } from '@app/store/types.js'; interface RemoteGraphQLStore { subscriptions: Array; diff --git a/api/src/store/modules/upnp.ts b/api/src/store/modules/upnp.ts index 5925b957e..f66f65002 100644 --- a/api/src/store/modules/upnp.ts +++ b/api/src/store/modules/upnp.ts @@ -2,12 +2,17 @@ import type { PayloadAction } from '@reduxjs/toolkit'; import type { Mapping } from '@runonflux/nat-upnp'; import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; -import { upnpLogger } from '@app/core'; -import { toNumberOrNull } from '@app/core/utils/casting'; -import { type AppDispatch, type RootState } from '@app/store'; -import { setUpnpState, setWanPortToValue } from '@app/store/modules/config'; -import { getUpnpMappings, getWanPortForUpnp, removeUpnpLease, renewUpnpLease } from '@app/upnp/helpers'; -import { initUpnpJobs, stopUpnpJobs } from '@app/upnp/jobs'; +import { upnpLogger } from '@app/core/log.js'; +import { toNumberOrNull } from '@app/core/utils/casting.js'; +import { type AppDispatch, type RootState } from '@app/store/index.js'; +import { setUpnpState, setWanPortToValue } from '@app/store/modules/config.js'; +import { + getUpnpMappings, + getWanPortForUpnp, + removeUpnpLease, + renewUpnpLease, +} from '@app/upnp/helpers.js'; +import { initUpnpJobs, stopUpnpJobs } from '@app/upnp/jobs.js'; interface UpnpState { upnpEnabled: boolean; diff --git a/api/src/store/state-parsers/devices.ts b/api/src/store/state-parsers/devices.ts index 5e36835f8..d825adf63 100644 --- a/api/src/store/state-parsers/devices.ts +++ b/api/src/store/state-parsers/devices.ts @@ -1,4 +1,4 @@ -import type { StateFileToIniParserMap } from '@app/store/types'; +import type { StateFileToIniParserMap } from '@app/store/types.js'; export type DevicesIni = Array>; diff --git a/api/src/store/state-parsers/network.ts b/api/src/store/state-parsers/network.ts index 6c6906402..7efe859d1 100644 --- a/api/src/store/state-parsers/network.ts +++ b/api/src/store/state-parsers/network.ts @@ -1,8 +1,8 @@ -import type { StateFileToIniParserMap } from '@app/store/types'; -import { type CommaSeparatedString } from '@app/core/types/global'; -import { type IniStringBoolean } from '@app/core/types/ini'; -import { type Network } from '@app/core/types/states/network'; -import { toBoolean } from '@app/core/utils/casting'; +import type { StateFileToIniParserMap } from '@app/store/types.js'; +import { type CommaSeparatedString } from '@app/core/types/global.js'; +import { type IniStringBoolean } from '@app/core/types/ini.js'; +import { type Network } from '@app/core/types/states/network.js'; +import { toBoolean } from '@app/core/utils/casting.js'; export type NetworkIni = Record< string, diff --git a/api/src/store/state-parsers/nfs.ts b/api/src/store/state-parsers/nfs.ts index 9842b88fb..9f4840aaa 100644 --- a/api/src/store/state-parsers/nfs.ts +++ b/api/src/store/state-parsers/nfs.ts @@ -1,5 +1,5 @@ -import type { SecIni } from '@app/core/types/states/sec'; -import type { StateFileToIniParserMap } from '@app/store/types'; +import type { SecIni } from '@app/core/types/states/sec.js'; +import type { StateFileToIniParserMap } from '@app/store/types.js'; export type NfsSharesIni = SecIni[]; diff --git a/api/src/store/state-parsers/nginx.ts b/api/src/store/state-parsers/nginx.ts index da80bccc0..c42603852 100644 --- a/api/src/store/state-parsers/nginx.ts +++ b/api/src/store/state-parsers/nginx.ts @@ -1,6 +1,6 @@ -import type { IniStringBooleanOrAuto } from '@app/core/types/ini'; -import type { StateFileToIniParserMap } from '@app/store/types'; -import { type FqdnEntry } from '@app/core/types/states/nginx'; +import type { IniStringBooleanOrAuto } from '@app/core/types/ini.js'; +import type { StateFileToIniParserMap } from '@app/store/types.js'; +import { type FqdnEntry } from '@app/core/types/states/nginx.js'; // Allow upper or lowercase FQDN6 const fqdnRegex = /^nginx(.*?)fqdn6?$/i; @@ -16,8 +16,6 @@ export type NginxIni = { nginxPort: string; nginxPortssl: string; nginxUsessl: IniStringBooleanOrAuto; - nginxWanip: string; - nginxWanaccess: string; [nginxInterfaceFqdn: string]: string; }; diff --git a/api/src/store/state-parsers/shares.ts b/api/src/store/state-parsers/shares.ts index ab3e1316f..4dc7315aa 100644 --- a/api/src/store/state-parsers/shares.ts +++ b/api/src/store/state-parsers/shares.ts @@ -1,6 +1,6 @@ -import type { StateFileToIniParserMap } from '@app/store/types'; -import { toNumberOrNullConvert } from '@app/core/utils/casting'; -import { type Share } from '@app/graphql/generated/api/types'; +import type { StateFileToIniParserMap } from '@app/store/types.js'; +import { toNumberOrNullConvert } from '@app/core/utils/casting.js'; +import { type Share } from '@app/graphql/generated/api/types.js'; export type SharesIni = Array<{ name: string; diff --git a/api/src/store/state-parsers/slots.ts b/api/src/store/state-parsers/slots.ts index b74895912..76cd3be29 100644 --- a/api/src/store/state-parsers/slots.ts +++ b/api/src/store/state-parsers/slots.ts @@ -1,8 +1,8 @@ -import type { ArrayDisk } from '@app/graphql/generated/api/types'; -import type { StateFileToIniParserMap } from '@app/store/types'; -import { type IniEnabled, type IniNumberBoolean } from '@app/core/types/ini'; -import { toBoolean, toNumber, toNumberOrNull, toNumberOrNullConvert } from '@app/core/utils'; -import { ArrayDiskStatus, ArrayDiskType } from '@app/graphql/generated/api/types'; +import type { ArrayDisk } from '@app/graphql/generated/api/types.js'; +import type { StateFileToIniParserMap } from '@app/store/types.js'; +import { type IniEnabled, type IniNumberBoolean } from '@app/core/types/ini.js'; +import { toBoolean, toNumber, toNumberOrNull, toNumberOrNullConvert } from '@app/core/utils/index.js'; +import { ArrayDiskStatus, ArrayDiskType } from '@app/graphql/generated/api/types.js'; type SlotStatus = 'DISK_OK'; type SlotFsStatus = 'Mounted'; diff --git a/api/src/store/state-parsers/smb.ts b/api/src/store/state-parsers/smb.ts index b6f86f63a..0d3955dd0 100644 --- a/api/src/store/state-parsers/smb.ts +++ b/api/src/store/state-parsers/smb.ts @@ -1,6 +1,6 @@ -import type { StateFileToIniParserMap } from '@app/store/types'; -import { type SecIni } from '@app/core/types/states/sec'; -import { type SmbSecurity, type SmbShares } from '@app/core/types/states/smb'; +import type { StateFileToIniParserMap } from '@app/store/types.js'; +import { type SecIni } from '@app/core/types/states/sec.js'; +import { type SmbSecurity, type SmbShares } from '@app/core/types/states/smb.js'; export interface IniSmbShare extends SecIni { /** diff --git a/api/src/store/state-parsers/users.ts b/api/src/store/state-parsers/users.ts index f42f2cd30..8be29015d 100644 --- a/api/src/store/state-parsers/users.ts +++ b/api/src/store/state-parsers/users.ts @@ -1,5 +1,5 @@ -import type { StateFileToIniParserMap } from '@app/store/types'; -import { type User } from '@app/core/types/states/user'; +import type { StateFileToIniParserMap } from '@app/store/types.js'; +import { type User } from '@app/core/types/states/user.js'; type BooleanString = 'yes' | 'no'; diff --git a/api/src/store/state-parsers/var.ts b/api/src/store/state-parsers/var.ts index ec6f41f63..86878b80d 100644 --- a/api/src/store/state-parsers/var.ts +++ b/api/src/store/state-parsers/var.ts @@ -1,8 +1,12 @@ -import type { DiskFsType } from '@app/graphql/generated/api/types'; -import type { StateFileToIniParserMap } from '@app/store/types'; -import { type IniStringBoolean, type IniStringBooleanOrAuto } from '@app/core/types/ini'; -import { toNumber } from '@app/core/utils'; -import { ArrayState, RegistrationState, registrationType } from '@app/graphql/generated/api/types'; +import type { StateFileToIniParserMap } from '@app/store/types.js'; +import { type IniStringBoolean, type IniStringBooleanOrAuto } from '@app/core/types/ini.js'; +import { toNumber } from '@app/core/utils/index.js'; +import { + ArrayState, + DiskFsType, + RegistrationState, + registrationType, +} from '@app/graphql/generated/api/types.js'; /** * Unraid registration check @@ -22,7 +26,7 @@ export type VarIni = { configState: string; csrfToken: string; defaultFormat: string; - defaultFsType: DiskFsType; + defaultFsType: string; deviceCount: string; domain: string; domainLogin: string; @@ -199,6 +203,7 @@ const safeParseMdState = (mdState: string | undefined): ArrayState => { export const parse: StateFileToIniParserMap['var'] = (iniFile) => { return { ...iniFile, + defaultFsType: DiskFsType[iniFile.defaultFsType] || DiskFsType.XFS, mdState: safeParseMdState(iniFile.mdState), bindMgt: iniBooleanOrAutoToJsBoolean(iniFile.bindMgt), cacheNumDevices: toNumber(iniFile.cacheNumDevices), diff --git a/api/src/store/store-sync.ts b/api/src/store/store-sync.ts index d0ca9d8f8..45dad597e 100644 --- a/api/src/store/store-sync.ts +++ b/api/src/store/store-sync.ts @@ -3,13 +3,13 @@ import { join } from 'path'; import { isEqual } from 'lodash-es'; -import type { RootState } from '@app/store'; -import { NODE_ENV } from '@app/environment'; -import { store } from '@app/store'; -import { syncInfoApps } from '@app/store/sync/info-apps-sync'; -import { syncRegistration } from '@app/store/sync/registration-sync'; -import { FileLoadStatus } from '@app/store/types'; -import { setupConfigPathWatch } from '@app/store/watch/config-watch'; +import type { RootState } from '@app/store/index.js'; +import { NODE_ENV } from '@app/environment.js'; +import { store } from '@app/store/index.js'; +import { syncInfoApps } from '@app/store/sync/info-apps-sync.js'; +import { syncRegistration } from '@app/store/sync/registration-sync.js'; +import { FileLoadStatus } from '@app/store/types.js'; +import { setupConfigPathWatch } from '@app/store/watch/config-watch.js'; export const startStoreSync = async () => { // The last state is stored so we don't end up in a loop of writing -> reading -> writing diff --git a/api/src/store/sync/config-disk-sync.ts b/api/src/store/sync/config-disk-sync.ts index c7cbcc94b..9a9ba7bce 100644 --- a/api/src/store/sync/config-disk-sync.ts +++ b/api/src/store/sync/config-disk-sync.ts @@ -1,11 +1,11 @@ import { writeFileSync } from 'fs'; -import type { ConfigType } from '@app/core/utils/files/config-file-normalizer'; -import { logger } from '@app/core/log'; -import { getWriteableConfig } from '@app/core/utils/files/config-file-normalizer'; -import { safelySerializeObjectToIni } from '@app/core/utils/files/safe-ini-serializer'; -import { store } from '@app/store'; -import { FileLoadStatus } from '@app/store/types'; +import type { ConfigType } from '@app/core/utils/files/config-file-normalizer.js'; +import { logger } from '@app/core/log.js'; +import { getWriteableConfig } from '@app/core/utils/files/config-file-normalizer.js'; +import { safelySerializeObjectToIni } from '@app/core/utils/files/safe-ini-serializer.js'; +import { store } from '@app/store/index.js'; +import { FileLoadStatus } from '@app/store/types.js'; export const writeConfigSync = (mode: ConfigType) => { const { config, paths } = store.getState(); diff --git a/api/src/store/sync/info-apps-sync.ts b/api/src/store/sync/info-apps-sync.ts index fcf4973c6..6746190ab 100644 --- a/api/src/store/sync/info-apps-sync.ts +++ b/api/src/store/sync/info-apps-sync.ts @@ -1,10 +1,10 @@ import { isEqual } from 'lodash-es'; -import type { StoreSubscriptionHandler } from '@app/store/types'; -import { logger } from '@app/core/log'; -import { pubsub, PUBSUB_CHANNEL } from '@app/core/pubsub'; -import { store } from '@app/store'; -import { DaemonConnectionStatus } from '@app/store/types'; +import type { StoreSubscriptionHandler } from '@app/store/types.js'; +import { logger } from '@app/core/log.js'; +import { pubsub, PUBSUB_CHANNEL } from '@app/core/pubsub.js'; +import { store } from '@app/store/index.js'; +import { DaemonConnectionStatus } from '@app/store/types.js'; type InfoAppsEvent = { info: { diff --git a/api/src/store/sync/registration-sync.ts b/api/src/store/sync/registration-sync.ts index 127abf5b8..1dc9c7df7 100644 --- a/api/src/store/sync/registration-sync.ts +++ b/api/src/store/sync/registration-sync.ts @@ -1,10 +1,10 @@ import { isEqual } from 'lodash-es'; -import type { StoreSubscriptionHandler } from '@app/store/types'; -import { logger } from '@app/core/log'; -import { pubsub, PUBSUB_CHANNEL } from '@app/core/pubsub'; -import { store } from '@app/store'; -import { FileLoadStatus } from '@app/store/types'; +import type { StoreSubscriptionHandler } from '@app/store/types.js'; +import { logger } from '@app/core/log.js'; +import { pubsub, PUBSUB_CHANNEL } from '@app/core/pubsub.js'; +import { store } from '@app/store/index.js'; +import { FileLoadStatus } from '@app/store/types.js'; export type RegistrationEvent = { registration: { diff --git a/api/src/store/types.ts b/api/src/store/types.ts index b687b5c41..a2e9df0e7 100644 --- a/api/src/store/types.ts +++ b/api/src/store/types.ts @@ -1,24 +1,24 @@ -import { type Subscription } from 'zen-observable-ts'; +import type { Subscription } from 'zen-observable-ts'; -import type { ArrayDisk, Share } from '@app/graphql/generated/api/types'; -import type { RootState } from '@app/store'; -import { type Devices } from '@app/core/types/states/devices'; -import { type Networks } from '@app/core/types/states/network'; -import { type NfsShares } from '@app/core/types/states/nfs'; -import { type Nginx } from '@app/core/types/states/nginx'; -import { type SmbShares } from '@app/core/types/states/smb'; -import { type Users } from '@app/core/types/states/user'; -import { type Var } from '@app/core/types/states/var'; -import { MinigraphStatus } from '@app/graphql/generated/api/types'; -import { type DevicesIni } from '@app/store/state-parsers/devices'; -import { type NetworkIni } from '@app/store/state-parsers/network'; -import { type NfsSharesIni } from '@app/store/state-parsers/nfs'; -import { type NginxIni } from '@app/store/state-parsers/nginx'; -import { type SharesIni } from '@app/store/state-parsers/shares'; -import { type SlotsIni } from '@app/store/state-parsers/slots'; -import { type SmbIni } from '@app/store/state-parsers/smb'; -import { type UsersIni } from '@app/store/state-parsers/users'; -import { type VarIni } from '@app/store/state-parsers/var'; +import type { ArrayDisk, Share } from '@app/graphql/generated/api/types.js'; +import type { RootState } from '@app/store/index.js'; +import { type Devices } from '@app/core/types/states/devices.js'; +import { type Networks } from '@app/core/types/states/network.js'; +import { type NfsShares } from '@app/core/types/states/nfs.js'; +import { type Nginx } from '@app/core/types/states/nginx.js'; +import { type SmbShares } from '@app/core/types/states/smb.js'; +import { type Users } from '@app/core/types/states/user.js'; +import { type Var } from '@app/core/types/states/var.js'; +import { MinigraphStatus } from '@app/graphql/generated/api/types.js'; +import { type DevicesIni } from '@app/store/state-parsers/devices.js'; +import { type NetworkIni } from '@app/store/state-parsers/network.js'; +import { type NfsSharesIni } from '@app/store/state-parsers/nfs.js'; +import { type NginxIni } from '@app/store/state-parsers/nginx.js'; +import { type SharesIni } from '@app/store/state-parsers/shares.js'; +import { type SlotsIni } from '@app/store/state-parsers/slots.js'; +import { type SmbIni } from '@app/store/state-parsers/smb.js'; +import { type UsersIni } from '@app/store/state-parsers/users.js'; +import { type VarIni } from '@app/store/state-parsers/var.js'; export enum FileLoadStatus { UNLOADED = 'UNLOADED', diff --git a/api/src/store/watch/config-watch.ts b/api/src/store/watch/config-watch.ts index efd4cbc90..fc6a80a05 100644 --- a/api/src/store/watch/config-watch.ts +++ b/api/src/store/watch/config-watch.ts @@ -2,12 +2,12 @@ import { existsSync, writeFileSync } from 'fs'; import { watch } from 'chokidar'; -import { logger } from '@app/core/log'; -import { getWriteableConfig } from '@app/core/utils/files/config-file-normalizer'; -import { safelySerializeObjectToIni } from '@app/core/utils/files/safe-ini-serializer'; -import { CHOKIDAR_USEPOLLING, ENVIRONMENT } from '@app/environment'; -import { getters, store } from '@app/store'; -import { initialState, loadConfigFile, logoutUser } from '@app/store/modules/config'; +import { logger } from '@app/core/log.js'; +import { getWriteableConfig } from '@app/core/utils/files/config-file-normalizer.js'; +import { safelySerializeObjectToIni } from '@app/core/utils/files/safe-ini-serializer.js'; +import { CHOKIDAR_USEPOLLING, ENVIRONMENT } from '@app/environment.js'; +import { getters, store } from '@app/store/index.js'; +import { initialState, loadConfigFile, logoutUser } from '@app/store/modules/config.js'; export const setupConfigPathWatch = () => { const myServersConfigPath = getters.paths()?.['myservers-config']; diff --git a/api/src/store/watch/docker-watch.ts b/api/src/store/watch/docker-watch.ts index feb8a368c..4eccfa67b 100644 --- a/api/src/store/watch/docker-watch.ts +++ b/api/src/store/watch/docker-watch.ts @@ -1,14 +1,16 @@ import DockerEE from 'docker-event-emitter'; import { debounce } from 'lodash-es'; -import { dockerLogger } from '@app/core/log'; -import { docker } from '@app/core/utils/index'; -import { store } from '@app/store'; -import { updateDockerState } from '@app/store/modules/docker'; +import { dockerLogger } from '@app/core/log.js'; +import { docker } from '@app/core/utils/clients/docker.js'; +import { store } from '@app/store/index.js'; +import { updateDockerState } from '@app/store/modules/docker.js'; const updateContainerCache = async () => { try { - const { getDockerContainers } = await import('@app/core/modules/docker'); + const { getDockerContainers } = await import( + '@app/core/modules/docker/get-docker-containers.js' + ); await getDockerContainers({ useCache: false }); } catch (err) { dockerLogger.warn('Caught error getting containers %o', err); diff --git a/api/src/store/watch/dynamix-config-watch.ts b/api/src/store/watch/dynamix-config-watch.ts index 3bf0f3490..4c3062182 100644 --- a/api/src/store/watch/dynamix-config-watch.ts +++ b/api/src/store/watch/dynamix-config-watch.ts @@ -1,7 +1,7 @@ import { watch } from 'chokidar'; -import { getters, store } from '@app/store'; -import { loadDynamixConfigFile } from '@app/store/actions/load-dynamix-config-file'; +import { loadDynamixConfigFile } from '@app/store/actions/load-dynamix-config-file.js'; +import { getters, store } from '@app/store/index.js'; export const setupDynamixConfigWatch = () => { const configPath = getters.paths()?.['dynamix-config']; diff --git a/api/src/store/watch/registration-watch.ts b/api/src/store/watch/registration-watch.ts index 6daa35d65..da63a03d2 100644 --- a/api/src/store/watch/registration-watch.ts +++ b/api/src/store/watch/registration-watch.ts @@ -1,8 +1,8 @@ import { watch } from 'chokidar'; -import { CHOKIDAR_USEPOLLING } from '@app/environment'; -import { store } from '@app/store'; -import { loadRegistrationKey } from '@app/store/modules/registration'; +import { CHOKIDAR_USEPOLLING } from '@app/environment.js'; +import { store } from '@app/store/index.js'; +import { loadRegistrationKey } from '@app/store/modules/registration.js'; export const setupRegistrationKeyWatch = () => { watch('/boot/config', { diff --git a/api/src/store/watch/state-watch.ts b/api/src/store/watch/state-watch.ts index d7d9b8622..e92909c61 100644 --- a/api/src/store/watch/state-watch.ts +++ b/api/src/store/watch/state-watch.ts @@ -1,18 +1,20 @@ import { join, parse } from 'path'; -import type { FSWatcher, WatchOptions } from 'chokidar'; +import type { FSWatcher, FSWInstanceOptions } from 'chokidar'; import { watch } from 'chokidar'; -import { emhttpLogger } from '@app/core/log'; -import { CHOKIDAR_USEPOLLING } from '@app/environment'; -import { getters, store } from '@app/store'; -import { loadSingleStateFile } from '@app/store/modules/emhttp'; -import { StateFileKey } from '@app/store/types'; +import { emhttpLogger } from '@app/core/log.js'; +import { CHOKIDAR_USEPOLLING } from '@app/environment.js'; +import { getters, store } from '@app/store/index.js'; +import { loadSingleStateFile } from '@app/store/modules/emhttp.js'; +import { StateFileKey } from '@app/store/types.js'; // Configure any excluded nchan channels that we support here const excludedWatches: StateFileKey[] = [StateFileKey.devs]; -const chokidarOptionsForStateKey = (key: StateFileKey): WatchOptions => { +const chokidarOptionsForStateKey = ( + key: StateFileKey +): Partial> => { if ([StateFileKey.disks, StateFileKey.shares].includes(key)) { return { usePolling: true, diff --git a/api/src/store/watch/var-run-watch.ts b/api/src/store/watch/var-run-watch.ts index 86cc0dcda..d1bfb8abd 100644 --- a/api/src/store/watch/var-run-watch.ts +++ b/api/src/store/watch/var-run-watch.ts @@ -1,10 +1,10 @@ import type DockerEE from 'docker-event-emitter'; import { watch } from 'chokidar'; -import { dockerLogger } from '@app/core/log'; -import { getters, store } from '@app/store/index'; -import { updateDockerState } from '@app/store/modules/docker'; -import { setupDockerWatch } from '@app/store/watch/docker-watch'; +import { dockerLogger } from '@app/core/log.js'; +import { getters, store } from '@app/store/index.js'; +import { updateDockerState } from '@app/store/modules/docker.js'; +import { setupDockerWatch } from '@app/store/watch/docker-watch.js'; export const setupVarRunWatch = () => { const paths = getters.paths(); diff --git a/api/src/types/my-servers-config.ts b/api/src/types/my-servers-config.ts index 04b5d453e..0bff49aad 100644 --- a/api/src/types/my-servers-config.ts +++ b/api/src/types/my-servers-config.ts @@ -1,6 +1,6 @@ import { z } from 'zod'; -import { DynamicRemoteAccessType, MinigraphStatus } from '@app/graphql/generated/api/types'; +import { DynamicRemoteAccessType, MinigraphStatus } from '@app/graphql/generated/api/types.js'; // Define Zod schemas const ApiConfigSchema = z.object({ diff --git a/api/src/unraid-api/app/app.module.ts b/api/src/unraid-api/app/app.module.ts index 0b2a140e3..89f14a011 100644 --- a/api/src/unraid-api/app/app.module.ts +++ b/api/src/unraid-api/app/app.module.ts @@ -5,14 +5,14 @@ import { ThrottlerModule } from '@nestjs/throttler'; import { AuthZGuard } from 'nest-authz'; import { LoggerModule } from 'nestjs-pino'; -import { apiLogger } from '@app/core/log'; -import { LOG_LEVEL } from '@app/environment'; -import { GraphqlAuthGuard } from '@app/unraid-api/auth/auth.guard'; -import { AuthModule } from '@app/unraid-api/auth/auth.module'; -import { CronModule } from '@app/unraid-api/cron/cron.module'; -import { GraphModule } from '@app/unraid-api/graph/graph.module'; -import { RestModule } from '@app/unraid-api/rest/rest.module'; -import { UnraidFileModifierModule } from '@app/unraid-api/unraid-file-modifier/unraid-file-modifier.module'; +import { apiLogger } from '@app/core/log.js'; +import { LOG_LEVEL } from '@app/environment.js'; +import { GraphqlAuthGuard } from '@app/unraid-api/auth/auth.guard.js'; +import { AuthModule } from '@app/unraid-api/auth/auth.module.js'; +import { CronModule } from '@app/unraid-api/cron/cron.module.js'; +import { GraphModule } from '@app/unraid-api/graph/graph.module.js'; +import { RestModule } from '@app/unraid-api/rest/rest.module.js'; +import { UnraidFileModifierModule } from '@app/unraid-api/unraid-file-modifier/unraid-file-modifier.module.js'; @Module({ imports: [ diff --git a/api/src/unraid-api/app/cors.ts b/api/src/unraid-api/app/cors.ts index 5ea022378..1cbd61399 100644 --- a/api/src/unraid-api/app/cors.ts +++ b/api/src/unraid-api/app/cors.ts @@ -1,12 +1,12 @@ -import { type CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface'; +import { type CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface.js'; import { GraphQLError } from 'graphql'; -import { getAllowedOrigins } from '@app/common/allowed-origins'; -import { apiLogger } from '@app/core/log'; -import { BYPASS_CORS_CHECKS } from '@app/environment'; -import { FastifyRequest } from '@app/types/fastify'; -import { type CookieService } from '@app/unraid-api/auth/cookie.service'; +import { getAllowedOrigins } from '@app/common/allowed-origins.js'; +import { apiLogger } from '@app/core/log.js'; +import { BYPASS_CORS_CHECKS } from '@app/environment.js'; +import { FastifyRequest } from '@app/types/fastify.js'; +import { type CookieService } from '@app/unraid-api/auth/cookie.service.js'; /** * Returns whether the origin is allowed to access the API. diff --git a/api/src/unraid-api/auth/api-key.service.spec.ts b/api/src/unraid-api/auth/api-key.service.spec.ts index 46dbc1e1a..1ce6186e0 100644 --- a/api/src/unraid-api/auth/api-key.service.spec.ts +++ b/api/src/unraid-api/auth/api-key.service.spec.ts @@ -6,17 +6,17 @@ import { ensureDir, ensureDirSync } from 'fs-extra'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { ZodError } from 'zod'; -import type { ApiKey, ApiKeyWithSecret } from '@app/graphql/generated/api/types'; -import { environment } from '@app/environment'; -import { ApiKeySchema, ApiKeyWithSecretSchema } from '@app/graphql/generated/api/operations'; -import { Resource, Role } from '@app/graphql/generated/api/types'; -import { getters, store } from '@app/store'; -import { updateUserConfig } from '@app/store/modules/config'; -import { FileLoadStatus } from '@app/store/types'; -import { ApiKeyService } from '@app/unraid-api/auth/api-key.service'; +import type { ApiKey, ApiKeyWithSecret } from '@app/graphql/generated/api/types.js'; +import { environment } from '@app/environment.js'; +import { ApiKeySchema, ApiKeyWithSecretSchema } from '@app/graphql/generated/api/operations.js'; +import { Resource, Role } from '@app/graphql/generated/api/types.js'; +import { getters, store } from '@app/store/index.js'; +import { updateUserConfig } from '@app/store/modules/config.js'; +import { FileLoadStatus } from '@app/store/types.js'; +import { ApiKeyService } from '@app/unraid-api/auth/api-key.service.js'; // Mock the store and its modules -vi.mock('@app/store', () => ({ +vi.mock('@app/store/index.js', () => ({ getters: { config: vi.fn(), paths: vi.fn(), @@ -27,10 +27,14 @@ vi.mock('@app/store', () => ({ }, })); -vi.mock('@app/store/modules/config', () => ({ - updateUserConfig: vi.fn(), - setLocalApiKey: vi.fn(), -})); +vi.mock('@app/store/modules/config.js', async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + updateUserConfig: vi.fn(), + setLocalApiKey: vi.fn(), + }; +}); // Mock fs/promises vi.mock('fs/promises', async () => ({ @@ -39,7 +43,7 @@ vi.mock('fs/promises', async () => ({ writeFile: vi.fn(), })); -vi.mock('@app/graphql/generated/api/operations', () => ({ +vi.mock('@app/graphql/generated/api/operations.js', () => ({ ApiKeyWithSecretSchema: vi.fn(), ApiKeySchema: vi.fn(), })); diff --git a/api/src/unraid-api/auth/api-key.service.ts b/api/src/unraid-api/auth/api-key.service.ts index 2367b7a56..ecd46b6e3 100644 --- a/api/src/unraid-api/auth/api-key.service.ts +++ b/api/src/unraid-api/auth/api-key.service.ts @@ -10,8 +10,8 @@ import { AuthActionVerb } from 'nest-authz'; import { v4 as uuidv4 } from 'uuid'; import { ZodError } from 'zod'; -import { environment } from '@app/environment'; -import { ApiKeySchema, ApiKeyWithSecretSchema } from '@app/graphql/generated/api/operations'; +import { environment } from '@app/environment.js'; +import { ApiKeySchema, ApiKeyWithSecretSchema } from '@app/graphql/generated/api/operations.js'; import { AddPermissionInput, ApiKey, @@ -19,10 +19,10 @@ import { Permission, Resource, Role, -} from '@app/graphql/generated/api/types'; -import { getters, store } from '@app/store'; -import { setLocalApiKey } from '@app/store/modules/config'; -import { FileLoadStatus } from '@app/store/types'; +} from '@app/graphql/generated/api/types.js'; +import { getters, store } from '@app/store/index.js'; +import { setLocalApiKey } from '@app/store/modules/config.js'; +import { FileLoadStatus } from '@app/store/types.js'; @Injectable() export class ApiKeyService implements OnModuleInit { diff --git a/api/src/unraid-api/auth/auth.guard.ts b/api/src/unraid-api/auth/auth.guard.ts index 1db228b3e..b73bbe942 100644 --- a/api/src/unraid-api/auth/auth.guard.ts +++ b/api/src/unraid-api/auth/auth.guard.ts @@ -5,13 +5,13 @@ import { GqlExecutionContext } from '@nestjs/graphql'; import { AuthGuard } from '@nestjs/passport'; import type { IncomingMessage } from 'http'; +import type { Observable } from 'rxjs'; import { parse as parseCookies } from 'cookie'; -import { type Observable } from 'rxjs'; -import type { FastifyRequest } from '@app/types/fastify'; -import { apiLogger } from '@app/core/log'; -import { UserCookieStrategy } from '@app/unraid-api/auth/cookie.strategy'; -import { ServerHeaderStrategy } from '@app/unraid-api/auth/header.strategy'; +import type { FastifyRequest } from '@app/types/fastify.js'; +import { apiLogger } from '@app/core/log.js'; +import { UserCookieStrategy } from '@app/unraid-api/auth/cookie.strategy.js'; +import { ServerHeaderStrategy } from '@app/unraid-api/auth/header.strategy.js'; /** * Context of incoming requests. diff --git a/api/src/unraid-api/auth/auth.module.ts b/api/src/unraid-api/auth/auth.module.ts index 59bf1b851..bc05527af 100644 --- a/api/src/unraid-api/auth/auth.module.ts +++ b/api/src/unraid-api/auth/auth.module.ts @@ -3,15 +3,15 @@ import { PassportModule } from '@nestjs/passport'; import { AUTHZ_ENFORCER, AuthZModule } from 'nest-authz'; -import { ApiKeyService } from '@app/unraid-api/auth/api-key.service'; -import { AuthService } from '@app/unraid-api/auth/auth.service'; -import { BASE_POLICY, CASBIN_MODEL } from '@app/unraid-api/auth/casbin'; -import { CasbinModule } from '@app/unraid-api/auth/casbin/casbin.module'; -import { CasbinService } from '@app/unraid-api/auth/casbin/casbin.service'; -import { CookieService, SESSION_COOKIE_CONFIG } from '@app/unraid-api/auth/cookie.service'; -import { UserCookieStrategy } from '@app/unraid-api/auth/cookie.strategy'; -import { ServerHeaderStrategy } from '@app/unraid-api/auth/header.strategy'; -import { getRequest } from '@app/utils'; +import { ApiKeyService } from '@app/unraid-api/auth/api-key.service.js'; +import { AuthService } from '@app/unraid-api/auth/auth.service.js'; +import { CasbinModule } from '@app/unraid-api/auth/casbin/casbin.module.js'; +import { CasbinService } from '@app/unraid-api/auth/casbin/casbin.service.js'; +import { BASE_POLICY, CASBIN_MODEL } from '@app/unraid-api/auth/casbin/index.js'; +import { CookieService, SESSION_COOKIE_CONFIG } from '@app/unraid-api/auth/cookie.service.js'; +import { UserCookieStrategy } from '@app/unraid-api/auth/cookie.strategy.js'; +import { ServerHeaderStrategy } from '@app/unraid-api/auth/header.strategy.js'; +import { getRequest } from '@app/utils.js'; @Module({ imports: [ diff --git a/api/src/unraid-api/auth/auth.service.spec.ts b/api/src/unraid-api/auth/auth.service.spec.ts index 0266ab229..de2549884 100644 --- a/api/src/unraid-api/auth/auth.service.spec.ts +++ b/api/src/unraid-api/auth/auth.service.spec.ts @@ -4,11 +4,11 @@ import { newEnforcer } from 'casbin'; import { AuthZService } from 'nest-authz'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import type { ApiKey, ApiKeyWithSecret, UserAccount } from '@app/graphql/generated/api/types'; -import { Resource, Role } from '@app/graphql/generated/api/types'; -import { ApiKeyService } from '@app/unraid-api/auth/api-key.service'; -import { AuthService } from '@app/unraid-api/auth/auth.service'; -import { CookieService } from '@app/unraid-api/auth/cookie.service'; +import type { ApiKey, ApiKeyWithSecret, UserAccount } from '@app/graphql/generated/api/types.js'; +import { Resource, Role } from '@app/graphql/generated/api/types.js'; +import { ApiKeyService } from '@app/unraid-api/auth/api-key.service.js'; +import { AuthService } from '@app/unraid-api/auth/auth.service.js'; +import { CookieService } from '@app/unraid-api/auth/cookie.service.js'; describe('AuthService', () => { let authService: AuthService; @@ -80,7 +80,7 @@ describe('AuthService', () => { it('should throw UnauthorizedException when session user is missing', async () => { vi.spyOn(cookieService, 'hasValidAuthCookie').mockResolvedValue(true); - vi.spyOn(authService, 'getSessionUser').mockResolvedValue(null); + vi.spyOn(authService, 'getSessionUser').mockResolvedValue(null as unknown as UserAccount); await expect(authService.validateCookiesCasbin({})).rejects.toThrow(UnauthorizedException); }); diff --git a/api/src/unraid-api/auth/auth.service.ts b/api/src/unraid-api/auth/auth.service.ts index 9e81d2954..3a90c6f14 100644 --- a/api/src/unraid-api/auth/auth.service.ts +++ b/api/src/unraid-api/auth/auth.service.ts @@ -2,12 +2,12 @@ import { Injectable, Logger, UnauthorizedException } from '@nestjs/common'; import { AuthZService } from 'nest-authz'; -import type { Permission, UserAccount } from '@app/graphql/generated/api/types'; -import { Role } from '@app/graphql/generated/api/types'; -import { getters } from '@app/store'; -import { ApiKeyService } from '@app/unraid-api/auth/api-key.service'; -import { CookieService } from '@app/unraid-api/auth/cookie.service'; -import { batchProcess, handleAuthError } from '@app/utils'; +import type { Permission, UserAccount } from '@app/graphql/generated/api/types.js'; +import { Role } from '@app/graphql/generated/api/types.js'; +import { getters } from '@app/store/index.js'; +import { ApiKeyService } from '@app/unraid-api/auth/api-key.service.js'; +import { CookieService } from '@app/unraid-api/auth/cookie.service.js'; +import { batchProcess, handleAuthError } from '@app/utils.js'; @Injectable() export class AuthService { diff --git a/api/src/unraid-api/auth/casbin/casbin.module.ts b/api/src/unraid-api/auth/casbin/casbin.module.ts index a04f4d022..f9c818464 100644 --- a/api/src/unraid-api/auth/casbin/casbin.module.ts +++ b/api/src/unraid-api/auth/casbin/casbin.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; -import { CasbinService } from '@app/unraid-api/auth/casbin/casbin.service'; +import { CasbinService } from '@app/unraid-api/auth/casbin/casbin.service.js'; @Module({ providers: [CasbinService], diff --git a/api/src/unraid-api/auth/casbin/casbin.service.ts b/api/src/unraid-api/auth/casbin/casbin.service.ts index 895559f8e..632d0ff8f 100644 --- a/api/src/unraid-api/auth/casbin/casbin.service.ts +++ b/api/src/unraid-api/auth/casbin/casbin.service.ts @@ -2,7 +2,7 @@ import { Injectable, InternalServerErrorException, Logger, OnModuleInit } from ' import { Model as CasbinModel, Enforcer, newEnforcer, StringAdapter } from 'casbin'; -import { LOG_LEVEL } from '@app/environment'; +import { LOG_LEVEL } from '@app/environment.js'; @Injectable() export class CasbinService { diff --git a/api/src/unraid-api/auth/casbin/index.ts b/api/src/unraid-api/auth/casbin/index.ts index 4a74aafe5..133d81d6d 100644 --- a/api/src/unraid-api/auth/casbin/index.ts +++ b/api/src/unraid-api/auth/casbin/index.ts @@ -1,2 +1,2 @@ -export * from './model'; -export * from './policy'; +export * from './model.js'; +export * from './policy.js'; diff --git a/api/src/unraid-api/auth/casbin/policy.ts b/api/src/unraid-api/auth/casbin/policy.ts index d2a0e6c77..88635f1fd 100644 --- a/api/src/unraid-api/auth/casbin/policy.ts +++ b/api/src/unraid-api/auth/casbin/policy.ts @@ -1,6 +1,6 @@ import { AuthAction } from 'nest-authz'; -import { Resource, Role } from '@app/graphql/generated/api/types'; +import { Resource, Role } from '@app/graphql/generated/api/types.js'; export const BASE_POLICY = ` # Admin permissions diff --git a/api/src/unraid-api/auth/cookie.service.spec.ts b/api/src/unraid-api/auth/cookie.service.spec.ts index 1998bdabd..40f00775d 100644 --- a/api/src/unraid-api/auth/cookie.service.spec.ts +++ b/api/src/unraid-api/auth/cookie.service.spec.ts @@ -5,7 +5,7 @@ import { writeFile } from 'node:fs/promises'; import { emptyDir } from 'fs-extra'; import { afterAll, beforeAll, describe, it } from 'vitest'; -import { CookieService, SESSION_COOKIE_CONFIG } from '@app/unraid-api/auth/cookie.service'; +import { CookieService, SESSION_COOKIE_CONFIG } from '@app/unraid-api/auth/cookie.service.js'; describe.concurrent('CookieService', () => { let service: CookieService; diff --git a/api/src/unraid-api/auth/cookie.service.ts b/api/src/unraid-api/auth/cookie.service.ts index e525d6cf8..12104b799 100644 --- a/api/src/unraid-api/auth/cookie.service.ts +++ b/api/src/unraid-api/auth/cookie.service.ts @@ -2,9 +2,9 @@ import { Inject, Injectable, Logger } from '@nestjs/common'; import { readFile } from 'fs/promises'; import { join } from 'path'; -import { fileExists } from '@app/core/utils/files/file-exists'; -import { getters } from '@app/store'; -import { batchProcess } from '@app/utils'; +import { fileExists } from '@app/core/utils/files/file-exists.js'; +import { getters } from '@app/store/index.js'; +import { batchProcess } from '@app/utils.js'; /** token for dependency injection of a session cookie options object */ export const SESSION_COOKIE_CONFIG = 'SESSION_COOKIE_CONFIG'; diff --git a/api/src/unraid-api/auth/cookie.strategy.ts b/api/src/unraid-api/auth/cookie.strategy.ts index e7db7790b..1343866c9 100644 --- a/api/src/unraid-api/auth/cookie.strategy.ts +++ b/api/src/unraid-api/auth/cookie.strategy.ts @@ -3,8 +3,8 @@ import { PassportStrategy } from '@nestjs/passport'; import { Strategy } from 'passport-custom'; -import type { CustomRequest } from '@app/unraid-api/types/request'; -import { AuthService } from '@app/unraid-api/auth/auth.service'; +import type { CustomRequest } from '@app/unraid-api/types/request.js'; +import { AuthService } from '@app/unraid-api/auth/auth.service.js'; const strategyName = 'user-cookie'; diff --git a/api/src/unraid-api/auth/header.strategy.ts b/api/src/unraid-api/auth/header.strategy.ts index 12bfd3aea..8b991e7c6 100644 --- a/api/src/unraid-api/auth/header.strategy.ts +++ b/api/src/unraid-api/auth/header.strategy.ts @@ -3,8 +3,8 @@ import { PassportStrategy } from '@nestjs/passport'; import { Strategy } from 'passport-http-header-strategy'; -import { User } from '@app/graphql/generated/api/types'; -import { AuthService } from '@app/unraid-api/auth/auth.service'; +import { User } from '@app/graphql/generated/api/types.js'; +import { AuthService } from '@app/unraid-api/auth/auth.service.js'; @Injectable() export class ServerHeaderStrategy extends PassportStrategy(Strategy, 'server-http-header') { diff --git a/api/src/unraid-api/auth/user.decorator.ts b/api/src/unraid-api/auth/user.decorator.ts index 6a090682d..791d62f90 100644 --- a/api/src/unraid-api/auth/user.decorator.ts +++ b/api/src/unraid-api/auth/user.decorator.ts @@ -1,8 +1,8 @@ import { createParamDecorator, ExecutionContext } from '@nestjs/common'; import { GqlContextType, GqlExecutionContext } from '@nestjs/graphql'; -import { UserSchema } from '@app/graphql/generated/api/operations'; -import { UserAccount } from '@app/graphql/generated/api/types'; +import { UserSchema } from '@app/graphql/generated/api/operations.js'; +import { UserAccount } from '@app/graphql/generated/api/types.js'; export const GraphqlUser = createParamDecorator( (data: null, context: ExecutionContext): UserAccount => { diff --git a/api/src/unraid-api/cli/apikey/add-api-key.questions.ts b/api/src/unraid-api/cli/apikey/add-api-key.questions.ts index c00c6fea1..34eaf0640 100644 --- a/api/src/unraid-api/cli/apikey/add-api-key.questions.ts +++ b/api/src/unraid-api/cli/apikey/add-api-key.questions.ts @@ -1,8 +1,8 @@ import { ChoicesFor, Question, QuestionSet, WhenFor } from 'nest-commander'; -import { Permission, Role } from '@app/graphql/generated/api/types'; -import { ApiKeyService } from '@app/unraid-api/auth/api-key.service'; -import { LogService } from '@app/unraid-api/cli/log.service'; +import { Permission, Role } from '@app/graphql/generated/api/types.js'; +import { ApiKeyService } from '@app/unraid-api/auth/api-key.service.js'; +import { LogService } from '@app/unraid-api/cli/log.service.js'; @QuestionSet({ name: 'add-api-key' }) export class AddApiKeyQuestionSet { diff --git a/api/src/unraid-api/cli/apikey/api-key.command.ts b/api/src/unraid-api/cli/apikey/api-key.command.ts index 1b9f4e109..acf4b0ebf 100644 --- a/api/src/unraid-api/cli/apikey/api-key.command.ts +++ b/api/src/unraid-api/cli/apikey/api-key.command.ts @@ -1,10 +1,10 @@ import { AuthActionVerb } from 'nest-authz'; import { Command, CommandRunner, InquirerService, Option } from 'nest-commander'; -import { Permission, Resource, Role } from '@app/graphql/generated/api/types'; -import { ApiKeyService } from '@app/unraid-api/auth/api-key.service'; -import { AddApiKeyQuestionSet } from '@app/unraid-api/cli/apikey/add-api-key.questions'; -import { LogService } from '@app/unraid-api/cli/log.service'; +import { Permission, Resource, Role } from '@app/graphql/generated/api/types.js'; +import { ApiKeyService } from '@app/unraid-api/auth/api-key.service.js'; +import { AddApiKeyQuestionSet } from '@app/unraid-api/cli/apikey/add-api-key.questions.js'; +import { LogService } from '@app/unraid-api/cli/log.service.js'; interface KeyOptions { name: string; diff --git a/api/src/unraid-api/cli/cli.module.ts b/api/src/unraid-api/cli/cli.module.ts index 8a8eeb087..b7d987128 100644 --- a/api/src/unraid-api/cli/cli.module.ts +++ b/api/src/unraid-api/cli/cli.module.ts @@ -1,28 +1,28 @@ import { Module } from '@nestjs/common'; -import { ApiKeyService } from '@app/unraid-api/auth/api-key.service'; -import { AddApiKeyQuestionSet } from '@app/unraid-api/cli/apikey/add-api-key.questions'; -import { ApiKeyCommand } from '@app/unraid-api/cli/apikey/api-key.command'; -import { ConfigCommand } from '@app/unraid-api/cli/config.command'; -import { DeveloperCommand } from '@app/unraid-api/cli/developer/developer.command'; -import { DeveloperQuestions } from '@app/unraid-api/cli/developer/developer.questions'; -import { LogService } from '@app/unraid-api/cli/log.service'; -import { LogsCommand } from '@app/unraid-api/cli/logs.command'; -import { PM2Service } from '@app/unraid-api/cli/pm2.service'; -import { ReportCommand } from '@app/unraid-api/cli/report.command'; -import { RestartCommand } from '@app/unraid-api/cli/restart.command'; -import { AddSSOUserCommand } from '@app/unraid-api/cli/sso/add-sso-user.command'; -import { AddSSOUserQuestionSet } from '@app/unraid-api/cli/sso/add-sso-user.questions'; -import { ListSSOUserCommand } from '@app/unraid-api/cli/sso/list-sso-user.command'; -import { RemoveSSOUserCommand } from '@app/unraid-api/cli/sso/remove-sso-user.command'; -import { RemoveSSOUserQuestionSet } from '@app/unraid-api/cli/sso/remove-sso-user.questions'; -import { SSOCommand } from '@app/unraid-api/cli/sso/sso.command'; -import { ValidateTokenCommand } from '@app/unraid-api/cli/sso/validate-token.command'; -import { StartCommand } from '@app/unraid-api/cli/start.command'; -import { StatusCommand } from '@app/unraid-api/cli/status.command'; -import { StopCommand } from '@app/unraid-api/cli/stop.command'; -import { SwitchEnvCommand } from '@app/unraid-api/cli/switch-env.command'; -import { VersionCommand } from '@app/unraid-api/cli/version.command'; +import { ApiKeyService } from '@app/unraid-api/auth/api-key.service.js'; +import { AddApiKeyQuestionSet } from '@app/unraid-api/cli/apikey/add-api-key.questions.js'; +import { ApiKeyCommand } from '@app/unraid-api/cli/apikey/api-key.command.js'; +import { ConfigCommand } from '@app/unraid-api/cli/config.command.js'; +import { DeveloperCommand } from '@app/unraid-api/cli/developer/developer.command.js'; +import { DeveloperQuestions } from '@app/unraid-api/cli/developer/developer.questions.js'; +import { LogService } from '@app/unraid-api/cli/log.service.js'; +import { LogsCommand } from '@app/unraid-api/cli/logs.command.js'; +import { PM2Service } from '@app/unraid-api/cli/pm2.service.js'; +import { ReportCommand } from '@app/unraid-api/cli/report.command.js'; +import { RestartCommand } from '@app/unraid-api/cli/restart.command.js'; +import { AddSSOUserCommand } from '@app/unraid-api/cli/sso/add-sso-user.command.js'; +import { AddSSOUserQuestionSet } from '@app/unraid-api/cli/sso/add-sso-user.questions.js'; +import { ListSSOUserCommand } from '@app/unraid-api/cli/sso/list-sso-user.command.js'; +import { RemoveSSOUserCommand } from '@app/unraid-api/cli/sso/remove-sso-user.command.js'; +import { RemoveSSOUserQuestionSet } from '@app/unraid-api/cli/sso/remove-sso-user.questions.js'; +import { SSOCommand } from '@app/unraid-api/cli/sso/sso.command.js'; +import { ValidateTokenCommand } from '@app/unraid-api/cli/sso/validate-token.command.js'; +import { StartCommand } from '@app/unraid-api/cli/start.command.js'; +import { StatusCommand } from '@app/unraid-api/cli/status.command.js'; +import { StopCommand } from '@app/unraid-api/cli/stop.command.js'; +import { SwitchEnvCommand } from '@app/unraid-api/cli/switch-env.command.js'; +import { VersionCommand } from '@app/unraid-api/cli/version.command.js'; @Module({ providers: [ diff --git a/api/src/unraid-api/cli/config.command.ts b/api/src/unraid-api/cli/config.command.ts index d18795e62..9d62ad181 100644 --- a/api/src/unraid-api/cli/config.command.ts +++ b/api/src/unraid-api/cli/config.command.ts @@ -3,8 +3,8 @@ import { readFile } from 'fs/promises'; import { Command, CommandRunner } from 'nest-commander'; -import { getters } from '@app/store/index'; -import { LogService } from '@app/unraid-api/cli/log.service'; +import { getters } from '@app/store/index.js'; +import { LogService } from '@app/unraid-api/cli/log.service.js'; @Injectable() @Command({ diff --git a/api/src/unraid-api/cli/developer/developer.command.ts b/api/src/unraid-api/cli/developer/developer.command.ts index c52b13476..9252d59e0 100644 --- a/api/src/unraid-api/cli/developer/developer.command.ts +++ b/api/src/unraid-api/cli/developer/developer.command.ts @@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common'; import { Command, CommandRunner, InquirerService } from 'nest-commander'; -import { loadConfigFile, updateUserConfig } from '@app/store/modules/config'; -import { writeConfigSync } from '@app/store/sync/config-disk-sync'; -import { DeveloperQuestions } from '@app/unraid-api/cli/developer/developer.questions'; -import { LogService } from '@app/unraid-api/cli/log.service'; -import { RestartCommand } from '@app/unraid-api/cli/restart.command'; +import { loadConfigFile, updateUserConfig } from '@app/store/modules/config.js'; +import { writeConfigSync } from '@app/store/sync/config-disk-sync.js'; +import { DeveloperQuestions } from '@app/unraid-api/cli/developer/developer.questions.js'; +import { LogService } from '@app/unraid-api/cli/log.service.js'; +import { RestartCommand } from '@app/unraid-api/cli/restart.command.js'; interface DeveloperOptions { disclaimer: boolean; @@ -31,7 +31,7 @@ export class DeveloperCommand extends CommandRunner { this.logger.warn('No changes made, disclaimer not accepted.'); process.exit(1); } - const { store } = await import('@app/store'); + const { store } = await import('@app/store/index.js'); await store.dispatch(loadConfigFile()); store.dispatch(updateUserConfig({ local: { sandbox: options.sandbox ? 'yes' : 'no' } })); writeConfigSync('flash'); diff --git a/api/src/unraid-api/cli/log.service.ts b/api/src/unraid-api/cli/log.service.ts index 54db45de4..74cd21255 100644 --- a/api/src/unraid-api/cli/log.service.ts +++ b/api/src/unraid-api/cli/log.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; -import { levels, LogLevel } from '@app/core/log'; -import { LOG_LEVEL } from '@app/environment'; +import { levels, LogLevel } from '@app/core/log.js'; +import { LOG_LEVEL } from '@app/environment.js'; @Injectable() export class LogService { diff --git a/api/src/unraid-api/cli/logs.command.ts b/api/src/unraid-api/cli/logs.command.ts index fe76016fd..c15d8e25a 100644 --- a/api/src/unraid-api/cli/logs.command.ts +++ b/api/src/unraid-api/cli/logs.command.ts @@ -1,6 +1,6 @@ import { Command, CommandRunner, Option } from 'nest-commander'; -import { PM2Service } from '@app/unraid-api/cli/pm2.service'; +import { PM2Service } from '@app/unraid-api/cli/pm2.service.js'; interface LogsOptions { lines: number; diff --git a/api/src/unraid-api/cli/pm2.service.ts b/api/src/unraid-api/cli/pm2.service.ts index de0e0fc01..e91ab8df3 100644 --- a/api/src/unraid-api/cli/pm2.service.ts +++ b/api/src/unraid-api/cli/pm2.service.ts @@ -6,9 +6,9 @@ import { join } from 'node:path'; import type { Options, Result, ResultPromise } from 'execa'; import { execa, ExecaError } from 'execa'; -import { PM2_PATH } from '@app/consts'; -import { PM2_HOME } from '@app/environment'; -import { LogService } from '@app/unraid-api/cli/log.service'; +import { PM2_PATH } from '@app/consts.js'; +import { PM2_HOME } from '@app/environment.js'; +import { LogService } from '@app/unraid-api/cli/log.service.js'; type CmdContext = Options & { /** A tag for logging & debugging purposes. Should represent the operation being performed. */ diff --git a/api/src/unraid-api/cli/report.command.ts b/api/src/unraid-api/cli/report.command.ts index f993e55fe..9613eb61f 100644 --- a/api/src/unraid-api/cli/report.command.ts +++ b/api/src/unraid-api/cli/report.command.ts @@ -2,10 +2,10 @@ import { readFile } from 'fs/promises'; import { Command, CommandRunner, Option } from 'nest-commander'; -import type { MyServersConfigMemory } from '@app/types/my-servers-config'; -import { getters } from '@app/store'; -import { MyServersConfigMemorySchema } from '@app/types/my-servers-config'; -import { LogService } from '@app/unraid-api/cli/log.service'; +import type { MyServersConfigMemory } from '@app/types/my-servers-config.js'; +import { getters } from '@app/store/index.js'; +import { MyServersConfigMemorySchema } from '@app/types/my-servers-config.js'; +import { LogService } from '@app/unraid-api/cli/log.service.js'; @Command({ name: 'report' }) export class ReportCommand extends CommandRunner { @@ -50,7 +50,7 @@ export class ReportCommand extends CommandRunner { async report(): Promise { try { - const { isUnraidApiRunning } = await import('@app/core/utils/pm2/unraid-api-running'); + const { isUnraidApiRunning } = await import('@app/core/utils/pm2/unraid-api-running.js'); const apiRunning = await isUnraidApiRunning().catch((err) => { this.logger.debug('failed to get PM2 state with error: ' + err); diff --git a/api/src/unraid-api/cli/restart.command.ts b/api/src/unraid-api/cli/restart.command.ts index 68e92a6b9..b9e48d696 100644 --- a/api/src/unraid-api/cli/restart.command.ts +++ b/api/src/unraid-api/cli/restart.command.ts @@ -1,8 +1,8 @@ import { Command, CommandRunner } from 'nest-commander'; -import { ECOSYSTEM_PATH } from '@app/consts'; -import { LogService } from '@app/unraid-api/cli/log.service'; -import { PM2Service } from '@app/unraid-api/cli/pm2.service'; +import { ECOSYSTEM_PATH } from '@app/consts.js'; +import { LogService } from '@app/unraid-api/cli/log.service.js'; +import { PM2Service } from '@app/unraid-api/cli/pm2.service.js'; @Command({ name: 'restart', description: 'Restart the Unraid API' }) export class RestartCommand extends CommandRunner { diff --git a/api/src/unraid-api/cli/sso/add-sso-user.command.ts b/api/src/unraid-api/cli/sso/add-sso-user.command.ts index dcc6fd512..f6d843390 100644 --- a/api/src/unraid-api/cli/sso/add-sso-user.command.ts +++ b/api/src/unraid-api/cli/sso/add-sso-user.command.ts @@ -3,12 +3,12 @@ import { Injectable } from '@nestjs/common'; import { CommandRunner, InquirerService, Option, SubCommand } from 'nest-commander'; import { v4 } from 'uuid'; -import { store } from '@app/store/index'; -import { addSsoUser, loadConfigFile } from '@app/store/modules/config'; -import { writeConfigSync } from '@app/store/sync/config-disk-sync'; -import { LogService } from '@app/unraid-api/cli/log.service'; -import { RestartCommand } from '@app/unraid-api/cli/restart.command'; -import { AddSSOUserQuestionSet } from '@app/unraid-api/cli/sso/add-sso-user.questions'; +import { store } from '@app/store/index.js'; +import { addSsoUser, loadConfigFile } from '@app/store/modules/config.js'; +import { writeConfigSync } from '@app/store/sync/config-disk-sync.js'; +import { LogService } from '@app/unraid-api/cli/log.service.js'; +import { RestartCommand } from '@app/unraid-api/cli/restart.command.js'; +import { AddSSOUserQuestionSet } from '@app/unraid-api/cli/sso/add-sso-user.questions.js'; interface AddSSOUserCommandOptions { disclaimer: string; diff --git a/api/src/unraid-api/cli/sso/list-sso-user.command.ts b/api/src/unraid-api/cli/sso/list-sso-user.command.ts index f331fa24c..241882b9a 100644 --- a/api/src/unraid-api/cli/sso/list-sso-user.command.ts +++ b/api/src/unraid-api/cli/sso/list-sso-user.command.ts @@ -2,9 +2,9 @@ import { Injectable } from '@nestjs/common'; import { CommandRunner, SubCommand } from 'nest-commander'; -import { store } from '@app/store/index'; -import { loadConfigFile } from '@app/store/modules/config'; -import { LogService } from '@app/unraid-api/cli/log.service'; +import { store } from '@app/store/index.js'; +import { loadConfigFile } from '@app/store/modules/config.js'; +import { LogService } from '@app/unraid-api/cli/log.service.js'; @Injectable() @SubCommand({ diff --git a/api/src/unraid-api/cli/sso/remove-sso-user.command.ts b/api/src/unraid-api/cli/sso/remove-sso-user.command.ts index 39fb3adc2..10a1ab405 100644 --- a/api/src/unraid-api/cli/sso/remove-sso-user.command.ts +++ b/api/src/unraid-api/cli/sso/remove-sso-user.command.ts @@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common'; import { CommandRunner, InquirerService, Option, OptionChoiceFor, SubCommand } from 'nest-commander'; -import { store } from '@app/store/index'; -import { loadConfigFile, removeSsoUser } from '@app/store/modules/config'; -import { writeConfigSync } from '@app/store/sync/config-disk-sync'; -import { LogService } from '@app/unraid-api/cli/log.service'; -import { RemoveSSOUserQuestionSet } from '@app/unraid-api/cli/sso/remove-sso-user.questions'; +import { store } from '@app/store/index.js'; +import { loadConfigFile, removeSsoUser } from '@app/store/modules/config.js'; +import { writeConfigSync } from '@app/store/sync/config-disk-sync.js'; +import { LogService } from '@app/unraid-api/cli/log.service.js'; +import { RemoveSSOUserQuestionSet } from '@app/unraid-api/cli/sso/remove-sso-user.questions.js'; interface RemoveSSOUserCommandOptions { username: string; diff --git a/api/src/unraid-api/cli/sso/remove-sso-user.questions.ts b/api/src/unraid-api/cli/sso/remove-sso-user.questions.ts index 3fe6b3156..e8285027e 100644 --- a/api/src/unraid-api/cli/sso/remove-sso-user.questions.ts +++ b/api/src/unraid-api/cli/sso/remove-sso-user.questions.ts @@ -1,7 +1,7 @@ import { ChoicesFor, Question, QuestionSet } from 'nest-commander'; -import { store } from '@app/store/index'; -import { LogService } from '@app/unraid-api/cli/log.service'; +import { store } from '@app/store/index.js'; +import { LogService } from '@app/unraid-api/cli/log.service.js'; @QuestionSet({ name: 'remove-user' }) export class RemoveSSOUserQuestionSet { diff --git a/api/src/unraid-api/cli/sso/sso.command.ts b/api/src/unraid-api/cli/sso/sso.command.ts index 3b4c9e216..2759de80b 100644 --- a/api/src/unraid-api/cli/sso/sso.command.ts +++ b/api/src/unraid-api/cli/sso/sso.command.ts @@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common'; import { Command, CommandRunner } from 'nest-commander'; -import { LogService } from '@app/unraid-api/cli/log.service'; -import { AddSSOUserCommand } from '@app/unraid-api/cli/sso/add-sso-user.command'; -import { ListSSOUserCommand } from '@app/unraid-api/cli/sso/list-sso-user.command'; -import { RemoveSSOUserCommand } from '@app/unraid-api/cli/sso/remove-sso-user.command'; -import { ValidateTokenCommand } from '@app/unraid-api/cli/sso/validate-token.command'; +import { LogService } from '@app/unraid-api/cli/log.service.js'; +import { AddSSOUserCommand } from '@app/unraid-api/cli/sso/add-sso-user.command.js'; +import { ListSSOUserCommand } from '@app/unraid-api/cli/sso/list-sso-user.command.js'; +import { RemoveSSOUserCommand } from '@app/unraid-api/cli/sso/remove-sso-user.command.js'; +import { ValidateTokenCommand } from '@app/unraid-api/cli/sso/validate-token.command.js'; @Injectable() @Command({ diff --git a/api/src/unraid-api/cli/sso/validate-token.command.ts b/api/src/unraid-api/cli/sso/validate-token.command.ts index 1af7cc41c..b00107437 100644 --- a/api/src/unraid-api/cli/sso/validate-token.command.ts +++ b/api/src/unraid-api/cli/sso/validate-token.command.ts @@ -2,10 +2,10 @@ import type { JWTPayload } from 'jose'; import { createLocalJWKSet, createRemoteJWKSet, decodeJwt, jwtVerify } from 'jose'; import { CommandRunner, SubCommand } from 'nest-commander'; -import { JWKS_LOCAL_PAYLOAD, JWKS_REMOTE_LINK } from '@app/consts'; -import { store } from '@app/store'; -import { loadConfigFile } from '@app/store/modules/config'; -import { LogService } from '@app/unraid-api/cli/log.service'; +import { JWKS_LOCAL_PAYLOAD, JWKS_REMOTE_LINK } from '@app/consts.js'; +import { store } from '@app/store/index.js'; +import { loadConfigFile } from '@app/store/modules/config.js'; +import { LogService } from '@app/unraid-api/cli/log.service.js'; @SubCommand({ name: 'validate-token', diff --git a/api/src/unraid-api/cli/start.command.ts b/api/src/unraid-api/cli/start.command.ts index 936c36adb..352f873d0 100644 --- a/api/src/unraid-api/cli/start.command.ts +++ b/api/src/unraid-api/cli/start.command.ts @@ -1,10 +1,10 @@ import { Command, CommandRunner, Option } from 'nest-commander'; -import type { LogLevel } from '@app/core/log'; -import { ECOSYSTEM_PATH } from '@app/consts'; -import { levels } from '@app/core/log'; -import { LogService } from '@app/unraid-api/cli/log.service'; -import { PM2Service } from '@app/unraid-api/cli/pm2.service'; +import type { LogLevel } from '@app/core/log.js'; +import { ECOSYSTEM_PATH } from '@app/consts.js'; +import { levels } from '@app/core/log.js'; +import { LogService } from '@app/unraid-api/cli/log.service.js'; +import { PM2Service } from '@app/unraid-api/cli/pm2.service.js'; interface StartCommandOptions { 'log-level'?: string; diff --git a/api/src/unraid-api/cli/status.command.ts b/api/src/unraid-api/cli/status.command.ts index 31d7bd275..4e78e938a 100644 --- a/api/src/unraid-api/cli/status.command.ts +++ b/api/src/unraid-api/cli/status.command.ts @@ -1,6 +1,6 @@ import { Command, CommandRunner } from 'nest-commander'; -import { PM2Service } from '@app/unraid-api/cli/pm2.service'; +import { PM2Service } from '@app/unraid-api/cli/pm2.service.js'; @Command({ name: 'status', description: 'Check status of unraid-api service' }) export class StatusCommand extends CommandRunner { diff --git a/api/src/unraid-api/cli/stop.command.ts b/api/src/unraid-api/cli/stop.command.ts index 840560618..6b55dd981 100644 --- a/api/src/unraid-api/cli/stop.command.ts +++ b/api/src/unraid-api/cli/stop.command.ts @@ -1,7 +1,7 @@ import { Command, CommandRunner, Option } from 'nest-commander'; -import { ECOSYSTEM_PATH } from '@app/consts'; -import { PM2Service } from '@app/unraid-api/cli/pm2.service'; +import { ECOSYSTEM_PATH } from '@app/consts.js'; +import { PM2Service } from '@app/unraid-api/cli/pm2.service.js'; interface StopCommandOptions { delete: boolean; diff --git a/api/src/unraid-api/cli/switch-env.command.ts b/api/src/unraid-api/cli/switch-env.command.ts index 343691886..7c4a7b0ea 100644 --- a/api/src/unraid-api/cli/switch-env.command.ts +++ b/api/src/unraid-api/cli/switch-env.command.ts @@ -3,11 +3,11 @@ import { join } from 'path'; import { Command, CommandRunner, Option } from 'nest-commander'; -import { cliLogger } from '@app/core/log'; -import { getters } from '@app/store'; -import { LogService } from '@app/unraid-api/cli/log.service'; -import { StartCommand } from '@app/unraid-api/cli/start.command'; -import { StopCommand } from '@app/unraid-api/cli/stop.command'; +import { cliLogger } from '@app/core/log.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'; interface SwitchEnvOptions { environment?: 'staging' | 'production'; @@ -62,7 +62,7 @@ export class SwitchEnvCommand extends CommandRunner { this.logger.warn('Stopping the Unraid API'); try { - await this.stopCommand.run(); + await this.stopCommand.run([], { delete: false }); } catch (err) { this.logger.warn('Failed to stop the Unraid API (maybe already stopped?)'); } diff --git a/api/src/unraid-api/cli/version.command.ts b/api/src/unraid-api/cli/version.command.ts index 97aac6b29..05a0c2800 100644 --- a/api/src/unraid-api/cli/version.command.ts +++ b/api/src/unraid-api/cli/version.command.ts @@ -1,7 +1,7 @@ import { Command, CommandRunner } from 'nest-commander'; -import { API_VERSION } from '@app/environment'; -import { LogService } from '@app/unraid-api/cli/log.service'; +import { API_VERSION } from '@app/environment.js'; +import { LogService } from '@app/unraid-api/cli/log.service.js'; @Command({ name: 'version' }) export class VersionCommand extends CommandRunner { diff --git a/api/src/unraid-api/cron/cron.module.ts b/api/src/unraid-api/cron/cron.module.ts index fb7215162..bc108f3db 100644 --- a/api/src/unraid-api/cron/cron.module.ts +++ b/api/src/unraid-api/cron/cron.module.ts @@ -1,8 +1,8 @@ import { Module } from '@nestjs/common'; import { ScheduleModule } from '@nestjs/schedule'; -import { LogRotateService } from '@app/unraid-api/cron/log-rotate.service'; -import { WriteFlashFileService } from '@app/unraid-api/cron/write-flash-file.service'; +import { LogRotateService } from '@app/unraid-api/cron/log-rotate.service.js'; +import { WriteFlashFileService } from '@app/unraid-api/cron/write-flash-file.service.js'; @Module({ imports: [ScheduleModule.forRoot()], diff --git a/api/src/unraid-api/cron/write-flash-file.service.ts b/api/src/unraid-api/cron/write-flash-file.service.ts index d03a74cd2..d32176e58 100644 --- a/api/src/unraid-api/cron/write-flash-file.service.ts +++ b/api/src/unraid-api/cron/write-flash-file.service.ts @@ -2,10 +2,10 @@ import { Injectable, Logger } from '@nestjs/common'; import { Cron } from '@nestjs/schedule'; import { readFile, writeFile } from 'fs/promises'; -import { ONE_DAY_MS, THIRTY_MINUTES_MS } from '@app/consts'; -import { sleep } from '@app/core/utils/misc/sleep'; -import { convertToFuzzyTime } from '@app/mothership/utils/convert-to-fuzzy-time'; -import { getters } from '@app/store/index'; +import { ONE_DAY_MS, THIRTY_MINUTES_MS } from '@app/consts.js'; +import { sleep } from '@app/core/utils/misc/sleep.js'; +import { convertToFuzzyTime } from '@app/mothership/utils/convert-to-fuzzy-time.js'; +import { getters } from '@app/store/index.js'; @Injectable() export class WriteFlashFileService { diff --git a/api/src/unraid-api/cron/write-flash-file.spec.ts b/api/src/unraid-api/cron/write-flash-file.spec.ts index c99fa5c42..3f40f97ad 100644 --- a/api/src/unraid-api/cron/write-flash-file.spec.ts +++ b/api/src/unraid-api/cron/write-flash-file.spec.ts @@ -2,8 +2,10 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; import { readFileSync, writeFileSync } from 'fs'; -import { getters } from '@app/store/index'; -import { WriteFlashFileService } from '@app/unraid-api/cron/write-flash-file.service'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { getters } from '@app/store/index.js'; +import { WriteFlashFileService } from '@app/unraid-api/cron/write-flash-file.service.js'; describe('WriteFlashFileService', () => { let service: WriteFlashFileService; @@ -26,21 +28,16 @@ describe('WriteFlashFileService', () => { expect(timestamp).toBeGreaterThan(0); const file = readFileSync(getters.paths()['myservers-keepalive'], 'utf8').toString(); - expect(file).toBe( - new Date(timestamp).toISOString(), - 'file contents match the returned timestamp' - ); + expect(file).toBe(new Date(timestamp).toISOString()); // Now make the file very old writeFileSync(getters.paths()['myservers-keepalive'], '2021-01-01T00:00:00.000Z'); expect(readFileSync(getters.paths()['myservers-keepalive'], 'utf8').toString()).toBe( - '2021-01-01T00:00:00.000Z', - 'file was updated' + '2021-01-01T00:00:00.000Z' ); await service.handleCron(); expect(readFileSync(getters.paths()['myservers-keepalive'], 'utf8').toString()).not.toBe( - '2021-01-01T00:00:00.000Z', - 'file was updated' + '2021-01-01T00:00:00.000Z' ); // Now make the file kind of old (one day ) @@ -52,8 +49,7 @@ describe('WriteFlashFileService', () => { await service.handleCron(); const contents = readFileSync(getters.paths()['myservers-keepalive'], 'utf8').toString(); expect(new Date(contents).getTime() + 1_000 * 60 * 60 * 12).toBeLessThan( - new Date(now).getTime(), - 'file was updated but is still older than today' + new Date(now).getTime() ); }); }); diff --git a/api/src/unraid-api/graph/connect/connect.resolver.spec.ts b/api/src/unraid-api/graph/connect/connect.resolver.spec.ts index cc595da26..bb4368191 100644 --- a/api/src/unraid-api/graph/connect/connect.resolver.spec.ts +++ b/api/src/unraid-api/graph/connect/connect.resolver.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { ConnectResolver } from '@app/unraid-api/graph/connect/connect.resolver'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { ConnectResolver } from '@app/unraid-api/graph/connect/connect.resolver.js'; describe('ConnectResolver', () => { let resolver: ConnectResolver; diff --git a/api/src/unraid-api/graph/connect/connect.resolver.ts b/api/src/unraid-api/graph/connect/connect.resolver.ts index fc1e2b642..e80cd3198 100644 --- a/api/src/unraid-api/graph/connect/connect.resolver.ts +++ b/api/src/unraid-api/graph/connect/connect.resolver.ts @@ -7,11 +7,15 @@ import { AuthActionVerb, AuthPossession, UsePermissions } from 'nest-authz'; import type { DynamicRemoteAccessStatus, EnableDynamicRemoteAccessInput, -} from '@app/graphql/generated/api/types'; -import { ConnectResolvers, DynamicRemoteAccessType, Resource } from '@app/graphql/generated/api/types'; -import { RemoteAccessController } from '@app/remoteAccess/remote-access-controller'; -import { store } from '@app/store/index'; -import { setAllowedRemoteAccessUrl } from '@app/store/modules/dynamic-remote-access'; +} from '@app/graphql/generated/api/types.js'; +import { + ConnectResolvers, + DynamicRemoteAccessType, + Resource, +} from '@app/graphql/generated/api/types.js'; +import { RemoteAccessController } from '@app/remoteAccess/remote-access-controller.js'; +import { store } from '@app/store/index.js'; +import { setAllowedRemoteAccessUrl } from '@app/store/modules/dynamic-remote-access.js'; @Resolver('Connect') export class ConnectResolver implements ConnectResolvers { diff --git a/api/src/unraid-api/graph/connect/connect.service.spec.ts b/api/src/unraid-api/graph/connect/connect.service.spec.ts index 37425b08e..03d239a83 100644 --- a/api/src/unraid-api/graph/connect/connect.service.spec.ts +++ b/api/src/unraid-api/graph/connect/connect.service.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { ConnectService } from '@app/unraid-api/graph/connect/connect.service'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { ConnectService } from '@app/unraid-api/graph/connect/connect.service.js'; describe('ConnectService', () => { let service: ConnectService; diff --git a/api/src/unraid-api/graph/graph.module.ts b/api/src/unraid-api/graph/graph.module.ts index 7bf088a54..b664bfedc 100644 --- a/api/src/unraid-api/graph/graph.module.ts +++ b/api/src/unraid-api/graph/graph.module.ts @@ -12,52 +12,49 @@ import { UUIDResolver, } from 'graphql-scalars'; -import { GraphQLLong } from '@app/graphql/resolvers/graphql-type-long'; -import { loadTypeDefs } from '@app/graphql/schema/loadTypesDefs'; -import { getters } from '@app/store/index'; -import { ConnectResolver } from '@app/unraid-api/graph/connect/connect.resolver'; -import { ConnectService } from '@app/unraid-api/graph/connect/connect.service'; -import { idPrefixPlugin } from '@app/unraid-api/graph/id-prefix-plugin'; -import { NetworkResolver } from '@app/unraid-api/graph/network/network.resolver'; -import { ResolversModule } from '@app/unraid-api/graph/resolvers/resolvers.module'; -import { sandboxPlugin } from '@app/unraid-api/graph/sandbox-plugin'; -import { ServicesResolver } from '@app/unraid-api/graph/services/services.resolver'; -import { SharesResolver } from '@app/unraid-api/graph/shares/shares.resolver'; +import { GraphQLLong } from '@app/graphql/resolvers/graphql-type-long.js'; +import { loadTypeDefs } from '@app/graphql/schema/loadTypesDefs.js'; +import { getters } from '@app/store/index.js'; +import { ConnectResolver } from '@app/unraid-api/graph/connect/connect.resolver.js'; +import { ConnectService } from '@app/unraid-api/graph/connect/connect.service.js'; +import { idPrefixPlugin } from '@app/unraid-api/graph/id-prefix-plugin.js'; +import { NetworkResolver } from '@app/unraid-api/graph/network/network.resolver.js'; +import { ResolversModule } from '@app/unraid-api/graph/resolvers/resolvers.module.js'; +import { sandboxPlugin } from '@app/unraid-api/graph/sandbox-plugin.js'; +import { ServicesResolver } from '@app/unraid-api/graph/services/services.resolver.js'; +import { SharesResolver } from '@app/unraid-api/graph/shares/shares.resolver.js'; @Module({ imports: [ ResolversModule, GraphQLModule.forRootAsync({ driver: ApolloDriver, - useFactory: async () => { - const typeDefs = await loadTypeDefs(); - return { - introspection: getters.config()?.local?.sandbox === 'yes', - playground: false, - context: ({ req, connectionParams, extra }) => ({ - req, - connectionParams, - extra, - }), - plugins: [sandboxPlugin, idPrefixPlugin], - subscriptions: { - 'graphql-ws': { - path: '/graphql', - }, + useFactory: async () => ({ + introspection: getters.config()?.local?.sandbox === 'yes', + playground: false, + context: ({ req, connectionParams, extra }: any) => ({ + req, + connectionParams, + extra, + }), + plugins: [sandboxPlugin, idPrefixPlugin] as any[], + subscriptions: { + 'graphql-ws': { + path: '/graphql', }, - path: '/graphql', - typeDefs: print(typeDefs), - resolvers: { - JSON: JSONResolver, - Long: GraphQLLong, - UUID: UUIDResolver, - DateTime: DateTimeResolver, - Port: PortResolver, - URL: URLResolver, - }, - validationRules: [NoUnusedVariablesRule], - }; - }, + }, + path: '/graphql', + typeDefs: print(await loadTypeDefs()), + resolvers: { + JSON: JSONResolver, + Long: GraphQLLong, + UUID: UUIDResolver, + DateTime: DateTimeResolver, + Port: PortResolver, + URL: URLResolver, + }, + validationRules: [NoUnusedVariablesRule], + }), }), ], providers: [NetworkResolver, ServicesResolver, SharesResolver, ConnectResolver, ConnectService], diff --git a/api/src/unraid-api/graph/id-prefix-plugin.ts b/api/src/unraid-api/graph/id-prefix-plugin.ts index bf08d1402..9c7ae36fd 100644 --- a/api/src/unraid-api/graph/id-prefix-plugin.ts +++ b/api/src/unraid-api/graph/id-prefix-plugin.ts @@ -1,7 +1,7 @@ import { type ApolloServerPlugin } from '@apollo/server'; -import { getServerIdentifier } from '@app/core/utils/server-identifier'; -import { updateObject } from '@app/utils'; +import { getServerIdentifier } from '@app/core/utils/server-identifier.js'; +import { updateObject } from '@app/utils.js'; type ObjectModifier = (obj: object) => void; diff --git a/api/src/unraid-api/graph/network/network.resolver.spec.ts b/api/src/unraid-api/graph/network/network.resolver.spec.ts index 6b18ebd81..fb52f0df3 100644 --- a/api/src/unraid-api/graph/network/network.resolver.spec.ts +++ b/api/src/unraid-api/graph/network/network.resolver.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { NetworkResolver } from '@app/unraid-api/graph/network/network.resolver'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { NetworkResolver } from '@app/unraid-api/graph/network/network.resolver.js'; describe('NetworkResolver', () => { let resolver: NetworkResolver; diff --git a/api/src/unraid-api/graph/network/network.resolver.ts b/api/src/unraid-api/graph/network/network.resolver.ts index 872b793cc..7252bc071 100644 --- a/api/src/unraid-api/graph/network/network.resolver.ts +++ b/api/src/unraid-api/graph/network/network.resolver.ts @@ -2,8 +2,8 @@ import { Query, ResolveField, Resolver } from '@nestjs/graphql'; import { AuthActionVerb, AuthPossession, UsePermissions } from 'nest-authz'; -import { AccessUrl, Network, Resource } from '@app/graphql/generated/api/types'; -import { getServerIps } from '@app/graphql/resolvers/subscription/network'; +import { AccessUrl, Network, Resource } from '@app/graphql/generated/api/types.js'; +import { getServerIps } from '@app/graphql/resolvers/subscription/network.js'; @Resolver('Network') export class NetworkResolver { diff --git a/api/src/unraid-api/graph/resolvers/api-key/api-key.resolver.spec.ts b/api/src/unraid-api/graph/resolvers/api-key/api-key.resolver.spec.ts index 3872c83fd..e709541ae 100644 --- a/api/src/unraid-api/graph/resolvers/api-key/api-key.resolver.spec.ts +++ b/api/src/unraid-api/graph/resolvers/api-key/api-key.resolver.spec.ts @@ -2,12 +2,12 @@ import { newEnforcer } from 'casbin'; import { AuthActionVerb, AuthPossession, AuthZService } from 'nest-authz'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import type { ApiKey } from '@app/graphql/generated/api/types'; -import { ApiKeyWithSecret, Resource, Role } from '@app/graphql/generated/api/types'; -import { ApiKeyService } from '@app/unraid-api/auth/api-key.service'; -import { AuthService } from '@app/unraid-api/auth/auth.service'; -import { CookieService } from '@app/unraid-api/auth/cookie.service'; -import { ApiKeyResolver } from '@app/unraid-api/graph/resolvers/api-key/api-key.resolver'; +import type { ApiKey } from '@app/graphql/generated/api/types.js'; +import { ApiKeyWithSecret, Resource, Role } from '@app/graphql/generated/api/types.js'; +import { ApiKeyService } from '@app/unraid-api/auth/api-key.service.js'; +import { AuthService } from '@app/unraid-api/auth/auth.service.js'; +import { CookieService } from '@app/unraid-api/auth/cookie.service.js'; +import { ApiKeyResolver } from '@app/unraid-api/graph/resolvers/api-key/api-key.resolver.js'; describe('ApiKeyResolver', () => { let resolver: ApiKeyResolver; diff --git a/api/src/unraid-api/graph/resolvers/api-key/api-key.resolver.ts b/api/src/unraid-api/graph/resolvers/api-key/api-key.resolver.ts index 7be02f2dc..eb7f77e90 100644 --- a/api/src/unraid-api/graph/resolvers/api-key/api-key.resolver.ts +++ b/api/src/unraid-api/graph/resolvers/api-key/api-key.resolver.ts @@ -10,11 +10,11 @@ import type { ApiKeyWithSecret, CreateApiKeyInput, RemoveRoleFromApiKeyInput, -} from '@app/graphql/generated/api/types'; -import { Resource, Role } from '@app/graphql/generated/api/types'; -import { ApiKeyService } from '@app/unraid-api/auth/api-key.service'; -import { GraphqlAuthGuard } from '@app/unraid-api/auth/auth.guard'; -import { AuthService } from '@app/unraid-api/auth/auth.service'; +} from '@app/graphql/generated/api/types.js'; +import { Resource, Role } from '@app/graphql/generated/api/types.js'; +import { ApiKeyService } from '@app/unraid-api/auth/api-key.service.js'; +import { GraphqlAuthGuard } from '@app/unraid-api/auth/auth.guard.js'; +import { AuthService } from '@app/unraid-api/auth/auth.service.js'; @Resolver('ApiKey') @UseGuards(GraphqlAuthGuard) diff --git a/api/src/unraid-api/graph/resolvers/array/array.resolver.spec.ts b/api/src/unraid-api/graph/resolvers/array/array.resolver.spec.ts index d27cdc63a..7f90be9c6 100644 --- a/api/src/unraid-api/graph/resolvers/array/array.resolver.spec.ts +++ b/api/src/unraid-api/graph/resolvers/array/array.resolver.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { ArrayResolver } from '@app/unraid-api/graph/resolvers/array/array.resolver'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { ArrayResolver } from '@app/unraid-api/graph/resolvers/array/array.resolver.js'; describe('ArrayResolver', () => { let resolver: ArrayResolver; diff --git a/api/src/unraid-api/graph/resolvers/array/array.resolver.ts b/api/src/unraid-api/graph/resolvers/array/array.resolver.ts index 4687ecc89..3a4e7ba50 100644 --- a/api/src/unraid-api/graph/resolvers/array/array.resolver.ts +++ b/api/src/unraid-api/graph/resolvers/array/array.resolver.ts @@ -2,10 +2,10 @@ import { Query, Resolver, Subscription } from '@nestjs/graphql'; import { AuthActionVerb, AuthPossession, UsePermissions } from 'nest-authz'; -import { getArrayData } from '@app/core/modules/array/get-array-data'; -import { createSubscription, PUBSUB_CHANNEL } from '@app/core/pubsub'; -import { Resource } from '@app/graphql/generated/api/types'; -import { store } from '@app/store/index'; +import { getArrayData } from '@app/core/modules/array/get-array-data.js'; +import { createSubscription, PUBSUB_CHANNEL } from '@app/core/pubsub.js'; +import { Resource } from '@app/graphql/generated/api/types.js'; +import { store } from '@app/store/index.js'; @Resolver('Array') export class ArrayResolver { diff --git a/api/src/unraid-api/graph/resolvers/cloud/cloud.resolver.spec.ts b/api/src/unraid-api/graph/resolvers/cloud/cloud.resolver.spec.ts index 5a105991c..627aa90f7 100644 --- a/api/src/unraid-api/graph/resolvers/cloud/cloud.resolver.spec.ts +++ b/api/src/unraid-api/graph/resolvers/cloud/cloud.resolver.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { CloudResolver } from '@app/unraid-api/graph/resolvers/cloud/cloud.resolver'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { CloudResolver } from '@app/unraid-api/graph/resolvers/cloud/cloud.resolver.js'; describe('CloudResolver', () => { let resolver: CloudResolver; diff --git a/api/src/unraid-api/graph/resolvers/cloud/cloud.resolver.ts b/api/src/unraid-api/graph/resolvers/cloud/cloud.resolver.ts index fb5a5c6f9..6aa648e32 100644 --- a/api/src/unraid-api/graph/resolvers/cloud/cloud.resolver.ts +++ b/api/src/unraid-api/graph/resolvers/cloud/cloud.resolver.ts @@ -7,21 +7,21 @@ import type { ConnectSignInInput, RemoteAccess, SetupRemoteAccessInput, -} from '@app/graphql/generated/api/types'; -import { getAllowedOrigins, getExtraOrigins } from '@app/common/allowed-origins'; +} from '@app/graphql/generated/api/types.js'; +import { getAllowedOrigins, getExtraOrigins } from '@app/common/allowed-origins.js'; import { DynamicRemoteAccessType, Resource, WAN_ACCESS_TYPE, WAN_FORWARD_TYPE, -} from '@app/graphql/generated/api/types'; -import { connectSignIn } from '@app/graphql/resolvers/mutation/connect/connect-sign-in'; -import { checkApi } from '@app/graphql/resolvers/query/cloud/check-api'; -import { checkCloud } from '@app/graphql/resolvers/query/cloud/check-cloud'; -import { checkMinigraphql } from '@app/graphql/resolvers/query/cloud/check-minigraphql'; -import { setupRemoteAccessThunk } from '@app/store/actions/setup-remote-access'; -import { getters, store } from '@app/store/index'; -import { logoutUser } from '@app/store/modules/config'; +} from '@app/graphql/generated/api/types.js'; +import { connectSignIn } from '@app/graphql/resolvers/mutation/connect/connect-sign-in.js'; +import { checkApi } from '@app/graphql/resolvers/query/cloud/check-api.js'; +import { checkCloud } from '@app/graphql/resolvers/query/cloud/check-cloud.js'; +import { checkMinigraphql } from '@app/graphql/resolvers/query/cloud/check-minigraphql.js'; +import { setupRemoteAccessThunk } from '@app/store/actions/setup-remote-access.js'; +import { getters, store } from '@app/store/index.js'; +import { logoutUser } from '@app/store/modules/config.js'; @Resolver('Cloud') export class CloudResolver { diff --git a/api/src/unraid-api/graph/resolvers/config/config.resolver.spec.ts b/api/src/unraid-api/graph/resolvers/config/config.resolver.spec.ts index a987891f4..2001aea96 100644 --- a/api/src/unraid-api/graph/resolvers/config/config.resolver.spec.ts +++ b/api/src/unraid-api/graph/resolvers/config/config.resolver.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { ConfigResolver } from '@app/unraid-api/graph/resolvers/config/config.resolver'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { ConfigResolver } from '@app/unraid-api/graph/resolvers/config/config.resolver.js'; describe('ConfigResolver', () => { let resolver: ConfigResolver; diff --git a/api/src/unraid-api/graph/resolvers/config/config.resolver.ts b/api/src/unraid-api/graph/resolvers/config/config.resolver.ts index 607ac440c..72ab3deec 100644 --- a/api/src/unraid-api/graph/resolvers/config/config.resolver.ts +++ b/api/src/unraid-api/graph/resolvers/config/config.resolver.ts @@ -2,11 +2,11 @@ import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; import { AuthActionVerb, AuthPossession, UsePermissions } from 'nest-authz'; -import type { AllowedOriginInput } from '@app/graphql/generated/api/types'; -import { getAllowedOrigins } from '@app/common/allowed-origins'; -import { Config, ConfigErrorState, Resource } from '@app/graphql/generated/api/types'; -import { getters, store } from '@app/store/index'; -import { updateAllowedOrigins } from '@app/store/modules/config'; +import type { AllowedOriginInput } from '@app/graphql/generated/api/types.js'; +import { getAllowedOrigins } from '@app/common/allowed-origins.js'; +import { Config, ConfigErrorState, Resource } from '@app/graphql/generated/api/types.js'; +import { getters, store } from '@app/store/index.js'; +import { updateAllowedOrigins } from '@app/store/modules/config.js'; @Resolver('Config') export class ConfigResolver { diff --git a/api/src/unraid-api/graph/resolvers/disks/disks.resolver.spec.ts b/api/src/unraid-api/graph/resolvers/disks/disks.resolver.spec.ts index f1c2a1f92..729b0c0f0 100644 --- a/api/src/unraid-api/graph/resolvers/disks/disks.resolver.spec.ts +++ b/api/src/unraid-api/graph/resolvers/disks/disks.resolver.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { DisksResolver } from '@app/unraid-api/graph/resolvers/disks/disks.resolver'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { DisksResolver } from '@app/unraid-api/graph/resolvers/disks/disks.resolver.js'; describe('DisksResolver', () => { let resolver: DisksResolver; diff --git a/api/src/unraid-api/graph/resolvers/disks/disks.resolver.ts b/api/src/unraid-api/graph/resolvers/disks/disks.resolver.ts index fa34723d5..baa7c5471 100644 --- a/api/src/unraid-api/graph/resolvers/disks/disks.resolver.ts +++ b/api/src/unraid-api/graph/resolvers/disks/disks.resolver.ts @@ -2,8 +2,8 @@ import { Query, Resolver } from '@nestjs/graphql'; import { AuthActionVerb, AuthPossession, UsePermissions } from 'nest-authz'; -import { getDisks } from '@app/core/modules/get-disks'; -import { Resource } from '@app/graphql/generated/api/types'; +import { getDisks } from '@app/core/modules/get-disks.js'; +import { Resource } from '@app/graphql/generated/api/types.js'; @Resolver('Disks') export class DisksResolver { diff --git a/api/src/unraid-api/graph/resolvers/display/display.resolver.spec.ts b/api/src/unraid-api/graph/resolvers/display/display.resolver.spec.ts index 1b49a7d0b..e40ab6476 100644 --- a/api/src/unraid-api/graph/resolvers/display/display.resolver.spec.ts +++ b/api/src/unraid-api/graph/resolvers/display/display.resolver.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { DisplayResolver } from '@app/unraid-api/graph/resolvers/display/display.resolver'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { DisplayResolver } from '@app/unraid-api/graph/resolvers/display/display.resolver.js'; describe('DisplayResolver', () => { let resolver: DisplayResolver; diff --git a/api/src/unraid-api/graph/resolvers/display/display.resolver.ts b/api/src/unraid-api/graph/resolvers/display/display.resolver.ts index 168af4eac..95fc57986 100644 --- a/api/src/unraid-api/graph/resolvers/display/display.resolver.ts +++ b/api/src/unraid-api/graph/resolvers/display/display.resolver.ts @@ -5,10 +5,10 @@ import { join } from 'node:path'; import { AuthActionVerb, AuthPossession, UsePermissions } from 'nest-authz'; -import type { Display } from '@app/graphql/generated/api/types'; -import { createSubscription, PUBSUB_CHANNEL } from '@app/core/pubsub'; -import { Resource } from '@app/graphql/generated/api/types'; -import { getters } from '@app/store/index'; +import type { Display } from '@app/graphql/generated/api/types.js'; +import { createSubscription, PUBSUB_CHANNEL } from '@app/core/pubsub.js'; +import { Resource } from '@app/graphql/generated/api/types.js'; +import { getters } from '@app/store/index.js'; const states = { // Success diff --git a/api/src/unraid-api/graph/resolvers/docker/docker.resolver.spec.ts b/api/src/unraid-api/graph/resolvers/docker/docker.resolver.spec.ts index 0dae66815..7d9df30d8 100644 --- a/api/src/unraid-api/graph/resolvers/docker/docker.resolver.spec.ts +++ b/api/src/unraid-api/graph/resolvers/docker/docker.resolver.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { DockerResolver } from '@app/unraid-api/graph/resolvers/docker/docker.resolver'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { DockerResolver } from '@app/unraid-api/graph/resolvers/docker/docker.resolver.js'; describe('DockerResolver', () => { let resolver: DockerResolver; diff --git a/api/src/unraid-api/graph/resolvers/docker/docker.resolver.ts b/api/src/unraid-api/graph/resolvers/docker/docker.resolver.ts index 231e7a0cc..3a347f73b 100644 --- a/api/src/unraid-api/graph/resolvers/docker/docker.resolver.ts +++ b/api/src/unraid-api/graph/resolvers/docker/docker.resolver.ts @@ -2,7 +2,7 @@ import { Query, ResolveField, Resolver } from '@nestjs/graphql'; import { AuthActionVerb, AuthPossession, UsePermissions } from 'nest-authz'; -import { Resource } from '@app/graphql/generated/api/types'; +import { Resource } from '@app/graphql/generated/api/types.js'; @Resolver('Docker') export class DockerResolver { @@ -25,7 +25,9 @@ export class DockerResolver { }) @ResolveField() public async containers() { - const { getDockerContainers } = await import('@app/core/modules/docker'); + const { getDockerContainers } = await import( + '@app/core/modules/docker/get-docker-containers.js' + ); return getDockerContainers({ useCache: false }); } diff --git a/api/src/unraid-api/graph/resolvers/flash/flash.resolver.spec.ts b/api/src/unraid-api/graph/resolvers/flash/flash.resolver.spec.ts index 61d8088d1..78a72a381 100644 --- a/api/src/unraid-api/graph/resolvers/flash/flash.resolver.spec.ts +++ b/api/src/unraid-api/graph/resolvers/flash/flash.resolver.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { FlashResolver } from '@app/unraid-api/graph/resolvers/flash/flash.resolver'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { FlashResolver } from '@app/unraid-api/graph/resolvers/flash/flash.resolver.js'; describe('FlashResolver', () => { let resolver: FlashResolver; diff --git a/api/src/unraid-api/graph/resolvers/flash/flash.resolver.ts b/api/src/unraid-api/graph/resolvers/flash/flash.resolver.ts index 2330e15ba..65c3a48d9 100644 --- a/api/src/unraid-api/graph/resolvers/flash/flash.resolver.ts +++ b/api/src/unraid-api/graph/resolvers/flash/flash.resolver.ts @@ -2,8 +2,8 @@ import { Query, Resolver } from '@nestjs/graphql'; import { AuthActionVerb, AuthPossession, UsePermissions } from 'nest-authz'; -import { Resource } from '@app/graphql/generated/api/types'; -import { getters } from '@app/store/index'; +import { Resource } from '@app/graphql/generated/api/types.js'; +import { getters } from '@app/store/index.js'; @Resolver('Flash') export class FlashResolver { diff --git a/api/src/unraid-api/graph/resolvers/info/info.resolver.spec.ts b/api/src/unraid-api/graph/resolvers/info/info.resolver.spec.ts index e7847010a..478ce2431 100644 --- a/api/src/unraid-api/graph/resolvers/info/info.resolver.spec.ts +++ b/api/src/unraid-api/graph/resolvers/info/info.resolver.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { InfoResolver } from '@app/unraid-api/graph/resolvers/info/info.resolver'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { InfoResolver } from '@app/unraid-api/graph/resolvers/info/info.resolver.js'; describe('InfoResolver', () => { let resolver: InfoResolver; diff --git a/api/src/unraid-api/graph/resolvers/info/info.resolver.ts b/api/src/unraid-api/graph/resolvers/info/info.resolver.ts index c9f496c76..f9dfae6e1 100644 --- a/api/src/unraid-api/graph/resolvers/info/info.resolver.ts +++ b/api/src/unraid-api/graph/resolvers/info/info.resolver.ts @@ -3,9 +3,9 @@ import { Query, ResolveField, Resolver, Subscription } from '@nestjs/graphql'; import { AuthActionVerb, AuthPossession, UsePermissions } from 'nest-authz'; import { baseboard, system } from 'systeminformation'; -import { createSubscription, PUBSUB_CHANNEL } from '@app/core/pubsub'; -import { getMachineId } from '@app/core/utils/misc/get-machine-id'; -import { Resource } from '@app/graphql/generated/api/types'; +import { createSubscription, PUBSUB_CHANNEL } from '@app/core/pubsub.js'; +import { getMachineId } from '@app/core/utils/misc/get-machine-id.js'; +import { Resource } from '@app/graphql/generated/api/types.js'; import { generateApps, generateCpu, @@ -14,7 +14,7 @@ import { generateMemory, generateOs, generateVersions, -} from '@app/graphql/resolvers/query/info'; +} from '@app/graphql/resolvers/query/info.js'; @Resolver('Info') export class InfoResolver { diff --git a/api/src/unraid-api/graph/resolvers/me/me.resolver.spec.ts b/api/src/unraid-api/graph/resolvers/me/me.resolver.spec.ts index 8e627d681..457f2827a 100644 --- a/api/src/unraid-api/graph/resolvers/me/me.resolver.spec.ts +++ b/api/src/unraid-api/graph/resolvers/me/me.resolver.spec.ts @@ -3,8 +3,8 @@ import { Test, TestingModule } from '@nestjs/testing'; import { AuthZService } from 'nest-authz'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { Me, Resource, Role, UserAccount } from '@app/graphql/generated/api/types'; -import { MeResolver } from '@app/unraid-api/graph/resolvers/me/me.resolver'; +import { Me, Resource, Role, UserAccount } from '@app/graphql/generated/api/types.js'; +import { MeResolver } from '@app/unraid-api/graph/resolvers/me/me.resolver.js'; describe('MeResolver', () => { let resolver: MeResolver; diff --git a/api/src/unraid-api/graph/resolvers/me/me.resolver.ts b/api/src/unraid-api/graph/resolvers/me/me.resolver.ts index 3108188e8..be7fc7aa3 100644 --- a/api/src/unraid-api/graph/resolvers/me/me.resolver.ts +++ b/api/src/unraid-api/graph/resolvers/me/me.resolver.ts @@ -2,9 +2,9 @@ import { Query, Resolver } from '@nestjs/graphql'; import { AuthActionVerb, AuthPossession, UsePermissions } from 'nest-authz'; -import type { UserAccount } from '@app/graphql/generated/api/types'; -import { Me, Resource } from '@app/graphql/generated/api/types'; -import { GraphqlUser } from '@app/unraid-api/auth/user.decorator'; +import type { UserAccount } from '@app/graphql/generated/api/types.js'; +import { Me, Resource } from '@app/graphql/generated/api/types.js'; +import { GraphqlUser } from '@app/unraid-api/auth/user.decorator.js'; @Resolver('Me') export class MeResolver { diff --git a/api/src/unraid-api/graph/resolvers/notifications/notifications.resolver.ts b/api/src/unraid-api/graph/resolvers/notifications/notifications.resolver.ts index 2f1ac4d3d..516c76215 100644 --- a/api/src/unraid-api/graph/resolvers/notifications/notifications.resolver.ts +++ b/api/src/unraid-api/graph/resolvers/notifications/notifications.resolver.ts @@ -6,12 +6,12 @@ import type { NotificationData, NotificationFilter, NotificationOverview, -} from '@app/graphql/generated/api/types'; -import { AppError } from '@app/core/errors/app-error'; -import { createSubscription, PUBSUB_CHANNEL } from '@app/core/pubsub'; -import { NotificationType, Resource } from '@app/graphql/generated/api/types'; -import { Importance } from '@app/graphql/generated/client/graphql'; -import { NotificationsService } from '@app/unraid-api/graph/resolvers/notifications/notifications.service'; +} from '@app/graphql/generated/api/types.js'; +import { AppError } from '@app/core/errors/app-error.js'; +import { createSubscription, PUBSUB_CHANNEL } from '@app/core/pubsub.js'; +import { NotificationType, Resource } from '@app/graphql/generated/api/types.js'; +import { Importance } from '@app/graphql/generated/client/graphql.js'; +import { NotificationsService } from '@app/unraid-api/graph/resolvers/notifications/notifications.service.js'; @Resolver('Notifications') export class NotificationsResolver { diff --git a/api/src/unraid-api/graph/resolvers/notifications/notifications.service.spec.ts b/api/src/unraid-api/graph/resolvers/notifications/notifications.service.spec.ts index cc933bc51..6263ea924 100644 --- a/api/src/unraid-api/graph/resolvers/notifications/notifications.service.spec.ts +++ b/api/src/unraid-api/graph/resolvers/notifications/notifications.service.spec.ts @@ -12,11 +12,11 @@ import type { NotificationData, NotificationFilter, NotificationOverview, -} from '@app/graphql/generated/api/types'; -import { type NotificationIni } from '@app/core/types/states/notification'; -import { NotificationSchema } from '@app/graphql/generated/api/operations'; -import { Importance, NotificationType } from '@app/graphql/generated/api/types'; -import { NotificationsService } from '@app/unraid-api/graph/resolvers/notifications/notifications.service'; +} from '@app/graphql/generated/api/types.js'; +import { type NotificationIni } from '@app/core/types/states/notification.js'; +import { NotificationSchema } from '@app/graphql/generated/api/operations.js'; +import { Importance, NotificationType } from '@app/graphql/generated/api/types.js'; +import { NotificationsService } from '@app/unraid-api/graph/resolvers/notifications/notifications.service.js'; // defined outside `describe` so it's defined inside the `beforeAll` // needed to mock the dynamix import @@ -41,7 +41,7 @@ describe.sequential('NotificationsService', () => { await mkdir(basePath, { recursive: true }); // need to mock the dynamix import bc the file watcher is init'ed in the service constructor // i.e. before we can mock service.paths() - vi.mock(import('../../../../store'), async (importOriginal) => { + vi.mock(import('../../../../store/index.js'), async (importOriginal) => { const mod = await importOriginal(); return { ...mod, @@ -411,7 +411,6 @@ describe.concurrent('NotificationsService legacy script compatibility', () => { expect.soft(result.escapedCommand).toMatchSnapshot(); if (result.failed) { - // @ts-expect-error this is correct; `execa`'s return type just isn't comprehensive // see https://github.com/sindresorhus/execa/blob/main/docs/errors.md#error-message // //* we use a snapshot because the script should only fail when it doesn't exist (ENOENT) diff --git a/api/src/unraid-api/graph/resolvers/notifications/notifications.service.ts b/api/src/unraid-api/graph/resolvers/notifications/notifications.service.ts index b9e96bb1b..acc1cfc49 100644 --- a/api/src/unraid-api/graph/resolvers/notifications/notifications.service.ts +++ b/api/src/unraid-api/graph/resolvers/notifications/notifications.service.ts @@ -16,18 +16,18 @@ import type { NotificationData, NotificationFilter, NotificationOverview, -} from '@app/graphql/generated/api/types'; -import { AppError } from '@app/core/errors/app-error'; -import { pubsub, PUBSUB_CHANNEL } from '@app/core/pubsub'; -import { NotificationIni } from '@app/core/types/states/notification'; -import { fileExists } from '@app/core/utils/files/file-exists'; -import { parseConfig } from '@app/core/utils/misc/parse-config'; -import { CHOKIDAR_USEPOLLING } from '@app/environment'; -import { NotificationSchema } from '@app/graphql/generated/api/operations'; -import { Importance, NotificationType } from '@app/graphql/generated/api/types'; -import { getters } from '@app/store'; -import { SortFn } from '@app/unraid-api/types/util'; -import { batchProcess, formatDatetime, isFulfilled, isRejected, unraidTimestamp } from '@app/utils'; +} from '@app/graphql/generated/api/types.js'; +import { AppError } from '@app/core/errors/app-error.js'; +import { pubsub, PUBSUB_CHANNEL } from '@app/core/pubsub.js'; +import { NotificationIni } from '@app/core/types/states/notification.js'; +import { fileExists } from '@app/core/utils/files/file-exists.js'; +import { parseConfig } from '@app/core/utils/misc/parse-config.js'; +import { CHOKIDAR_USEPOLLING } from '@app/environment.js'; +import { NotificationSchema } from '@app/graphql/generated/api/operations.js'; +import { Importance, NotificationType } from '@app/graphql/generated/api/types.js'; +import { getters } from '@app/store/index.js'; +import { SortFn } from '@app/unraid-api/types/util.js'; +import { batchProcess, formatDatetime, isFulfilled, isRejected, unraidTimestamp } from '@app/utils.js'; @Injectable() export class NotificationsService { diff --git a/api/src/unraid-api/graph/resolvers/online/online.resolver.spec.ts b/api/src/unraid-api/graph/resolvers/online/online.resolver.spec.ts index 1a08002af..64259b67d 100644 --- a/api/src/unraid-api/graph/resolvers/online/online.resolver.spec.ts +++ b/api/src/unraid-api/graph/resolvers/online/online.resolver.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { OnlineResolver } from '@app/unraid-api/graph/resolvers/online/online.resolver'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { OnlineResolver } from '@app/unraid-api/graph/resolvers/online/online.resolver.js'; describe('OnlineResolver', () => { let resolver: OnlineResolver; diff --git a/api/src/unraid-api/graph/resolvers/online/online.resolver.ts b/api/src/unraid-api/graph/resolvers/online/online.resolver.ts index 1d14d3979..df3d7a7e0 100644 --- a/api/src/unraid-api/graph/resolvers/online/online.resolver.ts +++ b/api/src/unraid-api/graph/resolvers/online/online.resolver.ts @@ -2,7 +2,7 @@ import { Query, Resolver } from '@nestjs/graphql'; import { AuthActionVerb, AuthPossession, UsePermissions } from 'nest-authz'; -import { Resource } from '@app/graphql/generated/api/types'; +import { Resource } from '@app/graphql/generated/api/types.js'; @Resolver('Online') export class OnlineResolver { diff --git a/api/src/unraid-api/graph/resolvers/owner/owner.resolver.spec.ts b/api/src/unraid-api/graph/resolvers/owner/owner.resolver.spec.ts index b4f7e833f..606220dad 100644 --- a/api/src/unraid-api/graph/resolvers/owner/owner.resolver.spec.ts +++ b/api/src/unraid-api/graph/resolvers/owner/owner.resolver.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { OwnerResolver } from '@app/unraid-api/graph/resolvers/owner/owner.resolver'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { OwnerResolver } from '@app/unraid-api/graph/resolvers/owner/owner.resolver.js'; describe('OwnerResolver', () => { let resolver: OwnerResolver; diff --git a/api/src/unraid-api/graph/resolvers/owner/owner.resolver.ts b/api/src/unraid-api/graph/resolvers/owner/owner.resolver.ts index 320284a78..f7febfed4 100644 --- a/api/src/unraid-api/graph/resolvers/owner/owner.resolver.ts +++ b/api/src/unraid-api/graph/resolvers/owner/owner.resolver.ts @@ -2,9 +2,9 @@ import { Query, Resolver, Subscription } from '@nestjs/graphql'; import { AuthActionVerb, AuthPossession, UsePermissions } from 'nest-authz'; -import { createSubscription, PUBSUB_CHANNEL } from '@app/core/pubsub'; -import { Resource } from '@app/graphql/generated/api/types'; -import { getters } from '@app/store/index'; +import { createSubscription, PUBSUB_CHANNEL } from '@app/core/pubsub.js'; +import { Resource } from '@app/graphql/generated/api/types.js'; +import { getters } from '@app/store/index.js'; @Resolver('Owner') export class OwnerResolver { diff --git a/api/src/unraid-api/graph/resolvers/registration/registration.resolver.spec.ts b/api/src/unraid-api/graph/resolvers/registration/registration.resolver.spec.ts index 8b1148fad..54087a82e 100644 --- a/api/src/unraid-api/graph/resolvers/registration/registration.resolver.spec.ts +++ b/api/src/unraid-api/graph/resolvers/registration/registration.resolver.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { RegistrationResolver } from '@app/unraid-api/graph/resolvers/registration/registration.resolver'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { RegistrationResolver } from '@app/unraid-api/graph/resolvers/registration/registration.resolver.js'; describe('RegistrationResolver', () => { let resolver: RegistrationResolver; diff --git a/api/src/unraid-api/graph/resolvers/registration/registration.resolver.ts b/api/src/unraid-api/graph/resolvers/registration/registration.resolver.ts index e80862acd..5d817bd14 100644 --- a/api/src/unraid-api/graph/resolvers/registration/registration.resolver.ts +++ b/api/src/unraid-api/graph/resolvers/registration/registration.resolver.ts @@ -2,12 +2,12 @@ import { Query, Resolver, Subscription } from '@nestjs/graphql'; import { AuthActionVerb, AuthPossession, UsePermissions } from 'nest-authz'; -import type { Registration } from '@app/graphql/generated/api/types'; -import { createSubscription, PUBSUB_CHANNEL } from '@app/core/pubsub'; -import { getKeyFile } from '@app/core/utils/misc/get-key-file'; -import { registrationType, Resource } from '@app/graphql/generated/api/types'; -import { getters } from '@app/store/index'; -import { FileLoadStatus } from '@app/store/types'; +import type { Registration } from '@app/graphql/generated/api/types.js'; +import { createSubscription, PUBSUB_CHANNEL } from '@app/core/pubsub.js'; +import { getKeyFile } from '@app/core/utils/misc/get-key-file.js'; +import { registrationType, Resource } from '@app/graphql/generated/api/types.js'; +import { getters } from '@app/store/index.js'; +import { FileLoadStatus } from '@app/store/types.js'; @Resolver('Registration') export class RegistrationResolver { diff --git a/api/src/unraid-api/graph/resolvers/resolvers.module.ts b/api/src/unraid-api/graph/resolvers/resolvers.module.ts index 0f36538c7..801fe64cc 100644 --- a/api/src/unraid-api/graph/resolvers/resolvers.module.ts +++ b/api/src/unraid-api/graph/resolvers/resolvers.module.ts @@ -1,24 +1,24 @@ import { Module } from '@nestjs/common'; -import { AuthModule } from '@app/unraid-api/auth/auth.module'; -import { ApiKeyResolver } from '@app/unraid-api/graph/resolvers/api-key/api-key.resolver'; -import { ArrayResolver } from '@app/unraid-api/graph/resolvers/array/array.resolver'; -import { CloudResolver } from '@app/unraid-api/graph/resolvers/cloud/cloud.resolver'; -import { ConfigResolver } from '@app/unraid-api/graph/resolvers/config/config.resolver'; -import { DisksResolver } from '@app/unraid-api/graph/resolvers/disks/disks.resolver'; -import { DisplayResolver } from '@app/unraid-api/graph/resolvers/display/display.resolver'; -import { DockerResolver } from '@app/unraid-api/graph/resolvers/docker/docker.resolver'; -import { FlashResolver } from '@app/unraid-api/graph/resolvers/flash/flash.resolver'; -import { InfoResolver } from '@app/unraid-api/graph/resolvers/info/info.resolver'; -import { MeResolver } from '@app/unraid-api/graph/resolvers/me/me.resolver'; -import { NotificationsResolver } from '@app/unraid-api/graph/resolvers/notifications/notifications.resolver'; -import { NotificationsService } from '@app/unraid-api/graph/resolvers/notifications/notifications.service'; -import { OnlineResolver } from '@app/unraid-api/graph/resolvers/online/online.resolver'; -import { OwnerResolver } from '@app/unraid-api/graph/resolvers/owner/owner.resolver'; -import { RegistrationResolver } from '@app/unraid-api/graph/resolvers/registration/registration.resolver'; -import { ServerResolver } from '@app/unraid-api/graph/resolvers/servers/server.resolver'; -import { VarsResolver } from '@app/unraid-api/graph/resolvers/vars/vars.resolver'; -import { VmsResolver } from '@app/unraid-api/graph/resolvers/vms/vms.resolver'; +import { AuthModule } from '@app/unraid-api/auth/auth.module.js'; +import { ApiKeyResolver } from '@app/unraid-api/graph/resolvers/api-key/api-key.resolver.js'; +import { ArrayResolver } from '@app/unraid-api/graph/resolvers/array/array.resolver.js'; +import { CloudResolver } from '@app/unraid-api/graph/resolvers/cloud/cloud.resolver.js'; +import { ConfigResolver } from '@app/unraid-api/graph/resolvers/config/config.resolver.js'; +import { DisksResolver } from '@app/unraid-api/graph/resolvers/disks/disks.resolver.js'; +import { DisplayResolver } from '@app/unraid-api/graph/resolvers/display/display.resolver.js'; +import { DockerResolver } from '@app/unraid-api/graph/resolvers/docker/docker.resolver.js'; +import { FlashResolver } from '@app/unraid-api/graph/resolvers/flash/flash.resolver.js'; +import { InfoResolver } from '@app/unraid-api/graph/resolvers/info/info.resolver.js'; +import { MeResolver } from '@app/unraid-api/graph/resolvers/me/me.resolver.js'; +import { NotificationsResolver } from '@app/unraid-api/graph/resolvers/notifications/notifications.resolver.js'; +import { NotificationsService } from '@app/unraid-api/graph/resolvers/notifications/notifications.service.js'; +import { OnlineResolver } from '@app/unraid-api/graph/resolvers/online/online.resolver.js'; +import { OwnerResolver } from '@app/unraid-api/graph/resolvers/owner/owner.resolver.js'; +import { RegistrationResolver } from '@app/unraid-api/graph/resolvers/registration/registration.resolver.js'; +import { ServerResolver } from '@app/unraid-api/graph/resolvers/servers/server.resolver.js'; +import { VarsResolver } from '@app/unraid-api/graph/resolvers/vars/vars.resolver.js'; +import { VmsResolver } from '@app/unraid-api/graph/resolvers/vms/vms.resolver.js'; @Module({ imports: [AuthModule], diff --git a/api/src/unraid-api/graph/resolvers/servers/server.resolver.spec.ts b/api/src/unraid-api/graph/resolvers/servers/server.resolver.spec.ts index 3f4462d3c..750cd2b2b 100644 --- a/api/src/unraid-api/graph/resolvers/servers/server.resolver.spec.ts +++ b/api/src/unraid-api/graph/resolvers/servers/server.resolver.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { ServerResolver } from '@app/unraid-api/graph/resolvers/servers/server.resolver'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { ServerResolver } from '@app/unraid-api/graph/resolvers/servers/server.resolver.js'; describe('ServersResolver', () => { let resolver: ServerResolver; diff --git a/api/src/unraid-api/graph/resolvers/servers/server.resolver.ts b/api/src/unraid-api/graph/resolvers/servers/server.resolver.ts index 18ce7324f..fcd35a2c5 100644 --- a/api/src/unraid-api/graph/resolvers/servers/server.resolver.ts +++ b/api/src/unraid-api/graph/resolvers/servers/server.resolver.ts @@ -2,10 +2,10 @@ import { Query, Resolver, Subscription } from '@nestjs/graphql'; import { AuthActionVerb, AuthPossession, UsePermissions } from 'nest-authz'; -import { createSubscription, PUBSUB_CHANNEL } from '@app/core/pubsub'; -import { Resource } from '@app/graphql/generated/api/types'; -import { type Server } from '@app/graphql/generated/client/graphql'; -import { getLocalServer } from '@app/graphql/schema/utils'; +import { createSubscription, PUBSUB_CHANNEL } from '@app/core/pubsub.js'; +import { Resource } from '@app/graphql/generated/api/types.js'; +import { type Server } from '@app/graphql/generated/client/graphql.js'; +import { getLocalServer } from '@app/graphql/schema/utils.js'; @Resolver('Server') export class ServerResolver { diff --git a/api/src/unraid-api/graph/resolvers/vars/vars.resolver.spec.ts b/api/src/unraid-api/graph/resolvers/vars/vars.resolver.spec.ts index 2514d5605..ae2975bcf 100644 --- a/api/src/unraid-api/graph/resolvers/vars/vars.resolver.spec.ts +++ b/api/src/unraid-api/graph/resolvers/vars/vars.resolver.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { VarsResolver } from '@app/unraid-api/graph/resolvers/vars/vars.resolver'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { VarsResolver } from '@app/unraid-api/graph/resolvers/vars/vars.resolver.js'; describe('VarsResolver', () => { let resolver: VarsResolver; diff --git a/api/src/unraid-api/graph/resolvers/vars/vars.resolver.ts b/api/src/unraid-api/graph/resolvers/vars/vars.resolver.ts index f688e099f..13715d32d 100644 --- a/api/src/unraid-api/graph/resolvers/vars/vars.resolver.ts +++ b/api/src/unraid-api/graph/resolvers/vars/vars.resolver.ts @@ -2,8 +2,8 @@ import { Query, Resolver } from '@nestjs/graphql'; import { AuthActionVerb, AuthPossession, UsePermissions } from 'nest-authz'; -import { Resource } from '@app/graphql/generated/api/types'; -import { getters } from '@app/store/index'; +import { Resource } from '@app/graphql/generated/api/types.js'; +import { getters } from '@app/store/index.js'; @Resolver('Vars') export class VarsResolver { diff --git a/api/src/unraid-api/graph/resolvers/vms/vms.resolver.spec.ts b/api/src/unraid-api/graph/resolvers/vms/vms.resolver.spec.ts index 3c1f86ede..e9d07b76b 100644 --- a/api/src/unraid-api/graph/resolvers/vms/vms.resolver.spec.ts +++ b/api/src/unraid-api/graph/resolvers/vms/vms.resolver.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { VmsResolver } from '@app/unraid-api/graph/resolvers/vms/vms.resolver'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { VmsResolver } from '@app/unraid-api/graph/resolvers/vms/vms.resolver.js'; describe('VmsResolver', () => { let resolver: VmsResolver; diff --git a/api/src/unraid-api/graph/resolvers/vms/vms.resolver.ts b/api/src/unraid-api/graph/resolvers/vms/vms.resolver.ts index ad8833670..841b1a56a 100644 --- a/api/src/unraid-api/graph/resolvers/vms/vms.resolver.ts +++ b/api/src/unraid-api/graph/resolvers/vms/vms.resolver.ts @@ -2,8 +2,8 @@ import { Query, ResolveField, Resolver } from '@nestjs/graphql'; import { AuthActionVerb, AuthPossession, UsePermissions } from 'nest-authz'; -import type { VmDomain } from '@app/graphql/generated/api/types'; -import { Resource } from '@app/graphql/generated/api/types'; +import type { VmDomain } from '@app/graphql/generated/api/types.js'; +import { Resource } from '@app/graphql/generated/api/types.js'; @Resolver('Vms') export class VmsResolver { @@ -22,12 +22,14 @@ export class VmsResolver { @ResolveField('domain') public async domain(): Promise> { try { - const { getDomains } = await import('@app/core/modules/vms/get-domains'); + const { getDomains } = await import('@app/core/modules/vms/get-domains.js'); const domains = await getDomains(); return domains; } catch (error) { // Consider using a proper logger here - throw new Error(`Failed to retrieve VM domains: ${error.message}`); + throw new Error( + `Failed to retrieve VM domains: ${error instanceof Error ? error.message : 'Unknown error'}` + ); } } } diff --git a/api/src/unraid-api/graph/sandbox-plugin.ts b/api/src/unraid-api/graph/sandbox-plugin.ts index af2a48555..75b512000 100644 --- a/api/src/unraid-api/graph/sandbox-plugin.ts +++ b/api/src/unraid-api/graph/sandbox-plugin.ts @@ -73,7 +73,7 @@ export const getPluginBasedOnSandbox = async (sandbox: boolean, csrfToken: strin * - Shared headers containing CSRF token */ async function renderSandboxPage(service: GraphQLServerContext) { - const { getters } = await import('@app/store'); + const { getters } = await import('@app/store/index.js'); const sandbox = getters.config().local.sandbox === 'yes'; const csrfToken = getters.emhttp().var.csrfToken; const plugin = await getPluginBasedOnSandbox(sandbox, csrfToken); diff --git a/api/src/unraid-api/graph/services/services.resolver.spec.ts b/api/src/unraid-api/graph/services/services.resolver.spec.ts index 60c9bf451..952517709 100644 --- a/api/src/unraid-api/graph/services/services.resolver.spec.ts +++ b/api/src/unraid-api/graph/services/services.resolver.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { ServicesResolver } from '@app/unraid-api/graph/services/services.resolver'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { ServicesResolver } from '@app/unraid-api/graph/services/services.resolver.js'; describe('ServicesResolver', () => { let resolver: ServicesResolver; diff --git a/api/src/unraid-api/graph/services/services.resolver.ts b/api/src/unraid-api/graph/services/services.resolver.ts index 253362c02..e87fa449c 100644 --- a/api/src/unraid-api/graph/services/services.resolver.ts +++ b/api/src/unraid-api/graph/services/services.resolver.ts @@ -2,10 +2,10 @@ import { Query, Resolver } from '@nestjs/graphql'; import { AuthActionVerb, AuthPossession, UsePermissions } from 'nest-authz'; -import { bootTimestamp } from '@app/common/dashboard/boot-timestamp'; -import { API_VERSION } from '@app/environment'; -import { DynamicRemoteAccessType, Resource, Service } from '@app/graphql/generated/api/types'; -import { store } from '@app/store/index'; +import { bootTimestamp } from '@app/common/dashboard/boot-timestamp.js'; +import { API_VERSION } from '@app/environment.js'; +import { DynamicRemoteAccessType, Resource, Service } from '@app/graphql/generated/api/types.js'; +import { store } from '@app/store/index.js'; @Resolver('Services') export class ServicesResolver { diff --git a/api/src/unraid-api/graph/shares/shares.resolver.spec.ts b/api/src/unraid-api/graph/shares/shares.resolver.spec.ts index 4bc0e8de8..cbb4d72d9 100644 --- a/api/src/unraid-api/graph/shares/shares.resolver.spec.ts +++ b/api/src/unraid-api/graph/shares/shares.resolver.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { SharesResolver } from '@app/unraid-api/graph/shares/shares.resolver'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { SharesResolver } from '@app/unraid-api/graph/shares/shares.resolver.js'; describe('SharesResolver', () => { let resolver: SharesResolver; diff --git a/api/src/unraid-api/graph/shares/shares.resolver.ts b/api/src/unraid-api/graph/shares/shares.resolver.ts index 6a3d95067..367b22ffc 100644 --- a/api/src/unraid-api/graph/shares/shares.resolver.ts +++ b/api/src/unraid-api/graph/shares/shares.resolver.ts @@ -2,8 +2,8 @@ import { Query, Resolver } from '@nestjs/graphql'; import { AuthActionVerb, AuthPossession, UsePermissions } from 'nest-authz'; -import { getShares } from '@app/core/utils/index'; -import { Resource } from '@app/graphql/generated/api/types'; +import { getShares } from '@app/core/utils/shares/get-shares.js'; +import { Resource } from '@app/graphql/generated/api/types.js'; @Resolver('Shares') export class SharesResolver { diff --git a/api/src/unraid-api/main.ts b/api/src/unraid-api/main.ts index d429ed402..bc8588cb1 100644 --- a/api/src/unraid-api/main.ts +++ b/api/src/unraid-api/main.ts @@ -5,13 +5,13 @@ import { FastifyAdapter } from '@nestjs/platform-fastify'; import fastifyCookie from '@fastify/cookie'; import { LoggerErrorInterceptor, Logger as PinoLogger } from 'nestjs-pino'; -import { apiLogger } from '@app/core/log'; -import { LOG_LEVEL, PORT } from '@app/environment'; -import { AppModule } from '@app/unraid-api/app/app.module'; -import { configureFastifyCors } from '@app/unraid-api/app/cors'; -import { CookieService } from '@app/unraid-api/auth/cookie.service'; -import { GraphQLExceptionsFilter } from '@app/unraid-api/exceptions/graphql-exceptions.filter'; -import { HttpExceptionFilter } from '@app/unraid-api/exceptions/http-exceptions.filter'; +import { apiLogger } from '@app/core/log.js'; +import { LOG_LEVEL, PORT } from '@app/environment.js'; +import { AppModule } from '@app/unraid-api/app/app.module.js'; +import { configureFastifyCors } from '@app/unraid-api/app/cors.js'; +import { CookieService } from '@app/unraid-api/auth/cookie.service.js'; +import { GraphQLExceptionsFilter } from '@app/unraid-api/exceptions/graphql-exceptions.filter.js'; +import { HttpExceptionFilter } from '@app/unraid-api/exceptions/http-exceptions.filter.js'; export async function bootstrapNestServer(): Promise { apiLogger.debug('Creating Nest Server'); diff --git a/api/src/unraid-api/observers/shutdown.observer.ts b/api/src/unraid-api/observers/shutdown.observer.ts index fe8062bc1..b97a2da23 100644 --- a/api/src/unraid-api/observers/shutdown.observer.ts +++ b/api/src/unraid-api/observers/shutdown.observer.ts @@ -2,7 +2,7 @@ import type { OnApplicationShutdown } from '@nestjs/common'; import { Injectable, Logger } from '@nestjs/common'; import { type IncomingMessage, type Server, type ServerResponse } from 'http'; -import { type FastifyInstance } from 'fastify'; +import type { FastifyInstance } from 'fastify'; /** * @todo Swap to this globally. This is a better way to handle shutdowns (right now they're handled in index.ts) diff --git a/api/src/unraid-api/rest/rest.controller.ts b/api/src/unraid-api/rest/rest.controller.ts index 25d84a94b..6c89f3686 100644 --- a/api/src/unraid-api/rest/rest.controller.ts +++ b/api/src/unraid-api/rest/rest.controller.ts @@ -2,10 +2,10 @@ import { Controller, Get, Logger, Param, Res } from '@nestjs/common'; import { AuthActionVerb, AuthPossession, UsePermissions } from 'nest-authz'; -import type { FastifyReply } from '@app/types/fastify'; -import { Resource } from '@app/graphql/generated/api/types'; -import { Public } from '@app/unraid-api/auth/public.decorator'; -import { RestService } from '@app/unraid-api/rest/rest.service'; +import type { FastifyReply } from '@app/types/fastify.js'; +import { Resource } from '@app/graphql/generated/api/types.js'; +import { Public } from '@app/unraid-api/auth/public.decorator.js'; +import { RestService } from '@app/unraid-api/rest/rest.service.js'; @Controller() export class RestController { diff --git a/api/src/unraid-api/rest/rest.module.ts b/api/src/unraid-api/rest/rest.module.ts index f4ecaac11..8f3b3292e 100644 --- a/api/src/unraid-api/rest/rest.module.ts +++ b/api/src/unraid-api/rest/rest.module.ts @@ -1,7 +1,7 @@ import { Module } from '@nestjs/common'; -import { RestController } from '@app/unraid-api/rest/rest.controller'; -import { RestService } from '@app/unraid-api/rest/rest.service'; +import { RestController } from '@app/unraid-api/rest/rest.controller.js'; +import { RestService } from '@app/unraid-api/rest/rest.service.js'; @Module({ imports: [], diff --git a/api/src/unraid-api/rest/rest.service.spec.ts b/api/src/unraid-api/rest/rest.service.spec.ts index 1f92887a3..4ed5a6896 100644 --- a/api/src/unraid-api/rest/rest.service.spec.ts +++ b/api/src/unraid-api/rest/rest.service.spec.ts @@ -1,7 +1,9 @@ import type { TestingModule } from '@nestjs/testing'; import { Test } from '@nestjs/testing'; -import { RestService } from '@app/unraid-api/rest/rest.service'; +import { beforeEach, describe, expect, it } from 'vitest'; + +import { RestService } from '@app/unraid-api/rest/rest.service.js'; describe('RestService', () => { let service: RestService; diff --git a/api/src/unraid-api/rest/rest.service.ts b/api/src/unraid-api/rest/rest.service.ts index eaa1a3d62..8b8f2902f 100644 --- a/api/src/unraid-api/rest/rest.service.ts +++ b/api/src/unraid-api/rest/rest.service.ts @@ -6,10 +6,13 @@ import { join } from 'node:path'; import { execa } from 'execa'; -import { getBannerPathIfPresent, getCasePathIfPresent } from '@app/core/utils/images/image-file-helpers'; -import { getters } from '@app/store/index'; -import { LogService } from '@app/unraid-api/cli/log.service'; -import { ReportCommand } from '@app/unraid-api/cli/report.command'; +import { + getBannerPathIfPresent, + getCasePathIfPresent, +} from '@app/core/utils/images/image-file-helpers.js'; +import { getters } from '@app/store/index.js'; +import { LogService } from '@app/unraid-api/cli/log.service.js'; +import { ReportCommand } from '@app/unraid-api/cli/report.command.js'; @Injectable() export class RestService { diff --git a/api/src/unraid-api/types/request.ts b/api/src/unraid-api/types/request.ts index ab92ef7bf..b9b3f8321 100644 --- a/api/src/unraid-api/types/request.ts +++ b/api/src/unraid-api/types/request.ts @@ -1,4 +1,4 @@ -import type { FastifyRequest } from '@app/types/fastify'; +import type { FastifyRequest } from '@app/types/fastify.js'; export interface CustomRequest extends FastifyRequest { headers: FastifyRequest['headers'] & { 'x-csrf-token'?: string }; diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/generic-modification.spec.ts b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/generic-modification.spec.ts index b538a4f90..6acd79e16 100644 --- a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/generic-modification.spec.ts +++ b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/generic-modification.spec.ts @@ -1,16 +1,16 @@ import { Logger } from '@nestjs/common'; import { readFile, writeFile } from 'fs/promises'; -import { afterEach } from 'node:test'; -import { basename, resolve } from 'path'; +import { basename, dirname, resolve } from 'path'; +import { fileURLToPath } from 'url'; import { describe, expect, test, vi } from 'vitest'; -import { FileModification } from '@app/unraid-api/unraid-file-modifier/file-modification'; -import AuthRequestModification from '@app/unraid-api/unraid-file-modifier/modifications/auth-request.modification'; -import DefaultPageLayoutModification from '@app/unraid-api/unraid-file-modifier/modifications/default-page-layout.modification'; -import { LogRotateModification } from '@app/unraid-api/unraid-file-modifier/modifications/log-rotate.modification'; -import NotificationsPageModification from '@app/unraid-api/unraid-file-modifier/modifications/notifications-page.modification'; -import SSOFileModification from '@app/unraid-api/unraid-file-modifier/modifications/sso.modification'; +import { FileModification } from '@app/unraid-api/unraid-file-modifier/file-modification.js'; +import AuthRequestModification from '@app/unraid-api/unraid-file-modifier/modifications/auth-request.modification.js'; +import DefaultPageLayoutModification from '@app/unraid-api/unraid-file-modifier/modifications/default-page-layout.modification.js'; +import { LogRotateModification } from '@app/unraid-api/unraid-file-modifier/modifications/log-rotate.modification.js'; +import NotificationsPageModification from '@app/unraid-api/unraid-file-modifier/modifications/notifications-page.modification.js'; +import SSOFileModification from '@app/unraid-api/unraid-file-modifier/modifications/sso.modification.js'; interface ModificationTestCase { ModificationClass: new (...args: ConstructorParameters) => FileModification; @@ -18,7 +18,8 @@ interface ModificationTestCase { fileName: string; } -const getPathToFixture = (fileName: string) => resolve(__dirname, `__fixtures__/downloaded/${fileName}`); +const getPathToFixture = (fileName: string) => + resolve(dirname(fileURLToPath(import.meta.url)), `__fixtures__/downloaded/${fileName}`); /** Modifications that patch the content of an existing file in one or more places. */ const patchTestCases: ModificationTestCase[] = [ @@ -83,12 +84,12 @@ const downloadOrRetrieveOriginalFile = async (filePath: string, fileUrl: string) return await readFile(filePath, 'utf-8').catch(() => ''); }; -async function testModification(testCase: ModificationTestCase, patcher: FileModification) { +async function testModification(testCase: ModificationTestCase) { const fileName = basename(testCase.fileUrl); const filePath = getPathToFixture(fileName); const originalContent = await downloadOrRetrieveOriginalFile(filePath, testCase.fileUrl); const logger = new Logger(); - patcher = await new testCase.ModificationClass(logger); + const patcher = await new testCase.ModificationClass(logger); const originalPath = patcher.filePath; // @ts-expect-error - Ignore for testing purposes patcher.filePath = filePath; @@ -111,7 +112,7 @@ async function testModification(testCase: ModificationTestCase, patcher: FileMod await expect(revertedContent).toMatch(originalContent); } -async function testInvalidModification(testCase: ModificationTestCase, patcher: FileModification) { +async function testInvalidModification(testCase: ModificationTestCase) { const mockLogger = { log: vi.fn(), error: vi.fn(), @@ -120,7 +121,7 @@ async function testInvalidModification(testCase: ModificationTestCase, patcher: verbose: vi.fn(), }; - patcher = new testCase.ModificationClass(mockLogger as unknown as Logger); + const patcher = new testCase.ModificationClass(mockLogger as unknown as Logger); // @ts-expect-error - Testing invalid pregenerated patches patcher.getPregeneratedPatch = vi.fn().mockResolvedValue('I AM NOT A VALID PATCH'); @@ -140,23 +141,17 @@ async function testInvalidModification(testCase: ModificationTestCase, patcher: const allTestCases = [...patchTestCases, ...simpleTestCases]; describe('File modifications', () => { - let patcher: FileModification; - test.each(allTestCases)( `$fileName modifier correctly applies to fresh install`, async (testCase) => { - await testModification(testCase, patcher); + await testModification(testCase); } ); test.each(patchTestCases)( `$fileName modifier correctly handles invalid content`, async (testCase) => { - await testInvalidModification(testCase, patcher); + await testInvalidModification(testCase); } ); - - afterEach(async () => { - await patcher?.rollback(); - }); }); diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/auth-request.modification.ts b/api/src/unraid-api/unraid-file-modifier/modifications/auth-request.modification.ts index 960fabb9b..55cdd6ff0 100644 --- a/api/src/unraid-api/unraid-file-modifier/modifications/auth-request.modification.ts +++ b/api/src/unraid-api/unraid-file-modifier/modifications/auth-request.modification.ts @@ -7,7 +7,7 @@ import { createPatch } from 'diff'; import { FileModification, ShouldApplyWithReason, -} from '@app/unraid-api/unraid-file-modifier/file-modification'; +} from '@app/unraid-api/unraid-file-modifier/file-modification.js'; export default class AuthRequestModification extends FileModification { public filePath: string = '/usr/local/emhttp/auth-request.php' as const; diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/default-page-layout.modification.ts b/api/src/unraid-api/unraid-file-modifier/modifications/default-page-layout.modification.ts index ff3231d4c..7c9d93c98 100644 --- a/api/src/unraid-api/unraid-file-modifier/modifications/default-page-layout.modification.ts +++ b/api/src/unraid-api/unraid-file-modifier/modifications/default-page-layout.modification.ts @@ -6,7 +6,7 @@ import { createPatch } from 'diff'; import { FileModification, ShouldApplyWithReason, -} from '@app/unraid-api/unraid-file-modifier/file-modification'; +} from '@app/unraid-api/unraid-file-modifier/file-modification.js'; export default class DefaultPageLayoutModification extends FileModification { id: string = 'default-page-layout'; diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/log-rotate.modification.ts b/api/src/unraid-api/unraid-file-modifier/modifications/log-rotate.modification.ts index 0d40703ac..3bded71b0 100644 --- a/api/src/unraid-api/unraid-file-modifier/modifications/log-rotate.modification.ts +++ b/api/src/unraid-api/unraid-file-modifier/modifications/log-rotate.modification.ts @@ -1,11 +1,11 @@ import { Logger } from '@nestjs/common'; import { readFile, rm, writeFile } from 'node:fs/promises'; -import { fileExists } from '@app/core/utils/files/file-exists'; +import { fileExists } from '@app/core/utils/files/file-exists.js'; import { FileModification, ShouldApplyWithReason, -} from '@app/unraid-api/unraid-file-modifier/file-modification'; +} from '@app/unraid-api/unraid-file-modifier/file-modification.js'; export class LogRotateModification extends FileModification { id: string = 'log-rotate'; diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/notifications-page.modification.ts b/api/src/unraid-api/unraid-file-modifier/modifications/notifications-page.modification.ts index 668eee49b..fc160cd02 100644 --- a/api/src/unraid-api/unraid-file-modifier/modifications/notifications-page.modification.ts +++ b/api/src/unraid-api/unraid-file-modifier/modifications/notifications-page.modification.ts @@ -3,7 +3,7 @@ import { readFile } from 'node:fs/promises'; import { FileModification, ShouldApplyWithReason, -} from '@app/unraid-api/unraid-file-modifier/file-modification'; +} from '@app/unraid-api/unraid-file-modifier/file-modification.js'; export default class NotificationsPageModification extends FileModification { id: string = 'notifications-page'; diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/sso.modification.ts b/api/src/unraid-api/unraid-file-modifier/modifications/sso.modification.ts index 07b6df99d..ec4cf0cbe 100644 --- a/api/src/unraid-api/unraid-file-modifier/modifications/sso.modification.ts +++ b/api/src/unraid-api/unraid-file-modifier/modifications/sso.modification.ts @@ -3,7 +3,7 @@ import { readFile } from 'node:fs/promises'; import { FileModification, ShouldApplyWithReason, -} from '@app/unraid-api/unraid-file-modifier/file-modification'; +} from '@app/unraid-api/unraid-file-modifier/file-modification.js'; export default class SSOFileModification extends FileModification { id: string = 'sso'; @@ -83,7 +83,7 @@ function verifyUsernamePasswordAndSSO(string $username, string $password): bool } async shouldApply(): Promise { - const { getters } = await import('@app/store/index'); + const { getters } = await import('@app/store/index.js'); const hasConfiguredSso = getters.config().remote.ssoSubIds.length > 0; return hasConfiguredSso ? { shouldApply: true, reason: 'SSO is configured - enabling support in .login.php' } diff --git a/api/src/unraid-api/unraid-file-modifier/unraid-file-modifier.module.ts b/api/src/unraid-api/unraid-file-modifier/unraid-file-modifier.module.ts index e251c8693..3b6329a28 100644 --- a/api/src/unraid-api/unraid-file-modifier/unraid-file-modifier.module.ts +++ b/api/src/unraid-api/unraid-file-modifier/unraid-file-modifier.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; -import { UnraidFileModificationService } from '@app/unraid-api/unraid-file-modifier/unraid-file-modifier.service'; +import { UnraidFileModificationService } from '@app/unraid-api/unraid-file-modifier/unraid-file-modifier.service.js'; @Module({ providers: [UnraidFileModificationService], diff --git a/api/src/unraid-api/unraid-file-modifier/unraid-file-modifier.service.ts b/api/src/unraid-api/unraid-file-modifier/unraid-file-modifier.service.ts index af7008b2e..363934d90 100644 --- a/api/src/unraid-api/unraid-file-modifier/unraid-file-modifier.service.ts +++ b/api/src/unraid-api/unraid-file-modifier/unraid-file-modifier.service.ts @@ -1,11 +1,11 @@ import { Injectable, Logger, OnModuleDestroy, OnModuleInit } from '@nestjs/common'; -import { FileModification } from '@app/unraid-api/unraid-file-modifier/file-modification'; -import AuthRequestModification from '@app/unraid-api/unraid-file-modifier/modifications/auth-request.modification'; -import DefaultPageLayoutModification from '@app/unraid-api/unraid-file-modifier/modifications/default-page-layout.modification'; -import { LogRotateModification } from '@app/unraid-api/unraid-file-modifier/modifications/log-rotate.modification'; -import NotificationsPageModification from '@app/unraid-api/unraid-file-modifier/modifications/notifications-page.modification'; -import SSOFileModification from '@app/unraid-api/unraid-file-modifier/modifications/sso.modification'; +import { FileModification } from '@app/unraid-api/unraid-file-modifier/file-modification.js'; +import AuthRequestModification from '@app/unraid-api/unraid-file-modifier/modifications/auth-request.modification.js'; +import DefaultPageLayoutModification from '@app/unraid-api/unraid-file-modifier/modifications/default-page-layout.modification.js'; +import { LogRotateModification } from '@app/unraid-api/unraid-file-modifier/modifications/log-rotate.modification.js'; +import NotificationsPageModification from '@app/unraid-api/unraid-file-modifier/modifications/notifications-page.modification.js'; +import SSOFileModification from '@app/unraid-api/unraid-file-modifier/modifications/sso.modification.js'; @Injectable() export class UnraidFileModificationService implements OnModuleInit, OnModuleDestroy { diff --git a/api/src/unraid-api/unraid-file-modifier/unraid-file-modifier.spec.ts b/api/src/unraid-api/unraid-file-modifier/unraid-file-modifier.spec.ts index c9299942f..a1fe59283 100644 --- a/api/src/unraid-api/unraid-file-modifier/unraid-file-modifier.spec.ts +++ b/api/src/unraid-api/unraid-file-modifier/unraid-file-modifier.spec.ts @@ -1,19 +1,26 @@ import { Logger } from '@nestjs/common'; import { Test, TestingModule } from '@nestjs/testing'; import { promises as fs } from 'fs'; -import { join } from 'path'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; import { createPatch } from 'diff'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { fileExistsSync } from '@app/core/utils/files/file-exists'; +import { fileExistsSync } from '@app/core/utils/files/file-exists.js'; import { FileModification, ShouldApplyWithReason, -} from '@app/unraid-api/unraid-file-modifier/file-modification'; -import { UnraidFileModificationService } from '@app/unraid-api/unraid-file-modifier/unraid-file-modifier.service'; +} from '@app/unraid-api/unraid-file-modifier/file-modification.js'; +import { UnraidFileModificationService } from '@app/unraid-api/unraid-file-modifier/unraid-file-modifier.service.js'; -const FIXTURE_PATH = join(__dirname, 'modifications', '__test__', '__fixtures__', 'text-patch-file.txt'); +const FIXTURE_PATH = join( + dirname(fileURLToPath(import.meta.url)), + 'modifications', + '__test__', + '__fixtures__', + 'text-patch-file.txt' +); const ORIGINAL_CONTENT = 'original'; class TestFileModification extends FileModification { diff --git a/api/src/upnp/helpers.ts b/api/src/upnp/helpers.ts index 45e8b009f..700c466eb 100644 --- a/api/src/upnp/helpers.ts +++ b/api/src/upnp/helpers.ts @@ -1,13 +1,13 @@ import type { Mapping } from '@runonflux/nat-upnp'; import { Client } from '@runonflux/nat-upnp'; -import { ONE_HOUR_SECS, THIRTY_SECONDS_MS } from '@app/consts'; -import { upnpLogger } from '@app/core/log'; -import { IS_DOCKER } from '@app/environment'; -import { convertToFuzzyTime } from '@app/mothership/utils/convert-to-fuzzy-time'; -import { getters } from '@app/store'; -import { type LeaseRenewalArgs } from '@app/store/modules/upnp'; -import { MockUpnpClient } from '@app/upnp/mock-upnp-client'; +import { ONE_HOUR_SECS, THIRTY_SECONDS_MS } from '@app/consts.js'; +import { upnpLogger } from '@app/core/log.js'; +import { IS_DOCKER } from '@app/environment.js'; +import { convertToFuzzyTime } from '@app/mothership/utils/convert-to-fuzzy-time.js'; +import { getters } from '@app/store/index.js'; +import { type LeaseRenewalArgs } from '@app/store/modules/upnp.js'; +import { MockUpnpClient } from '@app/upnp/mock-upnp-client.js'; // If we're in docker mode, load the mock client const upnpClient = IS_DOCKER diff --git a/api/src/upnp/jobs.ts b/api/src/upnp/jobs.ts index a4f2eb3ed..3c35ca812 100644 --- a/api/src/upnp/jobs.ts +++ b/api/src/upnp/jobs.ts @@ -1,8 +1,8 @@ import { CronJob } from 'cron'; -import { upnpLogger } from '@app/core/log'; -import { store } from '@app/store'; -import { enableUpnp } from '@app/store/modules/upnp'; +import { upnpLogger } from '@app/core/log.js'; +import { store } from '@app/store/index.js'; +import { enableUpnp } from '@app/store/modules/upnp.js'; class UPNPJobManager { private renewalTask: CronJob | null = null; diff --git a/api/src/utils.ts b/api/src/utils.ts index ab9f72d4a..24835409f 100644 --- a/api/src/utils.ts +++ b/api/src/utils.ts @@ -5,8 +5,8 @@ import { dirname } from 'node:path'; import strftime from 'strftime'; -import { UserAccount } from '@app/graphql/generated/api/types'; -import { FastifyRequest } from '@app/types/fastify'; +import { UserAccount } from '@app/graphql/generated/api/types.js'; +import { FastifyRequest } from '@app/types/fastify.js'; export function notNull(value: T): value is NonNullable { return value !== null; diff --git a/api/tsconfig.json b/api/tsconfig.json index 2e92c1a52..a0908b47f 100644 --- a/api/tsconfig.json +++ b/api/tsconfig.json @@ -20,8 +20,8 @@ }, "skipLibCheck": true, "target": "ESNext", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ - "module": "ESNext", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + "module": "NodeNext", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ + "moduleResolution": "nodenext", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ "allowJs": false, /* Allow javascript files to be compiled. */ "outDir": "./dist", /* Redirect output structure to the directory. */ "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ @@ -35,9 +35,13 @@ "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ "typeRoots": [ - "node_modules/@types/", + "node_modules/@types", + "node_modules", "./src/types/" - ], /* List of folders to include type definitions from. */ + ], + "types": [ + "node", + ], "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, "resolveJsonModule": true, diff --git a/api/vite.config.ts b/api/vite.config.ts index c0fcd6a8b..600468346 100644 --- a/api/vite.config.ts +++ b/api/vite.config.ts @@ -151,6 +151,7 @@ export default defineConfig(({ mode }): ViteUserConfig => { }, maxConcurrency: 10, globals: true, + environment: 'node', coverage: { all: true, include: ['src/**/*'], diff --git a/package.json b/package.json index 16af69a10..3ef7c33d3 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "test": "pnpm -r test", "lint": "pnpm -r lint", "lint:fix": "pnpm -r lint:fix", + "type-check": "pnpm -r type-check", "check": "manypkg check" }, "pnpm": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 40a03bc3c..c7bbbcf91 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,7 +22,7 @@ importers: version: 4.11.3(graphql@16.10.0) '@as-integrations/fastify': specifier: ^2.1.1 - version: 2.1.1(@apollo/server@4.11.3(graphql@16.10.0))(fastify@5.2.1) + version: 2.1.1(@apollo/server@4.11.3(graphql@16.10.0))(fastify@4.28.1) '@fastify/cookie': specifier: ^9.4.0 version: 9.4.0 @@ -43,28 +43,28 @@ importers: version: 10.8.2(graphql@16.10.0) '@nestjs/apollo': specifier: ^12.2.1 - version: 12.2.2(@apollo/server@4.11.3(graphql@16.10.0))(@as-integrations/fastify@2.1.1(@apollo/server@4.11.3(graphql@16.10.0))(fastify@5.2.1))(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/graphql@12.2.2(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1))(graphql@16.10.0)(reflect-metadata@0.1.14))(graphql@16.10.0) + version: 12.2.2(@apollo/server@4.11.3(graphql@16.10.0))(@as-integrations/fastify@2.1.1(@apollo/server@4.11.3(graphql@16.10.0))(fastify@4.28.1))(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/graphql@12.2.2(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2))(graphql@16.10.0)(reflect-metadata@0.1.14))(graphql@16.10.0) '@nestjs/common': specifier: ^10.4.7 - version: 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1) + version: 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2) '@nestjs/core': specifier: ^10.4.7 - version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1) + version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2) '@nestjs/graphql': specifier: ^12.2.1 - version: 12.2.2(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1))(graphql@16.10.0)(reflect-metadata@0.1.14) + version: 12.2.2(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2))(graphql@16.10.0)(reflect-metadata@0.1.14) '@nestjs/passport': specifier: ^10.0.3 - version: 10.0.3(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(passport@0.7.0) + version: 10.0.3(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(passport@0.7.0) '@nestjs/platform-fastify': specifier: ^10.4.7 - version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1)) + version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2)) '@nestjs/schedule': specifier: ^4.1.1 - version: 4.1.2(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1)) + version: 4.1.2(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2)) '@nestjs/throttler': specifier: ^6.2.1 - version: 6.4.0(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14) + version: 6.4.0(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14) '@reduxjs/toolkit': specifier: ^2.3.0 version: 2.5.1(react@19.0.0) @@ -108,7 +108,7 @@ importers: specifier: ^1.2.9 version: 1.2.9 convert: - specifier: ^5.5.1 + specifier: ^5.8.0 version: 5.8.0 cookie: specifier: ^1.0.2 @@ -137,6 +137,9 @@ importers: exit-hook: specifier: ^4.0.0 version: 4.0.0 + fastify: + specifier: ^4.28.1 + version: 4.28.1 filenamify: specifier: ^6.0.0 version: 6.0.0 @@ -150,7 +153,7 @@ importers: specifier: ^3.0.0 version: 3.0.0 got: - specifier: ^14.4.4 + specifier: ^14.4.6 version: 14.4.6 graphql: specifier: ^16.9.0 @@ -196,13 +199,13 @@ importers: version: 4.2.0 nest-authz: specifier: ^2.11.0 - version: 2.14.0(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1) + version: 2.14.0(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2) nest-commander: specifier: ^3.15.0 - version: 3.16.0(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1))(@types/inquirer@8.2.10)(typescript@5.7.3) + version: 3.16.0(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2))(@types/inquirer@8.2.10)(typescript@5.7.3) nestjs-pino: specifier: ^4.1.0 - version: 4.3.0(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(pino-http@10.4.0) + version: 4.3.0(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(pino-http@10.4.0) node-cache: specifier: ^5.1.2 version: 5.1.2 @@ -239,6 +242,9 @@ importers: request: specifier: ^2.88.2 version: 2.88.2 + rxjs: + specifier: ^7.8.2 + version: 7.8.2 semver: specifier: ^7.6.3 version: 7.7.1 @@ -254,10 +260,16 @@ importers: ws: specifier: ^8.18.0 version: 8.18.1 + zen-observable-ts: + specifier: ^1.1.0 + version: 1.1.0 zod: specifier: ^3.23.8 version: 3.24.2 devDependencies: + '@eslint/js': + specifier: ^9.21.0 + version: 9.21.0 '@graphql-codegen/add': specifier: ^5.0.3 version: 5.0.3(graphql@16.10.0) @@ -287,10 +299,10 @@ importers: version: 3.2.0(graphql@16.10.0) '@ianvs/prettier-plugin-sort-imports': specifier: ^4.4.0 - version: 4.4.1(@vue/compiler-sfc@3.5.13)(prettier@3.5.1) + version: 4.4.1(@vue/compiler-sfc@3.5.13)(prettier@3.5.2) '@nestjs/testing': specifier: ^10.4.7 - version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1)) + version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2)) '@originjs/vite-plugin-commonjs': specifier: ^1.0.3 version: 1.0.3 @@ -337,7 +349,7 @@ importers: specifier: ^4.2.5 version: 4.2.5 '@types/node': - specifier: ^22.9.0 + specifier: ^22.13.4 version: 22.13.4 '@types/pify': specifier: ^5.0.4 @@ -373,14 +385,20 @@ importers: specifier: 3.3.0 version: 3.3.0(@types/node@22.13.4)(typescript@5.7.3) eslint: - specifier: ^9.14.0 + specifier: ^9.20.1 version: 9.20.1(jiti@2.4.2) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.31.0(@typescript-eslint/parser@8.24.1(eslint@9.20.1(jiti@2.4.2))(typescript@5.7.3))(eslint@9.20.1(jiti@2.4.2)) eslint-plugin-no-relative-import-paths: specifier: ^1.6.1 version: 1.6.1 + eslint-plugin-node: + specifier: ^11.1.0 + version: 11.1.0(eslint@9.20.1(jiti@2.4.2)) eslint-plugin-prettier: specifier: ^5.2.3 - version: 5.2.3(@types/eslint@9.6.1)(eslint-config-prettier@10.0.1(eslint@9.20.1(jiti@2.4.2)))(eslint@9.20.1(jiti@2.4.2))(prettier@3.5.1) + version: 5.2.3(@types/eslint@9.6.1)(eslint-config-prettier@10.0.1(eslint@9.20.1(jiti@2.4.2)))(eslint@9.20.1(jiti@2.4.2))(prettier@3.5.2) graphql-codegen-typescript-validation-schema: specifier: ^0.17.0 version: 0.17.1(graphql@16.10.0) @@ -390,6 +408,9 @@ importers: nodemon: specifier: ^3.1.7 version: 3.1.9 + prettier: + specifier: ^3.5.2 + version: 3.5.2 rollup-plugin-node-externals: specifier: ^8.0.0 version: 8.0.0(rollup@4.34.6) @@ -1933,9 +1954,6 @@ packages: '@fastify/ajv-compiler@3.6.0': resolution: {integrity: sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ==} - '@fastify/ajv-compiler@4.0.2': - resolution: {integrity: sha512-Rkiu/8wIjpsf46Rr+Fitd3HRP+VsxUFDDeag0hs9L0ksfnwx2g7SPQQTFL0E8Qv+rfXzQOxBJnjUB9ITUDjfWQ==} - '@fastify/cookie@9.4.0': resolution: {integrity: sha512-Th+pt3kEkh4MQD/Q2q1bMuJIB5NX/D5SwSpOKu3G/tjoGbwfpurIMJsWSPS0SJJ4eyjtmQ8OipDQspf8RbUOlg==} @@ -1945,33 +1963,18 @@ packages: '@fastify/error@3.4.1': resolution: {integrity: sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ==} - '@fastify/error@4.0.0': - resolution: {integrity: sha512-OO/SA8As24JtT1usTUTKgGH7uLvhfwZPwlptRi2Dp5P4KKmJI3gvsZ8MIHnNwDs4sLf/aai5LzTyl66xr7qMxA==} - '@fastify/fast-json-stringify-compiler@4.3.0': resolution: {integrity: sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==} - '@fastify/fast-json-stringify-compiler@5.0.2': - resolution: {integrity: sha512-YdR7gqlLg1xZAQa+SX4sMNzQHY5pC54fu9oC5aYSUqBhyn6fkLkrdtKlpVdCNPlwuUuXA1PjFTEmvMF6ZVXVGw==} - '@fastify/formbody@7.4.0': resolution: {integrity: sha512-H3C6h1GN56/SMrZS8N2vCT2cZr7mIHzBHzOBa5OPpjfB/D6FzP9mMpE02ZzrFX0ANeh0BAJdoXKOF2e7IbV+Og==} - '@fastify/forwarded@3.0.0': - resolution: {integrity: sha512-kJExsp4JCms7ipzg7SJ3y8DwmePaELHxKYtg+tZow+k0znUTf3cb+npgyqm8+ATZOdmfgfydIebPDWM172wfyA==} - '@fastify/merge-json-schemas@0.1.1': resolution: {integrity: sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==} - '@fastify/merge-json-schemas@0.2.1': - resolution: {integrity: sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==} - '@fastify/middie@8.3.3': resolution: {integrity: sha512-+WHavMQr9CNTZoy2cjoDxoWp76kZ3JKjAtZj5sXNlxX5XBzHig0TeCPfPc+1+NQmliXtndT3PFwAjrQHE/6wnQ==} - '@fastify/proxy-addr@5.0.0': - resolution: {integrity: sha512-37qVVA1qZ5sgH7KpHkkC4z9SK6StIsIcOmpjvMPXNb3vx2GQxhZocogVYbr2PbbeLCQxYIPDok307xEvRZOzGA==} - '@fig/complete-commander@3.2.0': resolution: {integrity: sha512-1Holl3XtRiANVKURZwgpjCnPuV4RsHp+XC0MhgvyAX/avQwj7F2HUItYOvGi/bXjJCkEzgBZmVfCr0HBA+q+Bw==} peerDependencies: @@ -3137,6 +3140,9 @@ packages: cpu: [x64] os: [win32] + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + '@runonflux/nat-upnp@1.0.2': resolution: {integrity: sha512-XoNiay4AU1V6vsX3NaVYgsgxSYrq9hIcwkWqxfcYcrqB3tRHGMFo9mj3jCxvZEJkZklSFx855cjBI3PDW6FWIg==} @@ -3580,6 +3586,9 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/jsonfile@6.1.4': resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} @@ -3689,6 +3698,9 @@ packages: '@types/wtfnode@0.7.3': resolution: {integrity: sha512-UMkHpx+o2xRWLJ7PmT3bBzvIA9/0oFw80oPtY/xO4jfdq+Gznn4wP7K9B/JjMxyxy+wF+5oRPIykxeBbEDjwRg==} + '@types/zen-observable@0.8.3': + resolution: {integrity: sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw==} + '@typescript-eslint/eslint-plugin@8.24.1': resolution: {integrity: sha512-ll1StnKtBigWIGqvYDVuDmXJHVH4zLVot1yQ4fJtLpL7qacwkxJc1T0bptqw+miBQ/QfUbhl1TcQ4accW5KUyA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4388,10 +4400,30 @@ packages: array-ify@1.0.0: resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} + array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} + array.prototype.findlastindex@1.2.5: + resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + arrify@1.0.1: resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} engines: {node: '>=0.10.0'} @@ -4440,6 +4472,10 @@ packages: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + async-retry@1.3.3: resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} @@ -4486,9 +4522,6 @@ packages: avvio@8.4.0: resolution: {integrity: sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA==} - avvio@9.1.0: - resolution: {integrity: sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw==} - await-lock@2.2.2: resolution: {integrity: sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==} @@ -5397,6 +5430,18 @@ packages: resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} engines: {node: '>=18'} + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + dataloader@2.2.3: resolution: {integrity: sha512-y2krtASINtPFS1rSDjacrFgn1dcUuoREVabwlOGOe4SdxenREqwjwjElAdwvbGM7kgZz9a3KVicWR7vcz8rnzA==} @@ -5666,6 +5711,10 @@ packages: resolution: {integrity: sha512-/0YNa3ZDNeLr/tSckmD69+Gq+qVNhvKfAHNeZJBnp7EOP6RGKV8ORrJHkUn20So5wU+xxT7+1n5u8PjHbfjbSA==} engines: {node: '>= 8.0'} + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} @@ -5810,6 +5859,10 @@ packages: errx@0.1.0: resolution: {integrity: sha512-fZmsRiDNv07K6s2KkKFTiD2aIvECa7++PKyD5NC32tpRw46qZA3sOz+aM+/V9V0GDHxVTKLziveV4JhzBHDp9Q==} + es-abstract@1.23.9: + resolution: {integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==} + engines: {node: '>= 0.4'} + es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} @@ -5832,6 +5885,14 @@ packages: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + es6-error@4.1.1: resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} @@ -6026,12 +6087,49 @@ packages: peerDependencies: eslint: '*' + eslint-module-utils@2.12.0: + resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-es@3.0.1: + resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==} + engines: {node: '>=8.10.0'} + peerDependencies: + eslint: '>=4.19.1' + eslint-plugin-import-x@4.6.1: resolution: {integrity: sha512-wluSUifMIb7UfwWXqx7Yx0lE/SGCcGXECLx/9bCmbY2nneLwvAZ4vkd1IXDjPKFvdcdUgr1BaRnaRpx3k2+Pfw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 + eslint-plugin-import@2.31.0: + resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint-plugin-jsdoc@50.6.3: resolution: {integrity: sha512-NxbJyt1M5zffPcYZ8Nb53/8nnbIScmiLAMdoe0/FAszwb7lcSiX3iYBTsuF7RV84dZZJC8r3NghomrUXsmWvxQ==} engines: {node: '>=18'} @@ -6041,6 +6139,12 @@ packages: eslint-plugin-no-relative-import-paths@1.6.1: resolution: {integrity: sha512-YZNeOnsOrJcwhFw0X29MXjIzu2P/f5X2BZDPWw1R3VUYBRFxNIh77lyoL/XrMU9ewZNQPcEvAgL/cBOT1P330A==} + eslint-plugin-node@11.1.0: + resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==} + engines: {node: '>=8.10.0'} + peerDependencies: + eslint: '>=5.16.0' + eslint-plugin-prettier@5.2.3: resolution: {integrity: sha512-qJ+y0FfCp/mQYQ/vWQ3s7eUlFEL4PyKfAJxsnYTJ4YT73nsJBWqmEpFryxV9OeUiqmsTsYJ5Y+KDNaeP31wrRw==} engines: {node: ^14.18.0 || >=16.0.0} @@ -6096,6 +6200,14 @@ packages: peerDependencies: eslint: ^8.45.0 || ^9.0.0 + eslint-utils@2.1.0: + resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} + engines: {node: '>=6'} + + eslint-visitor-keys@1.3.0: + resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} + engines: {node: '>=4'} + eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -6277,9 +6389,6 @@ packages: fast-json-stringify@5.16.1: resolution: {integrity: sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g==} - fast-json-stringify@6.0.1: - resolution: {integrity: sha512-s7SJE83QKBZwg54dIbD5rCtzOBVD43V1ReWXXYqBgwCwHLYAAT0RQc/FmrQglXqWPpz6omtryJQOau5jI4Nrvg==} - fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} @@ -6315,9 +6424,6 @@ packages: fastify@4.28.1: resolution: {integrity: sha512-kFWUtpNr4i7t5vY2EJPCN2KgMVpuqfU4NjnJNCgiNB900oiDeYqaNDRcAfeBbOF5hGixixxcKnOU4KN9z6QncQ==} - fastify@5.2.1: - resolution: {integrity: sha512-rslrNBF67eg8/Gyn7P2URV8/6pz8kSAscFL4EThZJ8JBMaXacVdVE4hmUcnPNKERl5o/xTiBSLfdowBRhVF1WA==} - fastq@1.19.0: resolution: {integrity: sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==} @@ -6386,10 +6492,6 @@ packages: resolution: {integrity: sha512-Dobi7gcTEq8yszimcfp/R7+owiT4WncAJ7VTTgFH1jYJ5GaG1FbhjwDG820hptN0QDFvzVY3RfCzdInvGPGzjA==} engines: {node: '>=14'} - find-my-way@9.2.0: - resolution: {integrity: sha512-d3uCir8Hmg7W1Ywp8nKf2lJJYU9Nwinvo+1D39Dn09nz65UKXIxUh7j7K8zeWhxqe1WrkS7FJyON/Q/3lPoc6w==} - engines: {node: '>=14'} - find-node-modules@2.1.3: resolution: {integrity: sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg==} @@ -6521,6 +6623,10 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} @@ -6571,6 +6677,10 @@ packages: resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} engines: {node: '>=18'} + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + get-tsconfig@4.10.0: resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} @@ -6867,6 +6977,10 @@ packages: has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + has-symbols@1.1.0: resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} @@ -7139,10 +7253,6 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} - ipaddr.js@2.2.0: - resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==} - engines: {node: '>= 10'} - iron-webcrypto@1.2.1: resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} @@ -7161,6 +7271,10 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + is-bigint@1.1.0: resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} engines: {node: '>= 0.4'} @@ -7185,6 +7299,10 @@ packages: resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} engines: {node: '>= 0.4'} + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + is-date-object@1.1.0: resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} engines: {node: '>= 0.4'} @@ -7206,6 +7324,10 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} @@ -7358,6 +7480,10 @@ packages: resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} engines: {node: '>= 0.4'} + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + is-weakset@2.0.4: resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} engines: {node: '>= 0.4'} @@ -7533,9 +7659,6 @@ packages: json-schema-ref-resolver@1.0.1: resolution: {integrity: sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==} - json-schema-ref-resolver@2.0.1: - resolution: {integrity: sha512-HG0SIB9X4J8bwbxCbnd5FfPEbcXAJYTi1pBJeP/QPON+w8ovSME8iRG+ElHNxZNX2Qh6eYn1GdzJFS4cDFfx0Q==} - json-schema-to-typescript-lite@14.1.0: resolution: {integrity: sha512-b8K6P3aiLgiYKYcHacgZKrwPXPyjekqRPV5vkNfBt0EoohcOSXEbcuGzgi6KQmsAhuy5Mh2KMxofXodRhMxURA==} @@ -7558,6 +7681,10 @@ packages: resolution: {integrity: sha512-rvm6hunfCcqegwYaG5T4yKJWxc9FXFgBVrcTZ4XfSVRwa5HA/Xs+vB/Eo9treYYHCeNM0nrSUr82V/M31Urc7A==} engines: {node: '>= 0.2.0'} + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -7652,9 +7779,6 @@ packages: light-my-request@6.3.0: resolution: {integrity: sha512-bWTAPJmeWQH5suJNYwG0f5cs0p6ho9e6f1Ppoxv5qMosY+s9Ir2+ZLvvHcgA7VTDop4zl/NCHhOVVqU+kd++Ow==} - light-my-request@6.6.0: - resolution: {integrity: sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==} - lilconfig@3.1.3: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} @@ -8384,6 +8508,18 @@ packages: resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} engines: {node: '>= 0.4'} + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + obliterator@2.0.5: resolution: {integrity: sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==} @@ -8460,6 +8596,10 @@ packages: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + p-cancelable@4.0.1: resolution: {integrity: sha512-wBowNApzd45EIKdO1LaU+LrMBwAcjfPaYtVzV3lmfM3gf8Z4CHZsiIqlM8TZZ8okYvh5A1cP6gTfCRQtwUpaUg==} engines: {node: '>=14.16'} @@ -9124,6 +9264,11 @@ packages: engines: {node: '>=14'} hasBin: true + prettier@3.5.2: + resolution: {integrity: sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg==} + engines: {node: '>=14'} + hasBin: true + pretty-bytes@6.1.1: resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} engines: {node: ^14.13.1 || >=16.0.0} @@ -9240,7 +9385,6 @@ packages: engines: {node: '>=0.6.0', teleport: '>=0.2.0'} deprecated: |- You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other. - (For a CapTP with native promises, see @endo/eventual-send and @endo/captp) qs@6.13.0: @@ -9405,6 +9549,10 @@ packages: reflect-metadata@0.1.14: resolution: {integrity: sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==} + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} @@ -9420,6 +9568,10 @@ packages: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} + regexpp@3.2.0: + resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} + engines: {node: '>=8'} + registry-auth-token@5.1.0: resolution: {integrity: sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw==} engines: {node: '>=14'} @@ -9539,10 +9691,6 @@ packages: resolution: {integrity: sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ==} engines: {node: '>=10'} - ret@0.5.0: - resolution: {integrity: sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==} - engines: {node: '>=10'} - retry@0.13.1: resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} engines: {node: '>= 4'} @@ -9603,8 +9751,12 @@ packages: run-series@1.1.9: resolution: {integrity: sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==} - rxjs@7.8.1: - resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} @@ -9612,6 +9764,10 @@ packages: safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + safe-regex-test@1.1.0: resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} engines: {node: '>= 0.4'} @@ -9619,9 +9775,6 @@ packages: safe-regex2@3.1.0: resolution: {integrity: sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug==} - safe-regex2@4.0.1: - resolution: {integrity: sha512-goqsB+bSlOmVX+CiFX2PFc1OV88j5jvBqIM+DgqrucHnUguAUNtiNOs+aTadq2NqsLQ+TQ3UEVG3gtSFcdlkCg==} - safe-stable-stringify@2.5.0: resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} engines: {node: '>=10'} @@ -9662,9 +9815,6 @@ packages: secure-json-parse@2.7.0: resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} - secure-json-parse@3.0.2: - resolution: {integrity: sha512-H6nS2o8bWfpFEV6U38sOSjS7bTbdgbCGU9wEM6W14P5H0QOsz94KCusifV44GpHDTu2nqZbuDNhTzu+mjDSw1w==} - sembear@0.7.0: resolution: {integrity: sha512-XyLTEich2D02FODCkfdto3mB9DetWPLuTzr4tvoofe9SvyM27h4nQSbV3+iVcYQz94AFyKtqBv5pcZbj3k2hdA==} @@ -9724,6 +9874,10 @@ packages: resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} engines: {node: '>= 0.4'} + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + setimmediate@1.0.5: resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} @@ -10001,6 +10155,18 @@ packages: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} @@ -10405,6 +10571,9 @@ packages: typescript: optional: true + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + tsconfig-paths@4.2.0: resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} engines: {node: '>=6'} @@ -10487,6 +10656,22 @@ packages: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} @@ -10531,6 +10716,10 @@ packages: ultrahtml@1.5.3: resolution: {integrity: sha512-GykOvZwgDWZlTQMtp5jrD4BVL+gNn2NVlVafjcFUJ7taY20tqYdwdoWBFy6GBJsNTZe1GkGPkSl5knQAjtgceg==} + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + unc-path-regex@0.1.2: resolution: {integrity: sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==} engines: {node: '>=0.10.0'} @@ -11239,6 +11428,10 @@ packages: resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} engines: {node: '>= 0.4'} + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + which-collection@1.0.2: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} @@ -11438,6 +11631,9 @@ packages: engines: {node: '>=8.0.0'} hasBin: true + zen-observable-ts@1.1.0: + resolution: {integrity: sha512-1h4zlLSqI2cRLPJUHJFL8bCWHhkpuXkF+dbGkRaWjgDIG26DmzyshUMrdV/rL3UnR+mhaX4fRq8LPouq0MYYIA==} + zen-observable-ts@1.2.5: resolution: {integrity: sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==} @@ -11667,10 +11863,10 @@ snapshots: transitivePeerDependencies: - encoding - '@as-integrations/fastify@2.1.1(@apollo/server@4.11.3(graphql@16.10.0))(fastify@5.2.1)': + '@as-integrations/fastify@2.1.1(@apollo/server@4.11.3(graphql@16.10.0))(fastify@4.28.1)': dependencies: '@apollo/server': 4.11.3(graphql@16.10.0) - fastify: 5.2.1 + fastify: 4.28.1 fastify-plugin: 4.5.1 '@asamuzakjp/css-color@2.8.3': @@ -11703,7 +11899,7 @@ snapshots: '@babel/types': 7.26.8 '@types/gensync': 1.0.4 convert-source-map: 2.0.0 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -11723,7 +11919,7 @@ snapshots: '@babel/traverse': 7.26.9 '@babel/types': 7.26.9 convert-source-map: 2.0.0 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -12151,7 +12347,7 @@ snapshots: '@babel/parser': 7.26.8 '@babel/template': 7.26.8 '@babel/types': 7.26.8 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -12163,7 +12359,7 @@ snapshots: '@babel/parser': 7.26.9 '@babel/template': 7.26.9 '@babel/types': 7.26.9 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -12539,7 +12735,7 @@ snapshots: '@eslint/config-array@0.19.2': dependencies: '@eslint/object-schema': 2.1.6 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -12550,7 +12746,7 @@ snapshots: bundle-require: 5.1.0(esbuild@0.24.2) cac: 6.7.14 chokidar: 4.0.3 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) esbuild: 0.24.2 eslint: 9.21.0(jiti@2.4.2) fast-glob: 3.3.3 @@ -12582,7 +12778,7 @@ snapshots: '@eslint/eslintrc@3.2.0': dependencies: ajv: 6.12.6 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) espree: 10.3.0 globals: 14.0.0 ignore: 5.3.2 @@ -12596,7 +12792,7 @@ snapshots: '@eslint/eslintrc@3.3.0': dependencies: ajv: 6.12.6 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) espree: 10.3.0 globals: 14.0.0 ignore: 5.3.2 @@ -12629,12 +12825,6 @@ snapshots: ajv-formats: 2.1.1(ajv@8.17.1) fast-uri: 2.4.0 - '@fastify/ajv-compiler@4.0.2': - dependencies: - ajv: 8.17.1 - ajv-formats: 3.0.1(ajv@8.17.1) - fast-uri: 3.0.6 - '@fastify/cookie@9.4.0': dependencies: cookie-signature: 1.2.2 @@ -12647,31 +12837,19 @@ snapshots: '@fastify/error@3.4.1': {} - '@fastify/error@4.0.0': {} - '@fastify/fast-json-stringify-compiler@4.3.0': dependencies: fast-json-stringify: 5.16.1 - '@fastify/fast-json-stringify-compiler@5.0.2': - dependencies: - fast-json-stringify: 6.0.1 - '@fastify/formbody@7.4.0': dependencies: fast-querystring: 1.1.2 fastify-plugin: 4.5.1 - '@fastify/forwarded@3.0.0': {} - '@fastify/merge-json-schemas@0.1.1': dependencies: fast-deep-equal: 3.1.3 - '@fastify/merge-json-schemas@0.2.1': - dependencies: - dequal: 2.0.3 - '@fastify/middie@8.3.3': dependencies: '@fastify/error': 3.4.1 @@ -12679,15 +12857,10 @@ snapshots: path-to-regexp: 6.3.0 reusify: 1.0.4 - '@fastify/proxy-addr@5.0.0': - dependencies: - '@fastify/forwarded': 3.0.0 - ipaddr.js: 2.2.0 - '@fig/complete-commander@3.2.0(commander@11.1.0)': dependencies: commander: 11.1.0 - prettier: 3.5.1 + prettier: 3.5.2 '@floating-ui/core@1.6.9': dependencies: @@ -12709,10 +12882,10 @@ snapshots: - '@vue/composition-api' - vue - '@golevelup/nestjs-discovery@4.0.3(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1))': + '@golevelup/nestjs-discovery@4.0.3(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2))': dependencies: - '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1) - '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2) lodash: 4.17.21 '@graphql-codegen/add@3.2.3(graphql@16.10.0)': @@ -13016,7 +13189,7 @@ snapshots: dependencies: graphql: 16.10.0 lodash.sortby: 4.7.0 - tslib: 2.6.3 + tslib: 2.8.1 '@graphql-tools/executor-common@0.0.2(graphql@16.10.0)': dependencies: @@ -13175,12 +13348,12 @@ snapshots: '@graphql-tools/optimize@1.4.0(graphql@16.10.0)': dependencies: graphql: 16.10.0 - tslib: 2.6.3 + tslib: 2.8.1 '@graphql-tools/optimize@2.0.0(graphql@16.10.0)': dependencies: graphql: 16.10.0 - tslib: 2.6.3 + tslib: 2.8.1 '@graphql-tools/prisma-loader@8.0.17(@types/node@22.13.4)(graphql@16.10.0)': dependencies: @@ -13189,12 +13362,12 @@ snapshots: '@types/js-yaml': 4.0.9 '@whatwg-node/fetch': 0.10.3 chalk: 4.1.2 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) dotenv: 16.4.7 graphql: 16.10.0 graphql-request: 6.1.0(graphql@16.10.0) http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 + https-proxy-agent: 7.0.6(supports-color@9.4.0) jose: 5.10.0 js-yaml: 4.1.0 lodash: 4.17.21 @@ -13215,7 +13388,7 @@ snapshots: '@ardatan/relay-compiler': 12.0.0(graphql@16.10.0) '@graphql-tools/utils': 9.2.1(graphql@16.10.0) graphql: 16.10.0 - tslib: 2.6.3 + tslib: 2.8.1 transitivePeerDependencies: - encoding - supports-color @@ -13225,7 +13398,7 @@ snapshots: '@ardatan/relay-compiler': 12.0.2(graphql@16.10.0) '@graphql-tools/utils': 10.8.2(graphql@16.10.0) graphql: 16.10.0 - tslib: 2.6.3 + tslib: 2.8.1 transitivePeerDependencies: - encoding @@ -13292,13 +13465,13 @@ snapshots: '@graphql-tools/utils@8.13.1(graphql@16.10.0)': dependencies: graphql: 16.10.0 - tslib: 2.6.3 + tslib: 2.8.1 '@graphql-tools/utils@9.2.1(graphql@16.10.0)': dependencies: '@graphql-typed-document-node/core': 3.2.0(graphql@16.10.0) graphql: 16.10.0 - tslib: 2.6.3 + tslib: 2.8.1 '@graphql-tools/wrap@10.0.30(graphql@16.10.0)': dependencies: @@ -13353,6 +13526,19 @@ snapshots: transitivePeerDependencies: - supports-color + '@ianvs/prettier-plugin-sort-imports@4.4.1(@vue/compiler-sfc@3.5.13)(prettier@3.5.2)': + dependencies: + '@babel/generator': 7.26.8 + '@babel/parser': 7.26.8 + '@babel/traverse': 7.26.8 + '@babel/types': 7.26.8 + prettier: 3.5.2 + semver: 7.7.1 + optionalDependencies: + '@vue/compiler-sfc': 3.5.13 + transitivePeerDependencies: + - supports-color + '@internationalized/date@3.7.0': dependencies: '@swc/helpers': 0.5.15 @@ -13420,7 +13606,7 @@ snapshots: '@koa/router@12.0.2': dependencies: - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) http-errors: 2.0.0 koa-compose: 4.1.0 methods: 1.1.2 @@ -13430,7 +13616,7 @@ snapshots: '@kwsites/file-exists@1.1.1': dependencies: - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -13471,7 +13657,7 @@ snapshots: dependencies: consola: 3.4.0 detect-libc: 2.0.3 - https-proxy-agent: 7.0.6 + https-proxy-agent: 7.0.6(supports-color@9.4.0) node-fetch: 2.7.0 nopt: 8.1.0 semver: 7.7.1 @@ -13521,50 +13707,50 @@ snapshots: '@microsoft/tsdoc@0.14.2': {} - '@nestjs/apollo@12.2.2(@apollo/server@4.11.3(graphql@16.10.0))(@as-integrations/fastify@2.1.1(@apollo/server@4.11.3(graphql@16.10.0))(fastify@5.2.1))(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/graphql@12.2.2(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1))(graphql@16.10.0)(reflect-metadata@0.1.14))(graphql@16.10.0)': + '@nestjs/apollo@12.2.2(@apollo/server@4.11.3(graphql@16.10.0))(@as-integrations/fastify@2.1.1(@apollo/server@4.11.3(graphql@16.10.0))(fastify@4.28.1))(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/graphql@12.2.2(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2))(graphql@16.10.0)(reflect-metadata@0.1.14))(graphql@16.10.0)': dependencies: '@apollo/server': 4.11.3(graphql@16.10.0) '@apollo/server-plugin-landing-page-graphql-playground': 4.0.0(@apollo/server@4.11.3(graphql@16.10.0)) - '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1) - '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1) - '@nestjs/graphql': 12.2.2(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1))(graphql@16.10.0)(reflect-metadata@0.1.14) + '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/graphql': 12.2.2(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2))(graphql@16.10.0)(reflect-metadata@0.1.14) graphql: 16.10.0 iterall: 1.3.0 lodash.omit: 4.5.0 tslib: 2.8.1 optionalDependencies: - '@as-integrations/fastify': 2.1.1(@apollo/server@4.11.3(graphql@16.10.0))(fastify@5.2.1) + '@as-integrations/fastify': 2.1.1(@apollo/server@4.11.3(graphql@16.10.0))(fastify@4.28.1) - '@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1)': + '@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2)': dependencies: iterare: 1.2.1 reflect-metadata: 0.1.14 - rxjs: 7.8.1 + rxjs: 7.8.2 tslib: 2.8.1 uid: 2.0.2 - '@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1)': + '@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2) '@nuxtjs/opencollective': 0.3.2 fast-safe-stringify: 2.1.1 iterare: 1.2.1 path-to-regexp: 3.3.0 reflect-metadata: 0.1.14 - rxjs: 7.8.1 + rxjs: 7.8.2 tslib: 2.8.1 uid: 2.0.2 transitivePeerDependencies: - encoding - '@nestjs/graphql@12.2.2(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1))(graphql@16.10.0)(reflect-metadata@0.1.14)': + '@nestjs/graphql@12.2.2(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2))(graphql@16.10.0)(reflect-metadata@0.1.14)': dependencies: '@graphql-tools/merge': 9.0.11(graphql@16.10.0) '@graphql-tools/schema': 10.0.10(graphql@16.10.0) '@graphql-tools/utils': 10.6.1(graphql@16.10.0) - '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1) - '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1) - '@nestjs/mapped-types': 2.0.6(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14) + '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/mapped-types': 2.0.6(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14) chokidar: 4.0.1 fast-glob: 3.3.2 graphql: 16.10.0 @@ -13581,45 +13767,45 @@ snapshots: - bufferutil - utf-8-validate - '@nestjs/mapped-types@2.0.6(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)': + '@nestjs/mapped-types@2.0.6(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)': dependencies: - '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2) reflect-metadata: 0.1.14 - '@nestjs/passport@10.0.3(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(passport@0.7.0)': + '@nestjs/passport@10.0.3(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(passport@0.7.0)': dependencies: - '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2) passport: 0.7.0 - '@nestjs/platform-fastify@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1))': + '@nestjs/platform-fastify@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2))': dependencies: '@fastify/cors': 9.0.1 '@fastify/formbody': 7.4.0 '@fastify/middie': 8.3.3 - '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1) - '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2) fastify: 4.28.1 light-my-request: 6.3.0 path-to-regexp: 3.3.0 tslib: 2.8.1 - '@nestjs/schedule@4.1.2(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1))': + '@nestjs/schedule@4.1.2(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2))': dependencies: - '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1) - '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2) cron: 3.2.1 uuid: 11.0.3 - '@nestjs/testing@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1))': + '@nestjs/testing@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2))': dependencies: - '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1) - '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2) tslib: 2.8.1 - '@nestjs/throttler@6.4.0(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)': + '@nestjs/throttler@6.4.0(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)': dependencies: - '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1) - '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2) reflect-metadata: 0.1.14 '@netlify/functions@2.8.2': @@ -13823,7 +14009,7 @@ snapshots: dependencies: '@antfu/install-pkg': 1.0.0 '@clack/prompts': 0.10.0 - '@eslint/js': 9.20.0 + '@eslint/js': 9.21.0 '@nuxt/eslint-plugin': 1.1.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3) '@stylistic/eslint-plugin': 4.0.1(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3) '@typescript-eslint/eslint-plugin': 8.24.1(@typescript-eslint/parser@8.24.1(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3) @@ -14169,7 +14355,7 @@ snapshots: '@pm2/pm2-version-check@1.0.4': dependencies: - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -14390,6 +14576,8 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.34.6': optional: true + '@rtsao/scc@1.1.0': {} + '@runonflux/nat-upnp@1.0.2': dependencies: axios: 0.26.1 @@ -14900,7 +15088,7 @@ snapshots: '@types/inquirer@8.2.10': dependencies: '@types/through': 0.0.33 - rxjs: 7.8.1 + rxjs: 7.8.2 '@types/ip@1.1.3': dependencies: @@ -14916,6 +15104,8 @@ snapshots: '@types/json-schema@7.0.15': {} + '@types/json5@0.0.29': {} + '@types/jsonfile@6.1.4': dependencies: '@types/node': 22.13.4 @@ -15023,6 +15213,8 @@ snapshots: '@types/wtfnode@0.7.3': {} + '@types/zen-observable@0.8.3': {} + '@typescript-eslint/eslint-plugin@8.24.1(@typescript-eslint/parser@8.24.1(eslint@9.20.1(jiti@2.4.2))(typescript@5.7.3))(eslint@9.20.1(jiti@2.4.2))(typescript@5.7.3)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -15063,7 +15255,7 @@ snapshots: '@typescript-eslint/types': 8.24.1 '@typescript-eslint/typescript-estree': 8.24.1(typescript@5.7.3) '@typescript-eslint/visitor-keys': 8.24.1 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) eslint: 9.20.1(jiti@2.4.2) typescript: 5.7.3 transitivePeerDependencies: @@ -15075,7 +15267,7 @@ snapshots: '@typescript-eslint/types': 8.24.1 '@typescript-eslint/typescript-estree': 8.24.1(typescript@5.7.3) '@typescript-eslint/visitor-keys': 8.24.1 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) eslint: 9.21.0(jiti@2.4.2) typescript: 5.7.3 transitivePeerDependencies: @@ -15090,7 +15282,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 8.24.1(typescript@5.7.3) '@typescript-eslint/utils': 8.24.1(eslint@9.20.1(jiti@2.4.2))(typescript@5.7.3) - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) eslint: 9.20.1(jiti@2.4.2) ts-api-utils: 2.0.1(typescript@5.7.3) typescript: 5.7.3 @@ -15101,7 +15293,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 8.24.1(typescript@5.7.3) '@typescript-eslint/utils': 8.24.1(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3) - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) eslint: 9.21.0(jiti@2.4.2) ts-api-utils: 2.0.1(typescript@5.7.3) typescript: 5.7.3 @@ -15114,7 +15306,7 @@ snapshots: dependencies: '@typescript-eslint/types': 8.24.1 '@typescript-eslint/visitor-keys': 8.24.1 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 @@ -15260,7 +15452,7 @@ snapshots: dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 @@ -15279,7 +15471,7 @@ snapshots: dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 @@ -16052,8 +16244,50 @@ snapshots: array-ify@1.0.0: {} + array-includes@3.1.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + get-intrinsic: 1.2.7 + is-string: 1.1.1 + array-union@2.1.0: {} + array.prototype.findlastindex@1.2.5: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-shim-unscopables: 1.1.0 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-shim-unscopables: 1.1.0 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + get-intrinsic: 1.2.7 + is-array-buffer: 3.0.5 + arrify@1.0.1: {} asap@2.0.6: {} @@ -16094,6 +16328,8 @@ snapshots: astral-regex@2.0.0: {} + async-function@1.0.0: {} + async-retry@1.3.3: dependencies: retry: 0.13.1 @@ -16135,11 +16371,6 @@ snapshots: '@fastify/error': 3.4.1 fastq: 1.19.0 - avvio@9.1.0: - dependencies: - '@fastify/error': 4.0.0 - fastq: 1.19.0 - await-lock@2.2.2: {} aws-sign2@0.7.0: {} @@ -17036,7 +17267,7 @@ snapshots: cpx2@8.0.0: dependencies: debounce: 2.2.0 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) duplexer: 0.1.2 fs-extra: 11.3.0 glob: 11.0.1 @@ -17234,6 +17465,24 @@ snapshots: whatwg-mimetype: 4.0.0 whatwg-url: 14.1.1 + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-data-view: 1.0.2 + dataloader@2.2.3: {} date-fns@4.1.0: {} @@ -17417,14 +17666,14 @@ snapshots: docker-event-emitter@0.3.0(dockerode@3.3.5): dependencies: - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) dockerode: 3.3.5 transitivePeerDependencies: - supports-color docker-modem@3.0.8: dependencies: - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) readable-stream: 3.6.2 split-ca: 1.0.1 ssh2: 1.16.0 @@ -17439,6 +17688,10 @@ snapshots: transitivePeerDependencies: - supports-color + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + doctrine@3.0.0: dependencies: esutils: 2.0.3 @@ -17585,6 +17838,60 @@ snapshots: errx@0.1.0: {} + es-abstract@1.23.9: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.3 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.2.7 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-regex: 1.2.1 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.18 + es-define-property@1.0.1: {} es-errors@1.3.0: {} @@ -17614,6 +17921,16 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + es6-error@4.1.1: {} esbuild-android-64@0.14.54: @@ -17666,7 +17983,7 @@ snapshots: esbuild-register@3.6.0(esbuild@0.25.0): dependencies: - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) esbuild: 0.25.0 transitivePeerDependencies: - supports-color @@ -17836,12 +18153,28 @@ snapshots: dependencies: eslint: 9.21.0(jiti@2.4.2) + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.24.1(eslint@9.20.1(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint@9.20.1(jiti@2.4.2)): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.24.1(eslint@9.20.1(jiti@2.4.2))(typescript@5.7.3) + eslint: 9.20.1(jiti@2.4.2) + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + + eslint-plugin-es@3.0.1(eslint@9.20.1(jiti@2.4.2)): + dependencies: + eslint: 9.20.1(jiti@2.4.2) + eslint-utils: 2.1.0 + regexpp: 3.2.0 + eslint-plugin-import-x@4.6.1(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3): dependencies: '@types/doctrine': 0.0.9 '@typescript-eslint/scope-manager': 8.24.1 '@typescript-eslint/utils': 8.24.1(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3) - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) doctrine: 3.0.0 enhanced-resolve: 5.18.1 eslint: 9.21.0(jiti@2.4.2) @@ -17856,12 +18189,41 @@ snapshots: - supports-color - typescript + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.1(eslint@9.20.1(jiti@2.4.2))(typescript@5.7.3))(eslint@9.20.1(jiti@2.4.2)): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.20.1(jiti@2.4.2) + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.24.1(eslint@9.20.1(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint@9.20.1(jiti@2.4.2)) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.24.1(eslint@9.20.1(jiti@2.4.2))(typescript@5.7.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + eslint-plugin-jsdoc@50.6.3(eslint@9.21.0(jiti@2.4.2)): dependencies: '@es-joy/jsdoccomment': 0.49.0 are-docs-informative: 0.0.2 comment-parser: 1.4.1 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) escape-string-regexp: 4.0.0 eslint: 9.21.0(jiti@2.4.2) espree: 10.3.0 @@ -17875,10 +18237,20 @@ snapshots: eslint-plugin-no-relative-import-paths@1.6.1: {} - eslint-plugin-prettier@5.2.3(@types/eslint@9.6.1)(eslint-config-prettier@10.0.1(eslint@9.20.1(jiti@2.4.2)))(eslint@9.20.1(jiti@2.4.2))(prettier@3.5.1): + eslint-plugin-node@11.1.0(eslint@9.20.1(jiti@2.4.2)): dependencies: eslint: 9.20.1(jiti@2.4.2) - prettier: 3.5.1 + eslint-plugin-es: 3.0.1(eslint@9.20.1(jiti@2.4.2)) + eslint-utils: 2.1.0 + ignore: 5.3.2 + minimatch: 3.1.2 + resolve: 1.22.10 + semver: 6.3.1 + + eslint-plugin-prettier@5.2.3(@types/eslint@9.6.1)(eslint-config-prettier@10.0.1(eslint@9.20.1(jiti@2.4.2)))(eslint@9.20.1(jiti@2.4.2))(prettier@3.5.2): + dependencies: + eslint: 9.20.1(jiti@2.4.2) + prettier: 3.5.2 prettier-linter-helpers: 1.0.0 synckit: 0.9.2 optionalDependencies: @@ -17970,6 +18342,12 @@ snapshots: json-schema-to-typescript-lite: 14.1.0 ohash: 1.1.4 + eslint-utils@2.1.0: + dependencies: + eslint-visitor-keys: 1.3.0 + + eslint-visitor-keys@1.3.0: {} + eslint-visitor-keys@3.4.3: {} eslint-visitor-keys@4.2.0: {} @@ -17991,7 +18369,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) escape-string-regexp: 4.0.0 eslint-scope: 8.2.0 eslint-visitor-keys: 4.2.0 @@ -18032,7 +18410,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) escape-string-regexp: 4.0.0 eslint-scope: 8.2.0 eslint-visitor-keys: 4.2.0 @@ -18258,15 +18636,6 @@ snapshots: json-schema-ref-resolver: 1.0.1 rfdc: 1.4.1 - fast-json-stringify@6.0.1: - dependencies: - '@fastify/merge-json-schemas': 0.2.1 - ajv: 8.17.1 - ajv-formats: 3.0.1(ajv@8.17.1) - fast-uri: 3.0.6 - json-schema-ref-resolver: 2.0.1 - rfdc: 1.4.1 - fast-levenshtein@2.0.6: {} fast-npm-meta@0.2.2: {} @@ -18310,24 +18679,6 @@ snapshots: semver: 7.7.1 toad-cache: 3.7.0 - fastify@5.2.1: - dependencies: - '@fastify/ajv-compiler': 4.0.2 - '@fastify/error': 4.0.0 - '@fastify/fast-json-stringify-compiler': 5.0.2 - '@fastify/proxy-addr': 5.0.0 - abstract-logging: 2.0.1 - avvio: 9.1.0 - fast-json-stringify: 6.0.1 - find-my-way: 9.2.0 - light-my-request: 6.6.0 - pino: 9.6.0 - process-warning: 4.0.1 - rfdc: 1.4.1 - secure-json-parse: 3.0.2 - semver: 7.7.1 - toad-cache: 3.7.0 - fastq@1.19.0: dependencies: reusify: 1.0.4 @@ -18407,12 +18758,6 @@ snapshots: fast-querystring: 1.1.2 safe-regex2: 3.1.0 - find-my-way@9.2.0: - dependencies: - fast-deep-equal: 3.1.3 - fast-querystring: 1.1.2 - safe-regex2: 4.0.1 - find-node-modules@2.1.3: dependencies: findup-sync: 4.0.0 @@ -18546,6 +18891,15 @@ snapshots: function-bind@1.1.2: {} + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + functions-have-names@1.2.3: {} fuse.js@7.1.0: {} @@ -18594,6 +18948,12 @@ snapshots: '@sec-ant/readable-stream': 0.4.1 is-stream: 4.0.1 + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.7 + get-tsconfig@4.10.0: dependencies: resolve-pkg-maps: 1.0.0 @@ -18602,7 +18962,7 @@ snapshots: dependencies: basic-ftp: 5.0.5 data-uri-to-buffer: 6.0.2 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -18949,6 +19309,10 @@ snapshots: dependencies: es-define-property: 1.0.1 + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + has-symbols@1.1.0: {} has-tostringtag@1.0.2: @@ -19069,7 +19433,7 @@ snapshots: http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.3 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -19113,13 +19477,6 @@ snapshots: quick-lru: 5.1.1 resolve-alpn: 1.2.1 - https-proxy-agent@7.0.6: - dependencies: - agent-base: 7.1.3 - debug: 4.4.0(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - https-proxy-agent@7.0.6(supports-color@9.4.0): dependencies: agent-base: 7.1.3 @@ -19218,7 +19575,7 @@ snapshots: mute-stream: 0.0.8 ora: 5.4.1 run-async: 2.4.1 - rxjs: 7.8.1 + rxjs: 7.8.2 string-width: 4.2.3 strip-ansi: 6.0.1 through: 2.3.8 @@ -19236,7 +19593,7 @@ snapshots: mute-stream: 0.0.8 ora: 5.4.1 run-async: 2.4.1 - rxjs: 7.8.1 + rxjs: 7.8.2 string-width: 4.2.3 strip-ansi: 6.0.1 through: 2.3.8 @@ -19256,7 +19613,7 @@ snapshots: dependencies: '@ioredis/commands': 1.2.0 cluster-key-slot: 1.1.2 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) denque: 2.1.0 lodash.defaults: 4.2.0 lodash.isarguments: 3.1.0 @@ -19275,8 +19632,6 @@ snapshots: ipaddr.js@1.9.1: {} - ipaddr.js@2.2.0: {} - iron-webcrypto@1.2.1: {} is-absolute@1.0.0: @@ -19297,6 +19652,14 @@ snapshots: is-arrayish@0.2.1: {} + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.3 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + is-bigint@1.1.0: dependencies: has-bigints: 1.1.0 @@ -19320,6 +19683,12 @@ snapshots: dependencies: hasown: 2.0.2 + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.3 + get-intrinsic: 1.2.7 + is-typed-array: 1.1.15 + is-date-object@1.1.0: dependencies: call-bound: 1.0.3 @@ -19336,6 +19705,10 @@ snapshots: is-extglob@2.1.1: {} + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.3 + is-fullwidth-code-point@3.0.0: {} is-generator-function@1.1.0: @@ -19364,7 +19737,7 @@ snapshots: is-lower-case@2.0.2: dependencies: - tslib: 2.6.3 + tslib: 2.8.1 is-map@2.0.3: {} @@ -19455,12 +19828,16 @@ snapshots: is-upper-case@2.0.2: dependencies: - tslib: 2.6.3 + tslib: 2.8.1 is-utf8@0.2.1: {} is-weakmap@2.0.2: {} + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.3 + is-weakset@2.0.4: dependencies: call-bound: 1.0.3 @@ -19517,7 +19894,7 @@ snapshots: istanbul-lib-source-maps@5.0.6: dependencies: '@jridgewell/trace-mapping': 0.3.25 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) istanbul-lib-coverage: 3.2.2 transitivePeerDependencies: - supports-color @@ -19600,7 +19977,7 @@ snapshots: form-data: 4.0.2 html-encoding-sniffer: 4.0.0 http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 + https-proxy-agent: 7.0.6(supports-color@9.4.0) is-potential-custom-element-name: 1.0.1 nwsapi: 2.2.16 parse5: 7.2.1 @@ -19636,10 +20013,6 @@ snapshots: dependencies: fast-deep-equal: 3.1.3 - json-schema-ref-resolver@2.0.1: - dependencies: - dequal: 2.0.3 - json-schema-to-typescript-lite@14.1.0: dependencies: '@apidevtools/json-schema-ref-parser': 11.9.1 @@ -19660,6 +20033,10 @@ snapshots: remedial: 1.0.8 remove-trailing-spaces: 1.0.8 + json5@1.0.2: + dependencies: + minimist: 1.2.8 + json5@2.2.3: {} jsonfile@4.0.0: @@ -19713,7 +20090,7 @@ snapshots: koa-send@5.0.1: dependencies: - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) http-errors: 1.8.1 resolve-path: 1.4.0 transitivePeerDependencies: @@ -19733,7 +20110,7 @@ snapshots: content-disposition: 0.5.4 content-type: 1.0.5 cookies: 0.9.1 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) delegates: 1.0.0 depd: 2.0.0 destroy: 1.2.0 @@ -19786,12 +20163,6 @@ snapshots: process-warning: 4.0.1 set-cookie-parser: 2.7.1 - light-my-request@6.6.0: - dependencies: - cookie: 1.0.2 - process-warning: 4.0.1 - set-cookie-parser: 2.7.1 - lilconfig@3.1.3: {} lines-and-columns@1.2.4: {} @@ -19824,7 +20195,7 @@ snapshots: log-update: 4.0.0 p-map: 4.0.0 rfdc: 1.4.1 - rxjs: 7.8.1 + rxjs: 7.8.2 through: 2.3.8 wrap-ansi: 7.0.0 optionalDependencies: @@ -19945,11 +20316,11 @@ snapshots: lower-case-first@2.0.2: dependencies: - tslib: 2.6.3 + tslib: 2.8.1 lower-case@2.0.2: dependencies: - tslib: 2.6.3 + tslib: 2.8.1 lowercase-keys@3.0.0: {} @@ -20239,20 +20610,20 @@ snapshots: neo-async@2.6.2: {} - nest-authz@2.14.0(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1): + nest-authz@2.14.0(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2): dependencies: - '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1) - '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2) casbin: 5.38.0 reflect-metadata: 0.1.14 - rxjs: 7.8.1 + rxjs: 7.8.2 - nest-commander@3.16.0(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1))(@types/inquirer@8.2.10)(typescript@5.7.3): + nest-commander@3.16.0(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2))(@types/inquirer@8.2.10)(typescript@5.7.3): dependencies: '@fig/complete-commander': 3.2.0(commander@11.1.0) - '@golevelup/nestjs-discovery': 4.0.3(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1)) - '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1) - '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@golevelup/nestjs-discovery': 4.0.3(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2)) + '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(reflect-metadata@0.1.14)(rxjs@7.8.2) '@types/inquirer': 8.2.10 commander: 11.1.0 cosmiconfig: 8.3.6(typescript@5.7.3) @@ -20260,9 +20631,9 @@ snapshots: transitivePeerDependencies: - typescript - nestjs-pino@4.3.0(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1))(pino-http@10.4.0): + nestjs-pino@4.3.0(@nestjs/common@10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2))(pino-http@10.4.0): dependencies: - '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/common': 10.4.15(reflect-metadata@0.1.14)(rxjs@7.8.2) pino-http: 10.4.0 netmask@2.0.2: {} @@ -20678,6 +21049,26 @@ snapshots: has-symbols: 1.1.0 object-keys: 1.1.1 + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + obliterator@2.0.5: {} ofetch@1.4.1: @@ -20784,6 +21175,12 @@ snapshots: os-tmpdir@1.0.2: {} + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.2.7 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + p-cancelable@4.0.1: {} p-limit@1.3.0: @@ -20846,10 +21243,10 @@ snapshots: dependencies: '@tootallnate/quickjs-emscripten': 0.23.0 agent-base: 7.1.3 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) get-uri: 6.0.4 http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 + https-proxy-agent: 7.0.6(supports-color@9.4.0) pac-resolver: 7.0.1 socks-proxy-agent: 8.0.5 transitivePeerDependencies: @@ -21107,7 +21504,7 @@ snapshots: pm2-axon-rpc@0.7.1: dependencies: - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -21115,7 +21512,7 @@ snapshots: dependencies: amp: 0.3.1 amp-message: 0.1.2 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) escape-string-regexp: 4.0.0 transitivePeerDependencies: - supports-color @@ -21132,7 +21529,7 @@ snapshots: pm2-sysmonit@1.2.8: dependencies: async: 3.2.6 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) pidusage: 2.0.21 systeminformation: 5.25.11 tx2: 1.0.5 @@ -21154,7 +21551,7 @@ snapshots: commander: 2.15.1 croner: 4.1.97 dayjs: 1.11.13 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) enquirer: 2.3.6 eventemitter2: 5.0.1 fclone: 1.0.11 @@ -21391,7 +21788,7 @@ snapshots: postcss-styl@0.12.3: dependencies: - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) fast-diff: 1.3.0 lodash.sortedlastindex: 4.1.0 postcss: 8.5.3 @@ -21438,6 +21835,8 @@ snapshots: prettier@3.5.1: {} + prettier@3.5.2: {} + pretty-bytes@6.1.1: {} pretty-error@4.0.0: @@ -21500,9 +21899,9 @@ snapshots: proxy-agent@6.3.1: dependencies: agent-base: 7.1.3 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 + https-proxy-agent: 7.0.6(supports-color@9.4.0) lru-cache: 7.18.3 pac-proxy-agent: 7.1.0 proxy-from-env: 1.1.0 @@ -21784,6 +22183,17 @@ snapshots: reflect-metadata@0.1.14: {} + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.2.7 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + regenerator-runtime@0.14.1: {} regexp-ast-analysis@0.7.1: @@ -21802,6 +22212,8 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 + regexpp@3.2.0: {} + registry-auth-token@5.1.0: dependencies: '@pnpm/npm-conf': 2.3.1 @@ -21878,7 +22290,7 @@ snapshots: require-in-the-middle@5.2.0: dependencies: - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) module-details-from-path: 1.0.3 resolve: 1.22.10 transitivePeerDependencies: @@ -21935,8 +22347,6 @@ snapshots: ret@0.4.3: {} - ret@0.5.0: {} - retry@0.13.1: {} reusify@1.0.4: {} @@ -22006,14 +22416,27 @@ snapshots: run-series@1.1.9: {} - rxjs@7.8.1: + rxjs@7.8.2: dependencies: tslib: 2.8.1 + safe-array-concat@1.1.3: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + get-intrinsic: 1.2.7 + has-symbols: 1.1.0 + isarray: 2.0.5 + safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + safe-regex-test@1.1.0: dependencies: call-bound: 1.0.3 @@ -22024,10 +22447,6 @@ snapshots: dependencies: ret: 0.4.3 - safe-regex2@4.0.1: - dependencies: - ret: 0.5.0 - safe-stable-stringify@2.5.0: {} safer-buffer@2.1.2: {} @@ -22063,8 +22482,6 @@ snapshots: secure-json-parse@2.7.0: {} - secure-json-parse@3.0.2: {} - sembear@0.7.0: dependencies: semver: 7.7.1 @@ -22146,6 +22563,12 @@ snapshots: functions-have-names: 1.2.3 has-property-descriptors: 1.0.2 + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + setimmediate@1.0.5: {} setprototypeof@1.1.0: {} @@ -22248,7 +22671,7 @@ snapshots: dependencies: '@kwsites/file-exists': 1.1.1 '@kwsites/promise-deferred': 1.1.1 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -22312,7 +22735,7 @@ snapshots: socks-proxy-agent@8.0.5: dependencies: agent-base: 7.1.3 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) socks: 2.8.4 transitivePeerDependencies: - supports-color @@ -22377,7 +22800,7 @@ snapshots: sponge-case@1.0.1: dependencies: - tslib: 2.6.3 + tslib: 2.8.1 sprintf-js@1.0.3: {} @@ -22484,6 +22907,29 @@ snapshots: get-east-asian-width: 1.3.0 strip-ansi: 7.1.0 + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + string_decoder@1.1.1: dependencies: safe-buffer: 5.1.2 @@ -22543,7 +22989,7 @@ snapshots: stylus@0.57.0: dependencies: css: 3.0.0 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) glob: 7.2.3 safer-buffer: 2.1.2 sax: 1.2.4 @@ -22611,7 +23057,7 @@ snapshots: swap-case@2.0.2: dependencies: - tslib: 2.6.3 + tslib: 2.8.1 symbol-observable@1.2.0: {} @@ -22825,7 +23271,7 @@ snapshots: title-case@3.0.3: dependencies: - tslib: 2.6.3 + tslib: 2.8.1 tldts-core@6.1.78: {} @@ -22894,6 +23340,13 @@ snapshots: optionalDependencies: typescript: 5.7.3 + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + tsconfig-paths@4.2.0: dependencies: json5: 2.2.3 @@ -22957,6 +23410,39 @@ snapshots: media-typer: 0.3.0 mime-types: 2.1.35 + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + typedarray@0.0.6: {} typescript-eslint@8.24.1(eslint@9.20.1(jiti@2.4.2))(typescript@5.7.3): @@ -22988,6 +23474,13 @@ snapshots: ultrahtml@1.5.3: {} + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.3 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + unc-path-regex@0.1.2: {} uncrypto@0.1.3: {} @@ -23196,11 +23689,11 @@ snapshots: upper-case-first@2.0.2: dependencies: - tslib: 2.6.3 + tslib: 2.8.1 upper-case@2.0.2: dependencies: - tslib: 2.6.3 + tslib: 2.8.1 uqr@0.1.2: {} @@ -23268,7 +23761,7 @@ snapshots: vite-node@1.6.1(@types/node@20.17.19)(stylus@0.57.0)(terser@5.39.0): dependencies: cac: 6.7.14 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) pathe: 1.1.2 picocolors: 1.1.1 vite: 5.4.14(@types/node@20.17.19)(stylus@0.57.0)(terser@5.39.0) @@ -23286,7 +23779,7 @@ snapshots: vite-node@2.1.9(@types/node@22.13.4)(stylus@0.57.0)(terser@5.39.0): dependencies: cac: 6.7.14 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) es-module-lexer: 1.6.0 pathe: 1.1.2 vite: 5.4.14(@types/node@22.13.4)(stylus@0.57.0)(terser@5.39.0) @@ -23304,7 +23797,7 @@ snapshots: vite-node@3.0.6(@types/node@22.13.4)(jiti@2.4.2)(stylus@0.57.0)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0): dependencies: cac: 6.7.14 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) es-module-lexer: 1.6.0 pathe: 2.0.3 vite: 6.1.1(@types/node@22.13.4)(jiti@2.4.2)(stylus@0.57.0)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) @@ -23351,7 +23844,7 @@ snapshots: '@microsoft/api-extractor': 7.43.0(@types/node@20.17.19) '@rollup/pluginutils': 5.1.4(rollup@4.34.6) '@vue/language-core': 1.8.27(typescript@5.7.3) - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) kolorist: 1.8.0 magic-string: 0.30.17 typescript: 5.7.3 @@ -23367,7 +23860,7 @@ snapshots: dependencies: '@antfu/utils': 0.7.10 '@rollup/pluginutils': 5.1.4(rollup@4.34.6) - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) error-stack-parser-es: 0.1.5 fs-extra: 11.3.0 open: 10.1.0 @@ -23385,7 +23878,7 @@ snapshots: dependencies: '@antfu/utils': 0.7.10 '@rollup/pluginutils': 5.1.4(rollup@4.34.6) - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) error-stack-parser-es: 0.1.5 fs-extra: 11.3.0 open: 10.1.0 @@ -23400,7 +23893,7 @@ snapshots: vite-plugin-inspect@10.3.0(@nuxt/kit@3.15.4(magicast@0.3.5))(vite@5.4.14(@types/node@22.13.4)(stylus@0.57.0)(terser@5.39.0)): dependencies: ansis: 3.16.0 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) error-stack-parser-es: 1.0.5 open: 10.1.0 sirv: 3.0.1 @@ -23414,7 +23907,7 @@ snapshots: dependencies: '@rollup/pluginutils': 4.2.1 chalk: 4.1.2 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) vite: 6.1.1(@types/node@22.13.4)(jiti@2.4.2)(stylus@0.57.0)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0) optionalDependencies: '@swc/core': 1.10.18(@swc/helpers@0.5.15) @@ -23471,7 +23964,7 @@ snapshots: vite-tsconfig-paths@5.1.4(typescript@5.7.3)(vite@6.1.1(@types/node@22.13.4)(jiti@2.4.2)(stylus@0.57.0)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0)): dependencies: - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) globrex: 0.1.2 tsconfck: 3.1.5(typescript@5.7.3) optionalDependencies: @@ -23539,7 +24032,7 @@ snapshots: '@vitest/utils': 1.6.1 acorn-walk: 8.3.4 chai: 4.5.0 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) execa: 8.0.1 local-pkg: 0.5.1 magic-string: 0.30.17 @@ -23577,7 +24070,7 @@ snapshots: '@vitest/spy': 2.1.9 '@vitest/utils': 2.1.9 chai: 5.2.0 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) expect-type: 1.1.0 magic-string: 0.30.17 pathe: 1.1.2 @@ -23614,7 +24107,7 @@ snapshots: '@vitest/spy': 3.0.6 '@vitest/utils': 3.0.6 chai: 5.2.0 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) expect-type: 1.1.0 magic-string: 0.30.17 pathe: 2.0.3 @@ -23718,7 +24211,7 @@ snapshots: vue-eslint-parser@9.4.3(eslint@9.20.1(jiti@2.4.2)): dependencies: - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) eslint: 9.20.1(jiti@2.4.2) eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 @@ -23731,7 +24224,7 @@ snapshots: vue-eslint-parser@9.4.3(eslint@9.21.0(jiti@2.4.2)): dependencies: - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0(supports-color@9.4.0) eslint: 9.21.0(jiti@2.4.2) eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 @@ -23913,6 +24406,22 @@ snapshots: is-string: 1.1.1 is-symbol: 1.1.1 + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.3 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.0 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.18 + which-collection@1.0.2: dependencies: is-map: 2.0.3 @@ -24084,6 +24593,11 @@ snapshots: optionalDependencies: commander: 9.5.0 + zen-observable-ts@1.1.0: + dependencies: + '@types/zen-observable': 0.8.3 + zen-observable: 0.8.15 + zen-observable-ts@1.2.5: dependencies: zen-observable: 0.8.15 diff --git a/web/components/ConnectSettings/AllowedOrigins.vue b/web/components/ConnectSettings/AllowedOrigins.vue index 34264bcff..97516baf8 100644 --- a/web/components/ConnectSettings/AllowedOrigins.vue +++ b/web/components/ConnectSettings/AllowedOrigins.vue @@ -19,8 +19,7 @@ const origins = computed(() => { try { const newUrl = new URL(origin.trim()); newOrigins.push(newUrl.toString()); - // eslint-disable-next-line @typescript-eslint/no-unused-vars - } catch (e) { + } catch { errors.value.push(`Invalid origin: ${origin}`); } });