diff --git a/docs/docs/overrides/api.html b/docs/docs/overrides/api.html
index c018ff466..407b674c4 100644
--- a/docs/docs/overrides/api.html
+++ b/docs/docs/overrides/api.html
@@ -14,7 +14,7 @@
diff --git a/frontend/api/_base.ts b/frontend/api/_base.ts
index 660bf041b..3b3e40c81 100644
--- a/frontend/api/_base.ts
+++ b/frontend/api/_base.ts
@@ -18,33 +18,33 @@ export abstract class BaseAPI {
}
}
-export abstract class BaseCRUDAPI extends BaseAPI implements CrudAPIInterface {
+export abstract class BaseCRUDAPI extends BaseAPI implements CrudAPIInterface {
abstract baseRoute: string;
abstract itemRoute(itemId: string | number): string;
async getAll(start = 0, limit = 9999, params = {} as any) {
- return await this.requests.get(this.baseRoute, {
+ return await this.requests.get(this.baseRoute, {
params: { start, limit, ...params },
});
}
- async createOne(payload: U) {
- return await this.requests.post(this.baseRoute, payload);
+ async createOne(payload: CreateType) {
+ return await this.requests.post(this.baseRoute, payload);
}
async getOne(itemId: string | number) {
- return await this.requests.get(this.itemRoute(itemId));
+ return await this.requests.get(this.itemRoute(itemId));
}
- async updateOne(itemId: string | number, payload: T) {
- return await this.requests.put(this.itemRoute(itemId), payload);
+ async updateOne(itemId: string | number, payload: UpdateType) {
+ return await this.requests.put(this.itemRoute(itemId), payload);
}
- async patchOne(itemId: string, payload: Partial) {
- return await this.requests.patch(this.itemRoute(itemId), payload);
+ async patchOne(itemId: string, payload: Partial) {
+ return await this.requests.patch>(this.itemRoute(itemId), payload);
}
async deleteOne(itemId: string | number) {
- return await this.requests.delete(this.itemRoute(itemId));
+ return await this.requests.delete(this.itemRoute(itemId));
}
}
diff --git a/frontend/api/admin/admin-groups.ts b/frontend/api/admin/admin-groups.ts
index d8781fc86..2f87b3c2a 100644
--- a/frontend/api/admin/admin-groups.ts
+++ b/frontend/api/admin/admin-groups.ts
@@ -1,55 +1,19 @@
import { BaseCRUDAPI } from "../_base";
-import { UserOut } from "~/types/api-types/user";
+import { GroupBase, GroupInDB } from "~/types/api-types/user";
+import { GroupAdminUpdate } from "~/types/api-types/group";
const prefix = "/api";
-export interface Token {
- name: string;
- id: number;
- createdAt: Date;
-}
-
-export interface Preferences {
- privateGroup: boolean;
- firstDayOfWeek: number;
- recipePublic: boolean;
- recipeShowNutrition: boolean;
- recipeShowAssets: boolean;
- recipeLandscapeView: boolean;
- recipeDisableComments: boolean;
- recipeDisableAmount: boolean;
- groupId: number;
- id: number;
-}
-
-export interface GroupCreate {
- name: string;
-}
-
-export interface GroupRead extends GroupCreate {
- id: number;
- categories: any[];
- webhooks: any[];
- users: UserOut[];
- preferences: Preferences;
-}
-
-export interface AdminGroupUpdate {
- name: string;
- id: number;
- preferences: Preferences;
-}
-
const routes = {
adminUsers: `${prefix}/admin/groups`,
- adminUsersId: (id: number) => `${prefix}/admin/groups/${id}`,
+ adminUsersId: (id: string) => `${prefix}/admin/groups/${id}`,
};
-export class AdminGroupsApi extends BaseCRUDAPI {
+export class AdminGroupsApi extends BaseCRUDAPI {
baseRoute: string = routes.adminUsers;
itemRoute = routes.adminUsersId;
- async updateOne(id: number, payload: AdminGroupUpdate) {
+ async updateOne(id: string, payload: GroupAdminUpdate) {
// TODO: This should probably be a patch request, which isn't offered by the API currently
- return await this.requests.put(this.itemRoute(id), payload);
+ return await this.requests.put(this.itemRoute(id), payload);
}
}
diff --git a/frontend/api/admin/admin-tasks.ts b/frontend/api/admin/admin-tasks.ts
index 09e8f0aff..6fdd74488 100644
--- a/frontend/api/admin/admin-tasks.ts
+++ b/frontend/api/admin/admin-tasks.ts
@@ -1,5 +1,5 @@
import { BaseAPI } from "../_base";
-import { ServerTask } from "~/api/types/server-task";
+import { ServerTask } from "~/types/api-types/server";
const prefix = "/api";
diff --git a/frontend/api/admin/admin-users.ts b/frontend/api/admin/admin-users.ts
index f93eac79a..5df7a8287 100644
--- a/frontend/api/admin/admin-users.ts
+++ b/frontend/api/admin/admin-users.ts
@@ -8,7 +8,7 @@ const routes = {
adminUsersId: (tag: string) => `${prefix}/admin/users/${tag}`,
};
-export class AdminUsersApi extends BaseCRUDAPI {
+export class AdminUsersApi extends BaseCRUDAPI {
baseRoute: string = routes.adminUsers;
itemRoute = routes.adminUsersId;
}
diff --git a/frontend/api/class-interfaces/backups.ts b/frontend/api/class-interfaces/backups.ts
index 9f3f08938..ab8ddfae4 100644
--- a/frontend/api/class-interfaces/backups.ts
+++ b/frontend/api/class-interfaces/backups.ts
@@ -1,35 +1,5 @@
import { BaseAPI } from "../_base";
-
-export interface BackupOptions {
- recipes?: boolean;
- settings?: boolean;
- pages?: boolean;
- themes?: boolean;
- groups?: boolean;
- users?: boolean;
- notifications?: boolean;
-}
-
-export interface ImportBackup {
- name: string;
- options: BackupOptions;
-}
-
-export interface BackupJob {
- tag?: string;
- options: BackupOptions;
- templates?: string[];
-}
-
-export interface BackupFile {
- name: string;
- date: string;
-}
-
-export interface AllBackups {
- imports: BackupFile[];
- templates: string[];
-}
+import { AllBackups, BackupOptions, CreateBackup } from "~/types/api-types/admin";
const prefix = "/api";
@@ -52,7 +22,7 @@ export class BackupAPI extends BaseAPI {
/** Generates a backup of the recipe database in json format.
*/
- async createOne(payload: BackupJob) {
+ async createOne(payload: CreateBackup) {
return await this.requests.post(routes.backupsExportDatabase, payload);
}
diff --git a/frontend/api/class-interfaces/email.ts b/frontend/api/class-interfaces/email.ts
index c6faa96f2..91607cf93 100644
--- a/frontend/api/class-interfaces/email.ts
+++ b/frontend/api/class-interfaces/email.ts
@@ -1,4 +1,7 @@
import { BaseAPI } from "../_base";
+import { EmailInitationResponse, EmailInvitation } from "~/types/api-types/group";
+import { ForgotPassword } from "~/types/api-types/user";
+import { EmailTest } from "~/types/api-types/admin";
const routes = {
base: "/api/admin/email",
@@ -7,30 +10,16 @@ const routes = {
invitation: "/api/groups/invitations/email",
};
-export interface EmailResponse {
- success: boolean;
- error: string;
-}
-
-export interface EmailPayload {
- email: string;
-}
-
-export interface InvitationEmail {
- email: string;
- token: string;
-}
-
export class EmailAPI extends BaseAPI {
- test(payload: EmailPayload) {
- return this.requests.post(routes.base, payload);
+ test(payload: EmailTest) {
+ return this.requests.post(routes.base, payload);
}
- sendInvitation(payload: InvitationEmail) {
- return this.requests.post(routes.invitation, payload);
+ sendInvitation(payload: EmailInvitation) {
+ return this.requests.post(routes.invitation, payload);
}
- sendForgotPassword(payload: EmailPayload) {
- return this.requests.post(routes.forgotPassword, payload);
+ sendForgotPassword(payload: ForgotPassword) {
+ return this.requests.post(routes.forgotPassword, payload);
}
}
diff --git a/frontend/api/class-interfaces/group-cookbooks.ts b/frontend/api/class-interfaces/group-cookbooks.ts
index 853c14cff..533a134a6 100644
--- a/frontend/api/class-interfaces/group-cookbooks.ts
+++ b/frontend/api/class-interfaces/group-cookbooks.ts
@@ -8,7 +8,7 @@ const routes = {
cookbooksId: (id: number) => `${prefix}/groups/cookbooks/${id}`,
};
-export class CookbookAPI extends BaseCRUDAPI {
+export class CookbookAPI extends BaseCRUDAPI {
baseRoute: string = routes.cookbooks;
itemRoute = routes.cookbooksId;
diff --git a/frontend/api/class-interfaces/group-event-notifier.ts b/frontend/api/class-interfaces/group-event-notifier.ts
index 8d0ffa646..501baf864 100644
--- a/frontend/api/class-interfaces/group-event-notifier.ts
+++ b/frontend/api/class-interfaces/group-event-notifier.ts
@@ -1,5 +1,5 @@
import { BaseCRUDAPI } from "../_base";
-import { GroupEventNotifierCreate, GroupEventNotifierOut } from "~/types/api-types/group";
+import { GroupEventNotifierCreate, GroupEventNotifierOut, GroupEventNotifierUpdate } from "~/types/api-types/group";
const prefix = "/api";
@@ -8,7 +8,7 @@ const routes = {
eventNotifierId: (id: string | number) => `${prefix}/groups/events/notifications/${id}`,
};
-export class GroupEventNotifierApi extends BaseCRUDAPI {
+export class GroupEventNotifierApi extends BaseCRUDAPI {
baseRoute = routes.eventNotifier;
itemRoute = routes.eventNotifierId;
diff --git a/frontend/api/class-interfaces/group-mealplan-rules.ts b/frontend/api/class-interfaces/group-mealplan-rules.ts
index f4ac4e940..58c13814b 100644
--- a/frontend/api/class-interfaces/group-mealplan-rules.ts
+++ b/frontend/api/class-interfaces/group-mealplan-rules.ts
@@ -8,7 +8,7 @@ const routes = {
ruleId: (id: string | number) => `${prefix}/groups/mealplans/rules/${id}`,
};
-export class MealPlanRulesApi extends BaseCRUDAPI {
+export class MealPlanRulesApi extends BaseCRUDAPI {
baseRoute = routes.rule;
itemRoute = routes.ruleId;
}
diff --git a/frontend/api/class-interfaces/group-mealplan.ts b/frontend/api/class-interfaces/group-mealplan.ts
index e1543605f..02214ba52 100644
--- a/frontend/api/class-interfaces/group-mealplan.ts
+++ b/frontend/api/class-interfaces/group-mealplan.ts
@@ -1,5 +1,5 @@
import { BaseCRUDAPI } from "../_base";
-import { CreatRandomEntry } from "~/types/api-types/meal-plan";
+import { CreatePlanEntry, CreateRandomEntry, ReadPlanEntry, UpdatePlanEntry } from "~/types/api-types/meal-plan";
const prefix = "/api";
@@ -9,31 +9,12 @@ const routes = {
mealplanId: (id: string | number) => `${prefix}/groups/mealplans/${id}`,
};
-type PlanEntryType = "breakfast" | "lunch" | "dinner" | "side";
-
-export interface CreateMealPlan {
- date: string;
- entryType: PlanEntryType;
- title: string;
- text: string;
- recipeId?: string;
-}
-
-export interface UpdateMealPlan extends CreateMealPlan {
- id: number;
- groupId: number;
-}
-
-export interface MealPlan extends UpdateMealPlan {
- recipe: any;
-}
-
-export class MealPlanAPI extends BaseCRUDAPI {
+export class MealPlanAPI extends BaseCRUDAPI {
baseRoute = routes.mealplan;
itemRoute = routes.mealplanId;
- async setRandom(payload: CreatRandomEntry) {
+ async setRandom(payload: CreateRandomEntry) {
console.log(payload);
- return await this.requests.post(routes.random, payload);
+ return await this.requests.post(routes.random, payload);
}
}
diff --git a/frontend/api/class-interfaces/group-migrations.ts b/frontend/api/class-interfaces/group-migrations.ts
index 58e74d439..9f2c1b57f 100644
--- a/frontend/api/class-interfaces/group-migrations.ts
+++ b/frontend/api/class-interfaces/group-migrations.ts
@@ -1,13 +1,11 @@
import { BaseAPI } from "../_base";
-import { ReportSummary } from "./group-reports";
+import { ReportSummary } from "~/types/api-types/reports";
+import { SupportedMigrations } from "~/types/api-types/group";
const prefix = "/api";
-
-export type SupportedMigration = "nextcloud" | "chowdown" | "mealie_alpha" | "paprika";
-
export interface MigrationPayload {
addMigrationTag: boolean;
- migrationType: SupportedMigration;
+ migrationType: SupportedMigrations;
archive: File;
}
diff --git a/frontend/api/class-interfaces/group-multiple-purpose-labels.ts b/frontend/api/class-interfaces/group-multiple-purpose-labels.ts
index 98623a621..5f4299230 100644
--- a/frontend/api/class-interfaces/group-multiple-purpose-labels.ts
+++ b/frontend/api/class-interfaces/group-multiple-purpose-labels.ts
@@ -1,5 +1,5 @@
import { BaseCRUDAPI } from "../_base";
-import { MultiPurposeLabelCreate, MultiPurposeLabelOut } from "~/types/api-types/labels";
+import { MultiPurposeLabelCreate, MultiPurposeLabelOut, MultiPurposeLabelUpdate } from "~/types/api-types/labels";
const prefix = "/api";
@@ -8,7 +8,7 @@ const routes = {
labelsId: (id: string | number) => `${prefix}/groups/labels/${id}`,
};
-export class MultiPurposeLabelsApi extends BaseCRUDAPI {
+export class MultiPurposeLabelsApi extends BaseCRUDAPI {
baseRoute = routes.labels;
itemRoute = routes.labelsId;
}
diff --git a/frontend/api/class-interfaces/group-reports.ts b/frontend/api/class-interfaces/group-reports.ts
index daf8b3909..ca6323cc8 100644
--- a/frontend/api/class-interfaces/group-reports.ts
+++ b/frontend/api/class-interfaces/group-reports.ts
@@ -1,33 +1,8 @@
import { BaseAPI } from "../_base";
+import { ReportCategory, ReportOut, ReportSummary } from "~/types/api-types/reports";
const prefix = "/api";
-export type ReportCategory = "backup" | "restore" | "migration";
-
-export type SummaryStatus = "success" | "failure" | "partial" | "in-progress";
-
-export interface ReportEntry {
- id: string;
- reportId: string;
- timestamp: Date;
- success: boolean;
- message: string;
- exception: string;
-}
-
-export interface ReportSummary {
- id: string;
- timestamp: Date;
- category: ReportCategory;
- groupId: number;
- name: string;
- status: SummaryStatus;
-}
-
-export interface Report extends ReportSummary {
- entries: ReportEntry[];
-}
-
const routes = {
base: `${prefix}/groups/reports`,
getOne: (id: string) => `${prefix}/groups/reports/${id}`,
@@ -40,7 +15,7 @@ export class GroupReportsApi extends BaseAPI {
}
async getOne(id: string) {
- return await this.requests.get(routes.getOne(id));
+ return await this.requests.get(routes.getOne(id));
}
async deleteOne(id: string) {
diff --git a/frontend/api/class-interfaces/group-shopping-lists.ts b/frontend/api/class-interfaces/group-shopping-lists.ts
index 96be394bb..33430de63 100644
--- a/frontend/api/class-interfaces/group-shopping-lists.ts
+++ b/frontend/api/class-interfaces/group-shopping-lists.ts
@@ -4,7 +4,9 @@ import {
ShoppingListCreate,
ShoppingListItemCreate,
ShoppingListItemOut,
+ ShoppingListItemUpdate,
ShoppingListOut,
+ ShoppingListUpdate,
} from "~/types/api-types/group";
const prefix = "/api";
@@ -18,7 +20,7 @@ const routes = {
shoppingListItemsId: (id: string) => `${prefix}/groups/shopping/items/${id}`,
};
-export class ShoppingListsApi extends BaseCRUDAPI {
+export class ShoppingListsApi extends BaseCRUDAPI {
baseRoute = routes.shoppingLists;
itemRoute = routes.shoppingListsId;
@@ -31,7 +33,7 @@ export class ShoppingListsApi extends BaseCRUDAPI {
+export class ShoppingListItemsApi extends BaseCRUDAPI {
baseRoute = routes.shoppingListItems;
itemRoute = routes.shoppingListItemsId;
diff --git a/frontend/api/class-interfaces/group-tasks.ts b/frontend/api/class-interfaces/group-tasks.ts
index efd070afc..4c9c8c5b6 100644
--- a/frontend/api/class-interfaces/group-tasks.ts
+++ b/frontend/api/class-interfaces/group-tasks.ts
@@ -1,5 +1,5 @@
import { BaseAPI } from "../_base";
-import { ServerTask } from "~/api/types/server-task";
+import { ServerTask } from "~/types/api-types/server";
const prefix = "/api";
const routes = {
diff --git a/frontend/api/class-interfaces/group-webhooks.ts b/frontend/api/class-interfaces/group-webhooks.ts
index 7ba72ded0..c6a472c33 100644
--- a/frontend/api/class-interfaces/group-webhooks.ts
+++ b/frontend/api/class-interfaces/group-webhooks.ts
@@ -1,4 +1,5 @@
import { BaseCRUDAPI } from "../_base";
+import { CreateWebhook, ReadWebhook } from "~/types/api-types/group";
const prefix = "/api";
@@ -7,19 +8,7 @@ const routes = {
webhooksId: (id: string | number) => `${prefix}/groups/webhooks/${id}`,
};
-export interface CreateGroupWebhook {
- enabled: boolean;
- name: string;
- url: string;
- time: string;
-}
-
-export interface GroupWebhook extends CreateGroupWebhook {
- id: string;
- groupId: string;
-}
-
-export class WebhooksAPI extends BaseCRUDAPI {
+export class WebhooksAPI extends BaseCRUDAPI {
baseRoute = routes.webhooks;
itemRoute = routes.webhooksId;
}
diff --git a/frontend/api/class-interfaces/groups.ts b/frontend/api/class-interfaces/groups.ts
index 1bd4d872f..d50990045 100644
--- a/frontend/api/class-interfaces/groups.ts
+++ b/frontend/api/class-interfaces/groups.ts
@@ -1,6 +1,6 @@
import { BaseCRUDAPI } from "../_base";
-import { GroupInDB, UserOut } from "~/types/api-types/user";
-import { GroupStatistics, GroupStorage } from "~/types/api-types/group";
+import { CategoryBase, GroupBase, GroupInDB, UserOut } from "~/types/api-types/user";
+import { CreateInviteToken, GroupAdminUpdate, GroupStatistics, GroupStorage, ReadGroupPreferences, ReadInviteToken, SetPermissions, UpdateGroupPreferences } from "~/types/api-types/group";
const prefix = "/api";
@@ -20,82 +20,34 @@ const routes = {
groupsId: (id: string | number) => `${prefix}/admin/groups/${id}`,
};
-interface Category {
- id: number;
- name: string;
- slug: string;
-}
-
-export interface CreateGroup {
- name: string;
-}
-
-export interface UpdatePreferences {
- privateGroup: boolean;
- firstDayOfWeek: number;
- recipePublic: boolean;
- recipeShowNutrition: boolean;
- recipeShowAssets: boolean;
- recipeLandscapeView: boolean;
- recipeDisableComments: boolean;
- recipeDisableAmount: boolean;
-}
-
-export interface Preferences extends UpdatePreferences {
- id: number;
- group_id: number;
-}
-
-export interface Group extends CreateGroup {
- id: number;
- preferences: Preferences;
-}
-
-export interface CreateInvitation {
- uses: number;
-}
-
-export interface Invitation {
- group_id: number;
- token: string;
- uses_left: number;
-}
-
-export interface SetPermissions {
- userId: string;
- canInvite?: boolean;
- canManage?: boolean;
- canOrganize?: boolean;
-}
-
-export class GroupAPI extends BaseCRUDAPI {
+export class GroupAPI extends BaseCRUDAPI {
baseRoute = routes.groups;
itemRoute = routes.groupsId;
/** Returns the Group Data for the Current User
*/
async getCurrentUserGroup() {
- return await this.requests.get(routes.groupsSelf);
+ return await this.requests.get(routes.groupsSelf);
}
async getCategories() {
- return await this.requests.get(routes.categories);
+ return await this.requests.get(routes.categories);
}
- async setCategories(payload: Category[]) {
- return await this.requests.put(routes.categories, payload);
+ async setCategories(payload: CategoryBase[]) {
+ return await this.requests.put(routes.categories, payload);
}
async getPreferences() {
- return await this.requests.get(routes.preferences);
+ return await this.requests.get(routes.preferences);
}
- async setPreferences(payload: UpdatePreferences) {
+ async setPreferences(payload: UpdateGroupPreferences) {
// TODO: This should probably be a patch request, which isn't offered by the API currently
- return await this.requests.put(routes.preferences, payload);
+ return await this.requests.put(routes.preferences, payload);
}
- async createInvitation(payload: CreateInvitation) {
- return await this.requests.post(routes.invitation, payload);
+ async createInvitation(payload: CreateInviteToken) {
+ return await this.requests.post(routes.invitation, payload);
}
async fetchMembers() {
@@ -104,7 +56,7 @@ export class GroupAPI extends BaseCRUDAPI {
async setMemberPermissions(payload: SetPermissions) {
// TODO: This should probably be a patch request, which isn't offered by the API currently
- return await this.requests.put(routes.permissions, payload);
+ return await this.requests.put(routes.permissions, payload);
}
async statistics() {
diff --git a/frontend/api/class-interfaces/organizer-categories.ts b/frontend/api/class-interfaces/organizer-categories.ts
index dba4c6337..be049750a 100644
--- a/frontend/api/class-interfaces/organizer-categories.ts
+++ b/frontend/api/class-interfaces/organizer-categories.ts
@@ -10,7 +10,7 @@ const routes = {
categoriesSlug: (category: string) => `${prefix}/categories/slug/${category}`,
};
-export class CategoriesAPI extends BaseCRUDAPI {
+export class CategoriesAPI extends BaseCRUDAPI {
baseRoute: string = routes.categories;
itemRoute = routes.categoriesId;
diff --git a/frontend/api/class-interfaces/organizer-tags.ts b/frontend/api/class-interfaces/organizer-tags.ts
index 0433a1949..9d7366ea0 100644
--- a/frontend/api/class-interfaces/organizer-tags.ts
+++ b/frontend/api/class-interfaces/organizer-tags.ts
@@ -10,7 +10,7 @@ const routes = {
tagsSlug: (tag: string) => `${prefix}/tags/slug/${tag}`,
};
-export class TagsAPI extends BaseCRUDAPI {
+export class TagsAPI extends BaseCRUDAPI {
baseRoute: string = routes.tags;
itemRoute = routes.tagsId;
diff --git a/frontend/api/class-interfaces/organizer-tools.ts b/frontend/api/class-interfaces/organizer-tools.ts
index fbf29fca9..6dddcb9d6 100644
--- a/frontend/api/class-interfaces/organizer-tools.ts
+++ b/frontend/api/class-interfaces/organizer-tools.ts
@@ -11,7 +11,7 @@ const routes = {
toolsSlug: (id: string) => `${prefix}/tools/slug/${id}`,
};
-export class ToolsApi extends BaseCRUDAPI {
+export class ToolsApi extends BaseCRUDAPI {
baseRoute: string = routes.tools;
itemRoute = routes.toolsId;
diff --git a/frontend/api/class-interfaces/recipe-bulk-actions.ts b/frontend/api/class-interfaces/recipe-bulk-actions.ts
index 9c81fd362..838ea8256 100644
--- a/frontend/api/class-interfaces/recipe-bulk-actions.ts
+++ b/frontend/api/class-interfaces/recipe-bulk-actions.ts
@@ -1,45 +1,10 @@
import { BaseAPI } from "../_base";
+import { AssignCategories, AssignTags, DeleteRecipes, ExportRecipes } from "~/types/api-types/recipe";
+import { GroupDataExport } from "~/types/api-types/group";
-interface BasePayload {
- recipes: string[];
-}
-
-type exportType = "json";
-
+// Many bulk actions return nothing
// eslint-disable-next-line @typescript-eslint/no-empty-interface
-interface RecipeBulkDelete extends BasePayload {}
-
-interface RecipeBulkExport extends BasePayload {
- exportType: exportType;
-}
-
-interface RecipeBulkCategorize extends BasePayload {
- categories: string[];
-}
-
-interface RecipeBulkTag extends BasePayload {
- tags: string[];
-}
-
-interface BulkActionError {
- recipe: string;
- error: string;
-}
-
interface BulkActionResponse {
- success: boolean;
- message: string;
- errors: BulkActionError[];
-}
-
-export interface GroupDataExport {
- id: string;
- groupId: string;
- name: string;
- filename: string;
- path: string;
- size: string;
- expires: Date;
}
const prefix = "/api";
@@ -53,19 +18,19 @@ const routes = {
};
export class BulkActionsAPI extends BaseAPI {
- async bulkExport(payload: RecipeBulkExport) {
+ async bulkExport(payload: ExportRecipes) {
return await this.requests.post(routes.bulkExport, payload);
}
- async bulkCategorize(payload: RecipeBulkCategorize) {
+ async bulkCategorize(payload: AssignCategories) {
return await this.requests.post(routes.bulkCategorize, payload);
}
- async bulkTag(payload: RecipeBulkTag) {
+ async bulkTag(payload: AssignTags) {
return await this.requests.post(routes.bulkTag, payload);
}
- async bulkDelete(payload: RecipeBulkDelete) {
+ async bulkDelete(payload: DeleteRecipes) {
return await this.requests.post(routes.bulkDelete, payload);
}
@@ -74,6 +39,6 @@ export class BulkActionsAPI extends BaseAPI {
}
async purgeExports() {
- return await this.requests.delete(routes.purgeExports);
+ return await this.requests.delete(routes.purgeExports);
}
}
diff --git a/frontend/api/class-interfaces/recipe-foods.ts b/frontend/api/class-interfaces/recipe-foods.ts
index 12b4b9116..e7c15b5fc 100644
--- a/frontend/api/class-interfaces/recipe-foods.ts
+++ b/frontend/api/class-interfaces/recipe-foods.ts
@@ -9,7 +9,7 @@ const routes = {
merge: `${prefix}/foods/merge`,
};
-export class FoodAPI extends BaseCRUDAPI {
+export class FoodAPI extends BaseCRUDAPI {
baseRoute: string = routes.food;
itemRoute = routes.foodsFood;
diff --git a/frontend/api/class-interfaces/recipe-units.ts b/frontend/api/class-interfaces/recipe-units.ts
index 0650f14e6..e43cc4042 100644
--- a/frontend/api/class-interfaces/recipe-units.ts
+++ b/frontend/api/class-interfaces/recipe-units.ts
@@ -9,7 +9,7 @@ const routes = {
merge: `${prefix}/units/merge`,
};
-export class UnitAPI extends BaseCRUDAPI {
+export class UnitAPI extends BaseCRUDAPI {
baseRoute: string = routes.unit;
itemRoute = routes.unitsUnit;
diff --git a/frontend/api/class-interfaces/recipes/recipe-comments.ts b/frontend/api/class-interfaces/recipes/recipe-comments.ts
index c942b6c53..8c9a86a80 100644
--- a/frontend/api/class-interfaces/recipes/recipe-comments.ts
+++ b/frontend/api/class-interfaces/recipes/recipe-comments.ts
@@ -1,5 +1,5 @@
-import { RecipeComment, RecipeCommentCreate } from "./types";
import { BaseCRUDAPI } from "~/api/_base";
+import { RecipeCommentCreate, RecipeCommentOut, RecipeCommentUpdate } from "~/types/api-types/recipe";
const prefix = "/api";
@@ -9,11 +9,11 @@ const routes = {
commentsId: (id: string) => `${prefix}/comments/${id}`,
};
-export class CommentsApi extends BaseCRUDAPI {
+export class CommentsApi extends BaseCRUDAPI {
baseRoute: string = routes.comment;
itemRoute = routes.commentsId;
async byRecipe(slug: string) {
- return await this.requests.get(routes.byRecipe(slug));
+ return await this.requests.get(routes.byRecipe(slug));
}
}
diff --git a/frontend/api/class-interfaces/recipes/recipe-share.ts b/frontend/api/class-interfaces/recipes/recipe-share.ts
index 9ec0f166b..01f68654e 100644
--- a/frontend/api/class-interfaces/recipes/recipe-share.ts
+++ b/frontend/api/class-interfaces/recipes/recipe-share.ts
@@ -1,4 +1,5 @@
import { BaseCRUDAPI } from "~/api/_base";
+import { RecipeShareToken, RecipeShareTokenCreate } from "~/types/api-types/recipe";
const prefix = "/api";
@@ -7,20 +8,7 @@ const routes = {
shareTokenId: (id: string) => `${prefix}/shared/recipes/${id}`,
};
-export interface RecipeShareTokenCreate {
- recipeId: string;
- expiresAt?: Date;
-}
-
-export interface RecipeShareToken {
- recipeId: string;
- id: string;
- groupId: number;
- expiresAt: string;
- createdAt: string;
-}
-
-export class RecipeShareApi extends BaseCRUDAPI {
+export class RecipeShareApi extends BaseCRUDAPI {
baseRoute: string = routes.shareToken;
itemRoute = routes.shareTokenId;
}
diff --git a/frontend/api/class-interfaces/recipes/recipe.ts b/frontend/api/class-interfaces/recipes/recipe.ts
index ebd831db3..957f37675 100644
--- a/frontend/api/class-interfaces/recipes/recipe.ts
+++ b/frontend/api/class-interfaces/recipes/recipe.ts
@@ -1,11 +1,19 @@
-import { CreateAsset, ParsedIngredient, Parser, RecipeZipToken, BulkCreatePayload } from "./types";
import { CommentsApi } from "./recipe-comments";
import { RecipeShareApi } from "./recipe-share";
import { BaseCRUDAPI } from "~/api/_base";
-import { Recipe, CreateRecipe } from "~/types/api-types/recipe";
+import { Recipe, CreateRecipe, RecipeAsset, CreateRecipeByUrlBulk, ParsedIngredient, UpdateImageResponse, RecipeZipTokenResponse } from "~/types/api-types/recipe";
import { ApiRequestInstance } from "~/types/api";
+export type Parser = "nlp" | "brute";
+
+export interface CreateAsset {
+ name: string;
+ icon: string;
+ extension: string;
+ file: File;
+}
+
const prefix = "/api";
const routes = {
@@ -31,7 +39,7 @@ const routes = {
recipeShareToken: (token: string) => `${prefix}/recipes/shared/${token}`,
};
-export class RecipeAPI extends BaseCRUDAPI {
+export class RecipeAPI extends BaseCRUDAPI {
baseRoute: string = routes.recipesBase;
itemRoute = routes.recipesRecipeSlug;
@@ -58,7 +66,7 @@ export class RecipeAPI extends BaseCRUDAPI {
formData.append("extension", payload.extension);
formData.append("icon", payload.icon);
- return await this.requests.post(routes.recipesRecipeSlugAssets(recipeSlug), formData);
+ return await this.requests.post(routes.recipesRecipeSlugAssets(recipeSlug), formData);
}
updateImage(slug: string, fileObject: File) {
@@ -66,11 +74,11 @@ export class RecipeAPI extends BaseCRUDAPI {
formData.append("image", fileObject);
formData.append("extension", fileObject.name.split(".").pop() ?? "");
- return this.requests.put(routes.recipesRecipeSlugImage(slug), formData);
+ return this.requests.put(routes.recipesRecipeSlugImage(slug), formData);
}
updateImagebyURL(slug: string, url: string) {
- return this.requests.post(routes.recipesRecipeSlugImage(slug), { url });
+ return this.requests.post(routes.recipesRecipeSlugImage(slug), { url });
}
async testCreateOneUrl(url: string) {
@@ -81,8 +89,8 @@ export class RecipeAPI extends BaseCRUDAPI {
return await this.requests.post(routes.recipesCreateUrl, { url, includeTags });
}
- async createManyByUrl(payload: BulkCreatePayload) {
- return await this.requests.post(routes.recipesCreateUrlBulk, payload);
+ async createManyByUrl(payload: CreateRecipeByUrlBulk) {
+ return await this.requests.post(routes.recipesCreateUrlBulk, payload);
}
async parseIngredients(parser: Parser, ingredients: Array) {
@@ -96,7 +104,7 @@ export class RecipeAPI extends BaseCRUDAPI {
}
async getZipToken(recipeSlug: string) {
- return await this.requests.post(routes.recipesRecipeSlugExport(recipeSlug), {});
+ return await this.requests.post(routes.recipesRecipeSlugExport(recipeSlug), {});
}
getZipRedirectUrl(recipeSlug: string, token: string) {
diff --git a/frontend/api/class-interfaces/recipes/types.ts b/frontend/api/class-interfaces/recipes/types.ts
deleted file mode 100644
index 29d83a227..000000000
--- a/frontend/api/class-interfaces/recipes/types.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-import { CreateIngredientFood, CreateIngredientUnit, IngredientFood, IngredientUnit } from "~/types/api-types/recipe";
-import { RecipeCategory, RecipeTag } from "~/types/api-types/user";
-
-export type Parser = "nlp" | "brute";
-
-export interface Confidence {
- average?: number;
- comment?: number;
- name?: number;
- unit?: number;
- quantity?: number;
- food?: number;
-}
-
-export interface Ingredient {
- title?: string;
- note?: string;
- unit?: IngredientUnit | CreateIngredientUnit;
- food?: IngredientFood | CreateIngredientFood;
- disableAmount?: boolean;
- quantity?: number;
- referenceId?: string;
-}
-
-export interface ParsedIngredient {
- input: string
- confidence: Confidence;
- ingredient: Ingredient;
-}
-
-export interface BulkCreateRecipe {
- url: string;
- categories: RecipeCategory[];
- tags: RecipeTag[];
-}
-
-export interface BulkCreatePayload {
- imports: BulkCreateRecipe[];
-}
-
-export interface RecipeZipToken {
- token: string;
-}
-
-export interface CreateAsset {
- name: string;
- icon: string;
- extension: string;
- file: File;
-}
-
-export interface RecipeCommentCreate {
- recipeId: string;
- text: string;
-}
-
-export interface RecipeCommentUpdate extends RecipeCommentCreate {
- id: string;
-}
-
-interface RecipeCommentUser {
- id: string;
- username: string;
- admin: boolean;
-}
-
-export interface RecipeComment extends RecipeCommentUpdate {
- createdAt: any;
- updatedAt: any;
- userId: number;
- user: RecipeCommentUser;
-}
diff --git a/frontend/api/class-interfaces/users.ts b/frontend/api/class-interfaces/users.ts
index 5d2ab8c03..e48a1aef7 100644
--- a/frontend/api/class-interfaces/users.ts
+++ b/frontend/api/class-interfaces/users.ts
@@ -1,29 +1,5 @@
import { BaseCRUDAPI } from "../_base";
-import { UserIn, UserOut } from "~/types/api-types/user";
-
-// Interfaces
-
-interface ChangePassword {
- currentPassword: string;
- newPassword: string;
-}
-
-interface CreateAPIToken {
- name: string;
-}
-
-interface ResponseToken {
- token: string;
-}
-
-interface PasswordResetPayload {
- token: string;
- email: string;
- password: string;
- passwordConfirm: string;
-}
-
-// Code
+import { ChangePassword, DeleteTokenResponse, LongLiveTokenIn, LongLiveTokenOut, ResetPassword, UserBase, UserIn, UserOut } from "~/types/api-types/user";
const prefix = "/api";
@@ -43,7 +19,7 @@ const routes = {
usersApiTokensTokenId: (token_id: string | number) => `${prefix}/users/api-tokens/${token_id}`,
};
-export class UserApi extends BaseCRUDAPI {
+export class UserApi extends BaseCRUDAPI {
baseRoute: string = routes.users;
itemRoute = (itemid: string) => routes.usersId(itemid);
@@ -63,12 +39,12 @@ export class UserApi extends BaseCRUDAPI {
return await this.requests.put(routes.usersIdPassword(id), changePassword);
}
- async createAPIToken(tokenName: CreateAPIToken) {
- return await this.requests.post(routes.usersApiTokens, tokenName);
+ async createAPIToken(tokenName: LongLiveTokenIn) {
+ return await this.requests.post(routes.usersApiTokens, tokenName);
}
- async deleteAPIToken(tokenId: string | number) {
- return await this.requests.delete(routes.usersApiTokensTokenId(tokenId));
+ async deleteAPIToken(tokenId: number) {
+ return await this.requests.delete(routes.usersApiTokensTokenId(tokenId));
}
userProfileImage(id: string) {
@@ -76,7 +52,7 @@ export class UserApi extends BaseCRUDAPI {
return `/api/users/${id}/image`;
}
- async resetPassword(payload: PasswordResetPayload) {
+ async resetPassword(payload: ResetPassword) {
return await this.requests.post(routes.passwordReset, payload);
}
}
diff --git a/frontend/api/class-interfaces/utils.ts b/frontend/api/class-interfaces/utils.ts
index 73b3b874f..882da79f2 100644
--- a/frontend/api/class-interfaces/utils.ts
+++ b/frontend/api/class-interfaces/utils.ts
@@ -1,14 +1,11 @@
import { BaseAPI } from "../_base";
+import { FileTokenResponse } from "~/types/api-types/response";
const prefix = "/api";
-interface DownloadData {
- fileToken: string;
-}
-
export class UtilsAPI extends BaseAPI {
async download(url: string) {
- const { response } = await this.requests.get(url);
+ const { response } = await this.requests.get(url);
if (!response) {
return;
diff --git a/frontend/api/public/validators.ts b/frontend/api/public/validators.ts
index d20fe752e..148bcc7a6 100644
--- a/frontend/api/public/validators.ts
+++ b/frontend/api/public/validators.ts
@@ -1,8 +1,5 @@
import { BaseAPI } from "../_base";
-
-export type Validation = {
- valid: boolean;
-};
+import { ValidationResponse } from "~/types/api-types/response";
const prefix = "/api";
@@ -15,18 +12,18 @@ const routes = {
export class ValidatorsApi extends BaseAPI {
async group(name: string) {
- return await this.requests.get(routes.group(name));
+ return await this.requests.get(routes.group(name));
}
async username(name: string) {
- return await this.requests.get(routes.user(name));
+ return await this.requests.get(routes.user(name));
}
async email(email: string) {
- return await this.requests.get(routes.email(email));
+ return await this.requests.get(routes.email(email));
}
async recipe(groupId: string, name: string) {
- return await this.requests.get(routes.recipe(groupId, name));
+ return await this.requests.get(routes.recipe(groupId, name));
}
}
diff --git a/frontend/api/types/server-task.ts b/frontend/api/types/server-task.ts
deleted file mode 100644
index 18bc35216..000000000
--- a/frontend/api/types/server-task.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-export interface ServerTask {
- id: number;
- groupId: number;
- callback: string;
- createdAt: string;
- status: string;
- log: string;
-}
diff --git a/frontend/components/Domain/Group/GroupExportData.vue b/frontend/components/Domain/Group/GroupExportData.vue
index b1491882f..c7443eff3 100644
--- a/frontend/components/Domain/Group/GroupExportData.vue
+++ b/frontend/components/Domain/Group/GroupExportData.vue
@@ -20,7 +20,7 @@
-
diff --git a/frontend/components/Domain/Recipe/RecipeComments.vue b/frontend/components/Domain/Recipe/RecipeComments.vue
index 56a13e0c5..b47c4c05d 100644
--- a/frontend/components/Domain/Recipe/RecipeComments.vue
+++ b/frontend/components/Domain/Recipe/RecipeComments.vue
@@ -56,7 +56,7 @@
\ No newline at end of file
+
diff --git a/frontend/pages/admin/manage/groups/_id.vue b/frontend/pages/admin/manage/groups/_id.vue
index 6c4c79207..9589aa04c 100644
--- a/frontend/pages/admin/manage/groups/_id.vue
+++ b/frontend/pages/admin/manage/groups/_id.vue
@@ -28,8 +28,8 @@ import { defineComponent, useRoute, onMounted, ref } from "@nuxtjs/composition-a
import GroupPreferencesEditor from "~/components/Domain/Group/GroupPreferencesEditor.vue";
import { useAdminApi } from "~/composables/api";
import { alert } from "~/composables/use-toast";
+import { GroupInDB } from "~/types/api-types/user";
import { VForm } from "~/types/vuetify";
-import { GroupRead } from "~/api/admin/admin-groups";
export default defineComponent({
components: {
@@ -48,7 +48,7 @@ export default defineComponent({
const adminApi = useAdminApi();
- const group = ref(null);
+ const group = ref(null);
const userError = ref(false);
diff --git a/frontend/pages/admin/manage/groups/index.vue b/frontend/pages/admin/manage/groups/index.vue
index f7d93936b..202abb080 100644
--- a/frontend/pages/admin/manage/groups/index.vue
+++ b/frontend/pages/admin/manage/groups/index.vue
@@ -71,9 +71,9 @@
-
+
\ No newline at end of file
+
diff --git a/frontend/pages/admin/site-settings.vue b/frontend/pages/admin/site-settings.vue
index 0b369200f..cc2b0c578 100644
--- a/frontend/pages/admin/site-settings.vue
+++ b/frontend/pages/admin/site-settings.vue
@@ -259,7 +259,7 @@ export default defineComponent({
const { data } = await adminApi.about.checkApp();
if (data) {
- appConfig.value = data;
+ appConfig.value = { ...data, isSiteSecure: false};
}
appConfig.value.isSiteSecure = isLocalHostOrHttps();
@@ -323,7 +323,7 @@ export default defineComponent({
if (data.success) {
state.success = true;
} else {
- state.error = data.error;
+ state.error = data.error ?? "";
state.success = false;
}
}
diff --git a/frontend/pages/group/data/recipes.vue b/frontend/pages/group/data/recipes.vue
index eacda1572..db3a3b3c0 100644
--- a/frontend/pages/group/data/recipes.vue
+++ b/frontend/pages/group/data/recipes.vue
@@ -154,7 +154,7 @@ import { useUserApi } from "~/composables/api";
import { useRecipes, allRecipes } from "~/composables/recipes";
import { Recipe } from "~/types/api-types/recipe";
import GroupExportData from "~/components/Domain/Group/GroupExportData.vue";
-import { GroupDataExport } from "~/api/class-interfaces/recipe-bulk-actions";
+import { GroupDataExport } from "~/types/api-types/group";
import { MenuItem } from "~/components/global/BaseOverflowButton.vue";
const MODES = {
diff --git a/frontend/pages/group/mealplan/planner.vue b/frontend/pages/group/mealplan/planner.vue
index 7acaf1bff..86ba1defe 100644
--- a/frontend/pages/group/mealplan/planner.vue
+++ b/frontend/pages/group/mealplan/planner.vue
@@ -346,7 +346,7 @@ export default defineComponent({
date: "",
title: "",
text: "",
- recipeId: undefined as number | undefined,
+ recipeId: undefined as string | undefined,
entryType: "dinner" as PlanEntryType,
});
diff --git a/frontend/pages/group/migrations.vue b/frontend/pages/group/migrations.vue
index 763fdd2cc..ac5800993 100644
--- a/frontend/pages/group/migrations.vue
+++ b/frontend/pages/group/migrations.vue
@@ -66,10 +66,10 @@
-
diff --git a/frontend/types/api-types/admin.ts b/frontend/types/api-types/admin.ts
index 9b00e3d16..106646efe 100644
--- a/frontend/types/api-types/admin.ts
+++ b/frontend/types/api-types/admin.ts
@@ -50,10 +50,10 @@ export interface BackupOptions {
notifications?: boolean;
}
export interface CheckAppConfig {
- emailReady?: boolean;
- ldapReady?: boolean;
- baseUrlSet?: boolean;
- isUpToDate?: boolean;
+ emailReady: boolean;
+ ldapReady: boolean;
+ baseUrlSet: boolean;
+ isUpToDate: boolean;
}
export interface ChowdownURL {
url: string;
@@ -174,6 +174,16 @@ export interface CustomPageOut {
export interface DockerVolumeText {
text: string;
}
+export interface EmailReady {
+ ready: boolean;
+}
+export interface EmailSuccess {
+ success: boolean;
+ error?: string;
+}
+export interface EmailTest {
+ email: string;
+}
export interface GroupImport {
name: string;
status: boolean;
diff --git a/frontend/types/api-types/group.ts b/frontend/types/api-types/group.ts
index 1fed05ce8..a65627053 100644
--- a/frontend/types/api-types/group.ts
+++ b/frontend/types/api-types/group.ts
@@ -41,7 +41,7 @@ export interface EmailInvitation {
export interface GroupAdminUpdate {
id: string;
name: string;
- preferences: UpdateGroupPreferences;
+ preferences?: UpdateGroupPreferences;
}
export interface UpdateGroupPreferences {
privateGroup?: boolean;
diff --git a/frontend/types/api-types/meal-plan.ts b/frontend/types/api-types/meal-plan.ts
index 9aa07b8ca..a16f0551b 100644
--- a/frontend/types/api-types/meal-plan.ts
+++ b/frontend/types/api-types/meal-plan.ts
@@ -14,10 +14,6 @@ export interface Category {
name: string;
slug: string;
}
-export interface CreatRandomEntry {
- date: string;
- entryType?: PlanEntryType & string;
-}
export interface CreatePlanEntry {
date: string;
entryType?: PlanEntryType & string;
@@ -25,6 +21,10 @@ export interface CreatePlanEntry {
text?: string;
recipeId?: string;
}
+export interface CreateRandomEntry {
+ date: string;
+ entryType?: PlanEntryType & string;
+}
export interface ListItem {
title?: string;
text?: string;
diff --git a/frontend/types/api-types/recipe.ts b/frontend/types/api-types/recipe.ts
index 7016b2a68..038d748b9 100644
--- a/frontend/types/api-types/recipe.ts
+++ b/frontend/types/api-types/recipe.ts
@@ -26,15 +26,6 @@ export interface TagBase {
id: string;
slug: string;
}
-export interface BulkActionError {
- recipe: string;
- error: string;
-}
-export interface BulkActionsResponse {
- success: boolean;
- message: string;
- errors?: BulkActionError[];
-}
export interface CategoryIn {
name: string;
}
@@ -335,6 +326,9 @@ export interface RecipeToolSave {
onHand?: boolean;
groupId: string;
}
+export interface RecipeZipTokenResponse {
+ token: string;
+}
export interface SaveIngredientFood {
name: string;
description?: string;
@@ -373,3 +367,6 @@ export interface UnitFoodBase {
name: string;
description?: string;
}
+export interface UpdateImageResponse {
+ image: string;
+}
diff --git a/frontend/types/api-types/response.ts b/frontend/types/api-types/response.ts
index 83e53b52d..8e1cb0f5d 100644
--- a/frontend/types/api-types/response.ts
+++ b/frontend/types/api-types/response.ts
@@ -18,5 +18,5 @@ export interface SuccessResponse {
error?: boolean;
}
export interface ValidationResponse {
- valid?: boolean;
+ valid: boolean;
}
diff --git a/frontend/types/api-types/user.ts b/frontend/types/api-types/user.ts
index 4ac866de0..af9ec8267 100644
--- a/frontend/types/api-types/user.ts
+++ b/frontend/types/api-types/user.ts
@@ -31,6 +31,9 @@ export interface CreateUserRegistration {
seedData?: boolean;
locale?: string;
}
+export interface DeleteTokenResponse {
+ tokenDelete: string;
+}
export interface ForgotPassword {
email: string;
}
@@ -62,9 +65,7 @@ export interface UserOut {
cacheKey: string;
}
export interface LongLiveTokenOut {
- name: string;
- id: number;
- createdAt: string;
+ token: string;
}
export interface ReadGroupPreferences {
privateGroup?: boolean;
@@ -78,7 +79,7 @@ export interface ReadGroupPreferences {
groupId: string;
id: string;
}
-export interface LoingLiveTokenIn {
+export interface LongLiveTokenIn {
name: string;
}
export interface LongLiveTokenInDB {
diff --git a/mealie/routes/admin/admin_email.py b/mealie/routes/admin/admin_email.py
index d8f8e8eda..a80a25a9a 100644
--- a/mealie/routes/admin/admin_email.py
+++ b/mealie/routes/admin/admin_email.py
@@ -1,25 +1,12 @@
from fastapi import APIRouter
from mealie.routes._base import BaseAdminController, controller
-from mealie.schema._mealie import MealieModel
+from mealie.schema.admin.email import EmailReady, EmailSuccess, EmailTest
from mealie.services.email import EmailService
router = APIRouter(prefix="/email")
-class EmailReady(MealieModel):
- ready: bool
-
-
-class EmailSuccess(MealieModel):
- success: bool
- error: str = None
-
-
-class EmailTest(MealieModel):
- email: str
-
-
@controller(router)
class AdminEmailController(BaseAdminController):
@router.get("", response_model=EmailReady)
diff --git a/mealie/routes/groups/controller_mealplan.py b/mealie/routes/groups/controller_mealplan.py
index 49bbb0f47..6e00ac188 100644
--- a/mealie/routes/groups/controller_mealplan.py
+++ b/mealie/routes/groups/controller_mealplan.py
@@ -9,7 +9,7 @@ from mealie.routes._base import BaseUserController, controller
from mealie.routes._base.mixins import HttpRepo
from mealie.schema import mapper
from mealie.schema.meal_plan import CreatePlanEntry, ReadPlanEntry, SavePlanEntry, UpdatePlanEntry
-from mealie.schema.meal_plan.new_meal import CreatRandomEntry
+from mealie.schema.meal_plan.new_meal import CreateRandomEntry
from mealie.schema.meal_plan.plan_rules import PlanRulesDay
from mealie.schema.recipe.recipe import Recipe
from mealie.schema.response.responses import ErrorResponse
@@ -42,7 +42,7 @@ class GroupMealplanController(BaseUserController):
return self.repo.get_today(group_id=self.group_id)
@router.post("/random", response_model=ReadPlanEntry)
- def create_random_meal(self, data: CreatRandomEntry):
+ def create_random_meal(self, data: CreateRandomEntry):
"""
create_random_meal is a route that provides the randomized funcitonality for mealplaners.
It operates by following the rules setout in the Groups mealplan settings. If not settings
diff --git a/mealie/routes/recipe/bulk_actions.py b/mealie/routes/recipe/bulk_actions.py
index 50c932f77..f698590d5 100644
--- a/mealie/routes/recipe/bulk_actions.py
+++ b/mealie/routes/recipe/bulk_actions.py
@@ -7,13 +7,7 @@ from mealie.core.dependencies.dependencies import temporary_zip_path
from mealie.core.security import create_file_token
from mealie.routes._base import BaseUserController, controller
from mealie.schema.group.group_exports import GroupDataExport
-from mealie.schema.recipe.recipe_bulk_actions import (
- AssignCategories,
- AssignTags,
- BulkActionsResponse,
- DeleteRecipes,
- ExportRecipes,
-)
+from mealie.schema.recipe.recipe_bulk_actions import AssignCategories, AssignTags, DeleteRecipes, ExportRecipes
from mealie.schema.response.responses import SuccessResponse
from mealie.services.recipe.recipe_bulk_service import RecipeBulkActionsService
@@ -26,15 +20,16 @@ class RecipeBulkActionsController(BaseUserController):
def service(self) -> RecipeBulkActionsService:
return RecipeBulkActionsService(self.repos, self.user, self.group)
- @router.post("/tag", response_model=BulkActionsResponse)
+ # TODO Should these actions return some success response?
+ @router.post("/tag")
def bulk_tag_recipes(self, tag_data: AssignTags):
self.service.assign_tags(tag_data.recipes, tag_data.tags)
- @router.post("/categorize", response_model=BulkActionsResponse)
+ @router.post("/categorize")
def bulk_categorize_recipes(self, assign_cats: AssignCategories):
self.service.assign_categories(assign_cats.recipes, assign_cats.categories)
- @router.post("/delete", response_model=BulkActionsResponse)
+ @router.post("/delete")
def bulk_delete_recipes(self, delete_recipes: DeleteRecipes):
self.service.delete_recipes(delete_recipes.recipes)
diff --git a/mealie/routes/recipe/recipe_crud_routes.py b/mealie/routes/recipe/recipe_crud_routes.py
index 61bf83822..44999edef 100644
--- a/mealie/routes/recipe/recipe_crud_routes.py
+++ b/mealie/routes/recipe/recipe_crud_routes.py
@@ -27,6 +27,7 @@ from mealie.schema.recipe import Recipe, RecipeImageTypes, ScrapeRecipe
from mealie.schema.recipe.recipe import CreateRecipe, CreateRecipeByUrlBulk, RecipeSummary
from mealie.schema.recipe.recipe_asset import RecipeAsset
from mealie.schema.recipe.recipe_scraper import ScrapeRecipeTest
+from mealie.schema.recipe.request_helpers import RecipeZipTokenResponse, UpdateImageResponse
from mealie.schema.response.responses import ErrorResponse
from mealie.schema.server.tasks import ServerTaskNames
from mealie.services import urls
@@ -59,10 +60,6 @@ class RecipeGetAll(GetAll):
load_food: bool = False
-class UpdateImageResponse(BaseModel):
- image: str
-
-
class FormatResponse(BaseModel):
jjson: list[str] = Field(..., alias="json")
zip: list[str]
@@ -81,10 +78,10 @@ class RecipeExportController(BaseRecipeController):
def get_recipe_formats_and_templates(self):
return TemplateService().templates
- @router_exports.post("/{slug}/exports")
+ @router_exports.post("/{slug}/exports", response_model=RecipeZipTokenResponse)
def get_recipe_zip_token(self, slug: str):
"""Generates a recipe zip token to be used to download a recipe as a zip file"""
- return {"token": create_recipe_slug_token(slug)}
+ return RecipeZipTokenResponse(token=create_recipe_slug_token(slug))
@router_exports.get("/{slug}/exports", response_class=FileResponse)
def get_recipe_as_format(self, slug: str, template_name: str, temp_dir=Depends(temporary_dir)):
diff --git a/mealie/routes/users/api_tokens.py b/mealie/routes/users/api_tokens.py
index b65d3dc4b..0191f2598 100644
--- a/mealie/routes/users/api_tokens.py
+++ b/mealie/routes/users/api_tokens.py
@@ -5,17 +5,17 @@ from fastapi import HTTPException, status
from mealie.core.security import create_access_token
from mealie.routes._base import BaseUserController, controller
from mealie.routes._base.routers import UserAPIRouter
-from mealie.schema.user import CreateToken, LoingLiveTokenIn, LongLiveTokenInDB
+from mealie.schema.user import CreateToken, DeleteTokenResponse, LongLiveTokenIn, LongLiveTokenInDB, LongLiveTokenOut
router = UserAPIRouter(prefix="/users", tags=["Users: Tokens"])
@controller(router)
class UserApiTokensController(BaseUserController):
- @router.post("/api-tokens", status_code=status.HTTP_201_CREATED)
+ @router.post("/api-tokens", status_code=status.HTTP_201_CREATED, response_model=LongLiveTokenOut)
def create_api_token(
self,
- token_name: LoingLiveTokenIn,
+ token_name: LongLiveTokenIn,
):
"""Create api_token in the Database"""
@@ -33,9 +33,9 @@ class UserApiTokensController(BaseUserController):
new_token_in_db = self.repos.api_tokens.create(token_model)
if new_token_in_db:
- return {"token": token}
+ return LongLiveTokenOut(token=token)
- @router.delete("/api-tokens/{token_id}")
+ @router.delete("/api-tokens/{token_id}", response_model=DeleteTokenResponse)
def delete_api_token(self, token_id: int):
"""Delete api_token from the Database"""
token: LongLiveTokenInDB = self.repos.api_tokens.get(token_id)
@@ -45,6 +45,6 @@ class UserApiTokensController(BaseUserController):
if token.user.email == self.user.email:
deleted_token = self.repos.api_tokens.delete(token_id)
- return {"token_delete": deleted_token.name}
+ return DeleteTokenResponse(token_delete=deleted_token.name)
else:
raise HTTPException(status.HTTP_403_FORBIDDEN)
diff --git a/mealie/schema/admin/__init__.py b/mealie/schema/admin/__init__.py
index 7587c29e2..21eaeeb13 100644
--- a/mealie/schema/admin/__init__.py
+++ b/mealie/schema/admin/__init__.py
@@ -1,6 +1,7 @@
# GENERATED CODE - DO NOT MODIFY BY HAND
from .about import *
from .backup import *
+from .email import *
from .maintenance import *
from .migration import *
from .restore import *
diff --git a/mealie/schema/admin/about.py b/mealie/schema/admin/about.py
index edaeb71df..68b644f7e 100644
--- a/mealie/schema/admin/about.py
+++ b/mealie/schema/admin/about.py
@@ -28,10 +28,10 @@ class AdminAboutInfo(AppInfo):
class CheckAppConfig(MealieModel):
- email_ready: bool = False
- ldap_ready: bool = False
- base_url_set: bool = False
- is_up_to_date: bool = False
+ email_ready: bool
+ ldap_ready: bool
+ base_url_set: bool
+ is_up_to_date: bool
class DockerVolumeText(MealieModel):
diff --git a/mealie/schema/admin/email.py b/mealie/schema/admin/email.py
new file mode 100644
index 000000000..1f1a7180b
--- /dev/null
+++ b/mealie/schema/admin/email.py
@@ -0,0 +1,14 @@
+from mealie.schema._mealie import MealieModel
+
+
+class EmailReady(MealieModel):
+ ready: bool
+
+
+class EmailSuccess(MealieModel):
+ success: bool
+ error: str = None
+
+
+class EmailTest(MealieModel):
+ email: str
diff --git a/mealie/schema/group/group.py b/mealie/schema/group/group.py
index fe83f7b13..6f8d39cf1 100644
--- a/mealie/schema/group/group.py
+++ b/mealie/schema/group/group.py
@@ -1,3 +1,5 @@
+from typing import Optional
+
from pydantic import UUID4
from mealie.schema._mealie import MealieModel
@@ -8,4 +10,4 @@ from .group_preferences import UpdateGroupPreferences
class GroupAdminUpdate(MealieModel):
id: UUID4
name: str
- preferences: UpdateGroupPreferences
+ preferences: Optional[UpdateGroupPreferences] = None
diff --git a/mealie/schema/meal_plan/new_meal.py b/mealie/schema/meal_plan/new_meal.py
index 405e26f1f..0fa29e03f 100644
--- a/mealie/schema/meal_plan/new_meal.py
+++ b/mealie/schema/meal_plan/new_meal.py
@@ -16,7 +16,7 @@ class PlanEntryType(str, Enum):
side = "side"
-class CreatRandomEntry(MealieModel):
+class CreateRandomEntry(MealieModel):
date: date
entry_type: PlanEntryType = PlanEntryType.dinner
diff --git a/mealie/schema/recipe/recipe_bulk_actions.py b/mealie/schema/recipe/recipe_bulk_actions.py
index 9a1b003a4..f5a90cc14 100644
--- a/mealie/schema/recipe/recipe_bulk_actions.py
+++ b/mealie/schema/recipe/recipe_bulk_actions.py
@@ -26,14 +26,3 @@ class AssignTags(ExportBase):
class DeleteRecipes(ExportBase):
pass
-
-
-class BulkActionError(MealieModel):
- recipe: str
- error: str
-
-
-class BulkActionsResponse(MealieModel):
- success: bool
- message: str
- errors: list[BulkActionError] = []
diff --git a/mealie/schema/recipe/request_helpers.py b/mealie/schema/recipe/request_helpers.py
index 16e5ca2c7..960b8faae 100644
--- a/mealie/schema/recipe/request_helpers.py
+++ b/mealie/schema/recipe/request_helpers.py
@@ -12,3 +12,11 @@ class RecipeSlug(MealieModel):
class SlugResponse(BaseModel):
class Config:
schema_extra = {"example": "adult-mac-and-cheese"}
+
+
+class UpdateImageResponse(BaseModel):
+ image: str
+
+
+class RecipeZipTokenResponse(BaseModel):
+ token: str
diff --git a/mealie/schema/response/validation.py b/mealie/schema/response/validation.py
index 882725d19..93374c689 100644
--- a/mealie/schema/response/validation.py
+++ b/mealie/schema/response/validation.py
@@ -2,4 +2,4 @@ from pydantic import BaseModel
class ValidationResponse(BaseModel):
- valid: bool = False
+ valid: bool
diff --git a/mealie/schema/user/user.py b/mealie/schema/user/user.py
index a0c3256dd..a26dc9960 100644
--- a/mealie/schema/user/user.py
+++ b/mealie/schema/user/user.py
@@ -1,4 +1,3 @@
-from datetime import datetime
from pathlib import Path
from typing import Any, Optional
from uuid import UUID
@@ -18,19 +17,18 @@ from ..recipe import CategoryBase
settings = get_app_settings()
-class LoingLiveTokenIn(MealieModel):
+class LongLiveTokenIn(MealieModel):
name: str
-class LongLiveTokenOut(LoingLiveTokenIn):
- id: int
- created_at: datetime
+class LongLiveTokenOut(MealieModel):
+ token: str
class Config:
orm_mode = True
-class CreateToken(LoingLiveTokenIn):
+class CreateToken(LongLiveTokenIn):
user_id: UUID4
token: str
@@ -38,6 +36,13 @@ class CreateToken(LoingLiveTokenIn):
orm_mode = True
+class DeleteTokenResponse(MealieModel):
+ token_delete: str
+
+ class Config:
+ orm_mode = True
+
+
class ChangePassword(MealieModel):
current_password: str
new_password: str