diff --git a/examples/github-backed-catalog/.eslintrc.json b/examples/github-backed-catalog/.eslintrc.json index b6d57594..f50ee6ef 100644 --- a/examples/github-backed-catalog/.eslintrc.json +++ b/examples/github-backed-catalog/.eslintrc.json @@ -1,8 +1,5 @@ { - "extends": [ - "next", - "next/core-web-vitals" - ], + "extends": ["next", "next/core-web-vitals"], "ignorePatterns": ["!**/*", ".next/**/*"], "overrides": [ { diff --git a/examples/github-backed-catalog/.prettierignore b/examples/github-backed-catalog/.prettierignore new file mode 100644 index 00000000..961824bb --- /dev/null +++ b/examples/github-backed-catalog/.prettierignore @@ -0,0 +1,7 @@ +node_modules +**/.next/** +**/_next/** +**/dist/** +**/__tmp__/** +lerna.json +.github diff --git a/examples/github-backed-catalog/.prettierrc.json b/examples/github-backed-catalog/.prettierrc.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/examples/github-backed-catalog/.prettierrc.json @@ -0,0 +1 @@ +{} diff --git a/examples/github-backed-catalog/README.md b/examples/github-backed-catalog/README.md index 6c67e1ae..c6c4a49b 100644 --- a/examples/github-backed-catalog/README.md +++ b/examples/github-backed-catalog/README.md @@ -99,4 +99,3 @@ And run the production build with: ``` npm run start ``` - diff --git a/examples/github-backed-catalog/components/_shared/Breadcrumbs.tsx b/examples/github-backed-catalog/components/_shared/Breadcrumbs.tsx index 8d903fe7..a8bb42c1 100644 --- a/examples/github-backed-catalog/components/_shared/Breadcrumbs.tsx +++ b/examples/github-backed-catalog/components/_shared/Breadcrumbs.tsx @@ -1,20 +1,28 @@ import Link from "next/link"; import HomeIcon from "../icons/HomeIcon"; -export default function Breadcrumbs({ links }: { links: { title: string, href?: string, target?: string }[] }) { +export default function Breadcrumbs({ + links, +}: { + links: { title: string; href?: string; target?: string }[]; +}) { const current = links.at(-1); - return
- + return ( +
+ + + - {/* {links.length > 1 && links.slice(0, -1).map((link) => { + {/* {links.length > 1 && links.slice(0, -1).map((link) => { return <> / {link.title} })} */} - / - {current.title} -
-} \ No newline at end of file + / + {current.title} +
+ ); +} diff --git a/examples/github-backed-catalog/components/icons/ExternalLinkIcon.tsx b/examples/github-backed-catalog/components/icons/ExternalLinkIcon.tsx index 8437b7f0..454ad70a 100644 --- a/examples/github-backed-catalog/components/icons/ExternalLinkIcon.tsx +++ b/examples/github-backed-catalog/components/icons/ExternalLinkIcon.tsx @@ -1,3 +1,13 @@ export default function ExternalLinkIcon({ className = "" }) { - return
-} \ No newline at end of file + return ( +
+ + + +
+ ); +} diff --git a/examples/github-backed-catalog/components/icons/HomeIcon.tsx b/examples/github-backed-catalog/components/icons/HomeIcon.tsx index f99c396b..1b7873c5 100644 --- a/examples/github-backed-catalog/components/icons/HomeIcon.tsx +++ b/examples/github-backed-catalog/components/icons/HomeIcon.tsx @@ -1,3 +1,10 @@ export default function HomeIcon({ className = "" }) { - return
-} \ No newline at end of file + return ( +
+ + {" "} + + +
+ ); +} diff --git a/examples/github-backed-catalog/datasets.json b/examples/github-backed-catalog/datasets.json index 97a73c5b..ad07b64b 100644 --- a/examples/github-backed-catalog/datasets.json +++ b/examples/github-backed-catalog/datasets.json @@ -19,10 +19,7 @@ "owner": "datasets", "branch": "main", "repo": "investor-flow-of-funds-us", - "files": [ - "data/monthly.csv", - "data/weekly.csv" - ], + "files": ["data/monthly.csv", "data/weekly.csv"], "readme": "README.md" }, { @@ -38,7 +35,10 @@ "owner": "fivethirtyeight", "repo": "data", "branch": "master", - "files": ["nba-raptor/historical_RAPTOR_by_player.csv", "nba-raptor/historical_RAPTOR_by_team.csv"], + "files": [ + "nba-raptor/historical_RAPTOR_by_player.csv", + "nba-raptor/historical_RAPTOR_by_team.csv" + ], "readme": "nba-raptor/README.md" } ] diff --git a/examples/github-backed-catalog/index.d.ts b/examples/github-backed-catalog/index.d.ts index 7ba08fa1..2ac88d92 100644 --- a/examples/github-backed-catalog/index.d.ts +++ b/examples/github-backed-catalog/index.d.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -declare module '*.svg' { +declare module "*.svg" { const content: any; export const ReactComponent: any; export default content; diff --git a/examples/github-backed-catalog/lib/octokit.ts b/examples/github-backed-catalog/lib/octokit.ts index 2d580ffc..1c7d6586 100644 --- a/examples/github-backed-catalog/lib/octokit.ts +++ b/examples/github-backed-catalog/lib/octokit.ts @@ -1,4 +1,4 @@ -import { Octokit } from 'octokit'; +import { Octokit } from "octokit"; export interface GithubProject { owner: string; @@ -26,15 +26,16 @@ export async function getProjectReadme( ref: branch, }); const data = response.data as { content?: string }; - const fileContent = data.content ? data.content : ''; - if (fileContent === '') { + const fileContent = data.content ? data.content : ""; + if (fileContent === "") { return null; } - const decodedContent = Buffer.from(fileContent, 'base64').toString(); + const decodedContent = Buffer.from(fileContent, "base64").toString(); return decodedContent; } catch (error) { - console.log(error); - return null; + throw new Error( + "Couldn't get project readme please make sure that you are pointing to a valid repo and that the repo in question contains a README.md" + ); } } @@ -50,13 +51,13 @@ export async function getLastUpdated( const response = await octokit.rest.repos.listCommits({ owner, repo, - path: readme, ref: branch, }); return response.data[0].commit.committer.date; } catch (error) { - console.log(error); - return null; + throw new Error( + "Couldn't get project list of commits please make sure that you are pointing to a valid repo" + ); } } export async function getProjectMetadata( @@ -72,8 +73,9 @@ export async function getProjectMetadata( }); return response.data; } catch (error) { - console.log(error); - return null; + throw new Error( + "Couldn't get project metadata please make sure that you are pointing to a valid repo" + ); } } @@ -94,13 +96,32 @@ export async function getRepoContents( ref: branch, path: path, }); - const data = response.data as { download_url?: string, name: string, size: number }; - contents.push({ download_url: data.download_url, name: data.name, size: data.size}); + const data = response.data as { + download_url?: string; + name: string; + size: number; + }; + contents.push({ + download_url: data.download_url, + name: data.name, + size: data.size, + }); } return contents; } catch (error) { - console.log(error); - return null; + if ( + error.message === + 'This endpoint can only return blobs smaller than 100 MB in size. The requested blob is too large to fetch via the API, but you can always clone the repository via Git to obtain it.: {"resource":"Blob","field":"data","code":"too_large"}' + ) { + throw new Error( + `The requested files ${files.join( + ", " + )} are too big making it impossible to fetch via Github API` + ); + } + throw new Error( + "Couldn't get project contents please make sure that you are pointing to a valid repo" + ); } } @@ -120,22 +141,20 @@ export async function getProject(project: GithubProject, github_pat?: string) { project.readme, github_pat ); - if (!projectReadme) { - return null; + let projectData = []; + if (project.files) { + projectData = await getRepoContents( + project.owner, + project.repo, + project.branch, + project.files, + github_pat + ); } - const projectData = await getRepoContents( - project.owner, - project.repo, - project.branch, - project.files, - github_pat - ); - if (!projectData) { - return null; - } - const projectBase = project.readme.split('/').length > 1 - ? project.readme.split('/').slice(0, -1).join('/') - : '/' + const projectBase = + project.readme && project.readme.split("/").length > 1 + ? project.readme.split("/").slice(0, -1).join("/") + : "/"; const last_updated = await getLastUpdated( project.owner, project.repo, @@ -143,5 +162,11 @@ export async function getProject(project: GithubProject, github_pat?: string) { projectBase, github_pat ); - return { ...projectMetadata, files: projectData, readmeContent: projectReadme, last_updated, base_path: projectBase }; + return { + ...projectMetadata, + files: projectData, + readmeContent: projectReadme, + last_updated, + base_path: projectBase, + }; } diff --git a/examples/github-backed-catalog/next.config.js b/examples/github-backed-catalog/next.config.js index 69296447..8748d907 100644 --- a/examples/github-backed-catalog/next.config.js +++ b/examples/github-backed-catalog/next.config.js @@ -3,8 +3,8 @@ const nextConfig = { return { beforeFiles: [ { - source: '/@:org/:project*', - destination: '/@org/:org/:project*', + source: "/@:org/:project*", + destination: "/@org/:org/:project*", }, ], }; diff --git a/examples/github-backed-catalog/package-lock.json b/examples/github-backed-catalog/package-lock.json index c353dadd..af52004f 100644 --- a/examples/github-backed-catalog/package-lock.json +++ b/examples/github-backed-catalog/package-lock.json @@ -27,6 +27,7 @@ "@tailwindcss/typography": "^0.5.9", "autoprefixer": "^10.4.14", "postcss": "^8.4.23", + "prettier": "2.8.8", "tailwindcss": "^3.3.1" } }, @@ -4677,6 +4678,21 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", diff --git a/examples/github-backed-catalog/package.json b/examples/github-backed-catalog/package.json index 3b2097cd..8ac280ff 100644 --- a/examples/github-backed-catalog/package.json +++ b/examples/github-backed-catalog/package.json @@ -6,7 +6,8 @@ "dev": "next dev", "build": "next build", "start": "next start", - "lint": "next lint" + "lint": "next lint", + "prettier": "prettier --write ." }, "dependencies": { "@types/node": "18.16.0", @@ -28,6 +29,7 @@ "@tailwindcss/typography": "^0.5.9", "autoprefixer": "^10.4.14", "postcss": "^8.4.23", + "prettier": "2.8.8", "tailwindcss": "^3.3.1" } } diff --git a/examples/github-backed-catalog/pages/@org/[org]/[...path].tsx b/examples/github-backed-catalog/pages/@org/[org]/[...path].tsx index e29a9bc6..0f334ff1 100644 --- a/examples/github-backed-catalog/pages/@org/[org]/[...path].tsx +++ b/examples/github-backed-catalog/pages/@org/[org]/[...path].tsx @@ -1,22 +1,31 @@ -import { NextSeo } from 'next-seo'; -import { promises as fs } from 'fs'; -import path from 'path'; -import getConfig from 'next/config'; -import { getProject, GithubProject } from '../../../lib/octokit'; -import ReactMarkdown from 'react-markdown'; -import remarkGfm from 'remark-gfm'; -import Breadcrumbs from '../../../components/_shared/Breadcrumbs'; +import { NextSeo } from "next-seo"; +import { promises as fs } from "fs"; +import path from "path"; +import getConfig from "next/config"; +import { getProject, GithubProject } from "../../../lib/octokit"; +import ReactMarkdown from "react-markdown"; +import remarkGfm from "remark-gfm"; +import Breadcrumbs from "../../../components/_shared/Breadcrumbs"; export default function ProjectPage({ project }) { - const repoId = `@${project.repo_config.owner}/${project.repo_config.repo}` + const repoId = `@${project.repo_config.owner}/${project.repo_config.repo}`; return ( <> - +

{project.repo_config.name || repoId}

-

Repository: {project.html_url}

+

+ Repository:{" "} + + {project.html_url} + +

Files

@@ -54,7 +63,7 @@ export default function ProjectPage({ project }) {
-

Readme

+

Readme

{project.readmeContent} @@ -65,17 +74,14 @@ export default function ProjectPage({ project }) { // Generates `/posts/1` and `/posts/2` export async function getStaticPaths() { - const jsonDirectory = path.join( - process.cwd(), - 'datasets.json' - ); - const repos = await fs.readFile(jsonDirectory, 'utf8'); + const jsonDirectory = path.join(process.cwd(), "datasets.json"); + const repos = await fs.readFile(jsonDirectory, "utf8"); return { paths: JSON.parse(repos).map((repo) => { const projectPath = - repo.readme.split('/').length > 1 - ? repo.readme.split('/').slice(0, -1) + repo.readme && repo.readme.split("/").length > 1 + ? repo.readme.split("/").slice(0, -1) : null; let path = [repo.repo]; if (projectPath) { @@ -92,16 +98,13 @@ export async function getStaticPaths() { } export async function getStaticProps({ params }) { - const jsonDirectory = path.join( - process.cwd(), - 'datasets.json' - ); - const reposFile = await fs.readFile(jsonDirectory, 'utf8'); + const jsonDirectory = path.join(process.cwd(), "datasets.json"); + const reposFile = await fs.readFile(jsonDirectory, "utf8"); const repos: GithubProject[] = JSON.parse(reposFile); const repo = repos.find((_repo) => { const projectPath = - _repo.readme.split('/').length > 1 - ? _repo.readme.split('/').slice(0, -1) + _repo.readme && _repo.readme.split("/").length > 1 + ? _repo.readme.split("/").slice(0, -1) : null; let path = [_repo.repo]; if (projectPath) { diff --git a/examples/github-backed-catalog/pages/_app.tsx b/examples/github-backed-catalog/pages/_app.tsx index b14578b1..18ebdea4 100644 --- a/examples/github-backed-catalog/pages/_app.tsx +++ b/examples/github-backed-catalog/pages/_app.tsx @@ -1,6 +1,6 @@ -import { AppProps } from 'next/app'; -import Head from 'next/head'; -import './styles.css'; +import { AppProps } from "next/app"; +import Head from "next/head"; +import "./styles.css"; function CustomApp({ Component, pageProps }: AppProps) { return ( diff --git a/examples/github-backed-catalog/pages/index.tsx b/examples/github-backed-catalog/pages/index.tsx index 796edefe..c55521ba 100644 --- a/examples/github-backed-catalog/pages/index.tsx +++ b/examples/github-backed-catalog/pages/index.tsx @@ -1,21 +1,19 @@ -import { promises as fs } from 'fs'; -import path from 'path'; -import { getProject } from '../lib/octokit'; -import getConfig from 'next/config'; -import ExternalLinkIcon from '../components/icons/ExternalLinkIcon'; -import TimeAgo from 'react-timeago'; -import Link from 'next/link'; +import { promises as fs } from "fs"; +import path from "path"; +import { getProject } from "../lib/octokit"; +import getConfig from "next/config"; +import ExternalLinkIcon from "../components/icons/ExternalLinkIcon"; +import TimeAgo from "react-timeago"; +import Link from "next/link"; +import { NextSeo } from "next-seo"; export async function getStaticProps() { - const jsonDirectory = path.join( - process.cwd(), - '/datasets.json' - ); - const repos = await fs.readFile(jsonDirectory, 'utf8'); + const jsonDirectory = path.join(process.cwd(), "/datasets.json"); + const repos = await fs.readFile(jsonDirectory, "utf8"); const github_pat = getConfig().serverRuntimeConfig.github_pat; const projects = await Promise.all( - (JSON.parse(repos)).map(async (repo) => { + JSON.parse(repos).map(async (repo) => { const project = await getProject(repo, github_pat); return { ...project, repo_config: repo }; }) @@ -29,88 +27,112 @@ export async function getStaticProps() { export function Datasets({ projects }) { return ( -
-
-
-

- GitHub Datasets -

-

- Data catalog with datasets hosted on GitHub by 🌀 PortalJS -

-
-
-
-
- - - - - - - - - - - - {projects.map((project) => ( - - - - - - + <> + +
+
+
+

+ GitHub Datasets +

+

+ Data catalog with datasets hosted on GitHub by{" "} + + 🌀 PortalJS + +

+
+
+
+
+
- Name - - Repository - - Description - - Last updated -
- {project.repo_config.name - ? project.repo_config.name - : project.full_name + (project.base_path === '/' ? '' : '/' + project.base_path)} - - @{project.full_name} - - {project.repo_config.description - ? project.repo_config.description - : project.description} - - - - - info - -
+ + + + + + + - ))} - -
+ Name + + Repository + + Description + + Last updated +
+ + + {projects.map((project) => ( + + + {project.repo_config.name + ? project.repo_config.name + : project.full_name + + (project.base_path === "/" + ? "" + : "/" + project.base_path)} + + + + @{project.full_name}{" "} + + + + + {project.repo_config.description + ? project.repo_config.description + : project.description} + + + + + + + info + + + + ))} + + +
-
+ ); } diff --git a/examples/github-backed-catalog/postcss.config.js b/examples/github-backed-catalog/postcss.config.js index 33ad091d..12a703d9 100644 --- a/examples/github-backed-catalog/postcss.config.js +++ b/examples/github-backed-catalog/postcss.config.js @@ -3,4 +3,4 @@ module.exports = { tailwindcss: {}, autoprefixer: {}, }, -} +}; diff --git a/examples/github-backed-catalog/tailwind.config.js b/examples/github-backed-catalog/tailwind.config.js index bea4782c..12b40a02 100644 --- a/examples/github-backed-catalog/tailwind.config.js +++ b/examples/github-backed-catalog/tailwind.config.js @@ -8,8 +8,5 @@ module.exports = { theme: { extend: {}, }, - plugins: [ - require('@tailwindcss/typography') - ], -} - + plugins: [require("@tailwindcss/typography")], +};