proto-shared-utils.mjs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import * as fs from "fs/promises"
  2. import * as path from "path"
  3. /**
  4. * Parse proto files to extract service definitions
  5. * @param {string[]} protoFilePaths - Array of proto file paths
  6. * @param {string} protoDir - Base proto directory
  7. * @returns {Promise<Object>} Services object with service definitions
  8. */
  9. export async function parseProtoForServices(protoFilePaths, protoDir) {
  10. const services = {}
  11. for (const protoFilePath of protoFilePaths) {
  12. const content = await fs.readFile(path.join(protoDir, protoFilePath), "utf8")
  13. const serviceMatches = content.matchAll(/service\s+(\w+Service)\s*\{([\s\S]*?)\}/g)
  14. // Determine proto package from file path
  15. const protoPackage = protoFilePath.startsWith("host/") ? "host" : "cline"
  16. for (const serviceMatch of serviceMatches) {
  17. const serviceName = serviceMatch[1]
  18. const serviceKey = serviceName.replace("Service", "").toLowerCase()
  19. const serviceBody = serviceMatch[2]
  20. const methodMatches = serviceBody.matchAll(
  21. /rpc\s+(\w+)\s*\((stream\s)?([\w.]+)\)\s*returns\s*\((stream\s)?([\w.]+)\)/g,
  22. )
  23. const methods = []
  24. for (const methodMatch of methodMatches) {
  25. methods.push({
  26. name: methodMatch[1],
  27. requestType: methodMatch[3],
  28. responseType: methodMatch[5],
  29. isRequestStreaming: !!methodMatch[2],
  30. isResponseStreaming: !!methodMatch[4],
  31. })
  32. }
  33. services[serviceKey] = { name: serviceName, methods, protoPackage }
  34. }
  35. }
  36. return services
  37. }
  38. /**
  39. * Create service name map from parsed services
  40. * @param {Object} services - Services object from parseProtoForServices
  41. * @returns {Object} Service name map
  42. */
  43. export function createServiceNameMap(services) {
  44. const serviceNameMap = {}
  45. for (const [serviceKey, serviceDef] of Object.entries(services)) {
  46. const packagePrefix = serviceDef.protoPackage === "host" ? "host" : "cline"
  47. serviceNameMap[serviceKey] = `${packagePrefix}.${serviceDef.name}`
  48. }
  49. return serviceNameMap
  50. }
  51. /**
  52. * Log message only if verbose flag is set
  53. * @param {string} message - Message to log
  54. */
  55. export function logVerbose(message) {
  56. if (process.argv.includes("-v") || process.argv.includes("--verbose")) {
  57. console.log(message)
  58. }
  59. }