Files
formulation/src/lib/recipe-export.ts
T
nicholas 3c2bc768e0
Build & Deploy Formulation / Build & Push Image (push) Successful in 1m3s
Build & Deploy Formulation / deploy (push) Successful in 19s
refactor: simplify
## 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>
2026-08-30 20:22:09 -05:00

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;
}