UNPKG

@kitmi/utils

Version:

A JavaScript utility library for both server and browser

98 lines (97 loc) 3.69 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "default", { enumerable: true, get: function() { return _default; } }); const _types = require("@kitmi/types"); /** * Function arguments extractor. * @param {Array} args - Array of function arguments * @param {Array} types - Array of types, with suffix `?` as optional * @example * function withClient(...args) { * const [server, authenticator, testToRun, options] = fxargs(args, ['string?', 'string?', 'function', 'object?']); * // ... * } * * 1. withClient('http://localhost:3000', 'admin', (app) => {}); * - server: 'http://localhost:3000' * - authenticator: 'admin' * - testToRun: (app) => {} * - options: undefined * * 2. withClient('http://localhost:3000', (app) => {}); * - server: 'http://localhost:3000' * - authenticator: undefined * - testToRun: (app) => {} * - options: undefined * * 3. withClient((app) => {}); * - server: undefined * - authenticator: undefined * - testToRun: (app) => {} * - options: undefined */ function fxargs(args, types) { // eslint-disable-next-line no-new-array const result = new Array(types.length).fill(undefined); let argIndex = 0, lt = types.length, la = args.length; const optionalSpots = []; for(let i = 0; i < lt; i++){ const type = types[i]; const isOptional = type.endsWith('?'); const typeOptions = isOptional ? type.slice(0, -1).split('|') : type.split('|'); let matched = false; // Iterate over remaining args to find a match while(argIndex < la && !matched){ const value = args[argIndex]; if (typeOptions.some((typeOption)=>(0, _types.typeOf)(value) === typeOption)) { // Assign the value and increment the argument index result[i] = value; argIndex++; matched = true; if (isOptional) { optionalSpots.push(i); } else if (optionalSpots.length > 0 && typeOptions.every((typeOption)=>(0, _types.typeOf)(args[argIndex - 2]) !== typeOption)) { optionalSpots.length = 0; } } else if (isOptional) { break; } else { // Try pop up an optional value if (optionalSpots.length > 0 && lt - i >= la - argIndex + 1) { const optionalIndex = optionalSpots.pop(); for(let j = optionalIndex + 1; j < i; j++){ result[j] = result[j - 1]; } result[optionalIndex] = undefined; argIndex--; continue; } // No match found for a required type throw new Error(`Missing or invalid argument at index ${i}, expected "${type}".`); } } if (!matched && !isOptional) { // Try pop up an optional value 2, 2- if (optionalSpots.length > 0 && lt - i >= la - argIndex + 1) { const optionalIndex = optionalSpots.pop(); for(let j = optionalIndex + 1; j < i; j++){ result[j] = result[j - 1]; } result[optionalIndex] = undefined; argIndex--; i--; } else { throw new Error(`Missing argument at index ${i}, expected "${type}".`); } } } return result; } const _default = fxargs; //# sourceMappingURL=fxargs.js.map