diff --git a/app.ts b/app.ts index 2814743..d4850c6 100644 --- a/app.ts +++ b/app.ts @@ -1,19 +1,28 @@ -import { Application, Router } from "https://deno.land/x/oak@v12.1.0/mod.ts"; +import { Application, Router, HttpError, isHttpError } from "https://deno.land/x/oak@v12.1.0/mod.ts"; import { searchRepositoryWithTopic, getRepositoryTags, - getRepositoryContent + getRepositoryContent, + GiteaOption } from "./gitea.ts"; import { ContentsResponse } from "./gitea_api.d.ts"; import { Command } from "https://deno.land/x/cliffy@v0.25.7/mod.ts"; -// import { load } from "https://deno.land/std@0.181.0/dotenv/mod.ts"; -// const env = await load(); +import { load } from "https://deno.land/std@0.191.0/dotenv/mod.ts"; +const env = await load(); + +function getGiteaOptions(): GiteaOption| undefined{ + const token = env.TOKEN; + if (token === undefined){ + return undefined + } + return {token: token}; +} const app = new Application(); const router = new Router(); -const RelativeTopic = "denolib"; +const RelativeTopic = env.tag ?? "denolib"; export interface CompletionList { /** The list (or partial list) of completion items. */ @@ -58,7 +67,8 @@ router.get("/.well-known/deno-import-intellisense.json", (ctx) => { router.get("/packages/:package", async (ctx) => { const packageName = ctx.params.package; console.log(`searchRepositoryWithTopic: ${packageName}`); - const repositories = await searchRepositoryWithTopic(RelativeTopic); + const options = getGiteaOptions(); + const repositories = await searchRepositoryWithTopic(RelativeTopic, options); const repo_name = repositories.data?.map((repo) => repo.full_name) .filter(x => x !== undefined) .map(x=> x?.replace("/","@")) ?? []; @@ -75,7 +85,8 @@ router.get("/packages/:package/versions", async (ctx) => { const packageName = ctx.params.package; const [owner, repo] = packageName.split("@"); console.log(`getTags: owner: ${owner}, repo: ${repo}`); - const tags = await getRepositoryTags(owner, repo); + const options = getGiteaOptions(); + const tags = await getRepositoryTags(owner, repo, options); const candidate = ["main", ...tags.map((tag) => tag.name) as string[]] const completionList: CompletionList = { items: candidate, @@ -92,7 +103,8 @@ router.get("/packages/:package/:version/paths/:path*", async (ctx) => { const path = ctx.params.path; const [owner, repo] = packageName.split("@"); console.log(`getFilesEntry: owner: ${owner}, repo: ${repo}, path: ${path}, version: ${version}`); - const entries = await getRepositoryContent(owner, repo, path ?? "", version) as ContentsResponse[]; + const options = getGiteaOptions(); + const entries = await getRepositoryContent(owner, repo, path ?? "", version, options) as ContentsResponse[]; const completionList: CompletionList = { items: entries.map((entry) => entry.name) as string[], isIncomplete: false, @@ -108,7 +120,8 @@ router.get("/:package([a-z0-9_]*@[a-z0-9_]*)/:version?/:path*", async (ctx) => { const version = ctx.params.version; const path = ctx.params.path; console.log(`getFiles: owner: ${owner}, repo: ${repo}, path: ${path}, version: ${version}`); - const entries = await getRepositoryContent(owner, repo, path ?? "", version); + const options = getGiteaOptions(); + const entries = await getRepositoryContent(owner, repo, path ?? "", version, options); if (entries instanceof Array) { ctx.response.type = "application/json"; ctx.response.body = entries; @@ -124,6 +137,22 @@ router.get("/:package([a-z0-9_]*@[a-z0-9_]*)/:version?/:path*", async (ctx) => { }); +app.use(async (ctx, next) => { + try{ + await next(); + } + catch (err) { + if (isHttpError(err)) { + console.log(err); + ctx.response.status = err.status; + const { message, status, stack } = err; + ctx.response.body = { message, status, stack }; + } + else { + throw err; + } + } +}); app.use(router.routes()); app.use(router.allowedMethods()); diff --git a/gitea.ts b/gitea.ts index 1fa7b43..00438b4 100644 --- a/gitea.ts +++ b/gitea.ts @@ -2,29 +2,43 @@ import { SearchResults, Tag, ContentsResponse } from "./gitea_api.d.ts"; const ENDPOINT_URL = "https://git.prelude.duckdns.org/api/v1/"; -export async function searchRepositoryWithTopic(topic: string): Promise { +export interface GiteaOption{ + token: string; +} + +async function fetchFromGitea(url: string | URL, giteaOption? :GiteaOption): Promise { + const headers = new Headers(); + if (giteaOption) { + headers.append("Authorization", "token " + giteaOption.token); + } + const response = await fetch(url, { + headers: headers + } + ); + const data = await response.json(); + return data; +} + +export async function searchRepositoryWithTopic(topic: string, giteaOption? :GiteaOption): Promise { const url = new URL(ENDPOINT_URL+ "repos/search"); url.searchParams.append("q", topic); url.searchParams.append("topic", "true"); - const response = await fetch(url); - const data = await response.json(); + const data = await fetchFromGitea(url,giteaOption); return data; } export async function getRepositoryTags(owner:string, - repo:string): Promise{ + repo:string, giteaOption? :GiteaOption): Promise{ const url = new URL(ENDPOINT_URL+ "repos/"+owner+"/"+repo+"/tags"); - const response = await fetch(url); - const data = await response.json(); + const data = await fetchFromGitea(url,giteaOption); return data; } export async function getRepositoryContent(owner:string, - repo:string, path:string, ref:string): Promise{ + repo:string, path:string, ref:string, giteaOption? :GiteaOption): Promise{ const url = new URL(ENDPOINT_URL+ "repos/"+owner+"/"+repo+"/contents/"+path); url.searchParams.append("ref", ref); - const response = await fetch(url); - const data = await response.json(); + const data = await fetchFromGitea(url,giteaOption); return data; }