Skip to content

Commit b54b7db

Browse files
committed
add standlone protoc-gen-js npm package (@protocolbuffers/protoc-gen-js) for convenience
1 parent 5c70f21 commit b54b7db

File tree

9 files changed

+218
-3
lines changed

9 files changed

+218
-3
lines changed

MODULE.bazel.lock

Lines changed: 5 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

protoc_plugin/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules/
2+
bin/protoc-gen-js*
3+
protocolbuffers-protoc-gen-js-*.tgz

protoc_plugin/LICENSE.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
BSD 3-Clause License
2+
3+
Copyright (c) 2025, Google Inc.
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are met:
8+
9+
1. Redistributions of source code must retain the above copyright notice, this
10+
list of conditions and the following disclaimer.
11+
12+
2. Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
16+
3. Neither the name of the copyright holder nor the names of its
17+
contributors may be used to endorse or promote products derived from
18+
this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

protoc_plugin/bin/.gitkeep

Whitespace-only changes.

protoc_plugin/cli.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env node
2+
3+
const child_process = require("child_process");
4+
const PLUGIN = require("./");
5+
6+
child_process
7+
.spawn(PLUGIN, process.argv.slice(2), { stdio: "inherit" })
8+
.on("exit", (code) => process.exit(code));
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
const fs = require('fs');
2+
const os = require('os');
3+
const path = require('path');
4+
const AdmZip = require('adm-zip');
5+
6+
const VERSION = '4.0.0';
7+
const BIN_DIR = path.join(__dirname, 'bin');
8+
9+
function getZipFilename(currentSystem) {
10+
return `protobuf-javascript-${VERSION}-${currentSystem}.zip`;
11+
}
12+
13+
function getDownloadUrl(currentSystem) {
14+
return `https://github.com/protocolbuffers/protobuf-javascript/releases/download/v${VERSION}/${getZipFilename(currentSystem)}`;
15+
}
16+
17+
function unzip(zipFile, destDir, binaryName) {
18+
return new Promise((resolve, reject) => {
19+
const zip = new AdmZip(zipFile);
20+
21+
// Paths may be inconsistent between platforms. On MacOS and Windows,
22+
// the path seems to include the archive name while it doesn't on linux.
23+
// There's only one thing named protoc-gen-js(.exe), so just look for
24+
// that instead of trying to get the exact "entryName".
25+
const entries = zip.getEntries();
26+
let found = false;
27+
for (const entry of entries) {
28+
if (entry.name === binaryName) {
29+
zip.extractEntryTo(entry, destDir, false, true);
30+
found = true;
31+
break;
32+
}
33+
}
34+
35+
if (found) {
36+
resolve();
37+
} else {
38+
reject(new Error(`Binary ${binaryName} not found in zip file ${zipFile}`));
39+
}
40+
});
41+
}
42+
43+
function getCurrentSystem() {
44+
const platform = os.platform();
45+
const arch = os.arch();
46+
47+
if (platform === 'darwin') {
48+
if (arch === 'x64') {
49+
return 'osx-x86_64';
50+
}
51+
if (arch === 'arm64') {
52+
return 'osx-aarch_64';
53+
}
54+
} else if (platform === 'win32' && arch === 'x64') {
55+
return 'win64';
56+
} else if (platform === 'linux') {
57+
if (arch === 'x64') {
58+
return 'linux-x86_64';
59+
}
60+
if (arch === 'arm64') {
61+
return 'linux-aarch_64';
62+
}
63+
if (arch === 's390x') {
64+
return 'linux-s390_64';
65+
}
66+
}
67+
68+
console.error(`Unsupported platform: ${platform} ${arch}`);
69+
process.exit(1);
70+
}
71+
72+
async function main() {
73+
try {
74+
await fs.promises.mkdir(BIN_DIR, { recursive: true });
75+
const currentSystem = getCurrentSystem();
76+
77+
78+
const downloadUrl = getDownloadUrl(currentSystem);
79+
const zipFile = path.join(__dirname, getZipFilename(currentSystem));
80+
const isWindows = os.platform() === 'win32';
81+
const binaryName = isWindows ? 'protoc-gen-js.exe' : 'protoc-gen-js';
82+
const binaryPath = path.join(BIN_DIR, binaryName);
83+
84+
console.log(`Downloading ${downloadUrl}`);
85+
const response = await fetch(downloadUrl);
86+
if (!response.ok) {
87+
throw new Error(
88+
`Failed to download: ${response.status} ${response.statusText}`
89+
);
90+
}
91+
const buffer = await response.arrayBuffer();
92+
await fs.promises.writeFile(zipFile, Buffer.from(buffer));
93+
94+
console.log('Unzipping...');
95+
await unzip(zipFile, BIN_DIR, binaryName);
96+
97+
await fs.promises.unlink(zipFile);
98+
99+
console.log(`Making ${binaryPath} executable...`);
100+
if (!isWindows) {
101+
await fs.promises.chmod(binaryPath, 0o755);
102+
}
103+
104+
console.log('Done!');
105+
} catch (err) {
106+
console.error(`Failed to install protoc-gen-js: ${err.message}`);
107+
process.exit(1);
108+
}
109+
}
110+
111+
main();

protoc_plugin/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const path = require("path");
2+
const BIN_DIR = path.resolve(__dirname, "bin");
3+
const EXT = process.platform === "win32" ? ".exe" : "";
4+
5+
module.exports = path.resolve(BIN_DIR, "protoc-gen-js" + EXT);

protoc_plugin/package-lock.json

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

protoc_plugin/package.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "@protocolbuffers/protoc-gen-js",
3+
"version": "4.0.0",
4+
"description": "Standalone distribution of the protoc-gen-js plugin for Protocol Buffers",
5+
"author": "Google Protocol Buffers Team",
6+
"license": "BSD-3-Clause",
7+
"repository": {
8+
"type": "git",
9+
"url": "https://github.com/protocolbuffers/protobuf-javascript.git"
10+
},
11+
"type": "commonjs",
12+
"main": "index.js",
13+
"bin": {
14+
"protoc-gen-js": "cli.js"
15+
},
16+
"scripts": {
17+
"postinstall": "node download-protoc-gen-js.js"
18+
},
19+
"dependencies": {
20+
"adm-zip": "^0.5.16"
21+
},
22+
"engines": {
23+
"node": ">=18.0.0"
24+
}
25+
}

0 commit comments

Comments
 (0)