diff --git a/doc/release-notes/rl-2511.section.md b/doc/release-notes/rl-2511.section.md index 9213159a4d05..375310c2aa51 100644 --- a/doc/release-notes/rl-2511.section.md +++ b/doc/release-notes/rl-2511.section.md @@ -97,6 +97,8 @@ +- `mealie` has been updated to 3.0.2: This update introduces breaking changes in some API endpoints (see the [release changelog](https://github.com/mealie-recipes/mealie/releases/tag/v3.0.0)) + ### Breaking changes {#sec-nixpkgs-release-25.11-lib-breaking} - `reaction` has been updated to version 2, which includes some breaking changes. diff --git a/nixos/tests/mealie.nix b/nixos/tests/mealie.nix index 97dd4d048f48..3cb8fa23857b 100644 --- a/nixos/tests/mealie.nix +++ b/nixos/tests/mealie.nix @@ -15,6 +15,7 @@ services.mealie = { enable = true; port = 9001; + settings.ALLOW_SIGNUP = "true"; }; }; postgres = { @@ -27,16 +28,83 @@ }; testScript = '' - start_all() + import json + import urllib.parse + + def api_get(node, path, qry={}, **headers): + url = f"http://localhost:9001/api{path}" + if len(qry) > 0: + url += "?" + "&".join([f"{k}={urllib.parse.quote(v)}" for k, v in qry.items()]) + + headers = " ".join([f"-H '{k}: {str(v)}'" for k, v in headers.items()]) + + got = node.succeed(f"curl -s -X GET {headers} --fail {url}") + print(f"* GET {path}\n{got}") + return json.loads(got) + + def api_post(node, path, method="POST", urlencode=False, body={}, qry={}, **headers): + url = f"http://localhost:9001/api{path}" + if len(qry) > 0: + url += "?" + "&".join([f"{k}={urllib.parse.quote(v)}" for k, v in qry.items()]) + + if urlencode: + headers["Content-Type"] = "application/x-www-form-urlencoded" + print("BODY", body) + body = "&".join([f"{k}={urllib.parse.quote(str(v))}" for k, v in body.items()]) + else: + headers["Content-Type"] = "application/json" + body = json.dumps(body) + + headers["Accept"] = "application/json" + headers = " ".join([f"-H '{k}: {str(v)}'" for k, v in headers.items()]) + + got = node.succeed(f"curl -v --fail -X {method} {url} {headers} -d '{body}'") + print(f"* POST {path}\n{got}") + return json.loads(got) def test_mealie(node): node.wait_for_unit("mealie.service") node.wait_for_open_port(9001) node.succeed("curl --fail http://localhost:9001") + got = api_get(node, "/app/about") + assert got["version"] == "v${pkgs.mealie.version}" + + new_user = dict( + email=node.name + ".nomail@no.mail", + username="noname-" + node.name, + fullName="No Name" + node.name, + password="SuperSecure" + node.name, + passwordConfirm="SuperSecure" + node.name, + group="mygroup" + node.name, + ) + got = api_post(node, "/users/register", body=new_user) + got = api_post(node, "/auth/token", urlencode=True, body={ + "username": new_user["username"], + "password": new_user["password"], + "remember_me": False, + }) + assert "access_token" in got + token = "Bearer " + got["access_token"] + + got = api_get(node, "/recipes", authorization=token) + assert got["total"] == 0 + + slug = api_post(node, "/recipes", body={"name": "TestRecipe"}, authorization=token) + recipe = { "description": "Test recipe" } + got = api_post(node, f"/recipes/{slug}", body=recipe, method="PATCH", authorization=token) + got = api_get(node, "/recipes", authorization=token) + assert got["total"] > 0 + assert got["items"][0]["description"] == recipe["description"] + + postgres.start() + test_mealie(postgres) + postgres.send_monitor_command("quit") + postgres.wait_for_shutdown() + + sqlite.start() test_mealie(sqlite) sqlite.send_monitor_command("quit") sqlite.wait_for_shutdown() - test_mealie(postgres) ''; } diff --git a/pkgs/by-name/me/mealie/mealie-frontend.nix b/pkgs/by-name/me/mealie/mealie-frontend.nix index 5132f564e99a..444e0eac309f 100644 --- a/pkgs/by-name/me/mealie/mealie-frontend.nix +++ b/pkgs/by-name/me/mealie/mealie-frontend.nix @@ -1,12 +1,17 @@ src: version: { lib, + fetchFromGitHub, fetchYarnDeps, - nodejs_20, + dart-sass, + nodePackages_latest, fixup-yarn-lock, stdenv, yarn, }: +let + nodejs = nodePackages_latest.nodejs; +in stdenv.mkDerivation { name = "mealie-frontend"; inherit version; @@ -14,27 +19,29 @@ stdenv.mkDerivation { yarnOfflineCache = fetchYarnDeps { yarnLock = "${src}/frontend/yarn.lock"; - hash = "sha256-a2kIOQHaMzaMWId6+SSYN+SPQM2Ipa+F1ztFZgo3R6A="; + hash = "sha256-712mc/xksjXgnc0inthxE+ztSDl/4107oXw3vKcZD2g="; }; nativeBuildInputs = [ fixup-yarn-lock - nodejs_20 - (yarn.override { nodejs = nodejs_20; }) + nodejs + (yarn.override { inherit nodejs; }) ]; configurePhase = '' runHook preConfigure + sed -i 's+"@nuxt/fonts",+// NUXT FONTS DISABLED+g' nuxt.config.ts + export HOME=$(mktemp -d) yarn config --offline set yarn-offline-mirror "$yarnOfflineCache" fixup-yarn-lock yarn.lock - # TODO: Remove --ignore-engines once upstream supports nodejs_20+ - # https://github.com/mealie-recipes/mealie/issues/5400 - # https://github.com/mealie-recipes/mealie/pull/5184 - yarn install --frozen-lockfile --offline --no-progress --non-interactive --ignore-engines + yarn install --frozen-lockfile --offline --no-progress --non-interactive patchShebangs node_modules/ + mkdir -p node_modules/sass-embedded/dist/lib/src/vendor/dart-sass + ln -s ${dart-sass}/bin/dart-sass node_modules/sass-embedded/dist/lib/src/vendor/dart-sass/sass + runHook postConfigure ''; @@ -50,7 +57,7 @@ stdenv.mkDerivation { installPhase = '' runHook preInstall - mv dist $out + mv .output/public $out runHook postInstall ''; diff --git a/pkgs/by-name/me/mealie/package.nix b/pkgs/by-name/me/mealie/package.nix index 6a7897f9a79f..cd20fb65b996 100644 --- a/pkgs/by-name/me/mealie/package.nix +++ b/pkgs/by-name/me/mealie/package.nix @@ -11,12 +11,12 @@ }: let - version = "2.8.0"; + version = "3.0.2"; src = fetchFromGitHub { owner = "mealie-recipes"; repo = "mealie"; tag = "v${version}"; - hash = "sha256-0LUT7OdYoOZTdR/UXJO2eL2Afo2Y7GjBPIrjWUt205E="; + hash = "sha256-0GlHfyoVEqmfTDSN9BGXrLRkStRjWjv2qzZac2oYu7Q="; }; frontend = callPackage (import ./mealie-frontend.nix src version) { }; @@ -24,7 +24,6 @@ let pythonpkgs = python3Packages; python = pythonpkgs.python; in - pythonpkgs.buildPythonApplication rec { pname = "mealie"; inherit version src; @@ -46,9 +45,7 @@ pythonpkgs.buildPythonApplication rec { apprise authlib bcrypt - extruct fastapi - gunicorn html2text httpx ingredient-parser-nlp @@ -58,12 +55,12 @@ pythonpkgs.buildPythonApplication rec { openai orjson paho-mqtt - pillow pillow-heif psycopg2 pydantic-settings pyhumps pyjwt + python-dateutil python-dotenv python-ldap python-multipart