Skip to content

Commit

Permalink
Merge pull request #233 from pulsar-edit/refactor-constructions
Browse files Browse the repository at this point in the history
Refactor Package Constructs
  • Loading branch information
confused-Techie authored Jan 23, 2024
2 parents c99e22c + 21b8d89 commit c6d5770
Show file tree
Hide file tree
Showing 25 changed files with 401 additions and 202 deletions.
5 changes: 5 additions & 0 deletions src/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,9 @@ module.exports = {
ssoPaginate: require("./models/ssoPaginate.js"),
ssoRedirect: require("./models/ssoRedirect.js"),
ssoHTML: require("./models/ssoHTML.js"),
models: {
constructPackageObjectFull: require("./models/constructPackageObjectFull.js"),
constructPackageObjectShort: require("./models/constructPackageObjectShort.js"),
constructPackageObjectJSON: require("./models/constructPackageObjectJSON.js"),
}
};
2 changes: 1 addition & 1 deletion src/controllers/getOwnersOwnerName.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ module.exports = {
.addCalls("db.getSortedPackages", packages);
}

const packObjShort = await context.utils.constructPackageObjectShort(
const packObjShort = await context.models.constructPackageObjectShort(
packages.content
);

Expand Down
2 changes: 1 addition & 1 deletion src/controllers/getPackages.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ module.exports = {
.addCalls("db.getSortedPackages", packages);
}

const packObjShort = await context.utils.constructPackageObjectShort(
const packObjShort = await context.models.constructPackageObjectShort(
packages.content
);

Expand Down
2 changes: 1 addition & 1 deletion src/controllers/getPackagesFeatured.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ module.exports = {
.addCalls("db.getFeaturedPackages", packs);
}

const packObjShort = await context.utils.constructPackageObjectShort(
const packObjShort = await context.models.constructPackageObjectShort(
packs.content
);

Expand Down
2 changes: 1 addition & 1 deletion src/controllers/getPackagesPackageName.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ module.exports = {
return sso.notOk().addContent(pack).addCalls("db.getPackageByName", pack);
}

pack = await context.utils.constructPackageObjectFull(pack.content);
pack = await context.models.constructPackageObjectFull(pack.content);

if (params.engine !== false) {
// query.engine returns false if no valid query param is found.
Expand Down
10 changes: 9 additions & 1 deletion src/controllers/getPackagesPackageNameVersionsVersionName.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
module.exports = {
docs: {
summary: "Get the details of a specific package version.",
responses: {
200: {
description: "The `package.json` among other details of the package.",
content: {
"application/json": "$packageObjectJSON"
}
}
}
},
endpoint: {
method: "GET",
Expand Down Expand Up @@ -64,7 +72,7 @@ module.exports = {
.addCalls("db.getPackageVersionByNameAndVersion", pack);
}

const packRes = await context.utils.constructPackageObjectJSON(
const packRes = await context.models.constructPackageObjectJSON(
pack.content
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ module.exports = {
docs: {
summary:
"Previously undocumented endpoint. Allows for installation of a package.",
responses: [
{
302: {
description: "Redirect to the GitHub tarball URL.",
},
},
],
responses: {
302: {
description: "Redirect to the GitHub tarball URL."
}
}
},
endpoint: {
method: "GET",
Expand Down
2 changes: 1 addition & 1 deletion src/controllers/getPackagesSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ module.exports = {
.addCalls("db.getSortedPackages", packs);
}

const newPacks = await context.utils.constructPackageObjectShort(
const newPacks = await context.models.constructPackageObjectShort(
packs.content
);

Expand Down
2 changes: 1 addition & 1 deletion src/controllers/getStars.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ module.exports = {
.addCalls("db.getPackageCollectionByID", packCol);
}

let newCol = await context.utils.constructPackageObjectShort(
let newCol = await context.models.constructPackageObjectShort(
packCol.content
);

Expand Down
2 changes: 1 addition & 1 deletion src/controllers/getThemes.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ module.exports = {
.addCalls("db.getSortedPackages", packages);
}

const packObjShort = await context.utils.constructPackageObjectShort(
const packObjShort = await context.models.constructPackageObjectShort(
packages.content
);

Expand Down
2 changes: 1 addition & 1 deletion src/controllers/getThemesFeatured.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ module.exports = {
return sso.notOk().addContent(col).addCalls("db.getFeaturedThemes", col);
}

const newCol = await context.utils.constructPackageObjectShort(col.content);
const newCol = await context.models.constructPackageObjectShort(col.content);

const sso = new context.sso();

Expand Down
2 changes: 1 addition & 1 deletion src/controllers/getThemesSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ module.exports = {
.addCalls("db.getSortedPackages", packs);
}

const newPacks = await context.utils.constructPackageObjectShort(
const newPacks = await context.models.constructPackageObjectShort(
packs.content
);

Expand Down
2 changes: 1 addition & 1 deletion src/controllers/postPackages.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ module.exports = {
.addCalls("db.getPackageByName", newDbPack);
}

const packageObjectFull = await context.utils.constructPackageObjectFull(
const packageObjectFull = await context.models.constructPackageObjectFull(
newDbPack.content
);

Expand Down
2 changes: 1 addition & 1 deletion src/controllers/postPackagesPackageNameStar.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ module.exports = {
.addCalls("db.getPackageByName", pack);
}

pack = await context.utils.constructPackageObjectFull(pack.content);
pack = await context.models.constructPackageObjectFull(pack.content);

const sso = new context.sso();

Expand Down
63 changes: 63 additions & 0 deletions src/models/constructPackageObjectFull.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* @async
* @function constructPackageObjectFull
* @desc Takes the raw return of a full row from database.getPackageByName() and
* constructs a standardized package object full from it.
* This should be called only on the data provided by database.getPackageByName(),
* otherwise the behavior is unexpected.
* @param {object} pack - The anticipated raw SQL return that contains all data
* to construct a Package Object Full.
* @returns {object} A properly formatted and converted Package Object Full.
* @see {@link https://github.com/confused-Techie/atom-backend/blob/main/docs/returns.md#package-object-full}
* @see {@link https://github.com/confused-Techie/atom-backend/blob/main/docs/queries.md#retrieve-single-package--package-object-full}
*/
const logger = require("../logger.js");
const { server_url } = require("../config.js").getConfig();

module.exports =
async function constructPackageObjectFull(pack) {
const parseVersions = (vers) => {
let retVer = {};

for (const v of vers) {
retVer[v.semver] = v.meta;
retVer[v.semver].license = v.license;
retVer[v.semver].engines = v.engines;
retVer[v.semver].dist = {
tarball: `${server_url}/api/packages/${pack.name}/versions/${v.semver}/tarball`,
};
}

return retVer;
};

// We need to copy the metadata of the latest version in order to avoid an
// auto-reference in the versions array that leads to a freeze in JSON stringify stage.
//let newPack = structuredClone(pack?.versions[0]?.meta ?? {});
let newPack = pack.data;
newPack.name = pack.name;
newPack.downloads = pack.downloads;
newPack.owner = pack.owner;
newPack.stargazers_count = pack.stargazers_count;
newPack.versions = parseVersions(pack.versions);
// database.getPackageByName() sorts the JSON array versions in descending order,
// so no need to find the latest semver, it's the first one (index 0).
newPack.releases = { latest: pack?.versions[0]?.semver ?? "" };

if (!Array.isArray(newPack.badges)) {
// A package that has yet to receive any permenant badges
newPack.badges = [];
}

// Apply any custom deliver time badges
if (pack.creation_method === "User Made Package") {
newPack.badges.push({
title: "Made for Pulsar!",
type: "success",
});
}

logger.generic(6, "Built Package Object Full without Error");

return newPack;
}
46 changes: 46 additions & 0 deletions src/models/constructPackageObjectJSON.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* @async
* @function constructPackageObjectJSON
* @desc Takes the return of getPackageVersionByNameAndVersion and returns
* a recreation of the package.json with a modified dist.tarball key, pointing
* to this server for download.
* @param {object} pack - The expected raw SQL return of `getPackageVersionByNameAndVersion`
* @returns {object} A properly formatted Package Object Mini.
* @see {@link https://github.com/confused-Techie/atom-backend/blob/main/docs/returns.md#package-object-mini}
*/

const logger = require("../logger.js");
const { server_url } = require("../config.js").getConfig();

module.exports =
async function constructPackageObjectJSON(pack) {
const parseVersionObject = (v) => {
let newPack = v.meta;
if (newPack.sha) {
delete newPack.sha;
}
if (newPack.tarball_url) {
delete newPack.tarball_url;
}
newPack.dist ??= {};
newPack.dist.tarball = `${server_url}/api/packages/${v.meta.name}/versions/${v.semver}/tarball`;
newPack.engines = v.engines;
logger.generic(6, "Single Package Object JSON finished without Error");
return newPack;
};

if (!Array.isArray(pack)) {
const newPack = parseVersionObject(pack);

logger.generic(6, "Single Package Object JSON finished without Error");
return newPack;
}

let arrPack = [];
for (const p of pack) {
arrPack.push(parseVersionObject(p));
}

logger.generic(66, "Array Package Object JSON finished without Error");
return arrPack;
}
80 changes: 80 additions & 0 deletions src/models/constructPackageObjectShort.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* @async
* @function constructPackageObjectShort
* @desc Takes a single or array of rows from the db, and returns a JSON
* construction of package object shorts
* @param {object} pack - The anticipated raw SQL return that contains all data
* to construct a Package Object Short.
* @returns {object|array} A properly formatted and converted Package Object Short.
* @see {@link https://github.com/confused-Techie/atom-backend/blob/main/docs/returns.md#package-object-short}
* @see {@link https://github.com/confused-Techie/atom-backend/blob/main/docs/queries.md#retrieve-many-sorted-packages--package-object-short}
*/

const logger = require("../logger.js");

module.exports =
async function constructPackageObjectShort(pack) {
const parsePackageObject = (p) => {
let newPack = p.data;
newPack.downloads = p.downloads;
newPack.stargazers_count = p.stargazers_count;
newPack.releases = {
latest: p.semver,
};

if (!Array.isArray(newPack.badges)) {
// A package that has yet to receive any permenant badges
newPack.badges = [];
}

// Apply any custom deliver time badges
if (p.creation_method === "User Made Package") {
newPack.badges.push({ title: "Made for Pulsar!", type: "success" });
}

// Remove keys that aren't intended to exist in a Package Object Short
delete newPack.versions;

newPack.owner = p.owner;
return newPack;
};

if (Array.isArray(pack)) {
if (pack.length === 0) {
// Sometimes it seems an empty array will be passed here, in that case we will protect against
// manipulation of `undefined` objects
logger.generic(
5,
"Package Object Short Constructor Protected against 0 Length Array"
);

return pack;
}

let retPacks = [];
for (const p of pack) {
retPacks.push(parsePackageObject(p));
}

logger.generic(6, "Array Package Object Short Constructor without Error");
return retPacks;
}

// Not an array
if (
pack.data === undefined ||
pack.downloads === undefined ||
pack.stargazers_count === undefined ||
pack.semver === undefined
) {
logger.generic(
5,
"Package Object Short Constructor Protected against Undefined Required Values"
);

return {};
}

logger.generic(6, "Single Package Object Short Constructor without Error");
return parsePackageObject(pack);
}
Loading

0 comments on commit c6d5770

Please sign in to comment.