First Commit of registry itself
	
		
			
	
		
	
	
		
	
		
			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:
		
							
								
								
									
										133
									
								
								registry/src/http/api.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								registry/src/http/api.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,133 @@
 | 
			
		||||
import { ABC, Path, Compress, FS } from "../deps.ts";
 | 
			
		||||
 | 
			
		||||
import bucket from "../s3.ts";
 | 
			
		||||
import { isValidPackageName, basicauth, isValidFullVersion } from "../utils.ts";
 | 
			
		||||
 | 
			
		||||
import db, { IPackage } from "../db.ts";
 | 
			
		||||
 | 
			
		||||
import { v4 } from "https://deno.land/std/uuid/mod.ts";
 | 
			
		||||
 | 
			
		||||
export default function api(g: ABC.Group) {
 | 
			
		||||
   g.get("/", (ctx) => {
 | 
			
		||||
      return { version: "1" };
 | 
			
		||||
   });
 | 
			
		||||
 | 
			
		||||
   g.post("/package/:name", uploadPackage, basicauth("api"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function uploadPackage(ctx: ABC.Context) {
 | 
			
		||||
   const reqId = v4.generate();
 | 
			
		||||
   const filename = "./tmp/" + reqId + ".tar";
 | 
			
		||||
   const folder = "./tmp/" + reqId;
 | 
			
		||||
 | 
			
		||||
   try {
 | 
			
		||||
      const packageName = ctx.params.name;
 | 
			
		||||
 | 
			
		||||
      if (!isValidPackageName(packageName))
 | 
			
		||||
         throw new Error("Invalid package name");
 | 
			
		||||
 | 
			
		||||
      console.log("Writing body to tmp file:", filename);
 | 
			
		||||
      const file = await Deno.open(filename, {
 | 
			
		||||
         write: true,
 | 
			
		||||
         create: true,
 | 
			
		||||
      });
 | 
			
		||||
      await Deno.copy(ctx.request.body, file);
 | 
			
		||||
      file.close();
 | 
			
		||||
 | 
			
		||||
      console.log("Create unpacked folder");
 | 
			
		||||
 | 
			
		||||
      await Deno.mkdir(folder);
 | 
			
		||||
 | 
			
		||||
      console.log("Uncompressing tar");
 | 
			
		||||
 | 
			
		||||
      await Compress.Tar.uncompress(filename, folder);
 | 
			
		||||
 | 
			
		||||
      console.log("Reading meta.json");
 | 
			
		||||
 | 
			
		||||
      const fileContent = await Deno.readFile(Path.join(folder, "meta.json"));
 | 
			
		||||
 | 
			
		||||
      console.log("Parsing meta.json");
 | 
			
		||||
 | 
			
		||||
      const meta = JSON.parse(new TextDecoder().decode(fileContent));
 | 
			
		||||
 | 
			
		||||
      console.log("Checking meta.json");
 | 
			
		||||
 | 
			
		||||
      if (!meta?.version) {
 | 
			
		||||
         throw new Error("No version available in meta.json");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const packageVersion = meta.version;
 | 
			
		||||
 | 
			
		||||
      console.log("Checking correct version");
 | 
			
		||||
 | 
			
		||||
      if (!isValidFullVersion(packageVersion)) {
 | 
			
		||||
         throw new Error("Invalid version. Version must be in format: 0.0.0");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      console.log("Checking for previous uploads");
 | 
			
		||||
 | 
			
		||||
      let packageMeta = await db.findOne({ name: packageName });
 | 
			
		||||
 | 
			
		||||
      if (!packageMeta) {
 | 
			
		||||
         packageMeta = {
 | 
			
		||||
            name: packageName,
 | 
			
		||||
            versions: [],
 | 
			
		||||
         };
 | 
			
		||||
 | 
			
		||||
         await db.insert(packageMeta);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      console.log("Check if version was uploaded before");
 | 
			
		||||
 | 
			
		||||
      if (packageMeta.versions.find((e) => e === meta.version)) {
 | 
			
		||||
         throw new Error("Version was already uploaded!");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const bucketBase = "packages/" + packageName + "/" + packageVersion + "/";
 | 
			
		||||
 | 
			
		||||
      console.log("Uploading files to S3");
 | 
			
		||||
 | 
			
		||||
      const walker = FS.walk(folder, {
 | 
			
		||||
         includeFiles: true,
 | 
			
		||||
         includeDirs: false,
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      for await (const file of walker) {
 | 
			
		||||
         const relative = Path.relative(folder, file.path);
 | 
			
		||||
 | 
			
		||||
         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)),
 | 
			
		||||
            {}
 | 
			
		||||
         );
 | 
			
		||||
      }
 | 
			
		||||
      console.log("Setting new live version");
 | 
			
		||||
 | 
			
		||||
      //TODO: Better option, since this could error whith multiple upload to the same package
 | 
			
		||||
      await db.update(
 | 
			
		||||
         { name: packageName },
 | 
			
		||||
         {
 | 
			
		||||
            $set: { versions: [...packageMeta.versions, packageVersion] },
 | 
			
		||||
         }
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      console.log("Finished successfully");
 | 
			
		||||
   } catch (err) {
 | 
			
		||||
      console.error("Error while processing newly uploaded package");
 | 
			
		||||
      console.error(err);
 | 
			
		||||
      return {
 | 
			
		||||
         success: false,
 | 
			
		||||
         message: err.message,
 | 
			
		||||
      };
 | 
			
		||||
   } finally {
 | 
			
		||||
      console.log("Cleanup");
 | 
			
		||||
      await Deno.remove(filename).catch(console.error);
 | 
			
		||||
      await Deno.remove(folder, { recursive: true }).catch(console.error);
 | 
			
		||||
   }
 | 
			
		||||
   return {
 | 
			
		||||
      success: true,
 | 
			
		||||
   };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										53
									
								
								registry/src/http/raw.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								registry/src/http/raw.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,53 @@
 | 
			
		||||
import { ABC } from "../deps.ts";
 | 
			
		||||
 | 
			
		||||
import { sortVersions, extractPackagePath } from "../utils.ts";
 | 
			
		||||
 | 
			
		||||
import db, { IPackage } from "../db.ts";
 | 
			
		||||
 | 
			
		||||
import bucket from "../s3.ts";
 | 
			
		||||
 | 
			
		||||
export default function raw(g: ABC.Group) {
 | 
			
		||||
   g.get("/:package/*path", async (ctx) => {
 | 
			
		||||
      console.log(ctx.params, ctx.path);
 | 
			
		||||
      let [packageName, packageVersion] = extractPackagePath(
 | 
			
		||||
         ctx.params.package
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      const meta = await db.findOne({ name: packageName });
 | 
			
		||||
 | 
			
		||||
      console.log(packageName, await db.findOne({ name: packageName }));
 | 
			
		||||
 | 
			
		||||
      const E404 = () => {
 | 
			
		||||
         ctx.response.status = 404;
 | 
			
		||||
         ctx.response.body = "Not found!";
 | 
			
		||||
         throw new Error("Not found!");
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      if (!meta || meta.versions.length < 1) return E404();
 | 
			
		||||
 | 
			
		||||
      const versions = meta.versions.sort(sortVersions).reverse();
 | 
			
		||||
 | 
			
		||||
      if (!packageVersion) {
 | 
			
		||||
         packageVersion = versions[0];
 | 
			
		||||
      } else {
 | 
			
		||||
         const v = versions.filter((e) =>
 | 
			
		||||
            e.startsWith(packageVersion as string)
 | 
			
		||||
         );
 | 
			
		||||
         if (v.length < 1) return E404();
 | 
			
		||||
         packageVersion = v[0];
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const bucketPath = (
 | 
			
		||||
         "packages/" +
 | 
			
		||||
         packageName +
 | 
			
		||||
         "/" +
 | 
			
		||||
         packageVersion +
 | 
			
		||||
         "/" +
 | 
			
		||||
         ctx.params.path
 | 
			
		||||
      ).replace(/@/g, "§");
 | 
			
		||||
 | 
			
		||||
      console.log("Getting file from:", bucketPath);
 | 
			
		||||
 | 
			
		||||
      return (await bucket.getObject(bucketPath))?.body;
 | 
			
		||||
   });
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user