const { spawnSync } = require("child_process"); const { existsSync, mkdirSync } = require("fs"); const { resolve } = require("path"); const protocVersion = "3.5.1"; const examplesGeneratedPath = resolve(__dirname, "examples", "generated"); const examplesGeneratedGrpcWebPath = resolve(__dirname, "examples", "generated-grpc-web"); const examplesGeneratedGrpcNodePath = resolve(__dirname, "examples", "generated-grpc-node"); const examplesGeneratedGrpcJsNodePath = resolve(__dirname, "examples", "generated-grpc-js-node"); const binSuffix = process.platform === "win32" ? ".cmd" : ""; const nodeModulesBin = resolve(__dirname, "node_modules", ".bin"); const downloadPath = resolve(nodeModulesBin, "download") + binSuffix; const protocRoot = resolve(__dirname, "protoc"); const protocPath = resolve(protocRoot, "bin", "protoc"); const protocPluginPath = resolve(__dirname, "bin", "protoc-gen-ts") + binSuffix; const rimrafPath = resolve(nodeModulesBin, "rimraf") + binSuffix; const supportedPlatforms = { darwin: { downloadSuffix: "osx-x86_64", name: "Mac" }, linux: { downloadSuffix: "linux-x86_64", name: "Linux" }, win32: { downloadSuffix: "win32", name: "Windows" } }; const platform = supportedPlatforms[process.platform]; const platformName = platform ? platform.name : `UNKNOWN:${process.platform}`; console.log("You appear to be running on", platformName); requireBuild(); const glob = require("glob"); requireProtoc(); requireDir(examplesGeneratedPath); requireDir(examplesGeneratedGrpcWebPath); requireDir(examplesGeneratedGrpcNodePath); requireDir(examplesGeneratedGrpcJsNodePath); // Generate no services run(protocPath, `--proto_path=${__dirname}`, `--plugin=protoc-gen-ts=${protocPluginPath}`, `--js_out=import_style=commonjs,binary:${examplesGeneratedPath}`, `--ts_out=${examplesGeneratedPath}`, ...glob.sync(resolve(__dirname, "proto", "**/*.proto")) ); // Generate grpc-web services run(protocPath, `--proto_path=${__dirname}`, `--plugin=protoc-gen-ts=${protocPluginPath}`, `--js_out=import_style=commonjs,binary:${examplesGeneratedGrpcWebPath}`, `--ts_out=service=grpc-web:${examplesGeneratedGrpcWebPath}`, ...glob.sync(resolve(__dirname, "proto", "**/*.proto")) ); // Generate grpc-node services run(protocPath, `--proto_path=${__dirname}`, `--plugin=protoc-gen-ts=${protocPluginPath}`, `--plugin=protoc-gen-grpc=node_modules/.bin/grpc_tools_node_protoc_plugin`, `--js_out=import_style=commonjs,binary:${examplesGeneratedGrpcNodePath}`, `--ts_out=service=grpc-node:${examplesGeneratedGrpcNodePath}`, `--grpc_out=${examplesGeneratedGrpcNodePath}`, ...glob.sync(resolve(__dirname, "proto", "**/*.proto")) ); // Generate grpc-node services using grpc-js mode run(protocPath, `--proto_path=${__dirname}`, `--plugin=protoc-gen-ts=${protocPluginPath}`, `--plugin=protoc-gen-grpc=node_modules/.bin/grpc_tools_node_protoc_plugin`, `--js_out=import_style=commonjs,binary:${examplesGeneratedGrpcJsNodePath}`, `--ts_out=service=grpc-node,mode=grpc-js:${examplesGeneratedGrpcJsNodePath}`, `--grpc_out=grpc_js:${examplesGeneratedGrpcJsNodePath}`, ...glob.sync(resolve(__dirname, "proto", "**/*.proto")) ); run(rimrafPath, protocRoot); function requireBuild() { console.log("Ensuring we have NPM packages installed..."); run("npm", "install"); console.log("Compiling ts-protoc-gen..."); run("npm", "run", "build"); } function requireProtoc() { if (existsSync(protocPath)) { return; } if (!platform) { throw new Error( "Cannot download protoc. " + platformName + " is not currently supported by ts-protoc-gen" ); } console.log(`Downloading protoc v${protocVersion} for ${platform.name}`); const protocUrl = `https://github.com/google/protobuf/releases/download/v${protocVersion}/protoc-${protocVersion}-${platform.downloadSuffix}.zip`; run(downloadPath, "--extract", "--out", protocRoot, protocUrl); } function requireDir(path) { if (existsSync(path)) { run(rimrafPath, path); } mkdirSync(path); } function run(executablePath, ...args) { const result = spawnSync(executablePath, args, { shell: true, stdio: "inherit" }); if (result.status !== 0) { throw new Error(`Exited ${executablePath} with status ${result.status}`); } }