mirror of
https://github.com/cline/cline.git
synced 2026-10-31 10:58:32 +08:00
119 lines
4.2 KiB
JavaScript
Executable File
119 lines
4.2 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
import * as fs from "fs"
|
|
import path, { dirname } from "path"
|
|
import { fileURLToPath } from "url"
|
|
import { loadServicesFromProtoDescriptor, getFqn } from "./proto-utils.mjs"
|
|
|
|
const STANDALONE_SERVER_SETUP_FILE = path.resolve("src/generated/standalone/server-setup.ts")
|
|
const WEBVIEW_CLIENTS_FILE = path.resolve("webview-ui/src/services/grpc-client.ts")
|
|
|
|
const SCRIPT_NAME = path.relative(process.cwd(), fileURLToPath(import.meta.url))
|
|
|
|
async function main() {
|
|
const { protobusServices } = await loadServicesFromProtoDescriptor()
|
|
await generateWebviewProtobusClients(protobusServices)
|
|
await generateStandaloneProtobusServiceSetup(protobusServices)
|
|
|
|
console.log(`Generated ProtoBus files at:`)
|
|
console.log(`- ${WEBVIEW_CLIENTS_FILE}`)
|
|
console.log(`- ${STANDALONE_SERVER_SETUP_FILE}`)
|
|
}
|
|
|
|
async function generateWebviewProtobusClients(protobusServices) {
|
|
const clients = []
|
|
|
|
for (const [serviceName, def] of Object.entries(protobusServices)) {
|
|
const rpcs = []
|
|
for (const [rpcName, rpc] of Object.entries(def.service)) {
|
|
const requestType = getFqn(rpc.requestType.type.name)
|
|
const responseType = getFqn(rpc.responseType.type.name)
|
|
|
|
if (rpc.requestStream) {
|
|
throw new Error("Request streaming is not supported")
|
|
}
|
|
if (!rpc.responseStream) {
|
|
rpcs.push(` static async ${rpcName}(request: ${requestType}): Promise<${responseType}> {
|
|
return this.makeRequest("${rpcName}", request, ${requestType}.toJSON, ${responseType}.fromJSON)
|
|
}`)
|
|
} else {
|
|
rpcs.push(` static ${rpcName}(request: ${requestType}, callbacks: Callbacks<${responseType}>): ()=>void {
|
|
return this.makeStreamingRequest("${rpcName}", request, callbacks, ${requestType}.toJSON, ${responseType}.fromJSON)
|
|
}`)
|
|
}
|
|
}
|
|
clients.push(`export class ${serviceName}Client extends ProtoBusClient {
|
|
static override serviceName: string = "${serviceName}"
|
|
${rpcs.join("\n")}
|
|
}`)
|
|
}
|
|
|
|
// Create output file
|
|
let output = `// GENERATED CODE -- DO NOT EDIT!
|
|
// Generated by ${SCRIPT_NAME}
|
|
import * as proto from "@shared/proto/index"
|
|
import { ProtoBusClient, Callbacks } from "./grpc-client-base"
|
|
|
|
${clients.join("\n")}
|
|
`
|
|
// Write output file
|
|
fs.mkdirSync(dirname(WEBVIEW_CLIENTS_FILE), { recursive: true })
|
|
fs.writeFileSync(WEBVIEW_CLIENTS_FILE, output)
|
|
}
|
|
|
|
/**
|
|
* Generate imports and function to add all the handlers to the server for all services defined in the proto files.
|
|
*/
|
|
async function generateStandaloneProtobusServiceSetup(protobusServices) {
|
|
const imports = []
|
|
const handlerSetup = []
|
|
|
|
for (const [name, def] of Object.entries(protobusServices)) {
|
|
const domain = name.replace(/Service$/, "")
|
|
const dir = domain.charAt(0).toLowerCase() + domain.slice(1)
|
|
imports.push(`// ${domain} Service`)
|
|
handlerSetup.push(` // ${domain} Service`)
|
|
handlerSetup.push(` server.addService(cline.${name}Service, {`)
|
|
for (const [rpcName, rpc] of Object.entries(def.service)) {
|
|
imports.push(`import { ${rpcName} } from "@core/controller/${dir}/${rpcName}"`)
|
|
const requestType = "cline." + rpc.requestType.type.name
|
|
if (rpc.requestStream) {
|
|
throw new Error("Request streaming is not supported")
|
|
}
|
|
if (rpc.responseStream) {
|
|
handlerSetup.push(` ${rpcName}: wrapStreamingResponse<${requestType},void>(${rpcName}, controller),`)
|
|
} else {
|
|
const responseType = "cline." + rpc.responseType.type.name
|
|
handlerSetup.push(` ${rpcName}: wrapper<${requestType},${responseType}>(${rpcName}, controller),`)
|
|
}
|
|
}
|
|
handlerSetup.push(` });`)
|
|
imports.push("")
|
|
handlerSetup.push("")
|
|
}
|
|
|
|
// Create output file
|
|
let output = `// GENERATED CODE -- DO NOT EDIT!
|
|
// Generated by ${SCRIPT_NAME}
|
|
import * as grpc from "@grpc/grpc-js"
|
|
import { cline } from "@generated/grpc-js"
|
|
import { Controller } from "@core/controller"
|
|
import { GrpcHandlerWrapper, GrpcStreamingResponseHandlerWrapper } from "@hosts/external/grpc-types"
|
|
|
|
${imports.join("\n")}
|
|
export function addProtobusServices(
|
|
server: grpc.Server,
|
|
controller: Controller,
|
|
wrapper: GrpcHandlerWrapper,
|
|
wrapStreamingResponse: GrpcStreamingResponseHandlerWrapper,
|
|
): void {
|
|
${handlerSetup.join("\n")}
|
|
}
|
|
`
|
|
// Write output file
|
|
fs.mkdirSync(dirname(STANDALONE_SERVER_SETUP_FILE), { recursive: true })
|
|
fs.writeFileSync(STANDALONE_SERVER_SETUP_FILE, output)
|
|
}
|
|
|
|
main()
|