pulsar-edit / package-backend

Pulsar Server Backend for Packages
https://api.pulsar-edit.dev
MIT License
12 stars 11 forks source link

PackageObject Builder Pattern #89

Closed confused-Techie closed 1 year ago

confused-Techie commented 1 year ago

Requirements

Description of the Change

This PR creates the PackageObject.js which is a Package Object Builder. This builder has not been implemented with the rest of the codebase. This PR is used as a general sanity check prior to utilizing this further within the codebase.

This builds off of changes made in #86 or at least borrows from the methodology used there.

The major thing this repo deals with are the objects of packages, that is their data structure, but without any unified way of creating, modifying or validating these objects the code to do so is scattered throughout the codebase. (Which has brought concerns from some contributors that the object may contradict itself in some locations. Additionally this leads to wasteful time spent checking values or portions that have already been checked.

Using a Object Builder Pattern we can alleviate nearly all of these concerns by never allowing the rest of the codebase to directly modify a package, or give it the need.

Using a package builder we can have a unified location to do anything we might need to on the package.

It's current implementation is in it's obvious infancy, missing many features or functions that would be needed to properly export it's data to the database functions that would be saving it. But as the general concept and initial implementation it's been based off the needs and requirements of the VCS system to create packages during their first publish.

Which with the above implementation in mind would take nearly 200 lines of code form ./src/vcs.js and turn it into the following (Error checking is excluded purposefully as well as handling of async tasks):

let pack = new PackageObject().setOwnerRepo(ownerRepo);

pack.addPackageJSON(provider.packageJSON());

let tags = await provider.tags();

for (const tag of tags) {
  pack.Versions.addSemver(tags[tag].name);
  pack.Versions.addTarball(tags[tag].name, tags[tag].tarball_url);
  pack.Versions.addSha(tags[tag].name, tags[tag].commit.sha);
}

pack.setReadme(provider.readme());

pack.setRepositoryURL(determineProvider().url);
pack.setRepositoryType(determineProvider().type);

const package_object_full = pack.buildFull();

With this huge simplification in mind the goal was to make this object builder as simplistic as possible. Where no single function needs to do all that much, instead relying on the use of many functions to create the resulting object. Which these can all be chained if needed such as

let pack = new PackageObject().setOwnerRepo(ownerRepo)
  .addPackageJSON(provider.packageJSON())
  .setReadme(provider.readme())
  .setRepositoryURL(determineProvider().url)
  .setRepositoryType(determineProvider().type)
  .buildFull();

// pack is now equal to a standardized Package Object Full

If no major issues are brought up to this PR then it can be merged and work done to introduce this new builder to the rest of the codebase, ideally replacing all instances of working with package objects everywhere. Adding the proper returns needed to provide data to database functions and anything else. So that we can get everything all in one place, and like mentioned in the comments if wanted could go so far as to begin verifying the data structure with Joi which we already use in our tests to verify object data structure as needed.