| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- var __defProp = Object.defineProperty;
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
- var __getOwnPropNames = Object.getOwnPropertyNames;
- var __hasOwnProp = Object.prototype.hasOwnProperty;
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
- 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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
- // src/index.js
- var index_exports = {};
- __export(index_exports, {
- PathTrie: () => PathTrie
- });
- module.exports = __toCommonJS(index_exports);
- // src/path-trie.js
- var import_js_format = require("@e22m4u/js-format");
- var import_js_debug = require("@e22m4u/js-debug");
- var import_path_to_regexp = require("path-to-regexp");
- var _PathTrie = class _PathTrie extends import_js_debug.Debuggable {
- /**
- * Constructor.
- */
- constructor() {
- super({ noEnvNs: true, namespace: "jsPathTrie" });
- }
- /**
- * 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) {
- const debug = this.getDebuggerFor(this.add);
- if (typeof pathTemplate !== "string")
- throw new import_js_format.Errorf(
- "The first argument of PathTrie.add must be a String, but %v was given.",
- pathTemplate
- );
- if (value == null)
- throw new import_js_format.Errorf(
- "The second argument of PathTrie.add is required, but %v was given.",
- value
- );
- debug("Adding a value for the path %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) {
- const debug = this.getDebuggerFor(this.match);
- if (typeof path !== "string")
- throw new import_js_format.Errorf(
- "The first argument of PathTrie.match must be a String, but %v was given.",
- path
- );
- debug("Matching a value for 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) {
- const debug = this.getDebuggerFor(this._createNode);
- if (tokens.length === 0 && index === 0) {
- if (parent.value == null) {
- parent.value = value;
- } else if (parent.value !== value) {
- throw new import_js_format.Errorf('The duplicate path "" has a different value.');
- }
- debug("The value has been set for the root node.");
- return parent;
- }
- const token = tokens[index];
- if (token == null)
- throw new import_js_format.Errorf(
- "Invalid index %v was passed to PathTrie._createNode.",
- index
- );
- let child = parent.children[token];
- const isLast = tokens.length - 1 === index;
- if (child) {
- if (!isLast) {
- debug("The node %v already exists.", token);
- return this._createNode(tokens, index + 1, value, child);
- } else {
- debug("The node %v already exists.", token);
- if (child.value == null) {
- debug("The node %v has the same value.", token);
- child.value = value;
- } else if (child.value !== value) {
- throw new import_js_format.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 the last.", token);
- child.value = value;
- }
- if (token.indexOf(":") > -1) {
- debug("The node %v has parameters.", token);
- const modifiers = /([?*+{}])/.exec(token);
- if (modifiers)
- throw new import_js_format.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 import_js_format.Errorf(
- 'The symbol ":" should be used to define path parameters, but no parameters were 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 import_js_format.Errorf(
- 'The symbol ":" should be used to define path parameters, but no parameters were found in the path %v.',
- "/" + tokens.join("/")
- );
- }
- debug("The found parameters are %l.", child.names);
- }
- parent.children[token] = child;
- debug("The node %v has been 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) {
- const debug = this.getDebuggerFor(this._matchNode);
- if (tokens.length === 0 && index === 0) {
- if (parent.value) {
- debug("The path %v matched the root node.", "/" + tokens.join("/"));
- return { node: parent, params };
- }
- return;
- }
- const token = tokens[index];
- if (token == null)
- throw new import_js_format.Errorf(
- "Invalid index %v was passed to PathTrie._matchNode.",
- index
- );
- const resolvedNodes = this._matchChildrenNodes(token, parent);
- debug("%v nodes match the token %v.", resolvedNodes.length, token);
- if (!resolvedNodes.length) return;
- const isLast = tokens.length - 1 === index;
- if (isLast) {
- debug("The token %v is the 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 been 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 matching nodes were found for 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;
- }
- };
- __name(_PathTrie, "PathTrie");
- var PathTrie = _PathTrie;
- // Annotate the CommonJS export names for ESM import in node:
- 0 && (module.exports = {
- PathTrie
- });
|