@roots/bud-api
Version:
bud.js core module
85 lines (84 loc) • 2.88 kB
JavaScript
import { portOrPortsToNumbers, requestPorts, } from '@roots/bud-support/get-port';
import isArray from '@roots/bud-support/isArray';
import isEqual from '@roots/bud-support/isEqual';
import isNumber from '@roots/bud-support/isNumber';
import isString from '@roots/bud-support/isString';
import isUndefined from '@roots/bud-support/isUndefined';
/**
* bud.serve
*/
export const serve = async function (input, options) {
const bud = this.root;
if (!bud.isDevelopment)
return bud;
if (!bud?.server)
return bud;
let normalizedUrl = input instanceof URL ? input : bud.server.url;
let normalizedOptions = options ?? bud.hooks.filter(`dev.options`, {});
/**
* If input is a string, convert it to a {@link URL}
*/
if (isString(input))
normalizedUrl = new URL(input);
/**
* If input is a number or array of numbers,
* try to resolve the requested port(s) and
* assign to the {@link URL}
*/
if (isArray(input) || isNumber(input)) {
normalizedUrl.port = await requestPorts(portOrPortsToNumbers(bud.context.port ?? input));
}
/**
* If input is an object, convert it to a {@link URL}
* and {@link ServerOptions}
*/
if (!(input instanceof URL) &&
!isArray(input) &&
typeof input === `object`) {
normalizedUrl = await makeURLFromObject(bud, input, normalizedUrl);
normalizedOptions = await makeHttpOptions(bud, input, normalizedOptions);
}
bud.hooks.on(`dev.url`, normalizedUrl);
bud.hooks.on(`dev.options`, normalizedOptions);
return bud;
};
/**
* Process specification object
*/
const makeURLFromObject = async function (bud, options, url) {
if (options.url) {
return options.url instanceof URL ? options.url : new URL(options.url);
}
if (options.host)
url.hostname = options.host;
if (options.port)
url.port = await requestPorts(portOrPortsToNumbers(options.port));
if (url.protocol !== `https:` &&
[
!isUndefined(options.ssl),
!isUndefined(options.cert),
!isUndefined(options.key),
!isUndefined(options?.options?.cert),
!isUndefined(options?.options?.key),
isEqual(url.port, 443),
].some(Boolean))
url.protocol = `https:`;
return url;
};
/**
* Make ServerOptions from object
*
* @param bud - {@link Bud}
* @param input - {@link Options}
* @param resolvedOptions - {@link Options}
* @returns promise - {@link ServerOptions}
*/
const makeHttpOptions = async function (bud, input, resolvedOptions = {}) {
if (input.options)
resolvedOptions = input.options;
if (input.cert)
resolvedOptions.cert = await bud.fs.read(input.cert);
if (input.key)
resolvedOptions.key = await bud.fs.read(input.key);
return resolvedOptions;
};