add core features (#14)
Build & Deploy Formulation / Build & Push Image (push) Failing after 15s
Build & Deploy Formulation / deploy (push) Skipped

Reviewed-on: #14
Co-authored-by: Nicholas Ward <nicholaspward@outlook.com>
This commit was merged in pull request #14.
This commit is contained in:
2026-08-18 18:22:34 -05:00
committed by nicholas
parent 20e23b100f
commit 2a1e16ed30
125 changed files with 23392 additions and 2082 deletions
+4 -4
View File
@@ -3,6 +3,8 @@ import path from "node:path";
const json = (value, fallback) => { try { return JSON.parse(value); } catch { return fallback; } };
export const titleCase = (input) => input.split(/\s+/).map((word) => { const index = word.search(/\p{L}/u); return index === -1 ? word : word.slice(0, index) + word[index].toLocaleUpperCase() + word.slice(index + 1); }).join(" ");
export function createSiteProjection(database) {
const units = database.prepare("SELECT * FROM units ORDER BY id").all().map((row) => ({ schema_version:2,id:row.id,name:row.name,symbol:row.symbol,dimension:row.dimension,system:row.system,...(row.base_unit_id?{base_conversion:{base_unit_id:row.base_unit_id,factor:row.factor,...(row.offset!=null?{offset:row.offset}:{})}}:{}) }));
const aliasQuery=database.prepare("SELECT name,kind FROM ingredient_aliases WHERE ingredient_id=? ORDER BY name");
@@ -12,7 +14,7 @@ export function createSiteProjection(database) {
const mappingIdsQuery=database.prepare("SELECT id,mapping_type FROM source_mappings WHERE subject_type='ingredient' AND subject_id=? AND status='reviewed' ORDER BY id");
const ingredients = database.prepare("SELECT * FROM ingredients ORDER BY id").all().map((row) => {
const mappings=mappingIdsQuery.all(row.id), source=json(row.source_json,"{}");
return { schema_version:row.schema_version,id:row.id,name:row.name,...(row.description?{description:row.description}:{}),status:row.status,categories:json(row.categories_json,[]),tags:json(row.tags_json,[]),
return { schema_version:row.schema_version,id:row.id,name:titleCase(row.name),...(row.description?{description:row.description}:{}),status:row.status,categories:json(row.categories_json,[]),tags:json(row.tags_json,[]),
aliases:aliasQuery.all(row.id),
density_measurements:densityQuery.all(row.id).map((value)=>({id:value.id,mass:{quantity:value.mass_quantity,unit_id:value.mass_unit_id},volume:{quantity:value.volume_quantity,unit_id:value.volume_unit_id},...(value.temperature_c!=null?{temperature_c:value.temperature_c}:{}),...(value.state?{state:value.state}:{}),source:json(value.source_json,{})})),
measure_conversions:conversionQuery.all(row.id).map((value)=>({id:value.id,from:{quantity:value.from_quantity,unit_id:value.from_unit_id},to:{quantity:value.to_quantity,unit_id:value.to_unit_id},...(value.state?{state:value.state}:{}),source:json(value.source_json,{})})),
@@ -46,8 +48,6 @@ export function createSiteProjection(database) {
export function writeSiteProjection(database, target=path.resolve(process.cwd(),"generated","site-projection.json")) {
fs.mkdirSync(path.dirname(target),{recursive:true});
const temporary=`${target}.tmp`;
fs.writeFileSync(temporary,`${JSON.stringify(createSiteProjection(database))}\n`);
fs.renameSync(temporary,target);
fs.writeFileSync(target,`${JSON.stringify(createSiteProjection(database))}\n`);
return target;
}