@open-wc/dev-server-hmr
Version:
Plugin for HMR with web components
96 lines (84 loc) • 2.6 kB
JavaScript
/* eslint-disable no-param-reassign */
const picoMatch = require('picomatch');
const { isAbsolute, posix, sep } = require('path');
/** @typedef {(path: string) => boolean} Matcher */
/** @typedef {import('./hmrPlugin').WcHmrPluginConfig} WcHmrPluginConfig */
/**
* @param {string} msg
*/
function createErrorMessage(msg) {
return `[@open-wc/dev-server-hmr] ${msg}`;
}
/**
* @param {string} msg
*/
function createError(msg) {
return new Error(createErrorMessage(msg));
}
/**
* @param {WcHmrPluginConfig} config
* @param {keyof WcHmrPluginConfig} prop
*/
function assertOptionalArray(config, prop) {
if (config[prop] != null && !Array.isArray(config[prop])) {
throw createError(`Option ${prop} must be an array`);
}
}
/**
* @param {WcHmrPluginConfig} config
*/
function parseConfig(config) {
if (!Array.isArray(config.include) && !Array.isArray(config.exclude)) {
throw createError('Must provide either an "include" or "exclude" pattern in config.');
}
assertOptionalArray(config, 'include');
assertOptionalArray(config, 'exclude');
assertOptionalArray(config, 'patches');
assertOptionalArray(config, 'baseClasses');
assertOptionalArray(config, 'decorators');
assertOptionalArray(config, 'functions');
assertOptionalArray(config, 'presets');
config.baseClasses = config.baseClasses || [];
config.baseClasses.push({ name: 'HTMLElement' });
if (config.presets) {
for (const preset of config.presets) {
if (preset.patch) {
config.patches = config.patches || [];
config.patches.push(preset.patch);
}
if (preset.baseClasses) {
config.baseClasses.push(...preset.baseClasses);
}
if (preset.decorators) {
config.decorators = config.decorators || [];
config.decorators.push(...preset.decorators);
}
}
}
return { ...config };
}
/**
* @param {string} rootDir
* @param {string} pattern
* @returns {Matcher}
*/
function createMatcher(rootDir, pattern) {
const matcherRootDir = rootDir.split(sep).join('/');
const resolvedPattern =
!isAbsolute(pattern) && !pattern.startsWith('*')
? posix.join(matcherRootDir, pattern)
: pattern;
return picoMatch(resolvedPattern);
}
/**
* @param {string} rootDir
* @param {string[]} patterns
* @returns {Matcher}
*/
function createMatchers(rootDir, patterns) {
const matchers = patterns.map(p => createMatcher(rootDir, p));
return function matcher(path) {
return matchers.some(m => m(path));
};
}
module.exports = { createMatcher, createMatchers, parseConfig, createErrorMessage, createError };