Skip to content

Commit

Permalink
winget-source: documentation in JSDoc
Browse files Browse the repository at this point in the history
  • Loading branch information
stevapple committed Mar 7, 2023
1 parent ea34971 commit aec8bda
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 29 deletions.
4 changes: 2 additions & 2 deletions winget-source/sync-repo.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import { rm } from 'fs/promises'
import {
buildPathpartMap,
buildURIList,
checkEnvironmentVariables,
extractDatabaseFromBundle,
getLocalPath,
makeTempDirectory,
requireEnvironmentVariables,
syncFile
} from './utilities.js'

const { parallelLimit } = checkEnvironmentVariables();
const { parallelLimit } = requireEnvironmentVariables();

syncFile('source.msix').then(async _ => {
const temp = await makeTempDirectory('winget-repo-');
Expand Down
84 changes: 57 additions & 27 deletions winget-source/utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,21 @@ import process from 'process'
import { existsSync } from 'fs'
import { mkdir, mkdtemp, readFile, stat, utimes, writeFile } from 'fs/promises'

/** The remote URL for a pre-indexed WinGet source repository. */
const remote = process.env.WINGET_REPO_URL;

/** The local path to serve as the root of WinGet source repository. */
const local = process.env.TO;

/** Maximum sync jobs to be executed in parallel. Defaults to 8. */
const parallelLimit = parseInt(process.env.WINGET_REPO_JOBS ?? 8);

/**
* @param {Response} response
* Get last modified date from HTTP response headers.
*
* @returns {Date | undefined}
* @param {Response} response The HTTP `fetch` response to parse.
*
* @returns {Date | undefined} Last modified date derived from the response, if exists.
*/
function getLastModifiedDate(response) {
const lastModified = response.headers.get('Last-Modified');
Expand All @@ -25,9 +32,11 @@ function getLastModifiedDate(response) {
}

/**
* @param {Response} response
* Get content length from HTTP response headers.
*
* @param {Response} response The HTTP `fetch` response to parse.
*
* @returns {number}
* @returns {number} Content length derived from the response, in bytes.
*/
function getContentLength(response) {
const length = response.headers.get('Content-Length');
Expand All @@ -39,10 +48,12 @@ function getContentLength(response) {
}

/**
* @param {number} id
* @param {Map<number, { parent: number, pathpart: string }>} pathparts
* Resolve path parts against the local storage.
*
* @returns {string}
* @param {number} id The ID of the target path part.
* @param {Map<number, { parent: number, pathpart: string }>} pathparts Path part storage built from the database.
*
* @returns {string} Full URI resolved from the given ID.
*/
function resolvePathpart(id, pathparts) {
const pathpart = pathparts.get(id);
Expand All @@ -51,10 +62,12 @@ function resolvePathpart(id, pathparts) {
}

/**
* @param {Error?} error
* @param {{ rowid: number, parent: number, pathpart: string }[]} rows
* Build a local storage for path parts from database query.
*
* @param {Error?} error Database error thrown from the query, if any.
* @param {{ rowid: number, parent: number, pathpart: string }[]} rows Rows returned by the query.
*
* @returns {Map<number, { parent: number, pathpart: string }>}
* @returns {Map<number, { parent: number, pathpart: string }>} In-memory path part storage to query against.
*/
export function buildPathpartMap(error, rows) {
if (error) {
Expand All @@ -67,11 +80,13 @@ export function buildPathpartMap(error, rows) {
}

/**
* @param {Error?} error
* @param {{ pathpart: string, [key: string]: string }[]} rows
* @param {Map<number, { parent: number, pathpart: string }>} pathparts
* Build a list of all manifest URIs from database query.
*
* @returns {string[]}
* @param {Error?} error Database error thrown from the query, if any.
* @param {{ pathpart: string, [key: string]: string }[]} rows Rows returned by the query.
* @param {Map<number, { parent: number, pathpart: string }>} pathparts Path part storage built from the database.
*
* @returns {string[]} Manifest URIs to sync.
*/
export function buildURIList(error, rows, pathparts) {
if (error) {
Expand All @@ -81,19 +96,26 @@ export function buildURIList(error, rows, pathparts) {
return rows.map(row => resolvePathpart(row.pathpart, pathparts));
}

export function checkEnvironmentVariables() {
/**
* Check and return the required environment variables.
*
* @returns Environment variables to be used in the program.
*/
export function requireEnvironmentVariables() {
if (!remote || !local || !parallelLimit) {
console.error("required envirenent variable(s) not set!");
console.error("required environment variable(s) not set!");
process.exit(-1);
}
return { remote, local, parallelLimit };
}

/**
* @param {fs.PathLike} msixPath
* @param {fs.PathLike} directory
* Extract database file from the source bundle.
*
* @returns {Promise<string>}
* @param {fs.PathLike} msixPath Path of the MSIX bundle file.
* @param {fs.PathLike} directory Path of directory to save the file.
*
* @returns {Promise<string>} Path of the extracted `index.db` file.
*/
export async function extractDatabaseFromBundle(msixPath, directory) {
const bundle = await readFile(msixPath);
Expand All @@ -105,18 +127,22 @@ export async function extractDatabaseFromBundle(msixPath, directory) {
}

/**
* @param {string} uri
* Get the local sync path of a manifest.
*
* @param {string} uri Manifest URI.
*
* @returns {string}
* @returns {string} Expected local path of the manifest file.
*/
export function getLocalPath(uri) {
return path.join(local, uri);
}

/**
* @param {string} uri
* Get the remote URL of a manifest.
*
* @returns {URL}
* @param {string} uri Manifest URI.
*
* @returns {URL} Remote URL to get the manifest from.
*/
export function getRemoteURL(uri) {
const remoteURL = new URL(remote);
Expand All @@ -125,18 +151,22 @@ export function getRemoteURL(uri) {
}

/**
* @param {string} prefix
* Create a unique temporary directory with given prefix.
*
* @param {string} prefix Temporary directory name prefix. Must not contain path separators.
*
* @returns {Promise<string>}
* @returns {Promise<string>} Path to the created temporary directory.
*/
export async function makeTempDirectory(prefix) {
return await mkdtemp(path.join(os.tmpdir(), prefix));
}

/**
* @param {string} uri
* Sync a file with the remote server asynchronously.
*
* @param {string} uri URI to sync.
*
* @returns {Promise<boolean>}
* @returns {Promise<boolean>} If the file is new or updated.
*/
export async function syncFile(uri) {
const localPath = getLocalPath(uri);
Expand Down

0 comments on commit aec8bda

Please sign in to comment.