mirror of
https://github.com/NebulaServices/Nebula.git
synced 2025-05-14 12:20:01 -04:00
.
This commit is contained in:
parent
a62534618b
commit
06d02c42f1
18 changed files with 9778 additions and 0 deletions
169
server/marketplace.js
Normal file
169
server/marketplace.js
Normal file
|
@ -0,0 +1,169 @@
|
|||
import { createWriteStream } from "node:fs";
|
||||
import { constants, access, mkdir } from "node:fs/promises";
|
||||
import { pipeline } from "node:stream/promises";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { DataTypes, Sequelize } from "sequelize";
|
||||
import { parsedDoc } from "./config.js";
|
||||
const db = new Sequelize(parsedDoc.db.name, parsedDoc.db.username, parsedDoc.db.password, {
|
||||
host: parsedDoc.db.postgres ? `${parsedDoc.postgres.domain}` : "localhost",
|
||||
port: parsedDoc.db.postgres ? parsedDoc.postgres.port : undefined,
|
||||
dialect: parsedDoc.db.postgres ? "postgres" : "sqlite",
|
||||
logging: parsedDoc.server.server.logging,
|
||||
storage: "database.sqlite" //this is sqlite only
|
||||
});
|
||||
const catalogAssets = db.define("catalog_assets", {
|
||||
package_name: { type: DataTypes.STRING, unique: true },
|
||||
title: { type: DataTypes.TEXT },
|
||||
description: { type: DataTypes.TEXT },
|
||||
author: { type: DataTypes.TEXT },
|
||||
image: { type: DataTypes.TEXT },
|
||||
tags: { type: DataTypes.JSON, allowNull: true },
|
||||
version: { type: DataTypes.TEXT },
|
||||
background_image: { type: DataTypes.TEXT, allowNull: true },
|
||||
background_video: { type: DataTypes.TEXT, allowNull: true },
|
||||
payload: { type: DataTypes.TEXT },
|
||||
type: { type: DataTypes.TEXT }
|
||||
});
|
||||
function marketplaceAPI(app) {
|
||||
app.get("/api/catalog-stats/", (request, reply) => {
|
||||
reply.send({
|
||||
version: "1.0.0",
|
||||
spec: "Nebula Services",
|
||||
enabled: true
|
||||
});
|
||||
});
|
||||
app.get("/api/catalog-assets/", async (request, reply) => {
|
||||
try {
|
||||
const { page } = request.query;
|
||||
const pageNum = parseInt(page, 10) || 1;
|
||||
if (pageNum < 1) {
|
||||
reply.status(400).send({ error: "Page must be a positive number!" });
|
||||
}
|
||||
const offset = (pageNum - 1) * 20;
|
||||
const totalItems = await catalogAssets.count();
|
||||
const dbAssets = await catalogAssets.findAll({ offset: offset, limit: 20 });
|
||||
const assets = dbAssets.reduce((acc, asset) => {
|
||||
acc[asset.package_name] = {
|
||||
title: asset.title,
|
||||
description: asset.description,
|
||||
author: asset.author,
|
||||
image: asset.image,
|
||||
tags: asset.tags,
|
||||
version: asset.version,
|
||||
background_image: asset.background_image,
|
||||
background_video: asset.background_video,
|
||||
payload: asset.payload,
|
||||
type: asset.type
|
||||
};
|
||||
return acc;
|
||||
}, {});
|
||||
return reply.send({ assets, pages: Math.ceil(totalItems / 20) });
|
||||
}
|
||||
catch (error) {
|
||||
return reply.status(500).send({ error: "An error occured" });
|
||||
}
|
||||
});
|
||||
app.get("/api/packages/:package", async (request, reply) => {
|
||||
try {
|
||||
const packageRow = await catalogAssets.findOne({
|
||||
where: { package_name: request.params.package }
|
||||
});
|
||||
if (!packageRow)
|
||||
return reply.status(404).send({ error: "Package not found!" });
|
||||
const details = {
|
||||
title: packageRow.get("title"),
|
||||
description: packageRow.get("description"),
|
||||
image: packageRow.get("image"),
|
||||
author: packageRow.get("author"),
|
||||
tags: packageRow.get("tags"),
|
||||
version: packageRow.get("version"),
|
||||
background_image: packageRow.get("background_image"),
|
||||
background_video: packageRow.get("background_video"),
|
||||
payload: packageRow.get("payload"),
|
||||
type: packageRow.get("type")
|
||||
};
|
||||
reply.send(details);
|
||||
}
|
||||
catch (error) {
|
||||
reply.status(500).send({ error: "An unexpected error occured" });
|
||||
}
|
||||
});
|
||||
async function verifyReq(request, upload, data) {
|
||||
if (request.headers.psk !== parsedDoc.marketplace.psk) {
|
||||
return { status: 403, error: new Error("PSK isn't correct!") };
|
||||
}
|
||||
else if (upload && !request.headers.packagename) {
|
||||
return { status: 500, error: new Error("No packagename defined!") };
|
||||
}
|
||||
else if (upload && !data) {
|
||||
return { status: 400, error: new Error("No file uploaded!") };
|
||||
}
|
||||
else {
|
||||
return { status: 200 };
|
||||
}
|
||||
}
|
||||
app.post("/api/upload-asset", async (request, reply) => {
|
||||
const data = await request.file();
|
||||
const verify = await verifyReq(request, true, data);
|
||||
if (verify.error !== undefined) {
|
||||
reply.status(verify.status).send({ status: verify.error.message });
|
||||
}
|
||||
else {
|
||||
try {
|
||||
await pipeline(data.file, createWriteStream(fileURLToPath(new URL(`../database_assets/${request.headers.packagename}/${data.filename}`, import.meta.url))));
|
||||
}
|
||||
catch (error) {
|
||||
return reply.status(500).send({
|
||||
status: `File couldn't be uploaded! (Package most likely doesn't exist)`
|
||||
});
|
||||
}
|
||||
return reply.status(verify.status).send({ status: "File uploaded successfully!" });
|
||||
}
|
||||
});
|
||||
app.post("/api/create-package", async (request, reply) => {
|
||||
const verify = await verifyReq(request, false, undefined);
|
||||
if (verify.error !== undefined) {
|
||||
reply.status(verify.status).send({ status: verify.error.message });
|
||||
}
|
||||
else {
|
||||
const body = {
|
||||
package_name: request.body.uuid,
|
||||
title: request.body.title,
|
||||
image: request.body.image,
|
||||
author: request.body.author,
|
||||
version: request.body.version,
|
||||
description: request.body.description,
|
||||
tags: request.body.tags,
|
||||
payload: request.body.payload,
|
||||
background_video: request.body.background_video,
|
||||
background_image: request.body.background_image,
|
||||
type: request.body.type
|
||||
};
|
||||
await catalogAssets.create({
|
||||
package_name: body.package_name,
|
||||
title: body.title,
|
||||
image: body.image,
|
||||
author: body.author,
|
||||
version: body.version,
|
||||
description: body.description,
|
||||
tags: body.tags,
|
||||
payload: body.payload,
|
||||
background_video: body.background_video,
|
||||
background_image: body.background_image,
|
||||
type: body.type
|
||||
});
|
||||
const assets = fileURLToPath(new URL("../database_assets", import.meta.url));
|
||||
try {
|
||||
await access(`${assets}/${body.package_name}/`, constants.F_OK);
|
||||
return reply.status(500).send({ status: "Package already exists!" });
|
||||
}
|
||||
catch (err) {
|
||||
await mkdir(`${assets}/${body.package_name}/`);
|
||||
return reply
|
||||
.status(verify.status)
|
||||
.send({ status: "Package created successfully!" });
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
export { marketplaceAPI, db, catalogAssets };
|
Loading…
Add table
Add a link
Reference in a new issue