Browse Source

chore: adds CommonJS support

e22m4u 1 year ago
parent
commit
0236965871
4 changed files with 1541 additions and 1 deletions
  1. 1 0
      .husky/pre-commit
  2. 10 0
      build-cjs.js
  3. 1519 0
      dist/cjs/index.cjs
  4. 11 1
      package.json

+ 1 - 0
.husky/pre-commit

@@ -1,5 +1,6 @@
 npm run lint:fix
 npm run lint:fix
 npm run format
 npm run format
 npm run test
 npm run test
+npm run build:cjs
 
 
 git add -A
 git add -A

+ 10 - 0
build-cjs.js

@@ -0,0 +1,10 @@
+import * as esbuild from 'esbuild';
+
+await esbuild.build({
+  entryPoints: ['src/index.js'],
+  outfile: 'dist/cjs/index.cjs',
+  format: 'cjs',
+  platform: 'node',
+  target: ['node16'],
+  bundle: true,
+});

+ 1519 - 0
dist/cjs/index.cjs

@@ -0,0 +1,1519 @@
+var __create = Object.create;
+var __defProp = Object.defineProperty;
+var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
+var __getOwnPropNames = Object.getOwnPropertyNames;
+var __getProtoOf = Object.getPrototypeOf;
+var __hasOwnProp = Object.prototype.hasOwnProperty;
+var __commonJS = (cb, mod) => function __require() {
+  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
+};
+var __export = (target, all) => {
+  for (var name in all)
+    __defProp(target, name, { get: all[name], enumerable: true });
+};
+var __copyProps = (to, from, except, desc) => {
+  if (from && typeof from === "object" || typeof from === "function") {
+    for (let key of __getOwnPropNames(from))
+      if (!__hasOwnProp.call(to, key) && key !== except)
+        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
+  }
+  return to;
+};
+var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
+  // If the importer is in node compatibility mode or this is not an ESM
+  // file that has been converted to a CommonJS file using a Babel-
+  // compatible transform (i.e. "__esModule" has not been set), then set
+  // "default" to the CommonJS "module.exports" for node compatibility.
+  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
+  mod
+));
+var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
+
+// node_modules/path-to-regexp/dist/index.js
+var require_dist = __commonJS({
+  "node_modules/path-to-regexp/dist/index.js"(exports2) {
+    "use strict";
+    Object.defineProperty(exports2, "__esModule", { value: true });
+    exports2.TokenData = void 0;
+    exports2.parse = parse;
+    exports2.compile = compile;
+    exports2.match = match;
+    exports2.pathToRegexp = pathToRegexp2;
+    exports2.stringify = stringify;
+    var DEFAULT_DELIMITER = "/";
+    var NOOP_VALUE = (value) => value;
+    var ID_START = /^[$_\p{ID_Start}]$/u;
+    var ID_CONTINUE = /^[$\u200c\u200d\p{ID_Continue}]$/u;
+    var DEBUG_URL = "https://git.new/pathToRegexpError";
+    var SIMPLE_TOKENS = {
+      // Groups.
+      "{": "{",
+      "}": "}",
+      // Reserved.
+      "(": "(",
+      ")": ")",
+      "[": "[",
+      "]": "]",
+      "+": "+",
+      "?": "?",
+      "!": "!"
+    };
+    function escapeText(str) {
+      return str.replace(/[{}()\[\]+?!:*]/g, "\\$&");
+    }
+    function escape(str) {
+      return str.replace(/[.+*?^${}()[\]|/\\]/g, "\\$&");
+    }
+    function* lexer(str) {
+      const chars = [...str];
+      let i = 0;
+      function name() {
+        let value = "";
+        if (ID_START.test(chars[++i])) {
+          value += chars[i];
+          while (ID_CONTINUE.test(chars[++i])) {
+            value += chars[i];
+          }
+        } else if (chars[i] === '"') {
+          let pos = i;
+          while (i < chars.length) {
+            if (chars[++i] === '"') {
+              i++;
+              pos = 0;
+              break;
+            }
+            if (chars[i] === "\\") {
+              value += chars[++i];
+            } else {
+              value += chars[i];
+            }
+          }
+          if (pos) {
+            throw new TypeError(`Unterminated quote at ${pos}: ${DEBUG_URL}`);
+          }
+        }
+        if (!value) {
+          throw new TypeError(`Missing parameter name at ${i}: ${DEBUG_URL}`);
+        }
+        return value;
+      }
+      while (i < chars.length) {
+        const value = chars[i];
+        const type = SIMPLE_TOKENS[value];
+        if (type) {
+          yield { type, index: i++, value };
+        } else if (value === "\\") {
+          yield { type: "ESCAPED", index: i++, value: chars[i++] };
+        } else if (value === ":") {
+          const value2 = name();
+          yield { type: "PARAM", index: i, value: value2 };
+        } else if (value === "*") {
+          const value2 = name();
+          yield { type: "WILDCARD", index: i, value: value2 };
+        } else {
+          yield { type: "CHAR", index: i, value: chars[i++] };
+        }
+      }
+      return { type: "END", index: i, value: "" };
+    }
+    var Iter = class {
+      constructor(tokens) {
+        this.tokens = tokens;
+      }
+      peek() {
+        if (!this._peek) {
+          const next = this.tokens.next();
+          this._peek = next.value;
+        }
+        return this._peek;
+      }
+      tryConsume(type) {
+        const token = this.peek();
+        if (token.type !== type)
+          return;
+        this._peek = void 0;
+        return token.value;
+      }
+      consume(type) {
+        const value = this.tryConsume(type);
+        if (value !== void 0)
+          return value;
+        const { type: nextType, index } = this.peek();
+        throw new TypeError(`Unexpected ${nextType} at ${index}, expected ${type}: ${DEBUG_URL}`);
+      }
+      text() {
+        let result = "";
+        let value;
+        while (value = this.tryConsume("CHAR") || this.tryConsume("ESCAPED")) {
+          result += value;
+        }
+        return result;
+      }
+    };
+    var TokenData = class {
+      constructor(tokens) {
+        this.tokens = tokens;
+      }
+    };
+    exports2.TokenData = TokenData;
+    function parse(str, options = {}) {
+      const { encodePath = NOOP_VALUE } = options;
+      const it = new Iter(lexer(str));
+      function consume(endType) {
+        const tokens2 = [];
+        while (true) {
+          const path = it.text();
+          if (path)
+            tokens2.push({ type: "text", value: encodePath(path) });
+          const param = it.tryConsume("PARAM");
+          if (param) {
+            tokens2.push({
+              type: "param",
+              name: param
+            });
+            continue;
+          }
+          const wildcard = it.tryConsume("WILDCARD");
+          if (wildcard) {
+            tokens2.push({
+              type: "wildcard",
+              name: wildcard
+            });
+            continue;
+          }
+          const open = it.tryConsume("{");
+          if (open) {
+            tokens2.push({
+              type: "group",
+              tokens: consume("}")
+            });
+            continue;
+          }
+          it.consume(endType);
+          return tokens2;
+        }
+      }
+      const tokens = consume("END");
+      return new TokenData(tokens);
+    }
+    function compile(path, options = {}) {
+      const { encode = encodeURIComponent, delimiter = DEFAULT_DELIMITER } = options;
+      const data = path instanceof TokenData ? path : parse(path, options);
+      const fn = tokensToFunction(data.tokens, delimiter, encode);
+      return function path2(data2 = {}) {
+        const [path3, ...missing] = fn(data2);
+        if (missing.length) {
+          throw new TypeError(`Missing parameters: ${missing.join(", ")}`);
+        }
+        return path3;
+      };
+    }
+    function tokensToFunction(tokens, delimiter, encode) {
+      const encoders = tokens.map((token) => tokenToFunction(token, delimiter, encode));
+      return (data) => {
+        const result = [""];
+        for (const encoder of encoders) {
+          const [value, ...extras] = encoder(data);
+          result[0] += value;
+          result.push(...extras);
+        }
+        return result;
+      };
+    }
+    function tokenToFunction(token, delimiter, encode) {
+      if (token.type === "text")
+        return () => [token.value];
+      if (token.type === "group") {
+        const fn = tokensToFunction(token.tokens, delimiter, encode);
+        return (data) => {
+          const [value, ...missing] = fn(data);
+          if (!missing.length)
+            return [value];
+          return [""];
+        };
+      }
+      const encodeValue = encode || NOOP_VALUE;
+      if (token.type === "wildcard" && encode !== false) {
+        return (data) => {
+          const value = data[token.name];
+          if (value == null)
+            return ["", token.name];
+          if (!Array.isArray(value) || value.length === 0) {
+            throw new TypeError(`Expected "${token.name}" to be a non-empty array`);
+          }
+          return [
+            value.map((value2, index) => {
+              if (typeof value2 !== "string") {
+                throw new TypeError(`Expected "${token.name}/${index}" to be a string`);
+              }
+              return encodeValue(value2);
+            }).join(delimiter)
+          ];
+        };
+      }
+      return (data) => {
+        const value = data[token.name];
+        if (value == null)
+          return ["", token.name];
+        if (typeof value !== "string") {
+          throw new TypeError(`Expected "${token.name}" to be a string`);
+        }
+        return [encodeValue(value)];
+      };
+    }
+    function match(path, options = {}) {
+      const { decode = decodeURIComponent, delimiter = DEFAULT_DELIMITER } = options;
+      const { regexp, keys } = pathToRegexp2(path, options);
+      const decoders = keys.map((key) => {
+        if (decode === false)
+          return NOOP_VALUE;
+        if (key.type === "param")
+          return decode;
+        return (value) => value.split(delimiter).map(decode);
+      });
+      return function match2(input) {
+        const m = regexp.exec(input);
+        if (!m)
+          return false;
+        const path2 = m[0];
+        const params = /* @__PURE__ */ Object.create(null);
+        for (let i = 1; i < m.length; i++) {
+          if (m[i] === void 0)
+            continue;
+          const key = keys[i - 1];
+          const decoder = decoders[i - 1];
+          params[key.name] = decoder(m[i]);
+        }
+        return { path: path2, params };
+      };
+    }
+    function pathToRegexp2(path, options = {}) {
+      const { delimiter = DEFAULT_DELIMITER, end = true, sensitive = false, trailing = true } = options;
+      const keys = [];
+      const sources = [];
+      const flags = sensitive ? "" : "i";
+      const paths = Array.isArray(path) ? path : [path];
+      const items = paths.map((path2) => path2 instanceof TokenData ? path2 : parse(path2, options));
+      for (const { tokens } of items) {
+        for (const seq of flatten(tokens, 0, [])) {
+          const regexp2 = sequenceToRegExp(seq, delimiter, keys);
+          sources.push(regexp2);
+        }
+      }
+      let pattern = `^(?:${sources.join("|")})`;
+      if (trailing)
+        pattern += `(?:${escape(delimiter)}$)?`;
+      pattern += end ? "$" : `(?=${escape(delimiter)}|$)`;
+      const regexp = new RegExp(pattern, flags);
+      return { regexp, keys };
+    }
+    function* flatten(tokens, index, init) {
+      if (index === tokens.length) {
+        return yield init;
+      }
+      const token = tokens[index];
+      if (token.type === "group") {
+        const fork = init.slice();
+        for (const seq of flatten(token.tokens, 0, fork)) {
+          yield* flatten(tokens, index + 1, seq);
+        }
+      } else {
+        init.push(token);
+      }
+      yield* flatten(tokens, index + 1, init);
+    }
+    function sequenceToRegExp(tokens, delimiter, keys) {
+      let result = "";
+      let backtrack = "";
+      let isSafeSegmentParam = true;
+      for (let i = 0; i < tokens.length; i++) {
+        const token = tokens[i];
+        if (token.type === "text") {
+          result += escape(token.value);
+          backtrack += token.value;
+          isSafeSegmentParam || (isSafeSegmentParam = token.value.includes(delimiter));
+          continue;
+        }
+        if (token.type === "param" || token.type === "wildcard") {
+          if (!isSafeSegmentParam && !backtrack) {
+            throw new TypeError(`Missing text after "${token.name}": ${DEBUG_URL}`);
+          }
+          if (token.type === "param") {
+            result += `(${negate(delimiter, isSafeSegmentParam ? "" : backtrack)}+)`;
+          } else {
+            result += `([\\s\\S]+)`;
+          }
+          keys.push(token);
+          backtrack = "";
+          isSafeSegmentParam = false;
+          continue;
+        }
+      }
+      return result;
+    }
+    function negate(delimiter, backtrack) {
+      if (backtrack.length < 2) {
+        if (delimiter.length < 2)
+          return `[^${escape(delimiter + backtrack)}]`;
+        return `(?:(?!${escape(delimiter)})[^${escape(backtrack)}])`;
+      }
+      if (delimiter.length < 2) {
+        return `(?:(?!${escape(backtrack)})[^${escape(delimiter)}])`;
+      }
+      return `(?:(?!${escape(backtrack)}|${escape(delimiter)})[\\s\\S])`;
+    }
+    function stringify(data) {
+      return data.tokens.map(function stringifyToken(token, index, tokens) {
+        if (token.type === "text")
+          return escapeText(token.value);
+        if (token.type === "group") {
+          return `{${token.tokens.map(stringifyToken).join("")}}`;
+        }
+        const isSafe = isNameSafe(token.name) && isNextNameSafe(tokens[index + 1]);
+        const key = isSafe ? token.name : JSON.stringify(token.name);
+        if (token.type === "param")
+          return `:${key}`;
+        if (token.type === "wildcard")
+          return `*${key}`;
+        throw new TypeError(`Unexpected token: ${token}`);
+      }).join("");
+    }
+    function isNameSafe(name) {
+      const [first, ...rest] = name;
+      if (!ID_START.test(first))
+        return false;
+      return rest.every((char) => ID_CONTINUE.test(char));
+    }
+    function isNextNameSafe(token) {
+      if ((token === null || token === void 0 ? void 0 : token.type) !== "text")
+        return true;
+      return !ID_CONTINUE.test(token.value[0]);
+    }
+  }
+});
+
+// node_modules/ms/index.js
+var require_ms = __commonJS({
+  "node_modules/ms/index.js"(exports2, module2) {
+    var s = 1e3;
+    var m = s * 60;
+    var h = m * 60;
+    var d = h * 24;
+    var w = d * 7;
+    var y = d * 365.25;
+    module2.exports = function(val, options) {
+      options = options || {};
+      var type = typeof val;
+      if (type === "string" && val.length > 0) {
+        return parse(val);
+      } else if (type === "number" && isFinite(val)) {
+        return options.long ? fmtLong(val) : fmtShort(val);
+      }
+      throw new Error(
+        "val is not a non-empty string or a valid number. val=" + JSON.stringify(val)
+      );
+    };
+    function parse(str) {
+      str = String(str);
+      if (str.length > 100) {
+        return;
+      }
+      var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
+        str
+      );
+      if (!match) {
+        return;
+      }
+      var n = parseFloat(match[1]);
+      var type = (match[2] || "ms").toLowerCase();
+      switch (type) {
+        case "years":
+        case "year":
+        case "yrs":
+        case "yr":
+        case "y":
+          return n * y;
+        case "weeks":
+        case "week":
+        case "w":
+          return n * w;
+        case "days":
+        case "day":
+        case "d":
+          return n * d;
+        case "hours":
+        case "hour":
+        case "hrs":
+        case "hr":
+        case "h":
+          return n * h;
+        case "minutes":
+        case "minute":
+        case "mins":
+        case "min":
+        case "m":
+          return n * m;
+        case "seconds":
+        case "second":
+        case "secs":
+        case "sec":
+        case "s":
+          return n * s;
+        case "milliseconds":
+        case "millisecond":
+        case "msecs":
+        case "msec":
+        case "ms":
+          return n;
+        default:
+          return void 0;
+      }
+    }
+    function fmtShort(ms) {
+      var msAbs = Math.abs(ms);
+      if (msAbs >= d) {
+        return Math.round(ms / d) + "d";
+      }
+      if (msAbs >= h) {
+        return Math.round(ms / h) + "h";
+      }
+      if (msAbs >= m) {
+        return Math.round(ms / m) + "m";
+      }
+      if (msAbs >= s) {
+        return Math.round(ms / s) + "s";
+      }
+      return ms + "ms";
+    }
+    function fmtLong(ms) {
+      var msAbs = Math.abs(ms);
+      if (msAbs >= d) {
+        return plural(ms, msAbs, d, "day");
+      }
+      if (msAbs >= h) {
+        return plural(ms, msAbs, h, "hour");
+      }
+      if (msAbs >= m) {
+        return plural(ms, msAbs, m, "minute");
+      }
+      if (msAbs >= s) {
+        return plural(ms, msAbs, s, "second");
+      }
+      return ms + " ms";
+    }
+    function plural(ms, msAbs, n, name) {
+      var isPlural = msAbs >= n * 1.5;
+      return Math.round(ms / n) + " " + name + (isPlural ? "s" : "");
+    }
+  }
+});
+
+// node_modules/debug/src/common.js
+var require_common = __commonJS({
+  "node_modules/debug/src/common.js"(exports2, module2) {
+    function setup(env) {
+      createDebug.debug = createDebug;
+      createDebug.default = createDebug;
+      createDebug.coerce = coerce;
+      createDebug.disable = disable;
+      createDebug.enable = enable;
+      createDebug.enabled = enabled;
+      createDebug.humanize = require_ms();
+      createDebug.destroy = destroy;
+      Object.keys(env).forEach((key) => {
+        createDebug[key] = env[key];
+      });
+      createDebug.names = [];
+      createDebug.skips = [];
+      createDebug.formatters = {};
+      function selectColor(namespace) {
+        let hash = 0;
+        for (let i = 0; i < namespace.length; i++) {
+          hash = (hash << 5) - hash + namespace.charCodeAt(i);
+          hash |= 0;
+        }
+        return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
+      }
+      createDebug.selectColor = selectColor;
+      function createDebug(namespace) {
+        let prevTime;
+        let enableOverride = null;
+        let namespacesCache;
+        let enabledCache;
+        function debug2(...args) {
+          if (!debug2.enabled) {
+            return;
+          }
+          const self = debug2;
+          const curr = Number(/* @__PURE__ */ new Date());
+          const ms = curr - (prevTime || curr);
+          self.diff = ms;
+          self.prev = prevTime;
+          self.curr = curr;
+          prevTime = curr;
+          args[0] = createDebug.coerce(args[0]);
+          if (typeof args[0] !== "string") {
+            args.unshift("%O");
+          }
+          let index = 0;
+          args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format2) => {
+            if (match === "%%") {
+              return "%";
+            }
+            index++;
+            const formatter = createDebug.formatters[format2];
+            if (typeof formatter === "function") {
+              const val = args[index];
+              match = formatter.call(self, val);
+              args.splice(index, 1);
+              index--;
+            }
+            return match;
+          });
+          createDebug.formatArgs.call(self, args);
+          const logFn = self.log || createDebug.log;
+          logFn.apply(self, args);
+        }
+        debug2.namespace = namespace;
+        debug2.useColors = createDebug.useColors();
+        debug2.color = createDebug.selectColor(namespace);
+        debug2.extend = extend;
+        debug2.destroy = createDebug.destroy;
+        Object.defineProperty(debug2, "enabled", {
+          enumerable: true,
+          configurable: false,
+          get: () => {
+            if (enableOverride !== null) {
+              return enableOverride;
+            }
+            if (namespacesCache !== createDebug.namespaces) {
+              namespacesCache = createDebug.namespaces;
+              enabledCache = createDebug.enabled(namespace);
+            }
+            return enabledCache;
+          },
+          set: (v) => {
+            enableOverride = v;
+          }
+        });
+        if (typeof createDebug.init === "function") {
+          createDebug.init(debug2);
+        }
+        return debug2;
+      }
+      function extend(namespace, delimiter) {
+        const newDebug = createDebug(this.namespace + (typeof delimiter === "undefined" ? ":" : delimiter) + namespace);
+        newDebug.log = this.log;
+        return newDebug;
+      }
+      function enable(namespaces) {
+        createDebug.save(namespaces);
+        createDebug.namespaces = namespaces;
+        createDebug.names = [];
+        createDebug.skips = [];
+        let i;
+        const split = (typeof namespaces === "string" ? namespaces : "").split(/[\s,]+/);
+        const len = split.length;
+        for (i = 0; i < len; i++) {
+          if (!split[i]) {
+            continue;
+          }
+          namespaces = split[i].replace(/\*/g, ".*?");
+          if (namespaces[0] === "-") {
+            createDebug.skips.push(new RegExp("^" + namespaces.slice(1) + "$"));
+          } else {
+            createDebug.names.push(new RegExp("^" + namespaces + "$"));
+          }
+        }
+      }
+      function disable() {
+        const namespaces = [
+          ...createDebug.names.map(toNamespace),
+          ...createDebug.skips.map(toNamespace).map((namespace) => "-" + namespace)
+        ].join(",");
+        createDebug.enable("");
+        return namespaces;
+      }
+      function enabled(name) {
+        if (name[name.length - 1] === "*") {
+          return true;
+        }
+        let i;
+        let len;
+        for (i = 0, len = createDebug.skips.length; i < len; i++) {
+          if (createDebug.skips[i].test(name)) {
+            return false;
+          }
+        }
+        for (i = 0, len = createDebug.names.length; i < len; i++) {
+          if (createDebug.names[i].test(name)) {
+            return true;
+          }
+        }
+        return false;
+      }
+      function toNamespace(regexp) {
+        return regexp.toString().substring(2, regexp.toString().length - 2).replace(/\.\*\?$/, "*");
+      }
+      function coerce(val) {
+        if (val instanceof Error) {
+          return val.stack || val.message;
+        }
+        return val;
+      }
+      function destroy() {
+        console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.");
+      }
+      createDebug.enable(createDebug.load());
+      return createDebug;
+    }
+    module2.exports = setup;
+  }
+});
+
+// node_modules/debug/src/browser.js
+var require_browser = __commonJS({
+  "node_modules/debug/src/browser.js"(exports2, module2) {
+    exports2.formatArgs = formatArgs;
+    exports2.save = save;
+    exports2.load = load;
+    exports2.useColors = useColors;
+    exports2.storage = localstorage();
+    exports2.destroy = /* @__PURE__ */ (() => {
+      let warned = false;
+      return () => {
+        if (!warned) {
+          warned = true;
+          console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.");
+        }
+      };
+    })();
+    exports2.colors = [
+      "#0000CC",
+      "#0000FF",
+      "#0033CC",
+      "#0033FF",
+      "#0066CC",
+      "#0066FF",
+      "#0099CC",
+      "#0099FF",
+      "#00CC00",
+      "#00CC33",
+      "#00CC66",
+      "#00CC99",
+      "#00CCCC",
+      "#00CCFF",
+      "#3300CC",
+      "#3300FF",
+      "#3333CC",
+      "#3333FF",
+      "#3366CC",
+      "#3366FF",
+      "#3399CC",
+      "#3399FF",
+      "#33CC00",
+      "#33CC33",
+      "#33CC66",
+      "#33CC99",
+      "#33CCCC",
+      "#33CCFF",
+      "#6600CC",
+      "#6600FF",
+      "#6633CC",
+      "#6633FF",
+      "#66CC00",
+      "#66CC33",
+      "#9900CC",
+      "#9900FF",
+      "#9933CC",
+      "#9933FF",
+      "#99CC00",
+      "#99CC33",
+      "#CC0000",
+      "#CC0033",
+      "#CC0066",
+      "#CC0099",
+      "#CC00CC",
+      "#CC00FF",
+      "#CC3300",
+      "#CC3333",
+      "#CC3366",
+      "#CC3399",
+      "#CC33CC",
+      "#CC33FF",
+      "#CC6600",
+      "#CC6633",
+      "#CC9900",
+      "#CC9933",
+      "#CCCC00",
+      "#CCCC33",
+      "#FF0000",
+      "#FF0033",
+      "#FF0066",
+      "#FF0099",
+      "#FF00CC",
+      "#FF00FF",
+      "#FF3300",
+      "#FF3333",
+      "#FF3366",
+      "#FF3399",
+      "#FF33CC",
+      "#FF33FF",
+      "#FF6600",
+      "#FF6633",
+      "#FF9900",
+      "#FF9933",
+      "#FFCC00",
+      "#FFCC33"
+    ];
+    function useColors() {
+      if (typeof window !== "undefined" && window.process && (window.process.type === "renderer" || window.process.__nwjs)) {
+        return true;
+      }
+      if (typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
+        return false;
+      }
+      let m;
+      return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773
+      typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31?
+      // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
+      typeof navigator !== "undefined" && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker
+      typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
+    }
+    function formatArgs(args) {
+      args[0] = (this.useColors ? "%c" : "") + this.namespace + (this.useColors ? " %c" : " ") + args[0] + (this.useColors ? "%c " : " ") + "+" + module2.exports.humanize(this.diff);
+      if (!this.useColors) {
+        return;
+      }
+      const c = "color: " + this.color;
+      args.splice(1, 0, c, "color: inherit");
+      let index = 0;
+      let lastC = 0;
+      args[0].replace(/%[a-zA-Z%]/g, (match) => {
+        if (match === "%%") {
+          return;
+        }
+        index++;
+        if (match === "%c") {
+          lastC = index;
+        }
+      });
+      args.splice(lastC, 0, c);
+    }
+    exports2.log = console.debug || console.log || (() => {
+    });
+    function save(namespaces) {
+      try {
+        if (namespaces) {
+          exports2.storage.setItem("debug", namespaces);
+        } else {
+          exports2.storage.removeItem("debug");
+        }
+      } catch (error) {
+      }
+    }
+    function load() {
+      let r;
+      try {
+        r = exports2.storage.getItem("debug");
+      } catch (error) {
+      }
+      if (!r && typeof process !== "undefined" && "env" in process) {
+        r = process.env.DEBUG;
+      }
+      return r;
+    }
+    function localstorage() {
+      try {
+        return localStorage;
+      } catch (error) {
+      }
+    }
+    module2.exports = require_common()(exports2);
+    var { formatters } = module2.exports;
+    formatters.j = function(v) {
+      try {
+        return JSON.stringify(v);
+      } catch (error) {
+        return "[UnexpectedJSONParseError]: " + error.message;
+      }
+    };
+  }
+});
+
+// node_modules/has-flag/index.js
+var require_has_flag = __commonJS({
+  "node_modules/has-flag/index.js"(exports2, module2) {
+    "use strict";
+    module2.exports = (flag, argv = process.argv) => {
+      const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
+      const position = argv.indexOf(prefix + flag);
+      const terminatorPosition = argv.indexOf("--");
+      return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
+    };
+  }
+});
+
+// node_modules/supports-color/index.js
+var require_supports_color = __commonJS({
+  "node_modules/supports-color/index.js"(exports2, module2) {
+    "use strict";
+    var os = require("os");
+    var tty = require("tty");
+    var hasFlag = require_has_flag();
+    var { env } = process;
+    var forceColor;
+    if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
+      forceColor = 0;
+    } else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
+      forceColor = 1;
+    }
+    if ("FORCE_COLOR" in env) {
+      if (env.FORCE_COLOR === "true") {
+        forceColor = 1;
+      } else if (env.FORCE_COLOR === "false") {
+        forceColor = 0;
+      } else {
+        forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3);
+      }
+    }
+    function translateLevel(level) {
+      if (level === 0) {
+        return false;
+      }
+      return {
+        level,
+        hasBasic: true,
+        has256: level >= 2,
+        has16m: level >= 3
+      };
+    }
+    function supportsColor(haveStream, streamIsTTY) {
+      if (forceColor === 0) {
+        return 0;
+      }
+      if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
+        return 3;
+      }
+      if (hasFlag("color=256")) {
+        return 2;
+      }
+      if (haveStream && !streamIsTTY && forceColor === void 0) {
+        return 0;
+      }
+      const min = forceColor || 0;
+      if (env.TERM === "dumb") {
+        return min;
+      }
+      if (process.platform === "win32") {
+        const osRelease = os.release().split(".");
+        if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
+          return Number(osRelease[2]) >= 14931 ? 3 : 2;
+        }
+        return 1;
+      }
+      if ("CI" in env) {
+        if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "GITHUB_ACTIONS", "BUILDKITE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
+          return 1;
+        }
+        return min;
+      }
+      if ("TEAMCITY_VERSION" in env) {
+        return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
+      }
+      if (env.COLORTERM === "truecolor") {
+        return 3;
+      }
+      if ("TERM_PROGRAM" in env) {
+        const version = parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
+        switch (env.TERM_PROGRAM) {
+          case "iTerm.app":
+            return version >= 3 ? 3 : 2;
+          case "Apple_Terminal":
+            return 2;
+        }
+      }
+      if (/-256(color)?$/i.test(env.TERM)) {
+        return 2;
+      }
+      if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
+        return 1;
+      }
+      if ("COLORTERM" in env) {
+        return 1;
+      }
+      return min;
+    }
+    function getSupportLevel(stream) {
+      const level = supportsColor(stream, stream && stream.isTTY);
+      return translateLevel(level);
+    }
+    module2.exports = {
+      supportsColor: getSupportLevel,
+      stdout: translateLevel(supportsColor(true, tty.isatty(1))),
+      stderr: translateLevel(supportsColor(true, tty.isatty(2)))
+    };
+  }
+});
+
+// node_modules/debug/src/node.js
+var require_node = __commonJS({
+  "node_modules/debug/src/node.js"(exports2, module2) {
+    var tty = require("tty");
+    var util = require("util");
+    exports2.init = init;
+    exports2.log = log;
+    exports2.formatArgs = formatArgs;
+    exports2.save = save;
+    exports2.load = load;
+    exports2.useColors = useColors;
+    exports2.destroy = util.deprecate(
+      () => {
+      },
+      "Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."
+    );
+    exports2.colors = [6, 2, 3, 4, 5, 1];
+    try {
+      const supportsColor = require_supports_color();
+      if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {
+        exports2.colors = [
+          20,
+          21,
+          26,
+          27,
+          32,
+          33,
+          38,
+          39,
+          40,
+          41,
+          42,
+          43,
+          44,
+          45,
+          56,
+          57,
+          62,
+          63,
+          68,
+          69,
+          74,
+          75,
+          76,
+          77,
+          78,
+          79,
+          80,
+          81,
+          92,
+          93,
+          98,
+          99,
+          112,
+          113,
+          128,
+          129,
+          134,
+          135,
+          148,
+          149,
+          160,
+          161,
+          162,
+          163,
+          164,
+          165,
+          166,
+          167,
+          168,
+          169,
+          170,
+          171,
+          172,
+          173,
+          178,
+          179,
+          184,
+          185,
+          196,
+          197,
+          198,
+          199,
+          200,
+          201,
+          202,
+          203,
+          204,
+          205,
+          206,
+          207,
+          208,
+          209,
+          214,
+          215,
+          220,
+          221
+        ];
+      }
+    } catch (error) {
+    }
+    exports2.inspectOpts = Object.keys(process.env).filter((key) => {
+      return /^debug_/i.test(key);
+    }).reduce((obj, key) => {
+      const prop = key.substring(6).toLowerCase().replace(/_([a-z])/g, (_, k) => {
+        return k.toUpperCase();
+      });
+      let val = process.env[key];
+      if (/^(yes|on|true|enabled)$/i.test(val)) {
+        val = true;
+      } else if (/^(no|off|false|disabled)$/i.test(val)) {
+        val = false;
+      } else if (val === "null") {
+        val = null;
+      } else {
+        val = Number(val);
+      }
+      obj[prop] = val;
+      return obj;
+    }, {});
+    function useColors() {
+      return "colors" in exports2.inspectOpts ? Boolean(exports2.inspectOpts.colors) : tty.isatty(process.stderr.fd);
+    }
+    function formatArgs(args) {
+      const { namespace: name, useColors: useColors2 } = this;
+      if (useColors2) {
+        const c = this.color;
+        const colorCode = "\x1B[3" + (c < 8 ? c : "8;5;" + c);
+        const prefix = `  ${colorCode};1m${name} \x1B[0m`;
+        args[0] = prefix + args[0].split("\n").join("\n" + prefix);
+        args.push(colorCode + "m+" + module2.exports.humanize(this.diff) + "\x1B[0m");
+      } else {
+        args[0] = getDate() + name + " " + args[0];
+      }
+    }
+    function getDate() {
+      if (exports2.inspectOpts.hideDate) {
+        return "";
+      }
+      return (/* @__PURE__ */ new Date()).toISOString() + " ";
+    }
+    function log(...args) {
+      return process.stderr.write(util.formatWithOptions(exports2.inspectOpts, ...args) + "\n");
+    }
+    function save(namespaces) {
+      if (namespaces) {
+        process.env.DEBUG = namespaces;
+      } else {
+        delete process.env.DEBUG;
+      }
+    }
+    function load() {
+      return process.env.DEBUG;
+    }
+    function init(debug2) {
+      debug2.inspectOpts = {};
+      const keys = Object.keys(exports2.inspectOpts);
+      for (let i = 0; i < keys.length; i++) {
+        debug2.inspectOpts[keys[i]] = exports2.inspectOpts[keys[i]];
+      }
+    }
+    module2.exports = require_common()(exports2);
+    var { formatters } = module2.exports;
+    formatters.o = function(v) {
+      this.inspectOpts.colors = this.useColors;
+      return util.inspect(v, this.inspectOpts).split("\n").map((str) => str.trim()).join(" ");
+    };
+    formatters.O = function(v) {
+      this.inspectOpts.colors = this.useColors;
+      return util.inspect(v, this.inspectOpts);
+    };
+  }
+});
+
+// node_modules/debug/src/index.js
+var require_src = __commonJS({
+  "node_modules/debug/src/index.js"(exports2, module2) {
+    if (typeof process === "undefined" || process.type === "renderer" || process.browser === true || process.__nwjs) {
+      module2.exports = require_browser();
+    } else {
+      module2.exports = require_node();
+    }
+  }
+});
+
+// src/index.js
+var src_exports = {};
+__export(src_exports, {
+  PathTrie: () => PathTrie
+});
+module.exports = __toCommonJS(src_exports);
+
+// node_modules/@e22m4u/js-format/src/utils/is-class.js
+function isClass(value) {
+  if (!value) return false;
+  return typeof value === "function" && /^class\s/.test(Function.prototype.toString.call(value));
+}
+
+// node_modules/@e22m4u/js-format/src/value-to-string.js
+var BASE_CTOR_NAMES = [
+  "String",
+  "Number",
+  "Boolean",
+  "Object",
+  "Array",
+  "Function",
+  "Symbol",
+  "Map",
+  "Set",
+  "Date"
+];
+function valueToString(input) {
+  if (input == null) return String(input);
+  if (typeof input === "string") return `"${input}"`;
+  if (typeof input === "number" || typeof input === "boolean")
+    return String(input);
+  if (isClass(input)) return input.name ? input.name : "Class";
+  if (input.constructor && input.constructor.name)
+    return BASE_CTOR_NAMES.includes(input.constructor.name) ? input.constructor.name : `${input.constructor.name} (instance)`;
+  if (typeof input === "object" && input.constructor == null) return "Object";
+  return String(input);
+}
+
+// node_modules/@e22m4u/js-format/src/array-to-list.js
+var SEPARATOR = ", ";
+function arrayToList(input) {
+  if (Array.isArray(input) && input.length)
+    return input.map(valueToString).join(SEPARATOR);
+  return valueToString(input);
+}
+
+// node_modules/@e22m4u/js-format/src/format.js
+function format(pattern) {
+  if (pattern instanceof Date) {
+    pattern = pattern.toISOString();
+  } else if (typeof pattern !== "string") {
+    pattern = String(pattern);
+  }
+  const re = /(%?)(%([sdjvl]))/g;
+  const args = Array.prototype.slice.call(arguments, 1);
+  if (args.length) {
+    pattern = pattern.replace(re, function(match, escaped, ptn, flag) {
+      let arg = args.shift();
+      switch (flag) {
+        case "s":
+          arg = String(arg);
+          break;
+        case "d":
+          arg = Number(arg);
+          break;
+        case "j":
+          arg = JSON.stringify(arg);
+          break;
+        case "v":
+          arg = valueToString(arg);
+          break;
+        case "l":
+          arg = arrayToList(arg);
+          break;
+      }
+      if (!escaped) return arg;
+      args.unshift(arg);
+      return match;
+    });
+  }
+  if (args.length) pattern += " " + args.join(" ");
+  pattern = pattern.replace(/%{2}/g, "%");
+  return "" + pattern;
+}
+
+// node_modules/@e22m4u/js-format/src/errorf.js
+var Errorf = class extends Error {
+  /**
+   * Constructor.
+   *
+   * @param {string|undefined} pattern
+   * @param {any} args
+   */
+  constructor(pattern = void 0, ...args) {
+    const message = pattern != null ? format(pattern, ...args) : void 0;
+    super(message);
+  }
+};
+
+// src/path-trie.js
+var import_path_to_regexp = __toESM(require_dist(), 1);
+
+// src/utils/create-debugger.js
+var import_debug = __toESM(require_src(), 1);
+function createDebugger() {
+  const debug2 = (0, import_debug.default)(`jsPathTrie`);
+  return function(message, ...args) {
+    const interpolatedMessage = format(message, ...args);
+    return debug2(interpolatedMessage);
+  };
+}
+
+// src/path-trie.js
+var debug = createDebugger();
+var PathTrie = class {
+  /**
+   * Root node.
+   *
+   * @type {Node}
+   * @private
+   */
+  _root = {
+    token: "",
+    regexp: void 0,
+    names: [],
+    value: void 0,
+    children: {}
+  };
+  /**
+   * Add value.
+   *
+   * @param {string} pathTemplate
+   * @param {*} value
+   * @returns {this}
+   */
+  add(pathTemplate, value) {
+    if (typeof pathTemplate !== "string")
+      throw new Errorf(
+        "The first argument of PathTrie.add should be a String, but %v given.",
+        pathTemplate
+      );
+    if (value == null)
+      throw new Errorf(
+        "The second argument of PathTrie.add is required, but %v given.",
+        value
+      );
+    debug("Adding the value to %v.", pathTemplate);
+    const tokens = pathTemplate.split("/").filter(Boolean);
+    this._createNode(tokens, 0, value, this._root);
+    return this;
+  }
+  /**
+   * Match value.
+   *
+   * @param {string} path
+   * @returns {ResolvedValue|undefined}
+   */
+  match(path) {
+    if (typeof path !== "string")
+      throw new Errorf(
+        "The first argument of PathTrie.match should be a String, but %v given.",
+        path
+      );
+    debug("Matching a value with the path %v.", path);
+    const tokens = path.split("/").filter(Boolean);
+    const params = {};
+    const result = this._matchNode(tokens, 0, params, this._root);
+    if (!result || !result.node.value) return;
+    return { value: result.node.value, params };
+  }
+  /**
+   * Create node.
+   *
+   * @param {string[]} tokens
+   * @param {number} index
+   * @param {*} value
+   * @param {Node} parent
+   * @returns {Node}
+   * @private
+   */
+  _createNode(tokens, index, value, parent) {
+    if (tokens.length === 0 && index === 0) {
+      if (parent.value == null) {
+        parent.value = value;
+      } else if (parent.value !== value) {
+        throw new Errorf('The duplicate path "" has a different value.');
+      }
+      debug("The value has set to the root node.");
+      return parent;
+    }
+    const token = tokens[index];
+    if (token == null)
+      throw new Errorf(
+        "Invalid index %v has passed to the PathTrie._createNode.",
+        index
+      );
+    const isLast = tokens.length - 1 === index;
+    let child = parent.children[token];
+    if (isLast && child != null) {
+      debug("The node %v already exist.", token);
+      if (child.value == null) {
+        child.value = value;
+      } else if (child.value !== value) {
+        throw new Errorf(
+          "The duplicate path %v has a different value.",
+          "/" + tokens.join("/")
+        );
+      }
+      return child;
+    }
+    debug("The node %v does not exist.", token);
+    child = {
+      token,
+      regexp: void 0,
+      names: [],
+      value: void 0,
+      children: {}
+    };
+    if (isLast) {
+      debug("The node %v is last.", token);
+      child.value = value;
+    }
+    if (token.indexOf(":") > -1) {
+      debug("The node %v has parameters.", token);
+      const modifiers = /([?*+{}])/.exec(token);
+      if (modifiers)
+        throw new Errorf(
+          "The symbol %v is not supported in path %v.",
+          modifiers[0],
+          "/" + tokens.join("/")
+        );
+      let regexp, keys;
+      try {
+        const regexpAndKeys = (0, import_path_to_regexp.pathToRegexp)(token);
+        regexp = regexpAndKeys.regexp;
+        keys = regexpAndKeys.keys;
+      } catch (error) {
+        if (error.message.indexOf("Missing parameter") > -1)
+          throw new Errorf(
+            'The symbol ":" should be used to define path parameters, but no parameters found in the path %v.',
+            "/" + tokens.join("/")
+          );
+        throw error;
+      }
+      if (Array.isArray(keys) && keys.length) {
+        child.names = keys.map((p) => `${p.name}`);
+        child.regexp = regexp;
+      } else {
+        throw new Errorf(
+          'The symbol ":" should be used to define path parameters, but no parameters found in the path %v.',
+          "/" + tokens.join("/")
+        );
+      }
+      debug("Found parameters are %l.", child.names);
+    }
+    parent.children[token] = child;
+    debug("The node %v has created.", token);
+    if (isLast) return child;
+    return this._createNode(tokens, index + 1, value, child);
+  }
+  /**
+   * Match node.
+   *
+   * @param {string[]} tokens
+   * @param {number} index
+   * @param {object} params
+   * @param {Node} parent
+   * @returns {ResolvedNode|undefined}
+   * @private
+   */
+  _matchNode(tokens, index, params, parent) {
+    if (tokens.length === 0 && index === 0) {
+      if (parent.value) {
+        debug(
+          "The path %v matched with the root node.",
+          "/" + tokens.join("/")
+        );
+        return { node: parent, params };
+      }
+      return;
+    }
+    const token = tokens[index];
+    if (token == null)
+      throw new Errorf(
+        "Invalid index %v has passed to the PathTrie._matchNode.",
+        index
+      );
+    const resolvedNodes = this._matchChildrenNodes(token, parent);
+    debug("%v nodes matches the token %v.", resolvedNodes.length, token);
+    if (!resolvedNodes.length) return;
+    const isLast = tokens.length - 1 === index;
+    if (isLast) {
+      debug("The token %v is last.", token);
+      for (const child of resolvedNodes) {
+        debug("The node %v matches the token %v.", child.node.token, token);
+        if (child.node.value) {
+          debug("The node %v has a value.", child.node.token);
+          const paramNames = Object.keys(child.params);
+          if (paramNames.length) {
+            paramNames.forEach((name) => {
+              debug(
+                "The node %v has parameter %v with the value %v.",
+                child.node.token,
+                name,
+                child.params[name]
+              );
+            });
+          } else {
+            debug("The node %v has no parameters.", child.node.token);
+          }
+          Object.assign(params, child.params);
+          return { node: child.node, params };
+        }
+      }
+    } else {
+      for (const child of resolvedNodes) {
+        const result = this._matchNode(tokens, index + 1, params, child.node);
+        if (result) {
+          debug("A value has found for the path %v.", "/" + tokens.join("/"));
+          const paramNames = Object.keys(child.params);
+          if (paramNames.length) {
+            paramNames.forEach((name) => {
+              debug(
+                "The node %v has parameter %v with the value %v.",
+                child.node.token,
+                name,
+                child.params[name]
+              );
+            });
+          } else {
+            debug("The node %v has no parameters.", child.node.token);
+          }
+          Object.assign(params, child.params);
+          return result;
+        }
+      }
+    }
+    debug("No matched nodes with the path %v.", "/" + tokens.join("/"));
+    return void 0;
+  }
+  /**
+   * Match children nodes.
+   *
+   * @param {string} token
+   * @param {Node} parent
+   * @returns {ResolvedNode[]}
+   * @private
+   */
+  _matchChildrenNodes(token, parent) {
+    const resolvedNodes = [];
+    let child = parent.children[token];
+    if (child) {
+      resolvedNodes.push({ node: child, params: {} });
+      return resolvedNodes;
+    }
+    for (const key in parent.children) {
+      child = parent.children[key];
+      if (!child.names || !child.regexp) continue;
+      const match = child.regexp.exec(token);
+      if (match) {
+        const resolved = { node: child, params: {} };
+        let i = 0;
+        for (const name of child.names) {
+          const val = match[++i];
+          resolved.params[name] = decodeURIComponent(val);
+        }
+        resolvedNodes.push(resolved);
+      }
+    }
+    return resolvedNodes;
+  }
+};
+// Annotate the CommonJS export names for ESM import in node:
+0 && (module.exports = {
+  PathTrie
+});

+ 11 - 1
package.json

@@ -3,13 +3,22 @@
   "version": "0.0.3",
   "version": "0.0.3",
   "description": "A router for Node.js based on a prefix tree",
   "description": "A router for Node.js based on a prefix tree",
   "type": "module",
   "type": "module",
-  "main": "src/index.js",
+  "module": "./src/index.js",
+  "main": "./dist/cjs/index.cjs",
+  "exports": {
+    "import": "./src/index.js",
+    "require": "./dist/cjs/index.cjs"
+  },
+  "engines": {
+    "node": ">=16"
+  },
   "scripts": {
   "scripts": {
     "lint": "tsc && eslint ./src",
     "lint": "tsc && eslint ./src",
     "lint:fix": "tsc && eslint ./src --fix",
     "lint:fix": "tsc && eslint ./src --fix",
     "format": "prettier --write \"./src/**/*.js\"",
     "format": "prettier --write \"./src/**/*.js\"",
     "test": "npm run lint && c8 --reporter=text-summary mocha",
     "test": "npm run lint && c8 --reporter=text-summary mocha",
     "test:coverage": "npm run lint && c8 --reporter=text mocha",
     "test:coverage": "npm run lint && c8 --reporter=text mocha",
+    "build:cjs": "node build-cjs.js",
     "prepare": "husky"
     "prepare": "husky"
   },
   },
   "repository": {
   "repository": {
@@ -35,6 +44,7 @@
     "@eslint/js": "~9.12.0",
     "@eslint/js": "~9.12.0",
     "c8": "~10.1.2",
     "c8": "~10.1.2",
     "chai": "~5.1.1",
     "chai": "~5.1.1",
+    "esbuild": "~0.24.0",
     "eslint": "~9.12.0",
     "eslint": "~9.12.0",
     "eslint-config-prettier": "~9.1.0",
     "eslint-config-prettier": "~9.1.0",
     "eslint-plugin-chai-expect": "~3.1.0",
     "eslint-plugin-chai-expect": "~3.1.0",