diff --git a/package-lock.json b/package-lock.json index 6485dde..f34a88e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,10 @@ "": { "name": "plantwiki-svelte", "version": "0.0.1", + "dependencies": { + "fp-ts": "^2.16.1", + "io-ts": "^2.2.20" + }, "devDependencies": { "@sveltejs/adapter-auto": "^2.0.0", "@sveltejs/adapter-node": "^1.3.1", @@ -1287,6 +1291,11 @@ "node": ">=8" } }, + "node_modules/fp-ts": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.16.1.tgz", + "integrity": "sha512-by7U5W8dkIzcvDofUcO42yl9JbnHTEDBrzu3pt5fKT+Z4Oy85I21K80EYJYdjQGC2qum4Vo55Ag57iiIK4FYuA==" + }, "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -1476,6 +1485,14 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, + "node_modules/io-ts": { + "version": "2.2.20", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-2.2.20.tgz", + "integrity": "sha512-Rq2BsYmtwS5vVttie4rqrOCIfHCS9TgpRLFpKQCM1wZBBRY9nWVGmEvm2FnDbSE2un1UE39DvFpTR5UL47YDcA==", + "peerDependencies": { + "fp-ts": "^2.5.0" + } + }, "node_modules/is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", diff --git a/package.json b/package.json index 49d4cfa..61c198d 100644 --- a/package.json +++ b/package.json @@ -23,5 +23,9 @@ "vite": "^4.4.2", "vite-plugin-toml": "^0.6.0" }, - "type": "module" + "type": "module", + "dependencies": { + "fp-ts": "^2.16.1", + "io-ts": "^2.2.20" + } } diff --git a/src/lib/assets/plants/monstera-deliciosa.toml b/src/lib/assets/plants/monstera-deliciosa.toml index 36a36e8..b2de837 100644 --- a/src/lib/assets/plants/monstera-deliciosa.toml +++ b/src/lib/assets/plants/monstera-deliciosa.toml @@ -4,7 +4,7 @@ bin_name = "Monstera Deliciosa" [image] remote = "https://upload.wikimedia.org/wikipedia/commons/d/d4/New_Monstera_Deliciosa_Leaf.jpg" -format = "json" +format = "jpeg" width = 1512 source = "https://commons.wikimedia.org/wiki/File:New_Monstera_Deliciosa_Leaf.jpg" alt = """ diff --git a/src/lib/plants.ts b/src/lib/plants.ts index 402148c..64bfef1 100644 --- a/src/lib/plants.ts +++ b/src/lib/plants.ts @@ -1,43 +1,54 @@ import aloeVera from "$lib/assets/plants/aloe-vera.toml"; import monsteraDeliciosa from "$lib/assets/plants/monstera-deliciosa.toml"; +import { isLeft } from "fp-ts/lib/Either"; +import * as t from "io-ts"; +import { PathReporter } from "io-ts/lib/PathReporter"; -export type PlantData = { - slug: string; - name: string; - bin_name: string; +const PlantDataTS = t.type({ + slug: t.string, + name: t.string, + bin_name: t.string, - image: { - local?: string; - remote?: string; - format?: string; - width?: number; - source: string; - alt: string; - }; - temp: { - death: number; - lower: number; - upper: number; - }; - care: { - description: string; - water_schedule: string; - mist_schedule?: string; - fertilize_schedule?: string; - clean_schedule?: string; - }; - site: { - description: string; - light: string; - humidity?: string; - }; -}; + image: t.type({ + local: t.union([t.string, t.undefined]), + remote: t.union([t.string, t.undefined]), + format: t.union([t.string, t.undefined]), + width: t.union([t.number, t.undefined]), + source: t.string, + alt: t.string, + }), + temp: t.type({ + death: t.number, + lower: t.number, + upper: t.number, + }), + care: t.type({ + description: t.string, + water_schedule: t.string, + mist_schedule: t.union([t.string, t.undefined]), + fertilize_schedule: t.union([t.string, t.undefined]), + clean_schedule: t.union([t.string, t.undefined]), + }), + site: t.type({ + description: t.string, + light: t.string, + humidity: t.union([t.string, t.undefined]), + }), +}); + +export type PlantData = t.TypeOf; type PlantMap = { [key: PlantData["slug"]]: PlantData }; export const plants: PlantMap = [aloeVera, monsteraDeliciosa].reduce( (acc, cur) => { - acc[cur.slug] = cur; + const decoded = PlantDataTS.decode(cur); + if (isLeft(decoded)) { + throw Error( + `Invalid plant data ${PathReporter.report(decoded).join("\n")}`, + ); + } + acc[cur.slug] = decoded.right; return acc; }, {} as PlantMap, diff --git a/src/routes/+server.ts b/src/routes/+server.ts new file mode 100644 index 0000000..189f71e --- /dev/null +++ b/src/routes/+server.ts @@ -0,0 +1 @@ +export const prerender = true; diff --git a/src/routes/plants/[plant]/+page.ts b/src/routes/plants/[plant]/+page.ts index edd8de1..8fa3943 100644 --- a/src/routes/plants/[plant]/+page.ts +++ b/src/routes/plants/[plant]/+page.ts @@ -2,6 +2,8 @@ import { error } from "@sveltejs/kit"; import type { PageLoad } from "./$types"; import { plants, type PlantData } from "$lib/plants"; +export const prerender = "auto"; + export const load: PageLoad = ({ params }) => { if (plants[params.plant]) { return plants[params.plant] as PlantData;