diff --git a/modules/desktop/package.json b/modules/desktop/package.json index 6ae01e2..855be47 100644 --- a/modules/desktop/package.json +++ b/modules/desktop/package.json @@ -71,6 +71,7 @@ "dependencies": { "@electron/asar": "^3.2.3", "@types/bcryptjs": "^2.4.2", + "@types/js-yaml": "^4.0.5", "@vitest/coverage-c8": "^0.27.1", "axios": "^1.3.2", "bcryptjs": "^2.4.3", @@ -87,7 +88,8 @@ "semver": "^7.3.8", "svelte-markdown": "^0.2.3", "svelte-watch-resize": "^1.0.3", - "upath": "^2.0.1" + "upath": "^2.0.1", + "yaml": "^2.2.1" }, "pnpm": { "onlyBuiltDependencies": [ diff --git a/modules/desktop/src/libs/github.ts b/modules/desktop/src/libs/github.ts new file mode 100644 index 0000000..bad471f --- /dev/null +++ b/modules/desktop/src/libs/github.ts @@ -0,0 +1,35 @@ +import axios from 'axios'; +const yaml = window.require('yaml'); + +export async function getGithubOwnerRepo( + pkgYamlUrl: string +): Promise<{ owner: string; repo: string }> { + // https://github.com/teaxyz/pantry.core/blob/main/projects/sqlite.org/package.yml + // https://raw.githubusercontent.com/teaxyz/pantry.core/main/projects/sqlite.org/package.yml + let owner = ''; + let repo = ''; + + const url = pkgYamlUrl.replace('/github.com', '/raw.githubusercontent.com').replace('/blob', ''); + + const { data: rawYaml } = await axios.get(url); + + const data = await yaml.parse(rawYaml); + if (data?.versions?.github) { + [owner, repo] = data.versions.github.split('/').filter((b: string) => b); + } + + return { + owner, + repo + }; +} + +export async function getReadme(owner: string, repo: string): Promise { + let readme = ''; + const req = await axios.get(`https://api.github.com/repos/${owner}/${repo}/readme`); + if (req.data?.download_url) { + const reqDl = await axios.get(req.data.download_url); + readme = reqDl.data; + } + return readme; +} diff --git a/modules/desktop/src/libs/stores/pkgs.ts b/modules/desktop/src/libs/stores/pkgs.ts index 0a142c0..abebac5 100644 --- a/modules/desktop/src/libs/stores/pkgs.ts +++ b/modules/desktop/src/libs/stores/pkgs.ts @@ -2,10 +2,13 @@ import { writable } from 'svelte/store'; import type { GUIPackage } from '../types'; import { getPackages } from '@api'; import Fuse from 'fuse.js'; +import { getPackageBottles } from '@api'; + +import { getGithubOwnerRepo, getReadme } from '$libs/github'; export default function initPackagesStore() { let initialized = false; - const { subscribe, set } = writable([]); + const { subscribe, set, update } = writable([]); const packages: GUIPackage[] = []; let packagesIndex: Fuse; @@ -21,6 +24,19 @@ export default function initPackagesStore() { subscribe((v) => packages.push(...v)); + const updatePackageProp = (full_name: string, props: Partial) => { + update((pkgs) => { + const i = pkgs.findIndex((pkg) => pkg.full_name === full_name); + if (i >= 0) { + pkgs[i] = { + ...pkgs[i], + ...props + }; + } + return pkgs; + }); + }; + return { packages, subscribe, @@ -31,6 +47,44 @@ export default function initPackagesStore() { const res = packagesIndex.search(term, { limit }); const matchingPackages: GUIPackage[] = res.map((v) => v.item); return matchingPackages; + }, + subscribeToPackage: (slug: string, cb: (pkg: GUIPackage) => void) => { + subscribe((pkgs) => { + const foundPackage = pkgs.find((p) => p.slug === slug) as GUIPackage; + if (foundPackage) cb(foundPackage); + // get readme + // get contributors + // get github last modified + // subscribe((pkgs) => cb(pkgs[pkg])); + + // console.log('f:', foundPackage); + // getReadmeRaw(''); + + if (!foundPackage.bottles) { + getPackageBottles(foundPackage.full_name).then((bottles) => { + updatePackageProp(foundPackage.full_name, { bottles }); + }); + } + console.log(foundPackage); + if (!foundPackage.readme_md && foundPackage.package_yml_url) { + getGithubOwnerRepo(foundPackage.package_yml_url).then(async ({ owner, repo }) => { + if (owner && repo) { + const readme_md = await getReadme(owner, repo); + console.log(readme_md); + updatePackageProp(foundPackage.full_name, { readme_md }); + } + }); + } + }); } }; } + +async function getReadmeRaw(owner: string, repo: string): Promise { + // const rep = await getRepo('oven-sh', 'bun'); + // const repo = await octokit.request('GET /repos/{owner}/{repo}', { + // owner: '', + // repo: '', + // }); + return ''; +} diff --git a/modules/desktop/src/routes/packages/[slug]/+page.svelte b/modules/desktop/src/routes/packages/[slug]/+page.svelte index 8cba314..05ce657 100644 --- a/modules/desktop/src/routes/packages/[slug]/+page.svelte +++ b/modules/desktop/src/routes/packages/[slug]/+page.svelte @@ -26,37 +26,16 @@ let reviews: Review[]; let bottles: Bottle[] = []; let versions: string[] = []; + let readme: string; let tabs: Tab[] = []; - const setPkg = (pkgs: Package[]) => { - const foundPackage = pkgs.find(({ slug }) => slug === data?.slug) as Package; - if (!pkg && foundPackage) { - pkg = foundPackage; - tabs.push({ - label: 'details', - component: Markdown, - props: { pkg } - }); - } - - if (!reviews && pkg) { - packagesReviewStore.subscribe(pkg.full_name, (updatedReviews) => { - reviews = updatedReviews; - }); - } - }; - - packagesStore.subscribe(setPkg); - featuredPackages.subscribe(setPkg); - - onMount(async () => { - try { - const newBottles = await getPackageBottles(pkg.full_name); - const newVersion = newBottles.map((b) => b.version); + packagesStore.subscribeToPackage(data?.slug, (p) => { + pkg = p; + if (!bottles.length && pkg.bottles) { + const newVersion = pkg.bottles.map((b) => b.version); versions = [...new Set(newVersion)]; - - bottles.push(...newBottles); + bottles.push(...pkg.bottles); tabs = [ ...tabs, { @@ -67,10 +46,21 @@ } } ]; - } catch (err) { - console.error(err); + } + + if (!readme && pkg.readme_md) { + readme = pkg.readme_md; + tabs = [ + { + label: 'details', + component: Markdown, + props: { pkg, source: readme } + }, + ...tabs, + ]; } }); +
diff --git a/modules/ui/src/Markdown/Markdown.svelte b/modules/ui/src/Markdown/Markdown.svelte index 1eb6895..daf367a 100644 --- a/modules/ui/src/Markdown/Markdown.svelte +++ b/modules/ui/src/Markdown/Markdown.svelte @@ -5,7 +5,7 @@ import './styles.css'; // TODO: rm sample - import { md } from './sample'; + // import { md } from './sample'; export let source: string; @@ -15,5 +15,5 @@
- +
diff --git a/modules/ui/src/Tabs/Tabs.svelte b/modules/ui/src/Tabs/Tabs.svelte index a3879d7..f70f750 100644 --- a/modules/ui/src/Tabs/Tabs.svelte +++ b/modules/ui/src/Tabs/Tabs.svelte @@ -1,6 +1,6 @@