dwnpm
Version:
Decentralized Registry Package Manager (DRPM) helps developers publish, install, find and manage Decentralized Packages (DPKs) published to Decentralized Web Nodes (DWNs). DRPM does this by looking up a Decentralized Identifier (DID) to find its DID docum
207 lines • 8.07 kB
JavaScript
import { createHash } from 'crypto';
import { createReadStream, createWriteStream } from 'fs';
import { ensureDir, exists } from 'fs-extra';
import { access, readFile, writeFile } from 'fs/promises';
import { join } from 'path';
import { pipeline } from 'stream/promises';
import { DRPM_REGISTRY_DIR, DRPM_VERSION_PREFIXES } from '../config.js';
import { Logger } from '../utils/logger.js';
export class RegistryUtils {
// Saves the tarball file to path $HOME/.drpm/registry/name/version/name-version.tgz
static async saveDpkTarball({ name, version, data }) {
const dpkAtVersionPath = this.getDpkVersionPath({ name, version });
try {
await this.ensureDpkDir(dpkAtVersionPath);
Logger.info(`Ensured dir at ${dpkAtVersionPath}`);
}
catch (error) {
Logger.error(`DRegistry: Failed to ensure dir at ${dpkAtVersionPath}`, error);
return false;
}
const dpkTarballPath = this.getDpkTarballPath({ name, version });
try {
Logger.log(`Saving tarball to ${dpkTarballPath} ...`);
await pipeline(data, createWriteStream(dpkTarballPath));
return dpkTarballPath;
}
catch (error) {
Logger.error(`DRegistry: Failed to save dpk tarball to ${dpkTarballPath} `, error);
return false;
}
}
// Saves the metadata file to path $HOME/.drpm/registry/name/version/metadata.json
static async saveDpkMetadata({ name, version, data }) {
const dpkAtVersionPath = this.getDpkVersionPath({ name, version });
try {
await this.ensureDpkDir(dpkAtVersionPath);
}
catch (error) {
Logger.error(`DRegistry: Failed to ensure dir at ${dpkAtVersionPath}`, error);
return false;
}
const dpkMetadataPath = this.getDpkMetadataPath({ name, version });
try {
await writeFile(dpkMetadataPath, JSON.stringify(data, null, 2));
Logger.info(`Saved metadata to ${dpkMetadataPath}`);
return true;
}
catch (error) {
Logger.error(`DRegistry: Failed to save dpk metadata to ${dpkMetadataPath} `, error);
return false;
}
}
// Ensure the path to the $HOME/.drpm/registry/{dpk, dpk/version} directory exists
static async ensureDpkDir(path) {
try {
await ensureDir(path);
Logger.info(`Ensured dir at ${path}`);
return true;
}
catch (error) {
Logger.error(`DRegistry: Failed to ensure dir at ${path}`, error);
throw error;
}
}
// Get the path to the $HOME/.drpm/registry/name directory
static getDpkPath({ name }) {
Logger.info(`Getting dpk dir path for ${name}`);
return join(DRPM_REGISTRY_DIR, name);
}
;
// Get the path to the $HOME/.drpm/registry/name directory
static getDpkLatestPath({ name }) {
Logger.info(`Getting dpk dir path for ${name}`);
return join(DRPM_REGISTRY_DIR, name, 'latest');
}
;
// Get the path to the $HOME/.drpm/registry/name/version directory
static getDpkVersionPath({ name, version }) {
Logger.info(`Getting dpkVersion dir path for ${name}@${version}`);
return join(DRPM_REGISTRY_DIR, name, version);
}
;
// Get the path to the $HOME/.drpm/registry/name/version/metadata.json file
// e.g. /Users/username/.drpm/registry/tool5/6.1.0/metadata.json
static getDpkMetadataPath({ name, version }) {
Logger.info(`Getting metadata path for ${name}@${version}`);
return join(DRPM_REGISTRY_DIR, name, version, 'metadata.json');
}
;
// Get the path to the $HOME/.drpm/registry/dpk/version/dpk-version.tgz file
// e.g. /Users/username/.drpm/registry/tool5/6.1.0/tool5-6.1.0.tgz
static getDpkTarballPath({ name, version }) {
Logger.info(`Getting tarball path for ${name}@${version}`);
return join(DRPM_REGISTRY_DIR, name, version, `${name}-${version}.tgz`);
}
;
static async saveMetadataToPath({ path, metadata }) {
try {
await writeFile(path, JSON.stringify(metadata, null, 2));
Logger.info(`Saved metadata to ${path}`);
return true;
}
catch (error) {
Logger.error(`DRegistry: Failed to save metadata to ${path} `, error);
return false;
}
}
static async saveTarballToPath({ path, tarball }) {
try {
await pipeline(tarball, createWriteStream(path));
Logger.info(`Saved tarball to ${path}`);
return true;
}
catch (error) {
Logger.error(`DRegistry: Failed to save tarball to ${path} `, error);
return false;
}
}
static async loadDpkMetadata(path) {
try {
if (!await exists(path)) {
Logger.info(`DRegistry: metadata.json does not exist at path ${path}`);
return null;
}
await access(path);
const metadata = JSON.parse(await readFile(path, 'utf8'));
return metadata;
}
catch (error) {
Logger.error(`DRegistry: metadata.json does not exist at path ${path}`, error);
throw error;
}
}
;
static async loadDpkTarball(path) {
try {
if (!await exists(path)) {
Logger.info(`DRegistry: tarball does not exist at path ${path}`);
return null;
}
await access(path);
return path;
}
catch (error) {
Logger.error(`DRegistry: tarball does not exist at path ${path}`, error);
throw error;
}
}
;
static createMetadata(metadata) {
const { name, version } = metadata;
metadata.dist = this.createDist(name, version);
return {
name,
'dist-tags': { latest: version },
versions: { [version]: { ...metadata } },
};
}
static createDist(name, version) {
return {
shasum: '',
tarball: `http://registry.drpm.software/@drpm/${name}/-/${name}-${version}.tgz`
};
}
static updateMetadata(existingMetadata, newMetadata) {
const { name, version } = newMetadata;
newMetadata.dist = !newMetadata.dist.tarball
? this.createDist(name, version)
: newMetadata.dist;
const tgzPath = join(DRPM_REGISTRY_DIR, name, `${name}-${version}.tgz`);
newMetadata.dist.shasum = this.calculateShasum1(tgzPath);
existingMetadata['dist-tags'].latest = version;
existingMetadata.versions[version] = newMetadata;
return existingMetadata;
}
static calculateShasum1(path) {
const hash = createHash('sha1');
const stream = createReadStream(path);
return new Promise((resolve, reject) => {
stream.on('data', chunk => hash.update(chunk));
stream.on('end', () => {
const shasum = hash.digest('hex');
resolve(shasum);
});
stream.on('error', (error) => reject(error));
});
}
static isPrefixed(semver) {
return DRPM_VERSION_PREFIXES.some((prefix) => semver.startsWith(prefix));
}
static findPrefix(prefixed) {
const prefix = DRPM_VERSION_PREFIXES.find((prefix) => prefixed.startsWith(prefix));
return !prefix
? { version: prefixed, prefix: '' }
: { version: prefixed.slice(prefix.length), prefix };
}
static checkReqParams(params) {
return Object.entries(params).filter(([k, v]) => !v && k);
}
static routeFailure({ code, status, error }) {
return { ok: false, code: code ?? 404, status: status ?? 'Not Found', error };
}
static routeSuccess({ code, status, data }) {
return { ok: true, code: code ?? 200, status: status ?? 'OK', data };
}
}
//# sourceMappingURL=utils.js.map