UNPKG

gitvan

Version:

Autonomic Git-native development automation platform with AI-powered workflows

100 lines (84 loc) 2.48 kB
/** * GitVan Unrouting - Simple File-Based Job Router * 80/20 implementation: Route file changes to jobs using unrouting patterns */ import { parsePath, toRegExp } from "unrouting"; import { useGitVan } from "../core/context.mjs"; export function useUnrouting() { const ctx = useGitVan(); const cwd = ctx?.cwd || process.cwd(); return { /** * Parse file path and extract segments */ parsePath(filePath) { return parsePath(filePath); }, /** * Match file against pattern and extract parameters */ matchPattern(pattern, filePath) { const regex = toRegExp(pattern); // Add leading slash if not present (unrouting expects paths to start with /) const normalizedPath = filePath.startsWith("/") ? filePath : `/${filePath}`; const match = normalizedPath.match(regex); if (!match) return null; return { params: match.groups || {}, filePath, pattern, }; }, /** * Route file changes to jobs */ routeFiles(changedFiles, routes) { const jobQueue = []; for (const filePath of changedFiles) { // First-match-wins: stop at first matching route for (const route of routes) { const match = this.matchPattern(route.pattern, filePath); if (match) { // Extract parameters and bind to job payload const payload = this.bindPayload( route.job.with || {}, match.params, filePath ); jobQueue.push({ name: route.job.name, payload, filePath, routeId: route.id, }); // First-match-wins: break after first match break; } } } return jobQueue; }, /** * Bind parameters to job payload */ bindPayload(template, params, filePath) { const payload = {}; for (const [key, value] of Object.entries(template)) { if (typeof value === "string") { // Replace parameter placeholders let boundValue = value .replace(/:__file/g, filePath) .replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, (match, paramName) => { return params[paramName] || match; }); payload[key] = boundValue; } else { payload[key] = value; } } return payload; }, }; }