cleanup utils.js

Co-Authored-By: Andrew Calcutt <acalcutt@techidiots.net>
This commit is contained in:
acalcutt 2024-12-29 17:05:01 -05:00
parent c72d6f580c
commit 70d6986a9e

View file

@ -9,9 +9,10 @@ import { existsP } from './promises.js';
/** /**
* Restrict user input to an allowed set of options. * Restrict user input to an allowed set of options.
* @param opts * @param {string[]} opts - An array of allowed option strings.
* @param root0 * @param {object} [config] - Optional configuration object.
* @param root0.defaultValue * @param {string} [config.defaultValue] - The default value to return if input doesn't match.
* @returns {function(string): string} - A function that takes a value and returns it if valid or a default.
*/ */
export function allowedOptions(opts, { defaultValue } = {}) { export function allowedOptions(opts, { defaultValue } = {}) {
const values = Object.fromEntries(opts.map((key) => [key, key])); const values = Object.fromEntries(opts.map((key) => [key, key]));
@ -19,10 +20,11 @@ export function allowedOptions(opts, { defaultValue } = {}) {
} }
/** /**
* Replace local:// urls with public http(s):// urls * Replaces local:// URLs with public http(s):// URLs.
* @param req * @param {object} req - Express request object.
* @param url * @param {string} url - The URL string to fix.
* @param publicUrl * @param {string} publicUrl - The public URL prefix to use for replacements.
* @returns {string} - The fixed URL string.
*/ */
export function fixUrl(req, url, publicUrl) { export function fixUrl(req, url, publicUrl) {
if (!url || typeof url !== 'string' || url.indexOf('local://') !== 0) { if (!url || typeof url !== 'string' || url.indexOf('local://') !== 0) {
@ -40,12 +42,11 @@ export function fixUrl(req, url, publicUrl) {
} }
/** /**
* Generate new URL object * Generates a new URL object from the Express request.
* @param req * @param {object} req - Express request object.
* @params {object} req - Express request * @returns {URL} - URL object with correct host and optionally path.
* @returns {URL} object
*/ */
const getUrlObject = (req) => { function getUrlObject(req) {
const urlObject = new URL(`${req.protocol}://${req.headers.host}/`); const urlObject = new URL(`${req.protocol}://${req.headers.host}/`);
// support overriding hostname by sending X-Forwarded-Host http header // support overriding hostname by sending X-Forwarded-Host http header
urlObject.hostname = req.hostname; urlObject.hostname = req.hostname;
@ -56,16 +57,33 @@ const getUrlObject = (req) => {
urlObject.pathname = path.posix.join(xForwardedPath, urlObject.pathname); urlObject.pathname = path.posix.join(xForwardedPath, urlObject.pathname);
} }
return urlObject; return urlObject;
}; }
export const getPublicUrl = (publicUrl, req) => { /**
* Gets the public URL, either from a provided publicUrl or generated from the request.
* @param {string} publicUrl - The optional public URL to use.
* @param {object} req - The Express request object.
* @returns {string} - The final public URL string.
*/
export function getPublicUrl(publicUrl, req) {
if (publicUrl) { if (publicUrl) {
return publicUrl; return publicUrl;
} }
return getUrlObject(req).toString(); return getUrlObject(req).toString();
}; }
export const getTileUrls = ( /**
* Generates an array of tile URLs based on given parameters.
* @param {object} req - Express request object.
* @param {string | string[]} domains - Domain(s) to use for tile URLs.
* @param {string} path - The base path for the tiles.
* @param {number} [tileSize] - The size of the tile (optional).
* @param {string} format - The format of the tiles (e.g., 'png', 'jpg').
* @param {string} publicUrl - The public URL to use (if not using domains).
* @param {object} [aliases] - Aliases for format extensions.
* @returns {string[]} An array of tile URL strings.
*/
export function getTileUrls(
req, req,
domains, domains,
path, path,
@ -73,7 +91,7 @@ export const getTileUrls = (
format, format,
publicUrl, publicUrl,
aliases, aliases,
) => { ) {
const urlObject = getUrlObject(req); const urlObject = getUrlObject(req);
if (domains) { if (domains) {
if (domains.constructor === String && domains.length > 0) { if (domains.constructor === String && domains.length > 0) {
@ -132,9 +150,14 @@ export const getTileUrls = (
} }
return uris; return uris;
}; }
export const fixTileJSONCenter = (tileJSON) => { /**
* Fixes the center in the tileJSON if no center is available.
* @param {object} tileJSON - The tileJSON object to process.
* @returns {void}
*/
export function fixTileJSONCenter(tileJSON) {
if (tileJSON.bounds && !tileJSON.center) { if (tileJSON.bounds && !tileJSON.center) {
const fitWidth = 1024; const fitWidth = 1024;
const tiles = fitWidth / 256; const tiles = fitWidth / 256;
@ -147,10 +170,19 @@ export const fixTileJSONCenter = (tileJSON) => {
), ),
]; ];
} }
}; }
const getFontPbf = (allowedFonts, fontPath, name, range, fallbacks) => /**
new Promise((resolve, reject) => { * Retrieves font data for a given font and range.
* @param {object} allowedFonts - An object of allowed fonts.
* @param {string} fontPath - The path to the font directory.
* @param {string} name - The name of the font.
* @param {string} range - The range (e.g., '0-255') of the font to load.
* @param {object} [fallbacks] - Optional fallback font list.
* @returns {Promise<Buffer>} A promise that resolves with the font data Buffer or rejects with an error.
*/
function getFontPbf(allowedFonts, fontPath, name, range, fallbacks) {
return new Promise((resolve, reject) => {
if (!allowedFonts || (allowedFonts[name] && fallbacks)) { if (!allowedFonts || (allowedFonts[name] && fallbacks)) {
const filename = path.join(fontPath, name, `${range}.pbf`); const filename = path.join(fontPath, name, `${range}.pbf`);
if (!fallbacks) { if (!fallbacks) {
@ -192,14 +224,24 @@ const getFontPbf = (allowedFonts, fontPath, name, range, fallbacks) =>
reject(`Font not allowed: ${name}`); reject(`Font not allowed: ${name}`);
} }
}); });
}
export const getFontsPbf = async ( /**
* Combines multiple font pbf buffers into one.
* @param {object} allowedFonts - An object of allowed fonts.
* @param {string} fontPath - The path to the font directory.
* @param {string} names - Comma-separated font names.
* @param {string} range - The range of the font (e.g., '0-255').
* @param {object} [fallbacks] - Fallback font list.
* @returns {Promise<Buffer>} - A promise that resolves to the combined font data buffer.
*/
export async function getFontsPbf(
allowedFonts, allowedFonts,
fontPath, fontPath,
names, names,
range, range,
fallbacks, fallbacks,
) => { ) {
const fonts = names.split(','); const fonts = names.split(',');
const queue = []; const queue = [];
for (const font of fonts) { for (const font of fonts) {
@ -216,9 +258,14 @@ export const getFontsPbf = async (
const combined = combine(await Promise.all(queue), names); const combined = combine(await Promise.all(queue), names);
return Buffer.from(combined.buffer, 0, combined.buffer.length); return Buffer.from(combined.buffer, 0, combined.buffer.length);
}; }
export const listFonts = async (fontPath) => { /**
* Lists available fonts in a given font directory.
* @param {string} fontPath - The path to the font directory.
* @returns {Promise<object>} - Promise that resolves with an object where keys are the font names.
*/
export async function listFonts(fontPath) {
const existingFonts = {}; const existingFonts = {};
const files = await fsPromises.readdir(fontPath); const files = await fsPromises.readdir(fontPath);
@ -233,9 +280,14 @@ export const listFonts = async (fontPath) => {
} }
return existingFonts; return existingFonts;
}; }
export const isValidHttpUrl = (string) => { /**
* Checks if a string is a valid HTTP or HTTPS URL.
* @param {string} string - The string to validate.
* @returns {boolean} True if the string is a valid HTTP/HTTPS URL, false otherwise.
*/
export function isValidHttpUrl(string) {
let url; let url;
try { try {
@ -245,4 +297,4 @@ export const isValidHttpUrl = (string) => {
} }
return url.protocol === 'http:' || url.protocol === 'https:'; return url.protocol === 'http:' || url.protocol === 'https:';
}; }