UNPKG

@zenfs/core

Version:

A filesystem, anywhere

49 lines (48 loc) 2.36 kB
import { ErrnoError, Errno } from '../error.js'; import { levenshtein } from '../utils.js'; /** @internal */ export function isBackend(arg) { return arg != null && typeof arg == 'object' && 'isAvailable' in arg && typeof arg.isAvailable == 'function' && 'create' in arg && typeof arg.create == 'function'; } /** * Checks that `options` object is valid for the file system options. * @internal */ export async function checkOptions(backend, options) { if (typeof options != 'object' || options === null) { throw new ErrnoError(Errno.EINVAL, 'Invalid options'); } // Check for required options. for (const [optName, opt] of Object.entries(backend.options)) { const providedValue = options?.[optName]; if (providedValue === undefined || providedValue === null) { if (!opt.required) { continue; } /* Required option not provided. if any incorrect options provided, which ones are close to the provided one? (edit distance 5 === close)*/ const incorrectOptions = Object.keys(options) .filter(o => !(o in backend.options)) .map((a) => { return { str: a, distance: levenshtein(optName, a) }; }) .filter(o => o.distance < 5) .sort((a, b) => a.distance - b.distance); throw new ErrnoError(Errno.EINVAL, `${backend.name}: Required option '${optName}' not provided.${incorrectOptions.length > 0 ? ` You provided '${incorrectOptions[0].str}', did you mean '${optName}'.` : ''}`); } // Option provided, check type. const typeMatches = Array.isArray(opt.type) ? opt.type.indexOf(typeof providedValue) != -1 : typeof providedValue == opt.type; if (!typeMatches) { throw new ErrnoError(Errno.EINVAL, `${backend.name}: Value provided for option ${optName} is not the proper type. Expected ${Array.isArray(opt.type) ? `one of {${opt.type.join(', ')}}` : opt.type}, but received ${typeof providedValue}`); } if (opt.validator) { await opt.validator(providedValue); } // Otherwise: All good! } } /** @internal */ export function isBackendConfig(arg) { return arg != null && typeof arg == 'object' && 'backend' in arg && isBackend(arg.backend); }