Skip to content

Instantly share code, notes, and snippets.

@imyelo
Last active June 26, 2019 13:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save imyelo/cbd170de036d48225632c81589745195 to your computer and use it in GitHub Desktop.
Save imyelo/cbd170de036d48225632c81589745195 to your computer and use it in GitHub Desktop.
Compile V2Ray Protobuf to JavaScript
// Inspired by https://unpkg.com/@shynome/v2ray@4.18.6/package.json
const path = require('path')
const { src, dest } = require('gulp')
const through = require('through2')
const Vinyl = require('vinyl')
const pbjs = require('protobufjs/cli/pbjs')
const pbts = require('protobufjs/cli/pbts')
const GOPATH = process.env.GOPATH
const V2RAY_CORE_PATH = path.join(GOPATH, 'src')
const DIST_DIR = path.resolve(__dirname, '../lib/protobuf')
const callCli = (cli) => async (files, options) => {
return new Promise((resolve, reject) => {
let args = []
for (let key in options) {
args.push(`--${key}`)
args.push(options[key])
}
args = [...args, ...files]
cli.main(args, (error, output) => {
if (error) {
return reject(error)
}
resolve(output)
})
})
}
const newFile = (source, newFileName, newFileContents) => {
return new Vinyl({
base: source.base,
path: path.join(source.base, newFileName),
contents: Buffer.from(newFileContents, 'utf8'),
})
}
const compileJS = (filename = 'protobuf.js', options = {
target: 'static-module',
wrap: 'commonjs',
}) => {
let sources = []
return through.obj((file, encoding, callback) => {
if (file.isNull()) {
return callback()
}
if (file.isStream()) {
return callback(new Error('Streaming not supported'))
}
sources.push(file)
callback()
}, (callback) => {
callCli(pbjs)(sources.map(({ path }) => path), options).then((contents) =>
callback(null, newFile(sources[0], filename, contents))
)
})
}
const compileTS = (filename = 'protobuf.ts', options = {}) => {
return through.obj((source, encoding, callback) => {
if (source.isNull()) {
return callback()
}
if (source.isStream()) {
return callback(new Error('Streaming not supported'))
}
callCli(pbts)([source.path], options).then((contents) =>
callback(null, newFile(source, filename, contents))
)
})
}
;(() => {
src('github.com/v2ray/v2ray-core/**/*.proto', {
cwd: V2RAY_CORE_PATH,
})
.pipe(compileJS('v2ray.js'))
.pipe(dest(DIST_DIR))
.pipe(compileTS('v2ray.d.ts'))
.pipe(dest(DIST_DIR))
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment