 d7ad321176
			
		
	
	d7ad321176
	
	
	
		
			
			This comprehensive implementation includes: - FastAPI backend with MCP server integration - React/TypeScript frontend with Vite - PostgreSQL database with Redis caching - Grafana/Prometheus monitoring stack - Docker Compose orchestration - Full MCP protocol support for Claude Code integration Features: - Agent discovery and management across network - Visual workflow editor and execution engine - Real-time task coordination and monitoring - Multi-model support with specialized agents - Distributed development task allocation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			245 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			245 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| "use strict";
 | |
| // Claude-authored implementation of RFC 6570 URI Templates
 | |
| Object.defineProperty(exports, "__esModule", { value: true });
 | |
| exports.UriTemplate = void 0;
 | |
| const MAX_TEMPLATE_LENGTH = 1000000; // 1MB
 | |
| const MAX_VARIABLE_LENGTH = 1000000; // 1MB
 | |
| const MAX_TEMPLATE_EXPRESSIONS = 10000;
 | |
| const MAX_REGEX_LENGTH = 1000000; // 1MB
 | |
| class UriTemplate {
 | |
|     /**
 | |
|      * Returns true if the given string contains any URI template expressions.
 | |
|      * A template expression is a sequence of characters enclosed in curly braces,
 | |
|      * like {foo} or {?bar}.
 | |
|      */
 | |
|     static isTemplate(str) {
 | |
|         // Look for any sequence of characters between curly braces
 | |
|         // that isn't just whitespace
 | |
|         return /\{[^}\s]+\}/.test(str);
 | |
|     }
 | |
|     static validateLength(str, max, context) {
 | |
|         if (str.length > max) {
 | |
|             throw new Error(`${context} exceeds maximum length of ${max} characters (got ${str.length})`);
 | |
|         }
 | |
|     }
 | |
|     get variableNames() {
 | |
|         return this.parts.flatMap((part) => typeof part === 'string' ? [] : part.names);
 | |
|     }
 | |
|     constructor(template) {
 | |
|         UriTemplate.validateLength(template, MAX_TEMPLATE_LENGTH, "Template");
 | |
|         this.template = template;
 | |
|         this.parts = this.parse(template);
 | |
|     }
 | |
|     toString() {
 | |
|         return this.template;
 | |
|     }
 | |
|     parse(template) {
 | |
|         const parts = [];
 | |
|         let currentText = "";
 | |
|         let i = 0;
 | |
|         let expressionCount = 0;
 | |
|         while (i < template.length) {
 | |
|             if (template[i] === "{") {
 | |
|                 if (currentText) {
 | |
|                     parts.push(currentText);
 | |
|                     currentText = "";
 | |
|                 }
 | |
|                 const end = template.indexOf("}", i);
 | |
|                 if (end === -1)
 | |
|                     throw new Error("Unclosed template expression");
 | |
|                 expressionCount++;
 | |
|                 if (expressionCount > MAX_TEMPLATE_EXPRESSIONS) {
 | |
|                     throw new Error(`Template contains too many expressions (max ${MAX_TEMPLATE_EXPRESSIONS})`);
 | |
|                 }
 | |
|                 const expr = template.slice(i + 1, end);
 | |
|                 const operator = this.getOperator(expr);
 | |
|                 const exploded = expr.includes("*");
 | |
|                 const names = this.getNames(expr);
 | |
|                 const name = names[0];
 | |
|                 // Validate variable name length
 | |
|                 for (const name of names) {
 | |
|                     UriTemplate.validateLength(name, MAX_VARIABLE_LENGTH, "Variable name");
 | |
|                 }
 | |
|                 parts.push({ name, operator, names, exploded });
 | |
|                 i = end + 1;
 | |
|             }
 | |
|             else {
 | |
|                 currentText += template[i];
 | |
|                 i++;
 | |
|             }
 | |
|         }
 | |
|         if (currentText) {
 | |
|             parts.push(currentText);
 | |
|         }
 | |
|         return parts;
 | |
|     }
 | |
|     getOperator(expr) {
 | |
|         const operators = ["+", "#", ".", "/", "?", "&"];
 | |
|         return operators.find((op) => expr.startsWith(op)) || "";
 | |
|     }
 | |
|     getNames(expr) {
 | |
|         const operator = this.getOperator(expr);
 | |
|         return expr
 | |
|             .slice(operator.length)
 | |
|             .split(",")
 | |
|             .map((name) => name.replace("*", "").trim())
 | |
|             .filter((name) => name.length > 0);
 | |
|     }
 | |
|     encodeValue(value, operator) {
 | |
|         UriTemplate.validateLength(value, MAX_VARIABLE_LENGTH, "Variable value");
 | |
|         if (operator === "+" || operator === "#") {
 | |
|             return encodeURI(value);
 | |
|         }
 | |
|         return encodeURIComponent(value);
 | |
|     }
 | |
|     expandPart(part, variables) {
 | |
|         if (part.operator === "?" || part.operator === "&") {
 | |
|             const pairs = part.names
 | |
|                 .map((name) => {
 | |
|                 const value = variables[name];
 | |
|                 if (value === undefined)
 | |
|                     return "";
 | |
|                 const encoded = Array.isArray(value)
 | |
|                     ? value.map((v) => this.encodeValue(v, part.operator)).join(",")
 | |
|                     : this.encodeValue(value.toString(), part.operator);
 | |
|                 return `${name}=${encoded}`;
 | |
|             })
 | |
|                 .filter((pair) => pair.length > 0);
 | |
|             if (pairs.length === 0)
 | |
|                 return "";
 | |
|             const separator = part.operator === "?" ? "?" : "&";
 | |
|             return separator + pairs.join("&");
 | |
|         }
 | |
|         if (part.names.length > 1) {
 | |
|             const values = part.names
 | |
|                 .map((name) => variables[name])
 | |
|                 .filter((v) => v !== undefined);
 | |
|             if (values.length === 0)
 | |
|                 return "";
 | |
|             return values.map((v) => (Array.isArray(v) ? v[0] : v)).join(",");
 | |
|         }
 | |
|         const value = variables[part.name];
 | |
|         if (value === undefined)
 | |
|             return "";
 | |
|         const values = Array.isArray(value) ? value : [value];
 | |
|         const encoded = values.map((v) => this.encodeValue(v, part.operator));
 | |
|         switch (part.operator) {
 | |
|             case "":
 | |
|                 return encoded.join(",");
 | |
|             case "+":
 | |
|                 return encoded.join(",");
 | |
|             case "#":
 | |
|                 return "#" + encoded.join(",");
 | |
|             case ".":
 | |
|                 return "." + encoded.join(".");
 | |
|             case "/":
 | |
|                 return "/" + encoded.join("/");
 | |
|             default:
 | |
|                 return encoded.join(",");
 | |
|         }
 | |
|     }
 | |
|     expand(variables) {
 | |
|         let result = "";
 | |
|         let hasQueryParam = false;
 | |
|         for (const part of this.parts) {
 | |
|             if (typeof part === "string") {
 | |
|                 result += part;
 | |
|                 continue;
 | |
|             }
 | |
|             const expanded = this.expandPart(part, variables);
 | |
|             if (!expanded)
 | |
|                 continue;
 | |
|             // Convert ? to & if we already have a query parameter
 | |
|             if ((part.operator === "?" || part.operator === "&") && hasQueryParam) {
 | |
|                 result += expanded.replace("?", "&");
 | |
|             }
 | |
|             else {
 | |
|                 result += expanded;
 | |
|             }
 | |
|             if (part.operator === "?" || part.operator === "&") {
 | |
|                 hasQueryParam = true;
 | |
|             }
 | |
|         }
 | |
|         return result;
 | |
|     }
 | |
|     escapeRegExp(str) {
 | |
|         return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
 | |
|     }
 | |
|     partToRegExp(part) {
 | |
|         const patterns = [];
 | |
|         // Validate variable name length for matching
 | |
|         for (const name of part.names) {
 | |
|             UriTemplate.validateLength(name, MAX_VARIABLE_LENGTH, "Variable name");
 | |
|         }
 | |
|         if (part.operator === "?" || part.operator === "&") {
 | |
|             for (let i = 0; i < part.names.length; i++) {
 | |
|                 const name = part.names[i];
 | |
|                 const prefix = i === 0 ? "\\" + part.operator : "&";
 | |
|                 patterns.push({
 | |
|                     pattern: prefix + this.escapeRegExp(name) + "=([^&]+)",
 | |
|                     name,
 | |
|                 });
 | |
|             }
 | |
|             return patterns;
 | |
|         }
 | |
|         let pattern;
 | |
|         const name = part.name;
 | |
|         switch (part.operator) {
 | |
|             case "":
 | |
|                 pattern = part.exploded ? "([^/]+(?:,[^/]+)*)" : "([^/,]+)";
 | |
|                 break;
 | |
|             case "+":
 | |
|             case "#":
 | |
|                 pattern = "(.+)";
 | |
|                 break;
 | |
|             case ".":
 | |
|                 pattern = "\\.([^/,]+)";
 | |
|                 break;
 | |
|             case "/":
 | |
|                 pattern = "/" + (part.exploded ? "([^/]+(?:,[^/]+)*)" : "([^/,]+)");
 | |
|                 break;
 | |
|             default:
 | |
|                 pattern = "([^/]+)";
 | |
|         }
 | |
|         patterns.push({ pattern, name });
 | |
|         return patterns;
 | |
|     }
 | |
|     match(uri) {
 | |
|         UriTemplate.validateLength(uri, MAX_TEMPLATE_LENGTH, "URI");
 | |
|         let pattern = "^";
 | |
|         const names = [];
 | |
|         for (const part of this.parts) {
 | |
|             if (typeof part === "string") {
 | |
|                 pattern += this.escapeRegExp(part);
 | |
|             }
 | |
|             else {
 | |
|                 const patterns = this.partToRegExp(part);
 | |
|                 for (const { pattern: partPattern, name } of patterns) {
 | |
|                     pattern += partPattern;
 | |
|                     names.push({ name, exploded: part.exploded });
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         pattern += "$";
 | |
|         UriTemplate.validateLength(pattern, MAX_REGEX_LENGTH, "Generated regex pattern");
 | |
|         const regex = new RegExp(pattern);
 | |
|         const match = uri.match(regex);
 | |
|         if (!match)
 | |
|             return null;
 | |
|         const result = {};
 | |
|         for (let i = 0; i < names.length; i++) {
 | |
|             const { name, exploded } = names[i];
 | |
|             const value = match[i + 1];
 | |
|             const cleanName = name.replace("*", "");
 | |
|             if (exploded && value.includes(",")) {
 | |
|                 result[cleanName] = value.split(",");
 | |
|             }
 | |
|             else {
 | |
|                 result[cleanName] = value;
 | |
|             }
 | |
|         }
 | |
|         return result;
 | |
|     }
 | |
| }
 | |
| exports.UriTemplate = UriTemplate;
 | |
| //# sourceMappingURL=uriTemplate.js.map
 |