Merge branch 'mealie-next' into feat/standardize-units

This commit is contained in:
Michael Genson
2026-02-25 16:49:13 -06:00
committed by GitHub
53 changed files with 506 additions and 473 deletions

View File

@@ -61,3 +61,11 @@ _(fill-in or delete this section)_
<!-- <!--
Describe how you tested this change. Describe how you tested this change.
--> -->
## AI / LLM Assistance
_(REQUIRED)_
<!--
Describe to which degree an LLM was used in creating this pull request.
-->

View File

@@ -1,7 +1,7 @@
############################################### ###############################################
# Frontend Build # Frontend Build
############################################### ###############################################
FROM node:24@sha256:00e9195ebd49985a6da8921f419978d85dfe354589755192dc090425ce4da2f7 \ FROM node:24@sha256:3a09aa6354567619221ef6c45a5051b671f953f0a1924d1f819ffb236e520e6b \
AS frontend-builder AS frontend-builder
WORKDIR /frontend WORKDIR /frontend

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Must Be A Valid URL", "invalid-url": "Must Be A Valid URL",
"no-whitespace": "No Whitespace Allowed", "no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters", "min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Characters" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "يجب أن يكون عنوان URL صالحًا", "invalid-url": "يجب أن يكون عنوان URL صالحًا",
"no-whitespace": "لا يسمح باستخدام المسافات", "no-whitespace": "لا يسمح باستخدام المسافات",
"min-length": "يجب أن يكون على الأقل {min} أحرف", "min-length": "يجب أن يكون على الأقل {min} أحرف",
"max-length": "يجب أن يكون على الأكثر {max} أحرف" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Линкът трябва да е валиден", "invalid-url": "Линкът трябва да е валиден",
"no-whitespace": "Не са позволени интервали", "no-whitespace": "Не са позволени интервали",
"min-length": "Трябва да съдържа поне {min} знака", "min-length": "Трябва да съдържа поне {min} знака",
"max-length": "Трябва да съдържа най-много {max} знака" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "La URL ha de ser vàlida", "invalid-url": "La URL ha de ser vàlida",
"no-whitespace": "No es permeten espais en blanc", "no-whitespace": "No es permeten espais en blanc",
"min-length": "Ha de tenir almenys {min} caràcters", "min-length": "Ha de tenir almenys {min} caràcters",
"max-length": "Ha de tenir com a màxim {max} caràcters" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Musí být platná URL adresa", "invalid-url": "Musí být platná URL adresa",
"no-whitespace": "Mezery nejsou povoleny", "no-whitespace": "Mezery nejsou povoleny",
"min-length": "Musí být alespoň {min} znaků", "min-length": "Musí být alespoň {min} znaků",
"max-length": "Musí být nejvíce {max} znaků" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "URL'en skal være gyldig", "invalid-url": "URL'en skal være gyldig",
"no-whitespace": "Mellemrum er ikke tilladt", "no-whitespace": "Mellemrum er ikke tilladt",
"min-length": "Der skal mindst være {min} tegn", "min-length": "Der skal mindst være {min} tegn",
"max-length": "Der må højst være {max} tegn" "max-length": "Må højst være {max} tegn|Må højst være {max} tegn"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Muss eine gültige URL sein", "invalid-url": "Muss eine gültige URL sein",
"no-whitespace": "Kein Leerzeichen erlaubt", "no-whitespace": "Kein Leerzeichen erlaubt",
"min-length": "Muss mindestens {min} Zeichen haben", "min-length": "Muss mindestens {min} Zeichen haben",
"max-length": "Darf mindestens {max} Zeichen haben" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Πρέπει να είναι μια έγκυρη διεύθυνση URL", "invalid-url": "Πρέπει να είναι μια έγκυρη διεύθυνση URL",
"no-whitespace": "Δεν επιτρέπονται κενοί χαρακτήρες", "no-whitespace": "Δεν επιτρέπονται κενοί χαρακτήρες",
"min-length": "Πρέπει να αποτελείται από τουλάχιστον {min} χαρακτήρες", "min-length": "Πρέπει να αποτελείται από τουλάχιστον {min} χαρακτήρες",
"max-length": "Πρέπει να αποτελείται το πολύ από {max} χαρακτήρες" "max-length": "Πρέπει να αποτελείται το πολύ από {max} χαρακτήρα|Πρέπει να αποτελείται το πολύ από {max} χαρακτήρες"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Must Be A Valid URL", "invalid-url": "Must Be A Valid URL",
"no-whitespace": "No Whitespace Allowed", "no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters", "min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Characters" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Debe ser una URL válida", "invalid-url": "Debe ser una URL válida",
"no-whitespace": "No se permiten espacios en blanco", "no-whitespace": "No se permiten espacios en blanco",
"min-length": "Debe ser como mínimo {min} caracteres", "min-length": "Debe ser como mínimo {min} caracteres",
"max-length": "Debe ser como máximo {max} caracteres" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Must Be A Valid URL", "invalid-url": "Must Be A Valid URL",
"no-whitespace": "No Whitespace Allowed", "no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters", "min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Characters" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "URL ei ole kelvollinen", "invalid-url": "URL ei ole kelvollinen",
"no-whitespace": "Tekstissä ei saa olla välilyöntejä", "no-whitespace": "Tekstissä ei saa olla välilyöntejä",
"min-length": "Vähimmäispituus on {min} merkkiä", "min-length": "Vähimmäispituus on {min} merkkiä",
"max-length": "Enimmäispituus on {max} merkkiä" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Doit être une URL valide", "invalid-url": "Doit être une URL valide",
"no-whitespace": "Aucun espace n'est autorisé", "no-whitespace": "Aucun espace n'est autorisé",
"min-length": "Doit contenir au moins {min} caractères", "min-length": "Doit contenir au moins {min} caractères",
"max-length": "Doit contenir au maximum {max} caractères" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1423,8 +1423,8 @@
"is-greater-than-or-equal-to": "est supérieur ou égal à", "is-greater-than-or-equal-to": "est supérieur ou égal à",
"is-less-than": "est inférieure à", "is-less-than": "est inférieure à",
"is-less-than-or-equal-to": "est inférieur ou égal à", "is-less-than-or-equal-to": "est inférieur ou égal à",
"is-older-than": "is older than", "is-older-than": "est plus ancien que",
"is-newer-than": "is newer than" "is-newer-than": "est plus récent que"
}, },
"relational-keywords": { "relational-keywords": {
"is": "est", "is": "est",
@@ -1436,7 +1436,7 @@
"is-not-like": "n'est pas similaire à" "is-not-like": "n'est pas similaire à"
}, },
"dates": { "dates": {
"days-ago": "days ago|day ago|days ago" "days-ago": "jours|jour|jours"
} }
}, },
"validators": { "validators": {
@@ -1445,6 +1445,6 @@
"invalid-url": "Doit être une URL valide", "invalid-url": "Doit être une URL valide",
"no-whitespace": "Aucun espace n'est autorisé", "no-whitespace": "Aucun espace n'est autorisé",
"min-length": "", "min-length": "",
"max-length": "Doit contenir au maximum {max} caractères" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Doit être une URL valide", "invalid-url": "Doit être une URL valide",
"no-whitespace": "Aucun espace n'est autorisé", "no-whitespace": "Aucun espace n'est autorisé",
"min-length": "Doit contenir au moins {min} caractères", "min-length": "Doit contenir au moins {min} caractères",
"max-length": "Doit contenir au maximum {max} caractères" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Must Be A Valid URL", "invalid-url": "Must Be A Valid URL",
"no-whitespace": "No Whitespace Allowed", "no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters", "min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Characters" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Must Be A Valid URL", "invalid-url": "Must Be A Valid URL",
"no-whitespace": "No Whitespace Allowed", "no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters", "min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Characters" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Must Be A Valid URL", "invalid-url": "Must Be A Valid URL",
"no-whitespace": "No Whitespace Allowed", "no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters", "min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Characters" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Érvényes URL-nek kell lennie", "invalid-url": "Érvényes URL-nek kell lennie",
"no-whitespace": "Szóközt nem tartalmazhat", "no-whitespace": "Szóközt nem tartalmazhat",
"min-length": "Legalább {min} karakter legyen", "min-length": "Legalább {min} karakter legyen",
"max-length": "Legfeljebb {max} karakter legyen" "max-length": "Legfeljebb {max} karakter lehet|Legfeljebb {max} karakter lehet"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Verður að vera gild vefslóð", "invalid-url": "Verður að vera gild vefslóð",
"no-whitespace": "Engin bil leyfð", "no-whitespace": "Engin bil leyfð",
"min-length": "Verður að vera að lágmarki {min} stafir", "min-length": "Verður að vera að lágmarki {min} stafir",
"max-length": "Má vera að hámarki {max} stafir" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Lo URL Deve Essere Valido", "invalid-url": "Lo URL Deve Essere Valido",
"no-whitespace": "Gli Spazi Non Sono Ammessi", "no-whitespace": "Gli Spazi Non Sono Ammessi",
"min-length": "Deve Essere Almeno {min} Caratteri", "min-length": "Deve Essere Almeno {min} Caratteri",
"max-length": "Deve Essere Al Massimo {max} Caratteri" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Must Be A Valid URL", "invalid-url": "Must Be A Valid URL",
"no-whitespace": "No Whitespace Allowed", "no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters", "min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Characters" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "유효한 URL이어야 합니다.", "invalid-url": "유효한 URL이어야 합니다.",
"no-whitespace": "공백 허용 안 됨", "no-whitespace": "공백 허용 안 됨",
"min-length": "최소 {min}자 이상이어야 합니다", "min-length": "최소 {min}자 이상이어야 합니다",
"max-length": "최대 {min}자 이하여야 합니다" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Must Be A Valid URL", "invalid-url": "Must Be A Valid URL",
"no-whitespace": "No Whitespace Allowed", "no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters", "min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Characters" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Must Be A Valid URL", "invalid-url": "Must Be A Valid URL",
"no-whitespace": "No Whitespace Allowed", "no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters", "min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Characters" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Moet een geldige URL zijn", "invalid-url": "Moet een geldige URL zijn",
"no-whitespace": "Geen spaties toegestaan", "no-whitespace": "Geen spaties toegestaan",
"min-length": "Moet minimaal {min} tekens bevatten", "min-length": "Moet minimaal {min} tekens bevatten",
"max-length": "Zorg dat je {max} tekens gebruikt" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Må være en gyldig nettadresse", "invalid-url": "Må være en gyldig nettadresse",
"no-whitespace": "Ingen mellomrom tillatt", "no-whitespace": "Ingen mellomrom tillatt",
"min-length": "Må minst ha {min} tegn", "min-length": "Må minst ha {min} tegn",
"max-length": "Kan maksimalt ha {max} tegn" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Musi być prawidłowym odnośnikiem", "invalid-url": "Musi być prawidłowym odnośnikiem",
"no-whitespace": "Niedozwolone są puste spacje", "no-whitespace": "Niedozwolone są puste spacje",
"min-length": "Musi zawierać co najmniej {min} znaków", "min-length": "Musi zawierać co najmniej {min} znaków",
"max-length": "Musi zawierać co najwyżej {max} znaków" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Precisa ser uma URL válida", "invalid-url": "Precisa ser uma URL válida",
"no-whitespace": "Nenhum espaço em branco é permitido", "no-whitespace": "Nenhum espaço em branco é permitido",
"min-length": "Precisa ter pelo menos {min} caracteres", "min-length": "Precisa ter pelo menos {min} caracteres",
"max-length": "Pode ter até {max} caracteres" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "O URL deve ser válido", "invalid-url": "O URL deve ser válido",
"no-whitespace": "Não são permitidos espaços em branco", "no-whitespace": "Não são permitidos espaços em branco",
"min-length": "Deve ter pelo menos {min} caracteres", "min-length": "Deve ter pelo menos {min} caracteres",
"max-length": "Deve ter no máximo {max} caracteres" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Trebuie Să Fie Un URL Valid", "invalid-url": "Trebuie Să Fie Un URL Valid",
"no-whitespace": "Niciun Spațiu Alb Permis", "no-whitespace": "Niciun Spațiu Alb Permis",
"min-length": "Trebuie Să Aibă Cel Puțin {min} Caractere", "min-length": "Trebuie Să Aibă Cel Puțin {min} Caractere",
"max-length": "Trebuie Să Aibă Cel Mult {max} Caractere" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Must Be A Valid URL", "invalid-url": "Must Be A Valid URL",
"no-whitespace": "Без пробелов", "no-whitespace": "Без пробелов",
"min-length": "Must Be At Least {min} Characters", "min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Characters" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Musí byť platná URL", "invalid-url": "Musí byť platná URL",
"no-whitespace": "Prázdne znaky nepovolené", "no-whitespace": "Prázdne znaky nepovolené",
"min-length": "Musí mať aspoň {min} znakov", "min-length": "Musí mať aspoň {min} znakov",
"max-length": "Musí mať najviac {max} znakov" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "URL mora biti veljaven", "invalid-url": "URL mora biti veljaven",
"no-whitespace": "Presledki niso dovoljeni", "no-whitespace": "Presledki niso dovoljeni",
"min-length": "Mora vsebovati vsaj {min} znakov", "min-length": "Mora vsebovati vsaj {min} znakov",
"max-length": "Lahko je največ {max} znakov" "max-length": "Največ {max} znakov|Vsebuje lahko največ {max} znakov"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Мора бити валидан URL", "invalid-url": "Мора бити валидан URL",
"no-whitespace": "Размак није дозвољен", "no-whitespace": "Размак није дозвољен",
"min-length": "Мора бити најмање {min} карактера", "min-length": "Мора бити најмање {min} карактера",
"max-length": "Мора бити највише {max} карактера" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Måste var en giltig länk", "invalid-url": "Måste var en giltig länk",
"no-whitespace": "Ingen blanksteg tillåten", "no-whitespace": "Ingen blanksteg tillåten",
"min-length": "Måste vara minst {min} tecken", "min-length": "Måste vara minst {min} tecken",
"max-length": "Måste vara som mest {max} tecken" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Geçerli Bir URL Olmalıdır", "invalid-url": "Geçerli Bir URL Olmalıdır",
"no-whitespace": "No Whitespace Allowed", "no-whitespace": "No Whitespace Allowed",
"min-length": "En Az {min} Karakter Olmalıdır", "min-length": "En Az {min} Karakter Olmalıdır",
"max-length": "En Fazla {max} Karakter Olmalıdır" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Має бути дійсною URL-адресою", "invalid-url": "Має бути дійсною URL-адресою",
"no-whitespace": "Пробіли заборонені", "no-whitespace": "Пробіли заборонені",
"min-length": "Повинно бути не менше ніж {min} символів ", "min-length": "Повинно бути не менше ніж {min} символів ",
"max-length": "Повинно бути не більше ніж {max} символів" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Must Be A Valid URL", "invalid-url": "Must Be A Valid URL",
"no-whitespace": "No Whitespace Allowed", "no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters", "min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Characters" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Must Be A Valid URL", "invalid-url": "Must Be A Valid URL",
"no-whitespace": "No Whitespace Allowed", "no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters", "min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Characters" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

View File

@@ -1445,6 +1445,6 @@
"invalid-url": "Must Be A Valid URL", "invalid-url": "Must Be A Valid URL",
"no-whitespace": "No Whitespace Allowed", "no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters", "min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Characters" "max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -132,8 +132,8 @@
"baby greens": { "baby greens": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "baby greens", "name": "babysalater",
"plural_name": "baby greens" "plural_name": "babysalater"
}, },
"pumpkin": { "pumpkin": {
"aliases": [], "aliases": [],

View File

@@ -5419,8 +5419,8 @@
"zander": { "zander": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "zander", "name": "sandre",
"plural_name": "zanders" "plural_name": "sandres"
}, },
"amberjack": { "amberjack": {
"aliases": [], "aliases": [],
@@ -5485,14 +5485,14 @@
"beluga caviar": { "beluga caviar": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "beluga caviar", "name": "caviar de béluga",
"plural_name": "beluga caviars" "plural_name": "caviars de béluga"
}, },
"bombay duck": { "bombay duck": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "bombay duck", "name": "scopelidé",
"plural_name": "bombay ducks" "plural_name": "scopelidés"
} }
} }
}, },
@@ -5579,8 +5579,8 @@
"octopus": { "octopus": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "octopus", "name": "poulpe",
"plural_name": "octopi" "plural_name": "poulpes"
}, },
"kombu": { "kombu": {
"aliases": [], "aliases": [],
@@ -5609,8 +5609,8 @@
"soft-shell crab": { "soft-shell crab": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "soft-shell crab", "name": "crabe à carapace molle",
"plural_name": "soft-shell crabs" "plural_name": "crabes à carapace molle"
}, },
"scampi": { "scampi": {
"aliases": [], "aliases": [],
@@ -5633,8 +5633,8 @@
"baby squid": { "baby squid": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "baby squid", "name": "jeune calamar",
"plural_name": "baby squids" "plural_name": "jeunes calamars"
}, },
"squid ink": { "squid ink": {
"aliases": [], "aliases": [],
@@ -5651,14 +5651,14 @@
"dulse seaweed": { "dulse seaweed": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "dulse seaweed", "name": "dulse",
"plural_name": "dulse seaweeds" "plural_name": "dulses"
}, },
"roasted seaweed": { "roasted seaweed": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "roasted seaweed", "name": "algue grillée",
"plural_name": "roasted seaweeds" "plural_name": "algues grillées"
}, },
"smoked oyster": { "smoked oyster": {
"aliases": [], "aliases": [],
@@ -5700,25 +5700,25 @@
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "conque", "name": "conque",
"plural_name": "conches" "plural_name": "conques"
}, },
"arame": { "arame": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "arame", "name": "aramé",
"plural_name": "arames" "plural_name": "aramés"
}, },
"calamari steak": { "calamari steak": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "calamari steak", "name": "steak de calamar",
"plural_name": "calamari steaks" "plural_name": "steaks de calamar"
}, },
"mud crab": { "mud crab": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "mud crab", "name": "crabe de mangrove",
"plural_name": "mud crabs" "plural_name": "crabes de mangrove"
}, },
"sea urchin": { "sea urchin": {
"aliases": [], "aliases": [],
@@ -5753,14 +5753,14 @@
"sea snail": { "sea snail": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "sea snail", "name": "limace de mer",
"plural_name": "sea snails" "plural_name": "limaces de mer"
}, },
"aonori": { "aonori": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "aonori", "name": "algue Aonori",
"plural_name": "aonoris" "plural_name": "algues Aonori"
}, },
"prepared crab cake": { "prepared crab cake": {
"aliases": [], "aliases": [],
@@ -5771,8 +5771,8 @@
"sea lettuce": { "sea lettuce": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "sea lettuce", "name": "Ulve",
"plural_name": "sea lettuce" "plural_name": "Ulves"
}, },
"korean seaweed": { "korean seaweed": {
"aliases": [], "aliases": [],
@@ -5783,8 +5783,8 @@
"ogo seaweed": { "ogo seaweed": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "ogo seaweed", "name": "ogonori",
"plural_name": "ogo seaweeds" "plural_name": "ogonoris"
}, },
"seaweed caviar": { "seaweed caviar": {
"aliases": [], "aliases": [],
@@ -5818,7 +5818,7 @@
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "cannelle", "name": "cannelle",
"plural_name": "cinnamon" "plural_name": "cannelle"
}, },
"parsley": { "parsley": {
"aliases": [], "aliases": [],
@@ -5926,13 +5926,13 @@
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "poudre d'oignon", "name": "poudre d'oignon",
"plural_name": "onion powder" "plural_name": "oignon en poudre"
}, },
"ginger powder": { "ginger powder": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "poudre de gingembre", "name": "poudre de gingembre",
"plural_name": "ginger powder" "plural_name": "gingembre en poudre"
}, },
"panch puran": { "panch puran": {
"aliases": [], "aliases": [],
@@ -5968,7 +5968,7 @@
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "paprika fumé", "name": "paprika fumé",
"plural_name": "smoked paprika" "plural_name": "paprika fumé"
}, },
"fresh mint": { "fresh mint": {
"aliases": [], "aliases": [],
@@ -5997,20 +5997,20 @@
"allspice": { "allspice": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "allspice", "name": "quatre-épices",
"plural_name": "allspices" "plural_name": "quatre-épices"
}, },
"cracked pepper": { "cracked pepper": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "cracked pepper", "name": "poivre concassé",
"plural_name": "cracked pepper" "plural_name": "poivres concassés"
}, },
"peppercorn": { "peppercorn": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "peppercorn", "name": "poivre en grains",
"plural_name": "peppercorns" "plural_name": "poivres en grains"
}, },
"mustard seed": { "mustard seed": {
"aliases": [], "aliases": [],
@@ -6051,8 +6051,8 @@
"asafoetida": { "asafoetida": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "asafoetida", "name": "ase fétide",
"plural_name": "asafoetidas" "plural_name": "ase fétide"
}, },
"star anise": { "star anise": {
"aliases": [], "aliases": [],
@@ -6081,8 +6081,8 @@
"garlic granule": { "garlic granule": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "garlic granule", "name": "ail semoule",
"plural_name": "garlic granules" "plural_name": "ail semoule"
}, },
"celery seed": { "celery seed": {
"aliases": [], "aliases": [],
@@ -6358,7 +6358,7 @@
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "poudre de céleri", "name": "poudre de céleri",
"plural_name": "celery powder" "plural_name": "céleri en poudre"
}, },
"black cumin": { "black cumin": {
"aliases": [], "aliases": [],
@@ -6369,8 +6369,8 @@
"anardana": { "anardana": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "anardana", "name": "grenade en graine",
"plural_name": "anardanas" "plural_name": "grenade en graines"
}, },
"vietnamese mint": { "vietnamese mint": {
"aliases": [], "aliases": [],
@@ -6393,14 +6393,14 @@
"lemon verbena": { "lemon verbena": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "lemon verbena", "name": "verveine citronnelle",
"plural_name": "lemon verbenas" "plural_name": "verveines citronnelles"
}, },
"raw stevia": { "raw stevia": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "feuille de stévia brute", "name": "feuille de stévia brute",
"plural_name": "raw stevia" "plural_name": "stevia pur"
}, },
"achiote paste": { "achiote paste": {
"aliases": [], "aliases": [],
@@ -7344,8 +7344,8 @@
"hot curry": { "hot curry": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "hot curry", "name": "curry épicé",
"plural_name": "hot curries" "plural_name": "curry épicé"
}, },
"salt-free seasoning": { "salt-free seasoning": {
"aliases": [], "aliases": [],
@@ -10101,7 +10101,7 @@
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "sourdough bread", "name": "sourdough bread",
"plural_name": "sourdough breads" "plural_name": "pains au levain"
}, },
"rustic italian bread": { "rustic italian bread": {
"aliases": [], "aliases": [],
@@ -10251,7 +10251,7 @@
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "pita chip", "name": "pita chip",
"plural_name": "pita chips" "plural_name": "chips de pain pita"
}, },
"gluten free bread": { "gluten free bread": {
"aliases": [], "aliases": [],
@@ -15787,8 +15787,8 @@
"orange blossom water": { "orange blossom water": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "orange blossom water", "name": "eau de fleur doranger",
"plural_name": "orange blossom water" "plural_name": "eau de fleur doranger"
}, },
"liquid egg white": { "liquid egg white": {
"aliases": [], "aliases": [],

View File

@@ -2866,7 +2866,7 @@
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "zure melk", "name": "zure melk",
"plural_name": "sour milk" "plural_name": "karnemelk"
}, },
"ganache": { "ganache": {
"aliases": [], "aliases": [],
@@ -3003,8 +3003,8 @@
"dahi": { "dahi": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "dahi", "name": "dahi/curd (indiase yoghurt)",
"plural_name": "dahis" "plural_name": "dahi/curd (indiase yoghurt)"
}, },
"cinnamon sugar butter spread": { "cinnamon sugar butter spread": {
"aliases": [], "aliases": [],
@@ -3070,7 +3070,7 @@
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "passievruchten curd", "name": "passievruchten curd",
"plural_name": "passion-fruit curds" "plural_name": "passievrucht curd"
}, },
"pickled egg": { "pickled egg": {
"aliases": [], "aliases": [],
@@ -3893,7 +3893,7 @@
"brisket": { "brisket": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "", "name": "klapstuk",
"plural_name": "klapstukken" "plural_name": "klapstukken"
}, },
"deli ham": { "deli ham": {
@@ -4289,8 +4289,8 @@
"bologna": { "bologna": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "bologna", "name": "bolognese",
"plural_name": "bolognas" "plural_name": "bologneses"
}, },
"burger patty": { "burger patty": {
"aliases": [], "aliases": [],
@@ -4695,13 +4695,13 @@
"wild game bird": { "wild game bird": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "wild game bird", "name": "wild vogel",
"plural_name": "wild game birds" "plural_name": "wild game birds"
}, },
"turkey liver": { "turkey liver": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "turkey liver", "name": "kalkoenen levertjes",
"plural_name": "kalkoen levertjes" "plural_name": "kalkoen levertjes"
}, },
"chicken neck": { "chicken neck": {
@@ -4827,20 +4827,20 @@
"chicken ham": { "chicken ham": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "chicken ham", "name": "kipham",
"plural_name": "chicken hams" "plural_name": "kippenham"
}, },
"duck neck": { "duck neck": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "duck neck", "name": "eendennek",
"plural_name": "duck necks" "plural_name": "eendennekken"
}, },
"chicken chorizo": { "chicken chorizo": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "chicken chorizo", "name": "chorizo van Kip",
"plural_name": "chicken chorizoes" "plural_name": "chorizo's van Kip"
}, },
"chicken frame": { "chicken frame": {
"aliases": [], "aliases": [],
@@ -9540,8 +9540,8 @@
"fettuccine": { "fettuccine": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "fettuccine", "name": "fettucini",
"plural_name": "fettuccines" "plural_name": "fettucini's"
}, },
"orzo": { "orzo": {
"aliases": [], "aliases": [],
@@ -9552,8 +9552,8 @@
"pasta shell": { "pasta shell": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "pasta shell", "name": "pasta schelp",
"plural_name": "pasta shells" "plural_name": "pastaschelpen"
}, },
"bow-tie pasta": { "bow-tie pasta": {
"aliases": [], "aliases": [],
@@ -9571,7 +9571,7 @@
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "tortellini", "name": "tortellini",
"plural_name": "tortellinis" "plural_name": "tortellini's"
}, },
"cheese tortellini": { "cheese tortellini": {
"aliases": [], "aliases": [],

View File

@@ -139,8 +139,8 @@
"abbreviation": "" "abbreviation": ""
}, },
"sprig": { "sprig": {
"name": "sprig", "name": "ág",
"plural_name": "sprigs", "plural_name": "ág",
"description": "", "description": "",
"abbreviation": "" "abbreviation": ""
} }

View File

@@ -337,6 +337,11 @@ class RecipeIngredient(RecipeIngredientBase):
reference_id: UUID = Field(default_factory=uuid4) reference_id: UUID = Field(default_factory=uuid4)
model_config = ConfigDict(from_attributes=True) model_config = ConfigDict(from_attributes=True)
@field_validator("reference_id", mode="before")
@classmethod
def ensure_reference_id(cls, value) -> UUID:
return value or uuid4()
@field_validator("quantity", mode="before") @field_validator("quantity", mode="before")
@classmethod @classmethod
def validate_quantity(cls, value) -> NoneFloat: def validate_quantity(cls, value) -> NoneFloat:

View File

@@ -9,7 +9,7 @@ dependencies = [
"Jinja2==3.1.6", "Jinja2==3.1.6",
"Pillow==12.1.1", "Pillow==12.1.1",
"PyYAML==6.0.3", "PyYAML==6.0.3",
"SQLAlchemy==2.0.46", "SQLAlchemy==2.0.47",
"aiofiles==25.1.0", "aiofiles==25.1.0",
"alembic==1.18.4", "alembic==1.18.4",
"aniso8601==10.0.1", "aniso8601==10.0.1",
@@ -17,7 +17,7 @@ dependencies = [
"apprise==1.9.7", "apprise==1.9.7",
"bcrypt==5.0.0", "bcrypt==5.0.0",
"extruct==0.18.0", "extruct==0.18.0",
"fastapi==0.131.0", "fastapi==0.133.1",
"httpx==0.28.1", "httpx==0.28.1",
"lxml==6.0.2", "lxml==6.0.2",
"orjson==3.11.7", "orjson==3.11.7",
@@ -42,7 +42,7 @@ dependencies = [
"pydantic-settings==2.13.1", "pydantic-settings==2.13.1",
"pillow-heif==1.2.1", "pillow-heif==1.2.1",
"pyjwt==2.11.0", "pyjwt==2.11.0",
"openai==2.23.0", "openai==2.24.0",
"typing-extensions==4.15.0", "typing-extensions==4.15.0",
"itsdangerous==2.2.0", "itsdangerous==2.2.0",
"ingredient-parser-nlp==2.5.0", "ingredient-parser-nlp==2.5.0",

View File

@@ -19,6 +19,7 @@ from recipe_scrapers._schemaorg import SchemaOrg
from recipe_scrapers.plugins import SchemaOrgFillPlugin from recipe_scrapers.plugins import SchemaOrgFillPlugin
from slugify import slugify from slugify import slugify
from mealie.db.models.recipe import RecipeModel
from mealie.pkgs.safehttp.transport import AsyncSafeTransport from mealie.pkgs.safehttp.transport import AsyncSafeTransport
from mealie.schema.cookbook.cookbook import SaveCookBook from mealie.schema.cookbook.cookbook import SaveCookBook
from mealie.schema.recipe.recipe import Recipe, RecipeCategory, RecipeSummary, RecipeTag from mealie.schema.recipe.recipe import Recipe, RecipeCategory, RecipeSummary, RecipeTag
@@ -1252,6 +1253,25 @@ def test_get_recipe_by_slug_or_id(api_client: TestClient, unique_user: utils.Tes
assert recipe_data["id"] == recipe_id assert recipe_data["id"] == recipe_id
def test_get_recipe_ingredient_missing_reference_id(api_client: TestClient, unique_user: utils.TestUser):
slug = random_string()
response = api_client.post(api_routes.recipes, json={"name": slug}, headers=unique_user.token)
assert response.status_code == 201
# Manually edit the database to remove the reference id from the ingredient
session = unique_user.repos.session
recipe = session.query(RecipeModel).filter(RecipeModel.slug == slug).first()
recipe.recipe_ingredient[0].reference_id = None
session.commit()
# Make sure we can fetch the recipe and generate a new reference id
response = api_client.get(api_routes.recipes_slug(slug), headers=unique_user.token)
assert response.status_code == 200
recipe_data = response.json()
assert len(recipe_data["recipeIngredient"]) == 1
assert recipe_data["recipeIngredient"][0].get("referenceId")
@pytest.mark.parametrize("organizer_type", ["tags", "categories", "tools"]) @pytest.mark.parametrize("organizer_type", ["tags", "categories", "tools"])
def test_get_recipes_organizer_filter(api_client: TestClient, unique_user: utils.TestUser, organizer_type: str): def test_get_recipes_organizer_filter(api_client: TestClient, unique_user: utils.TestUser, organizer_type: str):
database = unique_user.repos database = unique_user.repos

View File

@@ -217,7 +217,7 @@ def test_preserve_future_made_date(api_client: TestClient, unique_user: TestUser
future_dt = datetime.now(UTC) + timedelta(days=random_int(1, 10)) future_dt = datetime.now(UTC) + timedelta(days=random_int(1, 10))
response = api_client.patch( response = api_client.patch(
api_routes.recipes_slug_last_made(recipe.slug), api_routes.recipes_slug_last_made(recipe.slug),
data=RecipeLastMade(timestamp=future_dt).model_dump_json(), json=RecipeLastMade(timestamp=future_dt).model_dump(mode="json"),
headers=unique_user.token, headers=unique_user.token,
) )
assert response.status_code == 200 assert response.status_code == 200

38
uv.lock generated
View File

@@ -399,7 +399,7 @@ wheels = [
[[package]] [[package]]
name = "fastapi" name = "fastapi"
version = "0.131.0" version = "0.133.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "annotated-doc" }, { name = "annotated-doc" },
@@ -408,9 +408,9 @@ dependencies = [
{ name = "typing-extensions" }, { name = "typing-extensions" },
{ name = "typing-inspection" }, { name = "typing-inspection" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/91/32/158cbf685b7d5a26f87131069da286bf10fc9fbf7fc968d169d48a45d689/fastapi-0.131.0.tar.gz", hash = "sha256:6531155e52bee2899a932c746c9a8250f210e3c3303a5f7b9f8a808bfe0548ff", size = 369612, upload-time = "2026-02-22T16:38:11.252Z" } sdist = { url = "https://files.pythonhosted.org/packages/22/6f/0eafed8349eea1fa462238b54a624c8b408cd1ba2795c8e64aa6c34f8ab7/fastapi-0.133.1.tar.gz", hash = "sha256:ed152a45912f102592976fde6cbce7dae1a8a1053da94202e51dd35d184fadd6", size = 378741, upload-time = "2026-02-25T18:18:17.398Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/ff/94/b58ec24c321acc2ad1327f69b033cadc005e0f26df9a73828c9e9c7db7ce/fastapi-0.131.0-py3-none-any.whl", hash = "sha256:ed0e53decccf4459de78837ce1b867cd04fa9ce4579497b842579755d20b405a", size = 103854, upload-time = "2026-02-22T16:38:09.814Z" }, { url = "https://files.pythonhosted.org/packages/d2/c9/a175a7779f3599dfa4adfc97a6ce0e157237b3d7941538604aadaf97bfb6/fastapi-0.133.1-py3-none-any.whl", hash = "sha256:658f34ba334605b1617a65adf2ea6461901bdb9af3a3080d63ff791ecf7dc2e2", size = 109029, upload-time = "2026-02-25T18:18:18.578Z" },
] ]
[[package]] [[package]]
@@ -911,7 +911,7 @@ requires-dist = [
{ name = "bcrypt", specifier = "==5.0.0" }, { name = "bcrypt", specifier = "==5.0.0" },
{ name = "beautifulsoup4", specifier = "==4.14.3" }, { name = "beautifulsoup4", specifier = "==4.14.3" },
{ name = "extruct", specifier = "==0.18.0" }, { name = "extruct", specifier = "==0.18.0" },
{ name = "fastapi", specifier = "==0.131.0" }, { name = "fastapi", specifier = "==0.133.1" },
{ name = "html2text", specifier = "==2025.4.15" }, { name = "html2text", specifier = "==2025.4.15" },
{ name = "httpx", specifier = "==0.28.1" }, { name = "httpx", specifier = "==0.28.1" },
{ name = "ingredient-parser-nlp", specifier = "==2.5.0" }, { name = "ingredient-parser-nlp", specifier = "==2.5.0" },
@@ -919,7 +919,7 @@ requires-dist = [
{ name = "itsdangerous", specifier = "==2.2.0" }, { name = "itsdangerous", specifier = "==2.2.0" },
{ name = "jinja2", specifier = "==3.1.6" }, { name = "jinja2", specifier = "==3.1.6" },
{ name = "lxml", specifier = "==6.0.2" }, { name = "lxml", specifier = "==6.0.2" },
{ name = "openai", specifier = "==2.23.0" }, { name = "openai", specifier = "==2.24.0" },
{ name = "orjson", specifier = "==3.11.7" }, { name = "orjson", specifier = "==3.11.7" },
{ name = "paho-mqtt", specifier = "==1.6.1" }, { name = "paho-mqtt", specifier = "==1.6.1" },
{ name = "pillow", specifier = "==12.1.1" }, { name = "pillow", specifier = "==12.1.1" },
@@ -939,7 +939,7 @@ requires-dist = [
{ name = "rapidfuzz", specifier = "==3.14.3" }, { name = "rapidfuzz", specifier = "==3.14.3" },
{ name = "recipe-scrapers", specifier = "==15.11.0" }, { name = "recipe-scrapers", specifier = "==15.11.0" },
{ name = "requests", specifier = "==2.32.5" }, { name = "requests", specifier = "==2.32.5" },
{ name = "sqlalchemy", specifier = "==2.0.46" }, { name = "sqlalchemy", specifier = "==2.0.47" },
{ name = "text-unidecode", specifier = "==1.3" }, { name = "text-unidecode", specifier = "==1.3" },
{ name = "typing-extensions", specifier = "==4.15.0" }, { name = "typing-extensions", specifier = "==4.15.0" },
{ name = "tzdata", specifier = "==2025.3" }, { name = "tzdata", specifier = "==2025.3" },
@@ -1145,7 +1145,7 @@ wheels = [
[[package]] [[package]]
name = "openai" name = "openai"
version = "2.23.0" version = "2.24.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "anyio" }, { name = "anyio" },
@@ -1157,9 +1157,9 @@ dependencies = [
{ name = "tqdm" }, { name = "tqdm" },
{ name = "typing-extensions" }, { name = "typing-extensions" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/61/4b/dc1d84b8237205ebe48a1b1c9c3a8e1ab9fd08b30811b6d787196df58fd6/openai-2.23.0.tar.gz", hash = "sha256:7d24cc8087d5e8eed58e98aaa823391d39d12f9a9a2755770f67c7bb2004d94c", size = 657323, upload-time = "2026-02-24T03:20:20.323Z" } sdist = { url = "https://files.pythonhosted.org/packages/55/13/17e87641b89b74552ed408a92b231283786523edddc95f3545809fab673c/openai-2.24.0.tar.gz", hash = "sha256:1e5769f540dbd01cb33bc4716a23e67b9d695161a734aff9c5f925e2bf99a673", size = 658717, upload-time = "2026-02-24T20:02:07.958Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/1d/5f/bcdf0fb510c24f021e485f920677da363cd59d6e0310171bf2cad6e052b5/openai-2.23.0-py3-none-any.whl", hash = "sha256:1041d40bebf845053fda1946104f8bf9c3e2df957a41c3878c55c72c352630e9", size = 1118971, upload-time = "2026-02-24T03:20:18.708Z" }, { url = "https://files.pythonhosted.org/packages/c9/30/844dc675ee6902579b8eef01ed23917cc9319a1c9c0c14ec6e39340c96d0/openai-2.24.0-py3-none-any.whl", hash = "sha256:fed30480d7d6c884303287bde864980a4b137b60553ffbcf9ab4a233b7a73d94", size = 1120122, upload-time = "2026-02-24T20:02:05.669Z" },
] ]
[[package]] [[package]]
@@ -1794,22 +1794,22 @@ wheels = [
[[package]] [[package]]
name = "sqlalchemy" name = "sqlalchemy"
version = "2.0.46" version = "2.0.47"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" },
{ name = "typing-extensions" }, { name = "typing-extensions" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/06/aa/9ce0f3e7a9829ead5c8ce549392f33a12c4555a6c0609bb27d882e9c7ddf/sqlalchemy-2.0.46.tar.gz", hash = "sha256:cf36851ee7219c170bb0793dbc3da3e80c582e04a5437bc601bfe8c85c9216d7", size = 9865393, upload-time = "2026-01-21T18:03:45.119Z" } sdist = { url = "https://files.pythonhosted.org/packages/cd/4b/1e00561093fe2cd8eef09d406da003c8a118ff02d6548498c1ae677d68d9/sqlalchemy-2.0.47.tar.gz", hash = "sha256:e3e7feb57b267fe897e492b9721ae46d5c7de6f9e8dee58aacf105dc4e154f3d", size = 9886323, upload-time = "2026-02-24T16:34:27.947Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/b6/35/d16bfa235c8b7caba3730bba43e20b1e376d2224f407c178fbf59559f23e/sqlalchemy-2.0.46-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3a9a72b0da8387f15d5810f1facca8f879de9b85af8c645138cba61ea147968c", size = 2153405, upload-time = "2026-01-21T19:05:54.143Z" }, { url = "https://files.pythonhosted.org/packages/80/88/74eb470223ff88ea6572a132c0b8de8c1d8ed7b843d3b44a8a3c77f31d39/sqlalchemy-2.0.47-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4fa91b19d6b9821c04cc8f7aa2476429cc8887b9687c762815aa629f5c0edec1", size = 2155687, upload-time = "2026-02-24T17:05:46.451Z" },
{ url = "https://files.pythonhosted.org/packages/06/6c/3192e24486749862f495ddc6584ed730c0c994a67550ec395d872a2ad650/sqlalchemy-2.0.46-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2347c3f0efc4de367ba00218e0ae5c4ba2306e47216ef80d6e31761ac97cb0b9", size = 3334702, upload-time = "2026-01-21T18:46:45.384Z" }, { url = "https://files.pythonhosted.org/packages/ef/ba/1447d3d558971b036cb93b557595cb5dcdfe728f1c7ac4dec16505ef5756/sqlalchemy-2.0.47-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7c5bbbd14eff577c8c79cbfe39a0771eecd20f430f3678533476f0087138f356", size = 3336978, upload-time = "2026-02-24T17:18:04.597Z" },
{ url = "https://files.pythonhosted.org/packages/ea/a2/b9f33c8d68a3747d972a0bb758c6b63691f8fb8a49014bc3379ba15d4274/sqlalchemy-2.0.46-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9094c8b3197db12aa6f05c51c05daaad0a92b8c9af5388569847b03b1007fb1b", size = 3347664, upload-time = "2026-01-21T18:40:09.979Z" }, { url = "https://files.pythonhosted.org/packages/8a/07/b47472d2ffd0776826f17ccf0b4d01b224c99fbd1904aeb103dffbb4b1cc/sqlalchemy-2.0.47-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a5a6c555da8d4280a3c4c78c5b7a3f990cee2b2884e5f934f87a226191682ff7", size = 3349939, upload-time = "2026-02-24T17:27:18.937Z" },
{ url = "https://files.pythonhosted.org/packages/aa/d2/3e59e2a91eaec9db7e8dc6b37b91489b5caeb054f670f32c95bcba98940f/sqlalchemy-2.0.46-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37fee2164cf21417478b6a906adc1a91d69ae9aba8f9533e67ce882f4bb1de53", size = 3277372, upload-time = "2026-01-21T18:46:47.168Z" }, { url = "https://files.pythonhosted.org/packages/bb/c6/95fa32b79b57769da3e16f054cf658d90940317b5ca0ec20eac84aa19c4f/sqlalchemy-2.0.47-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ed48a1701d24dff3bb49a5bce94d6bc84cbe33d98af2aa2d3cdcce3dea1709ec", size = 3279648, upload-time = "2026-02-24T17:18:07.038Z" },
{ url = "https://files.pythonhosted.org/packages/dd/dd/67bc2e368b524e2192c3927b423798deda72c003e73a1e94c21e74b20a85/sqlalchemy-2.0.46-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b1e14b2f6965a685c7128bd315e27387205429c2e339eeec55cb75ca4ab0ea2e", size = 3312425, upload-time = "2026-01-21T18:40:11.548Z" }, { url = "https://files.pythonhosted.org/packages/bb/c8/3d07e7c73928dc59a0bed40961ca4e313e797bce650b088e8d5fdd3ad939/sqlalchemy-2.0.47-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4f3178c920ad98158f0b6309382194df04b14808fa6052ae07099fdde29d5602", size = 3314695, upload-time = "2026-02-24T17:27:20.93Z" },
{ url = "https://files.pythonhosted.org/packages/43/82/0ecd68e172bfe62247e96cb47867c2d68752566811a4e8c9d8f6e7c38a65/sqlalchemy-2.0.46-cp312-cp312-win32.whl", hash = "sha256:412f26bb4ba942d52016edc8d12fb15d91d3cd46b0047ba46e424213ad407bcb", size = 2113155, upload-time = "2026-01-21T18:42:49.748Z" }, { url = "https://files.pythonhosted.org/packages/6b/d2/ed32b1611c1e19fdb028eee1adc5a9aa138c2952d09ae11f1670170f80ae/sqlalchemy-2.0.47-cp312-cp312-win32.whl", hash = "sha256:b9c11ac9934dd59ece9619fe42780a08abe2faab7b0543bb00d5eabea4f421b9", size = 2115502, upload-time = "2026-02-24T17:22:52.546Z" },
{ url = "https://files.pythonhosted.org/packages/bc/2a/2821a45742073fc0331dc132552b30de68ba9563230853437cac54b2b53e/sqlalchemy-2.0.46-cp312-cp312-win_amd64.whl", hash = "sha256:ea3cd46b6713a10216323cda3333514944e510aa691c945334713fca6b5279ff", size = 2140078, upload-time = "2026-01-21T18:42:51.197Z" }, { url = "https://files.pythonhosted.org/packages/fd/52/9de590356a4dd8e9ef5a881dbba64b2bbc4cbc71bf02bc68e775fb9b1899/sqlalchemy-2.0.47-cp312-cp312-win_amd64.whl", hash = "sha256:db43b72cf8274a99e089755c9c1e0b947159b71adbc2c83c3de2e38d5d607acb", size = 2142435, upload-time = "2026-02-24T17:22:54.268Z" },
{ url = "https://files.pythonhosted.org/packages/fc/a1/9c4efa03300926601c19c18582531b45aededfb961ab3c3585f1e24f120b/sqlalchemy-2.0.46-py3-none-any.whl", hash = "sha256:f9c11766e7e7c0a2767dda5acb006a118640c9fc0a4104214b96269bfb78399e", size = 1937882, upload-time = "2026-01-21T18:22:10.456Z" }, { url = "https://files.pythonhosted.org/packages/15/9f/7c378406b592fcf1fc157248607b495a40e3202ba4a6f1372a2ba6447717/sqlalchemy-2.0.47-py3-none-any.whl", hash = "sha256:e2647043599297a1ef10e720cf310846b7f31b6c841fee093d2b09d81215eb93", size = 1940159, upload-time = "2026-02-24T17:15:07.158Z" },
] ]
[[package]] [[package]]