## Summary - update recipe data, improve mobile - simplify app, API; remove bad MCP layer - consolidate database schema into initial migration Co-authored-by: Nicholas Ward <nicholaspward@outlook.com>
52 lines
2.9 KiB
TypeScript
52 lines
2.9 KiB
TypeScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import type { DatabaseSync } from "node:sqlite";
|
|
import YAML from "yaml";
|
|
import { editableRecipe, recipeStructure } from "./database";
|
|
|
|
export function exportRecipe(database: DatabaseSync, id: string) {
|
|
const row = editableRecipe(database, id);
|
|
if (!row) throw new Error(`Unknown recipe: ${id}`);
|
|
const recipe = JSON.parse(row.source_json);
|
|
recipe.title = row.title;
|
|
if (row.summary) recipe.summary = row.summary; else delete recipe.summary;
|
|
recipe.categories = JSON.parse(row.categories_json);
|
|
recipe.tags = JSON.parse(row.tags_json);
|
|
recipe.yield = { ...recipe.yield, amount: { ...recipe.yield.amount, quantity: row.yield_quantity, unit_id: row.yield_unit_id } };
|
|
delete recipe.yield.servings;
|
|
if (row.yield_basis) recipe.yield.basis = row.yield_basis; else delete recipe.yield.basis;
|
|
const structure = recipeStructure(database, id)!;
|
|
const oldComponents = new Map((recipe.components ?? []).map((component: { id: string }) => [component.id, component]));
|
|
recipe.components = structure.components.map((component) => {
|
|
const old = oldComponents.get(component.id) as Record<string, unknown> | undefined;
|
|
const oldItems = new Map(((old?.items as Array<{ id: string }> | undefined) ?? []).map((item) => [item.id, item]));
|
|
const exportedComponent = {
|
|
...(old ?? {}), id: component.id, name: component.name,
|
|
items: component.items.map((item) => {
|
|
const line = { ...(oldItems.get(item.id) ?? {}), id: item.id, reference: item.ingredient_id ? { ingredient_id: item.ingredient_id } : { recipe_id: item.subrecipe_id }, amount: { quantity: item.quantity, unit_id: item.unit_id } } as Record<string, unknown>;
|
|
for (const key of ["percentage", "basis_member", "optional", "notes", "prep"]) delete line[key];
|
|
if (item.percentage != null) line.percentage = item.percentage;
|
|
if (item.basis_member) line.basis_member = true;
|
|
if (item.optional) line.optional = true;
|
|
if (item.notes) line.notes = item.notes;
|
|
if (item.prep.length) line.prep = item.prep;
|
|
return line;
|
|
}),
|
|
} as Record<string, unknown>;
|
|
delete exportedComponent.notes;
|
|
if (component.notes?.length) exportedComponent.notes = component.notes;
|
|
return exportedComponent;
|
|
});
|
|
const oldSteps = new Map((recipe.steps ?? []).map((step: { id: string }) => [step.id, step]));
|
|
recipe.steps = structure.steps.map((step, index) => {
|
|
const value = { ...(oldSteps.get(step.id) ?? {}), id: step.id, order: index + 1, instruction: step.instruction } as Record<string, unknown>;
|
|
delete value.equipment_ids;
|
|
if (step.equipment_ids.length) value.equipment_ids = step.equipment_ids;
|
|
return value;
|
|
});
|
|
const target = path.resolve(process.cwd(), "culinary", "recipes", `${id}.yaml`);
|
|
fs.writeFileSync(target, YAML.stringify(recipe));
|
|
database.prepare("UPDATE recipes SET source_json = ? WHERE id = ?").run(JSON.stringify(recipe), id);
|
|
return target;
|
|
}
|