@grove-dev/astro 0.1.5 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/index.d.ts +4 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +56 -22
- package/dist/index.js.map +1 -1
- package/dist/layouts/index.d.ts +25 -0
- package/dist/layouts/index.d.ts.map +1 -0
- package/dist/layouts/index.js +25 -0
- package/dist/layouts/index.js.map +1 -0
- package/dist/lib/display.d.ts +33 -0
- package/dist/lib/display.d.ts.map +1 -0
- package/dist/lib/display.js +104 -0
- package/dist/lib/display.js.map +1 -0
- package/dist/lib/format.d.ts +30 -0
- package/dist/lib/format.d.ts.map +1 -0
- package/dist/lib/format.js +73 -0
- package/dist/lib/format.js.map +1 -0
- package/dist/lib/index.d.ts +26 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +26 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/lenses.d.ts +96 -0
- package/dist/lib/lenses.d.ts.map +1 -0
- package/dist/lib/lenses.js +181 -0
- package/dist/lib/lenses.js.map +1 -0
- package/dist/lib/repo.d.ts +30 -0
- package/dist/lib/repo.d.ts.map +1 -0
- package/dist/lib/repo.js +44 -0
- package/dist/lib/repo.js.map +1 -0
- package/dist/lib/scores.d.ts +38 -0
- package/dist/lib/scores.d.ts.map +1 -0
- package/dist/lib/scores.js +83 -0
- package/dist/lib/scores.js.map +1 -0
- package/dist/lib/search.d.ts +199 -0
- package/dist/lib/search.d.ts.map +1 -0
- package/dist/lib/search.js +357 -0
- package/dist/lib/search.js.map +1 -0
- package/dist/lib/taxonomy-counts.d.ts +25 -0
- package/dist/lib/taxonomy-counts.d.ts.map +1 -0
- package/dist/lib/taxonomy-counts.js +41 -0
- package/dist/lib/taxonomy-counts.js.map +1 -0
- package/package.json +7 -7
- package/src/components/AppsIndexRow.astro +204 -0
- package/src/components/AppsPagination.astro +126 -0
- package/src/components/CategoryGrid.astro +86 -17
- package/src/components/ContributorsGrid.astro +149 -0
- package/src/components/DecisionRow.astro +89 -0
- package/src/components/ExploreByCategory.astro +67 -0
- package/src/components/ExploreByStack.astro +72 -0
- package/src/components/Hero.astro +246 -0
- package/src/components/Icon.astro +223 -0
- package/src/components/ItemCard.astro +306 -30
- package/src/components/MinimalAbout.astro +82 -0
- package/src/components/OriginalCollection.astro +116 -0
- package/src/components/RecordSection.astro +88 -0
- package/src/components/RefinePanel.astro +197 -0
- package/src/components/ScoreBars.astro +92 -22
- package/src/components/SmartLensTabs.astro +71 -0
- package/src/components/StackGrid.astro +132 -0
- package/src/components/WhyThisExists.astro +116 -0
- package/src/index.ts +61 -14
- package/src/layouts/BaseLayout.astro +227 -15
- package/src/layouts/Container.astro +57 -0
- package/src/layouts/Footer.astro +235 -0
- package/src/layouts/Header.astro +159 -0
- package/src/layouts/SectionHeader.astro +58 -0
- package/{templates/default/src/components/layout → src/layouts}/Seo.astro +62 -38
- package/src/layouts/ThemeToggle.astro +110 -0
- package/src/layouts/astro-shim.d.ts +29 -0
- package/src/layouts/index.ts +24 -0
- package/src/lib/display.ts +118 -0
- package/src/lib/format.ts +65 -0
- package/src/lib/index.ts +26 -0
- package/src/lib/lenses.ts +241 -0
- package/src/lib/repo.ts +44 -0
- package/src/lib/scores.ts +94 -0
- package/src/lib/search.ts +481 -0
- package/src/lib/taxonomy-counts.ts +60 -0
- package/src/styles.css +366 -638
- package/templates/default/astro.config.mjs +8 -6
- package/templates/default/content/pages/about.md +66 -0
- package/templates/default/content/pages/methodology.md +103 -0
- package/templates/default/data/generated/records.full.json +8 -0
- package/templates/default/data/generated/records.index.json +7 -0
- package/templates/default/data/generated/records.json +8 -0
- package/templates/default/data/generated/site-config.json +31 -0
- package/templates/default/data/records/.gitkeep +0 -0
- package/templates/default/grove.config.ts +36 -0
- package/templates/default/package.json +6 -5
- package/templates/default/public/llms-full.txt +14 -0
- package/templates/default/public/llms.txt +11 -0
- package/templates/default/src/components/layout/BaseLayout.astro +10 -57
- package/templates/default/src/components/layout/Footer.astro +16 -134
- package/templates/default/src/components/layout/Header.astro +25 -126
- package/templates/default/src/data/records.ts +193 -0
- package/templates/default/src/lib/markdown.ts +171 -0
- package/templates/default/src/pages/about.astro +95 -429
- package/templates/default/src/pages/index.astro +263 -61
- package/templates/default/src/pages/projects/[slug].astro +480 -0
- package/templates/default/src/pages/projects/index.astro +193 -0
- package/templates/default/src/pages/sitemap.xml.ts +73 -61
- package/templates/default/src/pages/submit.astro +122 -411
- package/templates/default/src/styles/global.css +42 -68
- package/src/components/ActiveFilterChips.astro +0 -20
- package/src/components/DirectoryFilters.astro +0 -100
- package/src/components/DirectoryHero.astro +0 -32
- package/src/components/HealthBadge.astro +0 -12
- package/src/components/LensTabs.astro +0 -26
- package/src/components/MethodologyPanel.astro +0 -20
- package/src/components/Pagination.astro +0 -24
- package/src/components/ProjectDetail.astro +0 -166
- package/src/components/SubmitDraft.astro +0 -137
- package/templates/default/src/components/AppCard.astro +0 -248
- package/templates/default/src/components/AppSection.astro +0 -58
- package/templates/default/src/components/AppsIndexRow.astro +0 -230
- package/templates/default/src/components/AppsPagination.astro +0 -147
- package/templates/default/src/components/CategoryGrid.astro +0 -80
- package/templates/default/src/components/ContributorsGrid.astro +0 -105
- package/templates/default/src/components/DecisionRow.astro +0 -219
- package/templates/default/src/components/ExploreByCategory.astro +0 -74
- package/templates/default/src/components/ExploreByStack.astro +0 -102
- package/templates/default/src/components/Hero.astro +0 -176
- package/templates/default/src/components/MinimalAbout.astro +0 -57
- package/templates/default/src/components/OriginalCollection.astro +0 -144
- package/templates/default/src/components/RefinePanel.astro +0 -272
- package/templates/default/src/components/ScoreBars.astro +0 -72
- package/templates/default/src/components/SmartLensTabs.astro +0 -65
- package/templates/default/src/components/StackGrid.astro +0 -95
- package/templates/default/src/components/WhyThisExists.astro +0 -81
- package/templates/default/src/components/icons/Icon.astro +0 -148
- package/templates/default/src/components/layout/SectionHeader.astro +0 -42
- package/templates/default/src/components/layout/ThemeToggle.astro +0 -97
- package/templates/default/src/data/apps.ts +0 -149
- package/templates/default/src/data/categories.ts +0 -27
- package/templates/default/src/data/config.ts +0 -28
- package/templates/default/src/data/contributors.ts +0 -96
- package/templates/default/src/data/stacks.ts +0 -47
- package/templates/default/src/data/stats.ts +0 -65
- package/templates/default/src/data/types.ts +0 -248
- package/templates/default/src/lib/apps-search.ts +0 -228
- package/templates/default/src/lib/format.ts +0 -36
- package/templates/default/src/lib/lenses.ts +0 -98
- package/templates/default/src/lib/repo.ts +0 -12
- package/templates/default/src/lib/scores.ts +0 -51
- package/templates/default/src/lib/taxonomy-counts.ts +0 -31
- package/templates/default/src/pages/apps/[slug].astro +0 -709
- package/templates/default/src/pages/apps/index.astro +0 -669
- package/templates/default/src/pages/contributors.astro +0 -142
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import generatedJson from "../../data/generated/apps.json";
|
|
2
|
-
import type { OpenSourceApp, AppLabel } from "./types";
|
|
3
|
-
|
|
4
|
-
// ──────────────────────────────────────────────────────────────────────
|
|
5
|
-
// Source of truth: data/generated/apps.json, produced at build time
|
|
6
|
-
// from data/apps/*.yml by scripts/build-apps-json.mjs. The yml files
|
|
7
|
-
// are the human-edited source; this file is just a typed re-export
|
|
8
|
-
// that fills in safe defaults so consumers don't have to guard every
|
|
9
|
-
// optional field.
|
|
10
|
-
//
|
|
11
|
-
// When adding a new app: write a yml in data/apps/, run
|
|
12
|
-
// `pnpm run build:data`, and it will appear here.
|
|
13
|
-
// ──────────────────────────────────────────────────────────────────────
|
|
14
|
-
|
|
15
|
-
const generated = generatedJson as { apps: unknown[] };
|
|
16
|
-
|
|
17
|
-
type GeneratedApp = Partial<OpenSourceApp> & {
|
|
18
|
-
slug: string;
|
|
19
|
-
name: string;
|
|
20
|
-
repoUrl: string;
|
|
21
|
-
description?: string;
|
|
22
|
-
stack: string;
|
|
23
|
-
platforms: string[];
|
|
24
|
-
category: string;
|
|
25
|
-
activity?: {
|
|
26
|
-
stars?: number;
|
|
27
|
-
forks?: number;
|
|
28
|
-
lastCommitAt?: string | null;
|
|
29
|
-
contributors?: number;
|
|
30
|
-
updatedAt?: string;
|
|
31
|
-
};
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Auto-compute labels for an app from its activity block. Used as a
|
|
36
|
-
* fallback when a curator hasn't hand-set `labels:` in the yml. Drives
|
|
37
|
-
* the homepage "new / hot / mature" sections.
|
|
38
|
-
*
|
|
39
|
-
* mature — stars ≥ 500, OR very high stars (popular, established)
|
|
40
|
-
* hot — last commit within the last 6 months (currently active)
|
|
41
|
-
* new — emerging: not mature, not in the last commit window, or
|
|
42
|
-
* no commit signal at all
|
|
43
|
-
*
|
|
44
|
-
* Multiple labels can apply (a popular active project is both mature
|
|
45
|
-
* and hot).
|
|
46
|
-
*/
|
|
47
|
-
function computeLabels(g: GeneratedApp): AppLabel[] {
|
|
48
|
-
const labels: AppLabel[] = [];
|
|
49
|
-
// After the schemaVersion 1 migration, stars + lastCommitAt live at
|
|
50
|
-
// the top level of the generated record (the v1 normalizer in
|
|
51
|
-
// `app-schema.mjs` flattens `github.repository.stargazers_count`
|
|
52
|
-
// and `github.repository.pushed_at` to top-level). The old
|
|
53
|
-
// `g.activity.stars` shape still works for legacy records, so we
|
|
54
|
-
// fall back to it for mixed input.
|
|
55
|
-
const stars =
|
|
56
|
-
typeof g.stars === "number"
|
|
57
|
-
? g.stars
|
|
58
|
-
: typeof g.activity?.stars === "number"
|
|
59
|
-
? g.activity.stars
|
|
60
|
-
: 0;
|
|
61
|
-
const lastCommit = g.lastCommitAt ?? g.activity?.lastCommitAt;
|
|
62
|
-
|
|
63
|
-
if (stars >= 500) labels.push("mature");
|
|
64
|
-
if (stars >= 100 && stars < 500) labels.push("hot");
|
|
65
|
-
if (stars < 100) labels.push("new");
|
|
66
|
-
|
|
67
|
-
// Hot: recent commit and not already tagged as such
|
|
68
|
-
if (lastCommit) {
|
|
69
|
-
const sixMonthsAgo = new Date();
|
|
70
|
-
sixMonthsAgo.setMonth(sixMonthsAgo.getMonth() - 6);
|
|
71
|
-
if (new Date(lastCommit) >= sixMonthsAgo && !labels.includes("hot")) {
|
|
72
|
-
labels.push("hot");
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
return labels;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Map a generated yml-shaped record to the OpenSourceApp shape that
|
|
80
|
-
* pages expect. Fills defaults, flattens `activity.stars` → `stars`,
|
|
81
|
-
* and tolerates missing curation fields.
|
|
82
|
-
*/
|
|
83
|
-
function normalize(g: GeneratedApp): OpenSourceApp {
|
|
84
|
-
const a = g.activity ?? {};
|
|
85
|
-
return {
|
|
86
|
-
slug: g.slug,
|
|
87
|
-
name: g.name,
|
|
88
|
-
description: g.description ?? "",
|
|
89
|
-
repoUrl: g.repoUrl,
|
|
90
|
-
homepageUrl: g.homepageUrl,
|
|
91
|
-
stack: g.stack,
|
|
92
|
-
stacks: g.stacks,
|
|
93
|
-
platforms: g.platforms ?? [],
|
|
94
|
-
distribution: g.distribution,
|
|
95
|
-
category: g.category,
|
|
96
|
-
tags: g.tags,
|
|
97
|
-
logoUrl: g.logoUrl,
|
|
98
|
-
stars: typeof a.stars === "number" ? a.stars : g.stars,
|
|
99
|
-
license: g.license,
|
|
100
|
-
status: g.status,
|
|
101
|
-
addedAt: g.addedAt,
|
|
102
|
-
lastCommitAt: a.lastCommitAt ?? g.lastCommitAt,
|
|
103
|
-
labels: g.labels && g.labels.length > 0 ? g.labels : computeLabels(g),
|
|
104
|
-
// Curation (optional)
|
|
105
|
-
projectType: g.projectType,
|
|
106
|
-
stateManagement: g.stateManagement,
|
|
107
|
-
backend: g.backend,
|
|
108
|
-
architecture: g.architecture,
|
|
109
|
-
difficulty: g.difficulty,
|
|
110
|
-
codebaseSize: g.codebaseSize,
|
|
111
|
-
bestFor: g.bestFor,
|
|
112
|
-
whyListed: g.whyListed,
|
|
113
|
-
caveats: g.caveats,
|
|
114
|
-
goodFirstIssues: g.goodFirstIssues,
|
|
115
|
-
contributionGuide: g.contributionGuide,
|
|
116
|
-
launchedBy: g.launchedBy,
|
|
117
|
-
launchAsk: g.launchAsk,
|
|
118
|
-
lenses: g.lenses,
|
|
119
|
-
scores: g.scores,
|
|
120
|
-
curation: g.curation,
|
|
121
|
-
github: g.github,
|
|
122
|
-
health: g.health,
|
|
123
|
-
tier: g.tier,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const generatedApps = generated.apps as GeneratedApp[];
|
|
128
|
-
|
|
129
|
-
export const apps: OpenSourceApp[] = generatedApps.map(normalize);
|
|
130
|
-
|
|
131
|
-
// ── Convenience filters ──────────────────────────────────────────────
|
|
132
|
-
|
|
133
|
-
export function newApps(): OpenSourceApp[] {
|
|
134
|
-
return apps.filter((a) => a.labels?.includes("new"));
|
|
135
|
-
}
|
|
136
|
-
export function hotApps(): OpenSourceApp[] {
|
|
137
|
-
return apps.filter((a) => a.labels?.includes("hot"));
|
|
138
|
-
}
|
|
139
|
-
export function matureApps(): OpenSourceApp[] {
|
|
140
|
-
return apps.filter((a) => a.labels?.includes("mature"));
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// ── Lookups ──────────────────────────────────────────────────────────
|
|
144
|
-
|
|
145
|
-
const bySlug = new Map(apps.map((a) => [a.slug, a]));
|
|
146
|
-
|
|
147
|
-
export function appBySlug(slug: string): OpenSourceApp | undefined {
|
|
148
|
-
return bySlug.get(slug);
|
|
149
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export type Category = {
|
|
2
|
-
slug: string;
|
|
3
|
-
name: string;
|
|
4
|
-
blurb: string;
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
// Static taxonomy. Counts are NOT stored here — they are computed at
|
|
8
|
-
// build time from data/generated/apps.json via src/lib/category-counts.ts
|
|
9
|
-
// so the numbers always match what's actually rendered.
|
|
10
|
-
export const categories: Category[] = [
|
|
11
|
-
{ slug: "productivity", name: "Productivity", blurb: "Tasks, notes, calendars, knowledge bases." },
|
|
12
|
-
{ slug: "finance", name: "Finance", blurb: "Budgeting, wallets, expense tracking." },
|
|
13
|
-
{ slug: "education", name: "Education", blurb: "Flashcards, learning, reference apps." },
|
|
14
|
-
{ slug: "tools", name: "Tools", blurb: "Browsers, utilities, dev helpers, file tools." },
|
|
15
|
-
{ slug: "communication", name: "Communication", blurb: "Chat, messaging, social, team tools." },
|
|
16
|
-
{ slug: "health-and-fitness", name: "Health and Fitness", blurb: "Workouts, nutrition, wellness tracking." },
|
|
17
|
-
{ slug: "business", name: "Business", blurb: "Invoicing, jobs, marketplace, ops tools." },
|
|
18
|
-
{ slug: "games", name: "Games", blurb: "Open-source games and engines." },
|
|
19
|
-
{ slug: "media", name: "Media", blurb: "Music, movies, photos, audio and video." },
|
|
20
|
-
{ slug: "entertainment", name: "Entertainment", blurb: "TV, movies, books, anime, ebooks." },
|
|
21
|
-
{ slug: "social-network", name: "Social Network", blurb: "Decentralized social clients and readers." },
|
|
22
|
-
{ slug: "shopping", name: "Shopping", blurb: "E-commerce, delivery, food, retail." },
|
|
23
|
-
{ slug: "news", name: "News and Magazine", blurb: "Hacker News clients, RSS, magazines." },
|
|
24
|
-
{ slug: "travel", name: "Travel", blurb: "Flights, tourism, cab sharing, guides." },
|
|
25
|
-
{ slug: "lifestyle", name: "Lifestyle", blurb: "Habits, journaling, daily life tools." },
|
|
26
|
-
{ slug: "personalization", name: "Personalization", blurb: "Launchers, themes, customization." },
|
|
27
|
-
];
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Site config exposed to Astro pages.
|
|
3
|
-
*
|
|
4
|
-
* This file is the typed view of `curated.config.ts`. The CLI builds it
|
|
5
|
-
* from the project-root config at `grove build-data` time. Astro
|
|
6
|
-
* pages and components import it directly for branding strings.
|
|
7
|
-
*
|
|
8
|
-
* Do not edit by hand. Re-run `grove build-data` after changing
|
|
9
|
-
* `curated.config.ts`.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
export type SiteConfig = {
|
|
13
|
-
name: string;
|
|
14
|
-
tagline: string;
|
|
15
|
-
description: string;
|
|
16
|
-
siteUrl: string;
|
|
17
|
-
repoUrl: string;
|
|
18
|
-
itemLabel: string;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export const siteConfig: SiteConfig = {
|
|
22
|
-
name: "Grove",
|
|
23
|
-
tagline: "A living, health-aware developer directory.",
|
|
24
|
-
description: "A searchable directory of open-source projects — organized by stack, category, platform, license, activity, and maturity.",
|
|
25
|
-
siteUrl: "https://example.com",
|
|
26
|
-
repoUrl: "https://github.com/tortuvshin/grove",
|
|
27
|
-
itemLabel: "project",
|
|
28
|
-
};
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
export type Contributor = {
|
|
2
|
-
username: string;
|
|
3
|
-
name?: string;
|
|
4
|
-
avatarUrl: string;
|
|
5
|
-
profileUrl: string;
|
|
6
|
-
contributions?: number;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
// AUTO-GENERATED by scripts/sync-contributors.mjs — do not edit by hand.
|
|
10
|
-
// Re-run the script (or wait for the weekly workflow) to refresh from GitHub.
|
|
11
|
-
// Source: GET /repos/tortuvshin/open-apps/contributors (82 named contributors).
|
|
12
|
-
// Anonymous contributors are excluded — the homepage grid renders <a> avatars with no anonymous target.
|
|
13
|
-
export const contributors: Contributor[] = [
|
|
14
|
-
{ username: "tortuvshin", avatarUrl: "https://avatars.githubusercontent.com/u/9257227?v=4", profileUrl: "https://github.com/tortuvshin", contributions: 140 },
|
|
15
|
-
{ username: "j-j-gajjar", avatarUrl: "https://avatars.githubusercontent.com/u/57590688?v=4", profileUrl: "https://github.com/j-j-gajjar", contributions: 5 },
|
|
16
|
-
{ username: "ArizArmeidi", avatarUrl: "https://avatars.githubusercontent.com/u/60814961?v=4", profileUrl: "https://github.com/ArizArmeidi", contributions: 3 },
|
|
17
|
-
{ username: "vellt", avatarUrl: "https://avatars.githubusercontent.com/u/61885011?v=4", profileUrl: "https://github.com/vellt", contributions: 3 },
|
|
18
|
-
{ username: "tejasbadone", avatarUrl: "https://avatars.githubusercontent.com/u/81501235?v=4", profileUrl: "https://github.com/tejasbadone", contributions: 3 },
|
|
19
|
-
{ username: "ErfanRht", avatarUrl: "https://avatars.githubusercontent.com/u/68302442?v=4", profileUrl: "https://github.com/ErfanRht", contributions: 2 },
|
|
20
|
-
{ username: "monolidth", avatarUrl: "https://avatars.githubusercontent.com/u/71930307?v=4", profileUrl: "https://github.com/monolidth", contributions: 2 },
|
|
21
|
-
{ username: "proninyaroslav", avatarUrl: "https://avatars.githubusercontent.com/u/7840559?v=4", profileUrl: "https://github.com/proninyaroslav", contributions: 2 },
|
|
22
|
-
{ username: "Tarikul711", avatarUrl: "https://avatars.githubusercontent.com/u/9304805?v=4", profileUrl: "https://github.com/Tarikul711", contributions: 2 },
|
|
23
|
-
{ username: "lucalves", avatarUrl: "https://avatars.githubusercontent.com/u/17712401?v=4", profileUrl: "https://github.com/lucalves", contributions: 2 },
|
|
24
|
-
{ username: "1hanzla100", avatarUrl: "https://avatars.githubusercontent.com/u/59178380?v=4", profileUrl: "https://github.com/1hanzla100", contributions: 2 },
|
|
25
|
-
{ username: "jerichoi224", avatarUrl: "https://avatars.githubusercontent.com/u/4184001?v=4", profileUrl: "https://github.com/jerichoi224", contributions: 2 },
|
|
26
|
-
{ username: "tsvillain", avatarUrl: "https://avatars.githubusercontent.com/u/42140007?v=4", profileUrl: "https://github.com/tsvillain", contributions: 1 },
|
|
27
|
-
{ username: "TNT-Likely", avatarUrl: "https://avatars.githubusercontent.com/u/9278923?v=4", profileUrl: "https://github.com/TNT-Likely", contributions: 1 },
|
|
28
|
-
{ username: "sumittiware", avatarUrl: "https://avatars.githubusercontent.com/u/64718675?v=4", profileUrl: "https://github.com/sumittiware", contributions: 1 },
|
|
29
|
-
{ username: "simonbengtsson", avatarUrl: "https://avatars.githubusercontent.com/u/3586691?v=4", profileUrl: "https://github.com/simonbengtsson", contributions: 1 },
|
|
30
|
-
{ username: "shaxxx", avatarUrl: "https://avatars.githubusercontent.com/u/1778875?v=4", profileUrl: "https://github.com/shaxxx", contributions: 1 },
|
|
31
|
-
{ username: "88srzh", avatarUrl: "https://avatars.githubusercontent.com/u/61797666?v=4", profileUrl: "https://github.com/88srzh", contributions: 1 },
|
|
32
|
-
{ username: "SatyamX64", avatarUrl: "https://avatars.githubusercontent.com/u/62766656?v=4", profileUrl: "https://github.com/SatyamX64", contributions: 1 },
|
|
33
|
-
{ username: "sarvesh4396", avatarUrl: "https://avatars.githubusercontent.com/u/68162479?v=4", profileUrl: "https://github.com/sarvesh4396", contributions: 1 },
|
|
34
|
-
{ username: "illussna", avatarUrl: "https://avatars.githubusercontent.com/u/20238269?v=4", profileUrl: "https://github.com/illussna", contributions: 1 },
|
|
35
|
-
{ username: "SAHILDUDHAL21", avatarUrl: "https://avatars.githubusercontent.com/u/129080375?v=4", profileUrl: "https://github.com/SAHILDUDHAL21", contributions: 1 },
|
|
36
|
-
{ username: "SaadAAkash", avatarUrl: "https://avatars.githubusercontent.com/u/16515550?v=4", profileUrl: "https://github.com/SaadAAkash", contributions: 1 },
|
|
37
|
-
{ username: "Rohithgilla12", avatarUrl: "https://avatars.githubusercontent.com/u/19389850?v=4", profileUrl: "https://github.com/Rohithgilla12", contributions: 1 },
|
|
38
|
-
{ username: "teolemon", avatarUrl: "https://avatars.githubusercontent.com/u/1689815?v=4", profileUrl: "https://github.com/teolemon", contributions: 1 },
|
|
39
|
-
{ username: "Re4ch-Jay", avatarUrl: "https://avatars.githubusercontent.com/u/111555521?v=4", profileUrl: "https://github.com/Re4ch-Jay", contributions: 1 },
|
|
40
|
-
{ username: "pauek", avatarUrl: "https://avatars.githubusercontent.com/u/4069?v=4", profileUrl: "https://github.com/pauek", contributions: 1 },
|
|
41
|
-
{ username: "DaNnyKg07", avatarUrl: "https://avatars.githubusercontent.com/u/78636435?v=4", profileUrl: "https://github.com/DaNnyKg07", contributions: 1 },
|
|
42
|
-
{ username: "omar-h-omar", avatarUrl: "https://avatars.githubusercontent.com/u/58376513?v=4", profileUrl: "https://github.com/omar-h-omar", contributions: 1 },
|
|
43
|
-
{ username: "FatoomRe", avatarUrl: "https://avatars.githubusercontent.com/u/112693194?v=4", profileUrl: "https://github.com/FatoomRe", contributions: 1 },
|
|
44
|
-
{ username: "yon30c", avatarUrl: "https://avatars.githubusercontent.com/u/83658386?v=4", profileUrl: "https://github.com/yon30c", contributions: 1 },
|
|
45
|
-
{ username: "y-pakorn", avatarUrl: "https://avatars.githubusercontent.com/u/48324733?v=4", profileUrl: "https://github.com/y-pakorn", contributions: 1 },
|
|
46
|
-
{ username: "virlow-voice", avatarUrl: "https://avatars.githubusercontent.com/u/102702984?v=4", profileUrl: "https://github.com/virlow-voice", contributions: 1 },
|
|
47
|
-
{ username: "trizin", avatarUrl: "https://avatars.githubusercontent.com/u/25263018?v=4", profileUrl: "https://github.com/trizin", contributions: 1 },
|
|
48
|
-
{ username: "sparkleMing", avatarUrl: "https://avatars.githubusercontent.com/u/38350996?v=4", profileUrl: "https://github.com/sparkleMing", contributions: 1 },
|
|
49
|
-
{ username: "softjapan", avatarUrl: "https://avatars.githubusercontent.com/u/11269856?v=4", profileUrl: "https://github.com/softjapan", contributions: 1 },
|
|
50
|
-
{ username: "moda20", avatarUrl: "https://avatars.githubusercontent.com/u/23613485?v=4", profileUrl: "https://github.com/moda20", contributions: 1 },
|
|
51
|
-
{ username: "mihalycsaba", avatarUrl: "https://avatars.githubusercontent.com/u/50019470?v=4", profileUrl: "https://github.com/mihalycsaba", contributions: 1 },
|
|
52
|
-
{ username: "ivirtex", avatarUrl: "https://avatars.githubusercontent.com/u/57679865?v=4", profileUrl: "https://github.com/ivirtex", contributions: 1 },
|
|
53
|
-
{ username: "comerc", avatarUrl: "https://avatars.githubusercontent.com/u/1025241?v=4", profileUrl: "https://github.com/comerc", contributions: 1 },
|
|
54
|
-
{ username: "albemala", avatarUrl: "https://avatars.githubusercontent.com/u/2332860?v=4", profileUrl: "https://github.com/albemala", contributions: 1 },
|
|
55
|
-
{ username: "xal", avatarUrl: "https://avatars.githubusercontent.com/u/1388084?v=4", profileUrl: "https://github.com/xal", contributions: 1 },
|
|
56
|
-
{ username: "yash1200", avatarUrl: "https://avatars.githubusercontent.com/u/38391570?v=4", profileUrl: "https://github.com/yash1200", contributions: 1 },
|
|
57
|
-
{ username: "wad3g", avatarUrl: "https://avatars.githubusercontent.com/u/2086896?v=4", profileUrl: "https://github.com/wad3g", contributions: 1 },
|
|
58
|
-
{ username: "VarunS2002", avatarUrl: "https://avatars.githubusercontent.com/u/30069380?v=4", profileUrl: "https://github.com/VarunS2002", contributions: 1 },
|
|
59
|
-
{ username: "friebetill", avatarUrl: "https://avatars.githubusercontent.com/u/10923085?v=4", profileUrl: "https://github.com/friebetill", contributions: 1 },
|
|
60
|
-
{ username: "theachoem", avatarUrl: "https://avatars.githubusercontent.com/u/29684683?v=4", profileUrl: "https://github.com/theachoem", contributions: 1 },
|
|
61
|
-
{ username: "Enhancifire", avatarUrl: "https://avatars.githubusercontent.com/u/81345756?v=4", profileUrl: "https://github.com/Enhancifire", contributions: 1 },
|
|
62
|
-
{ username: "Ehtiram-Ullah", avatarUrl: "https://avatars.githubusercontent.com/u/157794767?v=4", profileUrl: "https://github.com/Ehtiram-Ullah", contributions: 1 },
|
|
63
|
-
{ username: "Deepanshu-Rohilla", avatarUrl: "https://avatars.githubusercontent.com/u/52520071?v=4", profileUrl: "https://github.com/Deepanshu-Rohilla", contributions: 1 },
|
|
64
|
-
{ username: "DattatreyaReddy", avatarUrl: "https://avatars.githubusercontent.com/u/58727124?v=4", profileUrl: "https://github.com/DattatreyaReddy", contributions: 1 },
|
|
65
|
-
{ username: "shurygindv", avatarUrl: "https://avatars.githubusercontent.com/u/38868386?v=4", profileUrl: "https://github.com/shurygindv", contributions: 1 },
|
|
66
|
-
{ username: "csuka1219", avatarUrl: "https://avatars.githubusercontent.com/u/70962953?v=4", profileUrl: "https://github.com/csuka1219", contributions: 1 },
|
|
67
|
-
{ username: "ChangJoo-Park", avatarUrl: "https://avatars.githubusercontent.com/u/1451365?v=4", profileUrl: "https://github.com/ChangJoo-Park", contributions: 1 },
|
|
68
|
-
{ username: "KyleKun", avatarUrl: "https://avatars.githubusercontent.com/u/36611739?v=4", profileUrl: "https://github.com/KyleKun", contributions: 1 },
|
|
69
|
-
{ username: "bipinct", avatarUrl: "https://avatars.githubusercontent.com/u/1249142?v=4", profileUrl: "https://github.com/bipinct", contributions: 1 },
|
|
70
|
-
{ username: "Spyy004", avatarUrl: "https://avatars.githubusercontent.com/u/54628130?v=4", profileUrl: "https://github.com/Spyy004", contributions: 1 },
|
|
71
|
-
{ username: "AyanDas-99", avatarUrl: "https://avatars.githubusercontent.com/u/86493736?v=4", profileUrl: "https://github.com/AyanDas-99", contributions: 1 },
|
|
72
|
-
{ username: "aryamangodara", avatarUrl: "https://avatars.githubusercontent.com/u/77824849?v=4", profileUrl: "https://github.com/aryamangodara", contributions: 1 },
|
|
73
|
-
{ username: "agordn52", avatarUrl: "https://avatars.githubusercontent.com/u/17294994?v=4", profileUrl: "https://github.com/agordn52", contributions: 1 },
|
|
74
|
-
{ username: "akmadan", avatarUrl: "https://avatars.githubusercontent.com/u/56507451?v=4", profileUrl: "https://github.com/akmadan", contributions: 1 },
|
|
75
|
-
{ username: "akashlilhare", avatarUrl: "https://avatars.githubusercontent.com/u/39927872?v=4", profileUrl: "https://github.com/akashlilhare", contributions: 1 },
|
|
76
|
-
{ username: "aditya-njr", avatarUrl: "https://avatars.githubusercontent.com/u/169588760?v=4", profileUrl: "https://github.com/aditya-njr", contributions: 1 },
|
|
77
|
-
{ username: "abhith", avatarUrl: "https://avatars.githubusercontent.com/u/7039457?v=4", profileUrl: "https://github.com/abhith", contributions: 1 },
|
|
78
|
-
{ username: "NaserElziadna", avatarUrl: "https://avatars.githubusercontent.com/u/24838963?v=4", profileUrl: "https://github.com/NaserElziadna", contributions: 1 },
|
|
79
|
-
{ username: "brownboycodes", avatarUrl: "https://avatars.githubusercontent.com/u/64550304?v=4", profileUrl: "https://github.com/brownboycodes", contributions: 1 },
|
|
80
|
-
{ username: "mzsdev1", avatarUrl: "https://avatars.githubusercontent.com/u/34914546?v=4", profileUrl: "https://github.com/mzsdev1", contributions: 1 },
|
|
81
|
-
{ username: "mllrr96", avatarUrl: "https://avatars.githubusercontent.com/u/28247455?v=4", profileUrl: "https://github.com/mllrr96", contributions: 1 },
|
|
82
|
-
{ username: "hadiuzzaman524", avatarUrl: "https://avatars.githubusercontent.com/u/52348628?v=4", profileUrl: "https://github.com/hadiuzzaman524", contributions: 1 },
|
|
83
|
-
{ username: "deandreamatias", avatarUrl: "https://avatars.githubusercontent.com/u/21011641?v=4", profileUrl: "https://github.com/deandreamatias", contributions: 1 },
|
|
84
|
-
{ username: "mateusz-bak", avatarUrl: "https://avatars.githubusercontent.com/u/32651935?v=4", profileUrl: "https://github.com/mateusz-bak", contributions: 1 },
|
|
85
|
-
{ username: "maksymilian-majer", avatarUrl: "https://avatars.githubusercontent.com/u/1215868?v=4", profileUrl: "https://github.com/maksymilian-majer", contributions: 1 },
|
|
86
|
-
{ username: "musfique113", avatarUrl: "https://avatars.githubusercontent.com/u/53111065?v=4", profileUrl: "https://github.com/musfique113", contributions: 1 },
|
|
87
|
-
{ username: "Mufaddal5253110", avatarUrl: "https://avatars.githubusercontent.com/u/60619133?v=4", profileUrl: "https://github.com/Mufaddal5253110", contributions: 1 },
|
|
88
|
-
{ username: "Kessir", avatarUrl: "https://avatars.githubusercontent.com/u/2332730?v=4", profileUrl: "https://github.com/Kessir", contributions: 1 },
|
|
89
|
-
{ username: "kaiwalyakoparkar", avatarUrl: "https://avatars.githubusercontent.com/u/53310847?v=4", profileUrl: "https://github.com/kaiwalyakoparkar", contributions: 1 },
|
|
90
|
-
{ username: "Livinglist", avatarUrl: "https://avatars.githubusercontent.com/u/7277662?v=4", profileUrl: "https://github.com/Livinglist", contributions: 1 },
|
|
91
|
-
{ username: "jerald-jacob", avatarUrl: "https://avatars.githubusercontent.com/u/25875900?v=4", profileUrl: "https://github.com/jerald-jacob", contributions: 1 },
|
|
92
|
-
{ username: "jaysavsani07", avatarUrl: "https://avatars.githubusercontent.com/u/43170852?v=4", profileUrl: "https://github.com/jaysavsani07", contributions: 1 },
|
|
93
|
-
{ username: "javipacheco", avatarUrl: "https://avatars.githubusercontent.com/u/456025?v=4", profileUrl: "https://github.com/javipacheco", contributions: 1 },
|
|
94
|
-
{ username: "7flash", avatarUrl: "https://avatars.githubusercontent.com/u/4569866?v=4", profileUrl: "https://github.com/7flash", contributions: 1 },
|
|
95
|
-
{ username: "floranguyen0", avatarUrl: "https://avatars.githubusercontent.com/u/72301141?v=4", profileUrl: "https://github.com/floranguyen0", contributions: 1 },
|
|
96
|
-
];
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
export type Stack = {
|
|
2
|
-
slug: string;
|
|
3
|
-
name: string;
|
|
4
|
-
blurb: string;
|
|
5
|
-
status: "live" | "expanding" | "planned";
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
// Static taxonomy. Counts are NOT stored here — they are computed at
|
|
9
|
-
// build time from data/generated/apps.json. See src/lib/stack-counts.ts.
|
|
10
|
-
export const stacks: Stack[] = [
|
|
11
|
-
{
|
|
12
|
-
slug: "flutter",
|
|
13
|
-
name: "Flutter",
|
|
14
|
-
blurb: "Dart-based, cross-platform mobile apps.",
|
|
15
|
-
status: "live",
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
slug: "react-native",
|
|
19
|
-
name: "React Native",
|
|
20
|
-
blurb: "JavaScript / TypeScript mobile apps using React.",
|
|
21
|
-
status: "expanding",
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
slug: "ios",
|
|
25
|
-
name: "iOS",
|
|
26
|
-
blurb: "Native Swift apps from the App Store and the open-source community.",
|
|
27
|
-
status: "expanding",
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
slug: "android",
|
|
31
|
-
name: "Android",
|
|
32
|
-
blurb: "Native Kotlin / Java apps with a long, mature history.",
|
|
33
|
-
status: "expanding",
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
slug: "kmp",
|
|
37
|
-
name: "Kotlin Multiplatform",
|
|
38
|
-
blurb: "Shared Kotlin codebases targeting iOS and Android.",
|
|
39
|
-
status: "planned",
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
slug: "capacitor",
|
|
43
|
-
name: "Capacitor",
|
|
44
|
-
blurb: "Hybrid mobile apps built on web standards.",
|
|
45
|
-
status: "planned",
|
|
46
|
-
},
|
|
47
|
-
];
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
// Site stats, derived from generated JSON files at build time.
|
|
2
|
-
//
|
|
3
|
-
// This file imports the same JSON the rest of the app uses, so the numbers
|
|
4
|
-
// here always match what's actually rendered. No hand-tuned magic numbers.
|
|
5
|
-
//
|
|
6
|
-
// Numbers in the rendered UI (hero, header, OriginalCollection) come from
|
|
7
|
-
// this module. If a number looks wrong, refresh the source data:
|
|
8
|
-
// - pnpm run sync:repo-stats → data/generated/repo-stats.json (open-apps repo)
|
|
9
|
-
// - pnpm run sync:contributors → src/data/contributors.ts
|
|
10
|
-
// - pnpm run refresh:activity → data/apps/*.yml (per-app activity, then build:data)
|
|
11
|
-
import generatedJson from "../../data/generated/apps.json";
|
|
12
|
-
import repoStats from "../../data/generated/repo-stats.json";
|
|
13
|
-
import { categories } from "./categories";
|
|
14
|
-
import { contributors } from "./contributors";
|
|
15
|
-
|
|
16
|
-
type GeneratedApp = {
|
|
17
|
-
stack?: string;
|
|
18
|
-
platforms?: string[];
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
type RepoStats = {
|
|
22
|
-
stars: number;
|
|
23
|
-
forks: number;
|
|
24
|
-
watchers?: number;
|
|
25
|
-
openIssues?: number;
|
|
26
|
-
defaultBranch?: string;
|
|
27
|
-
pushedAt?: string;
|
|
28
|
-
syncedAt?: string;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const raw = generatedJson as { apps?: GeneratedApp[] };
|
|
32
|
-
const apps: GeneratedApp[] = raw.apps ?? [];
|
|
33
|
-
const repo = repoStats as RepoStats;
|
|
34
|
-
|
|
35
|
-
const platforms = new Set<string>();
|
|
36
|
-
for (const a of apps) {
|
|
37
|
-
for (const p of a.platforms ?? []) platforms.add(p);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export type SiteStats = {
|
|
41
|
-
apps: number;
|
|
42
|
-
contributors: number;
|
|
43
|
-
stars: number;
|
|
44
|
-
forks: number;
|
|
45
|
-
categories: number;
|
|
46
|
-
stacks: number;
|
|
47
|
-
platforms: number;
|
|
48
|
-
originalRepo: string;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export const stats: SiteStats = {
|
|
52
|
-
apps: apps.length,
|
|
53
|
-
contributors: contributors.length,
|
|
54
|
-
// Stars/forks are the open-apps repo's own — sourced from
|
|
55
|
-
// data/generated/repo-stats.json, refreshed weekly by the
|
|
56
|
-
// sync-repo-stats workflow. Previously these were summed across
|
|
57
|
-
// every app in the directory, which produced 6-figure numbers
|
|
58
|
-
// for a 4k-star repo.
|
|
59
|
-
stars: repo.stars,
|
|
60
|
-
forks: repo.forks,
|
|
61
|
-
categories: categories.length,
|
|
62
|
-
stacks: new Set(apps.map((a) => a.stack).filter(Boolean)).size,
|
|
63
|
-
platforms: platforms.size,
|
|
64
|
-
originalRepo: "https://github.com/tortuvshin/open-apps",
|
|
65
|
-
};
|