Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
protoscript
Advanced tools
A Protobuf runtime and code generation tool for JavaScript and TypeScript
A Protobuf runtime and code generation tool for JavaScript and TypeScript
ProtoScript is a protocol buffers runtime and code generation tool for JavaScript and TypeScript.
ProtoScript consists of two parts:
A runtime. The interface is nearly identical to google-protobuf, but under the hood it is significantly smaller (9.6KB vs 46KB gzipped) and written in ESM to enable dead-code elimination. If you only use the generated JSON serializers, the protobuf runtime will be eliminated from the final build, resulting in an even smaller runtime (less than 1 KB).
A code generator. This is a replacement of protoc
's JavaScript generation that generates idiomatic JavaScript code, JSON serializers/deserializers, and includes TSDoc comments.
If you're looking for an RPC framework, you may be interested in TwirpScript, which uses ProtoScript under the hood to implement Twirp.
protobuf
or JSON
as the wire format.Idiomatic JavaScript and TypeScript code. ProtoScript generates and consumes plain JavaScript objects over classes. It does not generate any of Java idioms from protoc --js_out
such as the List
suffix naming for repeated fields, Map
suffix for maps, or the various getter and setter methods. Compare the generated code from ProtoScript's TypeScript example to the protoc example.
In-editor API documentation. Comments in your .proto
files become TSDoc comments in the generated code and will show inline documentation in supported editors.
JSON Serialization/Deserialization. Unlike protoc
, ProtoScript's code generation also generates JSON serialization and deserialization methods.
Small. ProtoScript's runtime and generated code are built to support tree shaking to minimize bundle sizes. This results in a significantly smaller bundle size than google-protobuf. ProtoScript's runtime is 67KB (9.6KB gzipped) compared to google-protobuf's 231KB (46KB gzipped). If you only use the generated JSON serializers, the protobuf runtime will be eliminated from the final build, resulting in a substantially smaller runtime (less than 1 KB).
Isomorphic. ProtoScript's generated serializers/deserializers can be consumed in the browser or Node.js runtimes.
No additional runtime dependencies.
If you have the following protobuf defined in user.proto
:
syntax = "proto3";
message User {
string first_name = 1;
string last_name = 2;
bool active = 3;
User manager = 4;
repeated string locations = 5;
map<string, string> projects = 6;
}
Using the User
generated by ProtoScript will look like this:
import { User, UserJSON } from "./user.pb.js";
const user = {
firstName: "Harry",
lastName: "Potter",
active: true,
locations: ["Hogwarts"],
projects: { DA: "Dumbledore's Army },
manager: {
firstName: "Albus",
lastName: "Dumbledore",
}
}
// protocol buffers
const bytes = User.encode(user);
console.log(bytes); // Uint8Array
const userFromBytes = User.decode(bytes);
console.log(userFromBytes); // our user above
// json
const json = UserJSON.encode(user)
console.log(json); // json string
const userFromJSON = UserJSON.decode(json);
console.log(userFromJSON); // our user above
// ProtoScript generates and consumes plain JavaScript objects (POJOs) over classes. If you want to generate a full message
// with default fields, you can use the #initialize method on the generated message class:
const user = User.initialize();
console.log(user);
// the generated object is just a POJO. You can encode any POJO as protobuf or json as long as it conforms to a subset of the message interface defined in your .proto:
console.log(User.encode(user))
console.log(UserJSON.encode(user))
Install the protocol buffers compiler:
MacOS:
brew install protobuf
Linux:
apt install -y protobuf-compiler
Windows:
choco install protoc
Or install from a precompiled binary.
Add this package to your project:
npm install protoscript
or yarn add protoscript
npx protoscript
protoc \
--plugin=protoc-gen-protoscript=./node_modules/protoscript/compiler.js
--protoscript_out=. \
--protoscript_opt=language=typescript \
Note: Windows users replace ./node_modules/protoscript/compiler.js
above with ./node_modules/protoscript/compiler.cmd
ProtoScript can be used with Buf.
buf.gen.yaml
version: v1
plugins:
- name: protoc-gen-protoscript
path: ./node_modules/protoscript/dist/compiler.js
out: .
opt:
- language=typescript
strategy: all
As a design goal, ProtoScript should always work with the strictest TypeScript compiler settings. If your generated ProtoScript files are failing type checking, please open an issue.
ProtoScript does not make any guarantees for tools like linters and formatters such as prettier or eslint. It generally does not make sense to run these tools against code generation artifacts, like the .pb.ts
or .pb.js
files generated by ProtoScript. This is because:
ProtoScript aims to be zero config, but can be configured via the cli interface, or when using the npx protoscript
command, by creating a proto.config.mjs
(or .js
or .cjs
) file in your project root.
Name | Description | Type |
---|---|---|
root |
The root directory. `.proto` files will be searched under this directory, and `proto` import paths will be resolved relative to this directory. ProtoScript will recursively search all subdirectories for `.proto` files.
Defaults to the project root. Example: If we have the following project structure:
Default: A.proto would
Setting // proto.config.mjs
A.proto would
TypeScript projects will generally want to set this value to match their | string (filepath) |
exclude |
An array of patterns that should be skipped when searching for `.proto` files.
Example: If we have the following project structure: /src /foo A.proto /bar B.proto Setting // proto.config.mjs
Will only process A.proto (B.proto) will be excluded from ProtoScript's code generation. | string[] (RegExp pattern) |
dest |
The destination folder for generated files.
Defaults to colocating generated files with the corresponding If we have the following project structure:
ProtoScript will generate the following:
Setting // proto.config.mjs
Note that the generated directory structure will mirror the Setting // proto.config.mjs
| string (filepath) |
language |
Whether to generate JavaScript or TypeScript.
If omitted, ProtoScript will attempt to autodetect the language by looking for a | javascript | typescript |
json |
JSON serializer options.
See https://developers.google.com/protocol-buffers/docs/proto3#json for more context. | { emitFieldsWithDefaultValues?: boolean, useProtoFieldName?: boolean } |
typecript |
TypeScript options.
| { emitDeclarationOnly?: boolean } |
ProtoScript's JSON serialization/deserialization implements the proto3 specification. If you find a discrepancy, please open an issue.
ProtoScript will serialize JSON keys as lowerCamelCase
versions of the proto field. Per the proto3 spec, the runtime will accept both lowerCamelCase
and the original proto field name when deserializing. You can provide the json_name
field option to specify an alternate key name. When doing so, the runtime will encode JSON messages using the the json_name
as the key, and will decode JSON messages using the json_name
if present, otherwise falling back to the lowerCamelCase
name and finally to the original proto field name.
PR's and issues welcomed! For more guidance check out CONTRIBUTING.md
See the project's MIT License.
FAQs
A Protobuf runtime and code generation tool for JavaScript and TypeScript
The npm package protoscript receives a total of 6,420 weekly downloads. As such, protoscript popularity was classified as popular.
We found that protoscript demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.