Skip to content

Commit 7b212d0

Browse files
committed
Add validation to apps list data and clean up entries
Signed-off-by: Andy Piper <andypiper@users.noreply.github.com>
1 parent 25c9dd9 commit 7b212d0

2 files changed

Lines changed: 73 additions & 17 deletions

File tree

data/apps.ts

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import dowstodon from "../public/apps/dowstodon.png"
5757
import fread from "../public/apps/fread.png"
5858
import plfe from "../public/apps/pl-fe.png"
5959

60+
import { z } from "zod"
6061
import type { StaticImageData } from "next/legacy/image"
6162

6263
export type appsList = {
@@ -82,6 +83,53 @@ export type appsList = {
8283
source_url?: string
8384
}[]
8485
}
86+
87+
// Zod schema for runtime validation
88+
const appSchema = z
89+
.object({
90+
name: z.string().min(1, "App name is required"),
91+
icon: z.any(),
92+
url: z.string().url("App URL must be a valid URL"),
93+
released_on: z.string().optional(),
94+
paid: z.boolean().optional(),
95+
hidden_from_all: z.boolean().optional(),
96+
categoryLabel: z.string().optional(),
97+
open: z.boolean().optional(),
98+
source_url: z.string().url("Source URL must be a valid URL").optional(),
99+
})
100+
.refine(
101+
(data) => {
102+
// If open source, source_url must be provided
103+
if (data.open === true && !data.source_url) {
104+
return false
105+
}
106+
return true
107+
},
108+
{
109+
message: "Open source apps (open: true) must have a source_url",
110+
}
111+
)
112+
113+
const appsListSchema = z.record(z.string(), z.array(appSchema))
114+
115+
/**
116+
* Validates the apps data structure at runtime.
117+
* Throws an error if validation fails.
118+
*/
119+
function validateApps(appsData: appsList): void {
120+
try {
121+
appsListSchema.parse(appsData)
122+
} catch (error) {
123+
if (error instanceof z.ZodError) {
124+
const errors = error.errors.map(
125+
(err) =>
126+
`${err.path.join(".")}: ${err.message} ${err.code === "custom" ? `(${JSON.stringify(err.params)})` : ""}`
127+
)
128+
throw new Error(`Apps validation failed:\n${errors.join("\n")}`)
129+
}
130+
throw error
131+
}
132+
}
85133
export const apps: appsList = {
86134
android: [
87135
{
@@ -123,6 +171,8 @@ export const apps: appsList = {
123171
icon: fedilab,
124172
url: "https://play.google.com/store/apps/details?id=app.fedilab.android",
125173
paid: false,
174+
open: true,
175+
source_url: "https://codeberg.org/tom79/Fedilab",
126176
},
127177
{
128178
released_on: "Jan 26, 2023",
@@ -193,6 +243,8 @@ export const apps: appsList = {
193243
name: "iMast",
194244
icon: imast,
195245
url: "https://apps.apple.com/app/imast/id1229461703",
246+
open: true,
247+
source_url: "https://github.com/cinderella-project/iMast",
196248
},
197249
{
198250
released_on: "Jan 19, 2023",
@@ -221,7 +273,7 @@ export const apps: appsList = {
221273
released_on: "Mar 24, 2023",
222274
name: "Woolly",
223275
icon: woolly,
224-
url: "https://apps.apple.com/us/app/woolly-for-mastodon/id6444360628",
276+
url: "https://apps.apple.com/app/woolly-for-mastodon/id6444360628",
225277
paid: true,
226278
open: false,
227279
},
@@ -286,7 +338,7 @@ export const apps: appsList = {
286338
released_on: "Aug 10, 2023",
287339
name: "SoraSNS",
288340
icon: sora,
289-
url: "https://apps.apple.com/us/app/sorasns-for-mastodon-bluesky/id6754866904",
341+
url: "https://apps.apple.com/app/sorasns-for-mastodon-bluesky/id6754866904",
290342
paid: false,
291343
open: false,
292344
},
@@ -302,12 +354,12 @@ export const apps: appsList = {
302354
released_on: "Jun 3, 2024",
303355
name: "Oxpecker (watchOS)",
304356
icon: oxpecker,
305-
url: "https://apps.apple.com/app/oxpecker-for-mastodon/id6474893905?platform=appleWatch",
357+
url: "https://apps.apple.com/app/oxpecker-for-mastodon/id6474893905",
306358
paid: true,
307359
open: false,
308360
},
309361
{
310-
released_on: "July 10th, 2024",
362+
released_on: "Jul 10, 2024",
311363
name: "Bubble",
312364
icon: bubble,
313365
url: "https://apps.apple.com/app/bubble/id6477757490",
@@ -319,7 +371,7 @@ export const apps: appsList = {
319371
released_on: "Jan 1, 2024",
320372
name: "Odous (watchOS)",
321373
icon: odous,
322-
url: "https://apps.apple.com/us/app/id6446084064",
374+
url: "https://apps.apple.com/app/id6446084064",
323375
paid: true,
324376
open: false,
325377
},
@@ -372,7 +424,7 @@ export const apps: appsList = {
372424
icon: tooty,
373425
url: "https://n1k0.github.io/tooty/v2/",
374426
open: true,
375-
source_url: "https://github.com/n1k0/tooty ",
427+
source_url: "https://github.com/n1k0/tooty",
376428
},
377429
{
378430
name: "Mastodeck",
@@ -509,34 +561,39 @@ export const apps: appsList = {
509561
icon: amidon,
510562
url: "https://github.com/BlitterStudio/amidon",
511563
open: true,
564+
source_url: "https://github.com/BlitterStudio/amidon",
512565
},
513566
{
514567
released_on: "Feb 5, 2023",
515568
name: "BREXXTODON",
516569
icon: brexxtodon,
517570
url: "https://github.com/mainframed/BREXXTODON",
518571
open: true,
572+
source_url: "https://github.com/mainframed/BREXXTODON",
519573
},
520574
{
521575
released_on: "Nov 14, 2022",
522576
name: "DOStodon",
523577
icon: dostodon,
524578
url: "https://github.com/SuperIlu/DOStodon",
525579
open: true,
580+
source_url: "https://github.com/SuperIlu/DOStodon",
526581
},
527582
{
528583
released_on: "Nov 20, 2022",
529584
name: "Macstodon",
530585
icon: macstodon,
531586
url: "https://github.com/smallsco/macstodon",
532587
open: true,
588+
source_url: "https://github.com/smallsco/macstodon",
533589
},
534590
{
535591
released_on: "Apr 14, 2023",
536592
name: "Masto9",
537593
icon: mastonine,
538594
url: "https://sr.ht/~julienxx/Masto9/",
539595
open: true,
596+
source_url: "https://sr.ht/~julienxx/Masto9/",
540597
},
541598
{
542599
released_on: "Mar 6, 2023",
@@ -552,13 +609,15 @@ export const apps: appsList = {
552609
icon: mastodonforworkgroups,
553610
url: "https://github.com/meyskens/mastodon-for-workgroups",
554611
open: true,
612+
source_url: "https://github.com/meyskens/mastodon-for-workgroups",
555613
},
556614
{
557615
released_on: "Sep 12, 2023",
558616
name: "Heffalump",
559617
icon: heffalump,
560618
url: "https://github.com/knickish/heffalump",
561619
open: true,
620+
source_url: "https://github.com/knickish/heffalump",
562621
},
563622
{
564623
released_on: "Sep 17, 2023",
@@ -567,6 +626,7 @@ export const apps: appsList = {
567626
url: "https://github.com/Havoc6502/MOStodon",
568627
paid: false,
569628
open: true,
629+
source_url: "https://github.com/Havoc6502/MOStodon",
570630
},
571631
{
572632
released_on: "Jan 06, 2018",
@@ -579,3 +639,6 @@ export const apps: appsList = {
579639
},
580640
],
581641
}
642+
643+
// Validate apps data at module load time
644+
validateApps(apps)

yarn.lock

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3526,17 +3526,10 @@ __metadata:
35263526
languageName: node
35273527
linkType: hard
35283528

3529-
"caniuse-lite@npm:^1.0.30001579, caniuse-lite@npm:^1.0.30001716":
3530-
version: 1.0.30001717
3531-
resolution: "caniuse-lite@npm:1.0.30001717"
3532-
checksum: 10c0/6c0bb1e5182fd578ebe97ee2203250849754a4e17d985839fab527ad27e125a4c4ffce3ece5505217fedf30ea0bbc17ac9f93e9ac525c0389ccba61c6e8345dc
3533-
languageName: node
3534-
linkType: hard
3535-
3536-
"caniuse-lite@npm:^1.0.30001688, caniuse-lite@npm:^1.0.30001702":
3537-
version: 1.0.30001703
3538-
resolution: "caniuse-lite@npm:1.0.30001703"
3539-
checksum: 10c0/ed88e318da28e9e59c4ac3a2e3c42859558b7b713aebf03696a1f916e4ed4b70734dda82be04635e2b62ec355b8639bbed829b7b12ff528d7f9cc31a3a5bea91
3529+
"caniuse-lite@npm:^1.0.30001579, caniuse-lite@npm:^1.0.30001688, caniuse-lite@npm:^1.0.30001702, caniuse-lite@npm:^1.0.30001716":
3530+
version: 1.0.30001757
3531+
resolution: "caniuse-lite@npm:1.0.30001757"
3532+
checksum: 10c0/3ccb71fa2bf1f8c96ff1bf9b918b08806fed33307e20a3ce3259155fda131eaf96cfcd88d3d309c8fd7f8285cc71d89a3b93648a1c04814da31c301f98508d42
35403533
languageName: node
35413534
linkType: hard
35423535

0 commit comments

Comments
 (0)