UNPKG

@bufbuild/protoplugin

Version:

Helps to create your own Protocol Buffers code generators.

85 lines (84 loc) 2.79 kB
// Copyright 2021-2025 Buf Technologies, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import { isPluginOptionError, reasonToString } from "./error.js"; import { fromBinary, toBinary } from "@bufbuild/protobuf"; import { CodeGeneratorRequestSchema, CodeGeneratorResponseSchema, } from "@bufbuild/protobuf/wkt"; /** * Run a plugin with Node.js. * * ``` * #!/usr/bin/env node * const {runNodeJs} = require("@bufbuild/protoplugin"); * const {myPlugin} = require("./protoc-gen-x-plugin.js"); * runNodeJs(myPlugin); * ``` */ export function runNodeJs(plugin) { const args = process.argv.slice(2); if ((args.length === 1 && args[0] === "-v") || args[0] === "--version") { process.stdout.write(`${plugin.name} ${plugin.version}\n`); process.exit(0); return; } if (args.length !== 0) { process.stderr.write(`${plugin.name} accepts a google.protobuf.compiler.CodeGeneratorRequest on stdin and writes a CodeGeneratorResponse to stdout\n`); process.exit(1); return; } readBytes(process.stdin) .then((data) => { const req = fromBinary(CodeGeneratorRequestSchema, data); const res = plugin.run(req); return writeBytes(process.stdout, toBinary(CodeGeneratorResponseSchema, res)); }) .then(() => process.exit(0)) .catch((reason) => { const message = isPluginOptionError(reason) ? reason.message : reasonToString(reason); process.stderr.write(`${plugin.name}: ${message}\n`); process.exit(1); return; }); } /** * Read a stream to the end. */ function readBytes(stream) { return new Promise((resolve, reject) => { const chunks = []; stream.on("data", (chunk) => chunks.push(chunk)); stream.on("end", () => { resolve(Buffer.concat(chunks)); }); stream.on("error", (err) => { reject(err); }); }); } /** * Write a chunk of bytes to a stream. */ function writeBytes(stream, data) { return new Promise((resolve, reject) => { stream.write(data, (err) => { if (err) { reject(err); } else { resolve(); } }); }); }