configure.js 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /**
  2. * @typedef {import('./types.js').Options} Options
  3. * @typedef {import('./types.js').State} State
  4. */
  5. const own = {}.hasOwnProperty
  6. /**
  7. * @param {State} base
  8. * @param {Options} extension
  9. * @returns {State}
  10. */
  11. export function configure(base, extension) {
  12. let index = -1
  13. /** @type {keyof Options} */
  14. let key
  15. // First do subextensions.
  16. if (extension.extensions) {
  17. while (++index < extension.extensions.length) {
  18. configure(base, extension.extensions[index])
  19. }
  20. }
  21. for (key in extension) {
  22. if (own.call(extension, key)) {
  23. switch (key) {
  24. case 'extensions': {
  25. // Empty.
  26. break
  27. }
  28. /* c8 ignore next 4 */
  29. case 'unsafe': {
  30. list(base[key], extension[key])
  31. break
  32. }
  33. case 'join': {
  34. list(base[key], extension[key])
  35. break
  36. }
  37. case 'handlers': {
  38. map(base[key], extension[key])
  39. break
  40. }
  41. default: {
  42. // @ts-expect-error: matches.
  43. base.options[key] = extension[key]
  44. }
  45. }
  46. }
  47. }
  48. return base
  49. }
  50. /**
  51. * @template T
  52. * @param {Array<T>} left
  53. * @param {Array<T> | null | undefined} right
  54. */
  55. function list(left, right) {
  56. if (right) {
  57. left.push(...right)
  58. }
  59. }
  60. /**
  61. * @template T
  62. * @param {Record<string, T>} left
  63. * @param {Record<string, T> | null | undefined} right
  64. */
  65. function map(left, right) {
  66. if (right) {
  67. Object.assign(left, right)
  68. }
  69. }