Neil Patrick's Mansion

    protoscript
    TypeScript icon, indicating that this package has built-in type declarations

    0.0.8 • Public • Published

    ProtoScript

    A Protobuf runtime and code generation tool for JavaScript and TypeScript

    What is this? 🧐

    ProtoScript is a protocol buffers runtime and code generation tool for JavaScript, written in TypeScript.

    ProtoScript consists of two parts:

    1. Runtime. This is nearly identical to google-protobuf, but significantly smaller (9.6KB vs 46KB gzipped) and written in ESM to enable dead-code elimination.

    2. Code generation. 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.

    Highlights 🛠

    1. Idiomatic JavaScript / TypeScript code. None of the Java idioms that protoc --js_out generates such as the List suffix naming for repeated fields, Map suffix for maps, or the various getter and setter methods. ProtoScript generates and consumes plain JavaScript objects over classes. Compare the TypeScript example to the protoc example.

    2. In-editor API documentation. Comments in your .proto files become TSDoc comments in the generated code and will show inline documentation in supported editors.

    3. JSON Serialization/Deserialization. Unlike protoc, ProtoScript's code generation generates JSON serialization and deserialization methods.

    4. Small. ProtoScript's runtime and generated code are built with 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).

    5. Isomorphic. ProtoScript's generated serializers/deserializers can be consumed in the browser or Node.js runtimes.

    6. No additional runtime dependencies.

    Installation 📦

    1. 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.

    2. Add this package to your project: npm install protoscript or yarn add protoscript

    Examples 🚀

    npx

    npx protoscript

    cli

    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

    Buf

    ProtoScript can be used with Buf.

    buf.gen.yaml

    version: v1
    plugins:
      - name: protoc-gen-protoscript
        path: ./node_modules/protoscript/compiler.js
        out: .
        opt:
          - language=typescript
        strategy: all
    

    Working with other tools

    TypeScript

    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.

    Linters

    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:

    1. The permutations of preferences and plugins for these tools quickly explode beyond what is feasible for a single tool to target. There are always new tools that could be added as well.
    2. The code is generated automatically, and not all rules are auto fixable. This means there are cases that would always require manual intervention by the user.
    3. Autogenerated code is readonly, and expected to be correct. Autogenerated code has a much difference maintenance cycle than code written by hand, and should generally be treated as a binary or a dependency. You don't lint your node_modules!

    Configuration 🛠

    ProtoScript aims to be zero config, but can be configured via the cli interface, or when using the npx protoscript command, by creating a .protoscript.json 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:

    /src
      A.proto
      B.proto
    

    Default:

    A.proto would import B.proto as follows:

    import "src/B.proto";

    Setting root to src:

    // .protoscript.json

    {
      "root": "src"
    }

    A.proto would import B.proto as follows:

    import "B.proto";

    TypeScript projects will generally want to set this value to match their rootDir, particularly when using Protocol Buffers Well-Known Types so that the generated well-known type files are under the rootDir.

    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 exclude to ["/bar/"]:

    // .protoscript.json

    {
      "exclude": ["/bar/"]
    }

    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 proto definition.

    If we have the following project structure:

    /src
      A.proto
      B.proto
    

    ProtoScript will generate the following:

    /src
      A.proto
      A.pb.ts
      B.proto
      B.pb.ts
    

    Setting dest to out will generate the following:

    // .protoscript.json

    {
      "dest": "out",
    }
    /src
      A.proto
      B.proto
    /out
      /src
        A.pb.ts
        B.pb.ts
    

    Note that the generated directory structure will mirror the proto paths exactly as is, only nested under the dest directory. If you want to change this, for instance, to omit src from the out directory above, you can set the root.

    Setting root to src (in addition to setting dest to out) will generate the following:

    // .protoscript.json

    {
      "root": "src",
      "dest": "out",
    }
    /src
      A.proto
      B.proto
    /out
      A.pb.ts
      B.pb.ts
    
    string (filepath)
    language Whether to generate JavaScript or TypeScript.

    If omitted, ProtoScript will attempt to autodetect the language by looking for a tsconfig.json in the project root. If found, ProtoScript will generate TypeScript, otherwise JavaScript.

    javascript | typescript
    json JSON serializer options.

    emitFieldsWithDefaultValues - Fields with default values are omitted by default in proto3 JSON. Setting this to true will serialize fields with their default values.

    useProtoFieldName - Field names are converted to lowerCamelCase by default in proto3 JSON. Setting this to true will use the proto field name as the JSON key when serializing JSON. Either way, Proto3 JSON parsers are required to accept both the converted lowerCamelCase name and the proto field name.

    See https://developers.google.com/protocol-buffers/docs/proto3#json for more context.

    { emitFieldsWithDefaultValues?: boolean, useProtoFieldName?: boolean }
    typecript TypeScript options.

    emitDeclarationOnly - Only emit TypeScript type definitions.

    { emitDeclarationOnly?: boolean }

    JSON

    ProtoScript's JSON serialization/deserialization implements the proto3 specification. This is nearly complete, but still in progress.

    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 accept the json_name and the origin proto field name, but not lowerCamelCase.

    Contributing 👫

    PR's and issues welcomed! For more guidance check out CONTRIBUTING.md

    Licensing 📃

    See the project's MIT License.

    Install

    npm i protoscript

    DownloadsWeekly Downloads

    445

    Version

    0.0.8

    License

    MIT

    Unpacked Size

    343 kB

    Total Files

    41

    Last publish

    Collaborators

    • tatethurston