Adding basic file browsing support
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import { ABC, Path, Compress, FS } from "../deps.ts";
|
||||
import { ABC, Path, Compress, FS, Colors } from "../deps.ts";
|
||||
|
||||
import bucket from "../s3.ts";
|
||||
import { isValidPackageName, basicauth, isValidFullVersion } from "../utils.ts";
|
||||
@ -138,16 +138,14 @@ async function uploadPackage(ctx: ABC.Context) {
|
||||
});
|
||||
|
||||
for await (const file of walker) {
|
||||
const relative = Path.relative(folder, file.path);
|
||||
const relative = Path.relative(folder, file.path).replace("\\", "/");
|
||||
|
||||
console.log("Normalised path:", relative.replace("\\", "/"));
|
||||
|
||||
const bucketPath = (bucketBase + relative).replace(/@/g, "§");
|
||||
|
||||
console.log("Uploading file:", file.path, bucketPath, bucketBase);
|
||||
await bucket.putObject(
|
||||
bucketPath,
|
||||
await Deno.readAll(await Deno.open(file.path)),
|
||||
{}
|
||||
);
|
||||
const body = await Deno.readAll(await Deno.open(file.path));
|
||||
await bucket.putObject(bucketPath, body, {});
|
||||
}
|
||||
console.log("Setting new live version");
|
||||
|
||||
@ -168,7 +166,9 @@ async function uploadPackage(ctx: ABC.Context) {
|
||||
success: true,
|
||||
};
|
||||
} catch (err) {
|
||||
console.error("Error while processing newly uploaded package");
|
||||
console.error(
|
||||
Colors.red("Error while processing newly uploaded package")
|
||||
);
|
||||
console.error(err);
|
||||
return {
|
||||
success: false,
|
||||
|
@ -1,5 +1,11 @@
|
||||
import { ABC } from "../deps.ts";
|
||||
import { extractPackagePath, getFile } from "../utils.ts";
|
||||
import { Path } from "../deps.ts";
|
||||
import type { ABC } from "../deps.ts";
|
||||
import {
|
||||
extractPackagePath,
|
||||
getAbsolutePackageVersion,
|
||||
getFile,
|
||||
} from "../utils.ts";
|
||||
import db from "../db.ts";
|
||||
|
||||
const MAX_FIXED_CACHE_AGE = 60 * 60 * 24 * 365;
|
||||
const MAX_FLOATING_CACHE_AGE = 60 * 30;
|
||||
@ -11,16 +17,27 @@ export default function raw(g: ABC.Group) {
|
||||
ctx.params.package
|
||||
);
|
||||
|
||||
const pkg = await db.package.findOne({ name: packageName });
|
||||
packageVersion = getAbsolutePackageVersion(pkg, packageVersion);
|
||||
|
||||
const E404 = () => {
|
||||
ctx.response.status = 404;
|
||||
ctx.response.body = "// Not found!";
|
||||
};
|
||||
|
||||
const result = await getFile(
|
||||
packageName,
|
||||
packageVersion,
|
||||
ctx.params.path
|
||||
);
|
||||
const filepath = ctx.params.path;
|
||||
const result = await getFile(packageName, packageVersion, filepath);
|
||||
|
||||
if (filepath.endsWith(".js")) {
|
||||
const tsFile = filepath.substr(0, filepath.length - 3) + ".d.ts";
|
||||
const tsResult = await getFile(packageName, packageVersion, tsFile);
|
||||
if (tsResult) {
|
||||
ctx.response.headers.set(
|
||||
"X-TypeScript-Types",
|
||||
"./" + Path.posix.basename(tsFile)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (packageVersion && result) {
|
||||
ctx.response.headers.set(
|
||||
|
@ -1,8 +1,16 @@
|
||||
import { ABC } from "../deps.ts";
|
||||
import { basicauth, extractPackagePath, sortVersions } from "../utils.ts";
|
||||
import type { ABC } from "../deps.ts";
|
||||
import {
|
||||
basicauth,
|
||||
extractPackagePath,
|
||||
getBucketFilePath,
|
||||
getFile,
|
||||
getAbsolutePackageVersion,
|
||||
sortVersions,
|
||||
} from "../utils.ts";
|
||||
|
||||
import { Hash } from "../deps.ts";
|
||||
import { Hash, Path } from "../deps.ts";
|
||||
import db, { IPackage } from "../db.ts";
|
||||
import bucket from "../s3.ts";
|
||||
|
||||
const MAX_CACHE_AGE = 60 * 30; // 30 Minutes
|
||||
|
||||
@ -44,6 +52,7 @@ export default function views(g: ABC.Application) {
|
||||
ctx.response.headers.set("cache-control", CACHE_CONTROL);
|
||||
ctx.response.headers.set("E-Tag", etag);
|
||||
});
|
||||
|
||||
g.get("/package/:package", async (ctx) => {
|
||||
let [packageName, packageVersion] = extractPackagePath(
|
||||
ctx.params.package
|
||||
@ -61,4 +70,84 @@ export default function views(g: ABC.Application) {
|
||||
ctx.response.headers.set("cache-control", CACHE_CONTROL);
|
||||
ctx.response.headers.set("E-Tag", etag);
|
||||
});
|
||||
|
||||
async function handleBrowse(ctx: ABC.Context) {
|
||||
const E404 = () => {
|
||||
ctx.response.status = 404;
|
||||
ctx.response.body = "// Not found!";
|
||||
};
|
||||
|
||||
let [packageName, packageVersion] = extractPackagePath(
|
||||
ctx.params.package
|
||||
);
|
||||
|
||||
const pkg = await db.package.findOne({ name: packageName });
|
||||
packageVersion = getAbsolutePackageVersion(pkg, packageVersion);
|
||||
|
||||
if (!packageVersion) return E404();
|
||||
|
||||
const path = ctx.params.path || "";
|
||||
|
||||
const fileContent = await getFile(packageName, packageVersion, path);
|
||||
if (fileContent) {
|
||||
await ctx.render("browse_file", {
|
||||
pkg,
|
||||
version: packageVersion,
|
||||
content: new TextDecoder().decode(fileContent.data),
|
||||
ext: Path.extname(path),
|
||||
path: `${packageName}@${packageVersion}/${path}`,
|
||||
});
|
||||
} else {
|
||||
const bucketPath = await getBucketFilePath(
|
||||
packageName,
|
||||
packageVersion,
|
||||
path
|
||||
);
|
||||
if (!bucketPath) return E404();
|
||||
|
||||
console.log(bucketPath);
|
||||
|
||||
const filesItr = bucket.listAllObjects({
|
||||
batchSize: 100,
|
||||
prefix: bucketPath,
|
||||
// delimiter: "/",
|
||||
});
|
||||
|
||||
let files: { name: string; size: number }[] = [];
|
||||
let directories: Set<string> = new Set();
|
||||
let readme: string | null = null;
|
||||
for await (let file of filesItr) {
|
||||
const relPath = Path.posix.relative(bucketPath, file.key || "");
|
||||
if (relPath.indexOf("/") >= 0) {
|
||||
directories.add(relPath.split("/")[0]);
|
||||
} else {
|
||||
files.push({ name: relPath, size: file.size || -1 });
|
||||
if (relPath.toLowerCase() === "readme.md") {
|
||||
let readmeCont = await getFile(
|
||||
packageName,
|
||||
packageVersion,
|
||||
Path.posix.join(path, relPath)
|
||||
);
|
||||
if (readmeCont) {
|
||||
readme = new TextDecoder().decode(readmeCont?.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await ctx.render("browse_folder", {
|
||||
pkg,
|
||||
version: packageVersion,
|
||||
readme,
|
||||
files,
|
||||
directories: Array.from(directories.values()).map((e) => ({
|
||||
name: e,
|
||||
})),
|
||||
path: `${packageName}@${packageVersion}/${path}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
g.get("/browse/:package", handleBrowse);
|
||||
g.get("/browse/:package/*path", handleBrowse);
|
||||
}
|
||||
|
Reference in New Issue
Block a user