Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

ts-proto

stephenh1.3mISC2.6.1TypeScript support: included

npm build

readme

npm build

ts-proto

ts-proto transforms your .proto files into strongly-typed, idiomatic TypeScript files!

ts-proto 2.x Release Notes

The 2.x release of ts-proto migrated the low-level Protobuf serializing that its encode and decode method use from the venerable, but aging & stagnant, protobufjs package to @bufbuild/protobuf.

If you only used the encode and decode methods, this should largely be a non-breaking change.

However, if you used any code that used the old protobufjs Writer or Reader classes, you'll need to update your code to use the new @bufbuild/protobuf classes:

import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";

If migrating to @bufbuild/protobuf is a blocker for you, you can pin your ts-proto version to 1.x.

Disclaimer & apology: I had intended to release ts-proto 2.x as an alpha release, but didn't get the semantic-release config correct, and so ts-proto 2.x was published as a major release without a proper alpha/beta cycle.

If you could file reports (or better PRs!) for any issues you come across while the release is still fresh, that would be greatly appreciated.

Any tips or tricks for others on the migration would also be appreciated!

Table of contents

Overview

ts-proto generates TypeScript types from protobuf schemas.

I.e. given a person.proto schema like:

message Person {
  string name = 1;
}

ts-proto will generate a person.ts file like:

interface Person {
  name: string
}

const Person = {
  encode(person): Writer { ... }
  decode(reader): Person { ... }
  toJSON(person): unknown { ... }
  fromJSON(data): Person { ... }
}

It also knows about services and will generate types for them as well, i.e.:

export interface PingService {
  ping(request: PingRequest): Promise<PingResponse>;
}

It will also generate client implementations of PingService; currently Twirp, grpc-web, grpc-js and nestjs are supported.

QuickStart

  • npm install ts-proto
  • protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto --ts_proto_out=. ./simple.proto
    • (Note that the output parameter name, ts_proto_out, is named based on the suffix of the plugin's name, i.e. "ts_proto" suffix in the --plugin=./node_modules/.bin/protoc-gen-ts_proto parameter becomes the _out prefix, per protoc's CLI conventions.)
    • On Windows, use protoc --plugin=protoc-gen-ts_proto=".\\node_modules\\.bin\\protoc-gen-ts_proto.cmd" --ts_proto_out=. ./simple.proto (see #93)
    • Ensure you're using a modern protoc (see installation instructions for your platform, i.e. protoc v3.0.0 doesn't support the _opt flag

This will generate *.ts source files for the given *.proto types.

If you want to package these source files into an npm package to distribute to clients, just run tsc on them as usual to generate the .js/.d.ts files, and deploy the output as a regular npm package.

Buf

If you're using Buf, pass strategy: all in your buf.gen.yaml file (docs).

version: v1
plugins:
  - name: ts
    out: ../gen/ts
    strategy: all
    path: ../node_modules/ts-proto/protoc-gen-ts_proto

To prevent buf push from reading irrelevant .proto files, configure buf.yaml like so:

build:
  excludes: [node_modules]

You can also use the official plugin published to the Buf Registry.

version: v1
plugins:
  - plugin: buf.build/community/stephenh-ts-proto
    out: ../gen/ts
    opt:
      - outputServices=...
      - useExactTypes=...

ESM

If you're using a modern TS setup with either esModuleInterop or running in an ESM environment, you'll need to pass ts_proto_opts of:

  • esModuleInterop=true if using esModuleInterop in your tsconfig.json, and
  • importSuffix=.js if executing the generated ts-proto code in an ESM environment

Goals

In terms of the code that ts-proto generates, the general goals are:

  • Idiomatic TypeScript/ES6 types
    • ts-proto is a clean break from either the built-in Google/Java-esque JS code of protoc or the "make .d.ts files the *.js comments" approach of protobufjs
    • (Technically the protobufjs/minimal package is used for actually reading/writing bytes.)
  • TypeScript-first output
  • Interfaces over classes
    • As much as possible, types are just interfaces, so you can work with messages just like regular hashes/data structures.
  • Only supports codegen *.proto-to-*.ts workflow, currently no runtime reflection/loading of dynamic .proto files

Non-Goals

Note that ts-proto is not an out-of-the-box RPC framework; instead it's more of a swiss-army knife (as witnessed by its many config options), that lets you build exactly the RPC framework you'd like on top of it (i.e. that best integrates with your company's protobuf ecosystem; for better or worse, protobuf RPC is still a somewhat fragmented ecosystem).

If you'd like an out-of-the-box RPC framework built on top of ts-proto, there are a few examples:

(Note for potential contributors, if you develop other frameworks/mini-frameworks, or even blog posts/tutorials, on using ts-proto, we're happy to link to them.)

We also don't support clients for google.api.http-based Google Cloud APIs, see #948 if you'd like to submit a PR.

Example Types

The generated types are "just data", i.e.:

export interface Simple {
  name: string;
  age: number;
  createdAt: Date | undefined;
  child: Child | undefined;
  state: StateEnum;
  grandChildren: Child[];
  coins: number[];
}

Along with encode/decode factory methods:

export const Simple = {
  create(baseObject?: DeepPartial<Simple>): Simple {
    ...
  },

  encode(message: Simple, writer: Writer = Writer.create()): Writer {
    ...
  },

  decode(reader: Reader, length?: number): Simple {
    ...
  },

  fromJSON(object: any): Simple {
    ...
  },

  fromPartial(object: DeepPartial<Simple>): Simple {
    ...
  },

  toJSON(message: Simple): unknown {
    ...
  },
};

This allows idiomatic TS/JS usage like:

const bytes = Simple.encode({ name: ..., age: ..., ... }).finish();
const simple = Simple.decode(Reader.create(bytes));
const { name, age } = simple;

Which can dramatically ease integration when converting to/from other layers without creating a class and calling the right getters/setters.

Highlights

  • A poor man's attempt at "please give us back optional types"

    The canonical protobuf wrapper types, i.e. google.protobuf.StringValue, are mapped as optional values, i.e. string | undefined, which means for primitives we can kind of pretend the protobuf type system has optional types.

    (Update: ts-proto now also supports the proto3 optional keyword.)

  • Timestamps are mapped as Date

    (Configurable with the useDate parameter.)

  • fromJSON/toJSON use the proto3 canonical JSON encoding format (e.g. timestamps are ISO strings), unlike protobufjs.

  • ObjectIds can be mapped as mongodb.ObjectId

    (Configurable with the useMongoObjectId parameter.)

Auto-Batching / N+1 Prevention

(Note: this is currently only supported by the Twirp clients.)

If you're using ts-proto's clients to call backend micro-services, similar to the N+1 problem in SQL applications, it is easy for micro-service clients to (when serving an individual request) inadvertently trigger multiple separate RPC calls for "get book 1", "get book 2", "get book 3", that should really be batched into a single "get books [1, 2, 3]" (assuming the backend supports a batch-oriented RPC method).

ts-proto can help with this, and essentially auto-batch your individual "get book" calls into batched "get books" calls.

For ts-proto to do this, you need to implement your service's RPC methods with the batching convention of:

  • A method name of Batch<OperationName>
  • The Batch<OperationName> input type has a single repeated field (i.e. repeated string ids = 1)
  • The Batch<OperationName> output type has either a:
    • A single repeated field (i.e. repeated Foo foos = 1) where the output order is the same as the input ids order, or
    • A map of the input to an output (i.e. map<string, Entity> entities = 1;)

When ts-proto recognizes methods of this pattern, it will automatically create a "non-batch" version of <OperationName> for the client, i.e. client.Get<OperationName>, that takes a single id and returns a single result.

This provides the client code with the illusion that it can make individual Get<OperationName> calls (which is generally preferable/easier when implementing the client's business logic), but the actual implementation that ts-proto provides will end up making Batch<OperationName> calls to the backend service.

You also need to enable the useContext=true build-time parameter, which gives all client methods a Go-style ctx parameter, with a getDataLoaders method that lets ts-proto cache/resolve request-scoped DataLoaders, which provide the fundamental auto-batch detection/flushing behavior.

See the batching.proto file and related tests for examples/more details.

But the net effect is that ts-proto can provide SQL-/ORM-style N+1 prevention for clients calls, which can be critical especially in high-volume / highly-parallel implementations like GraphQL front-end gateways calling backend micro-services.

Usage

ts-proto is a protoc plugin, so you run it by (either directly in your project, or more likely in your mono-repo schema pipeline, i.e. like Ibotta or Namely):

  • Add ts-proto to your package.json
  • Run npm install to download it
  • Invoke protoc with a plugin parameter like:
protoc --plugin=node_modules/ts-proto/protoc-gen-ts_proto ./batching.proto -I.

ts-proto can also be invoked with Gradle using the protobuf-gradle-plugin:

protobuf {
    plugins {
        // `ts` can be replaced by any unused plugin name, e.g. `tsproto`
        ts {
            path = 'path/to/plugin'
        }
    }

    // This section only needed if you provide plugin options
    generateProtoTasks {
        all().each { task ->
            task.plugins {
                // Must match plugin ID declared above
                ts {
                    option 'foo=bar'
                }
            }
        }
    }
}

Generated code will be placed in the Gradle build directory.

Supported options

  • With --ts_proto_opt=globalThisPolyfill=true, ts-proto will include a polyfill for globalThis.

    Defaults to false, i.e. we assume globalThis is available.

  • With --ts_proto_opt=context=true, the services will have a Go-style ctx parameter, which is useful for tracing/logging/etc. if you're not using node's async_hooks api due to performance reasons.

  • With --ts_proto_opt=forceLong=long, all 64-bit numbers will be parsed as instances of Long (using the long library).

    With --ts_proto_opt=forceLong=string, all 64-bit numbers will be output as strings.

    With --ts_proto_opt=forceLong=bigint, all 64-bit numbers will be output as BigInts. This option still uses the long library to encode/decode internally within protobuf.js, but then converts to/from BigInts in the ts-proto-generated code.

    The default behavior is forceLong=number, which will internally still use the long library to encode/decode values on the wire (so you will still see a util.Long = Long line in your output), but will convert the long values to number automatically for you. Note that a runtime error is thrown if, while doing this conversion, a 64-bit value is larger than can be correctly stored as a number.

  • With --ts_proto_opt=useJsTypeOverride, 64-bit numbers will be output as the FieldOption.JSType specified on the field. This takes precedence over the forceLong option provided.

  • With --ts_proto_opt=esModuleInterop=true changes output to be esModuleInterop compliant.

    Specifically the Long imports will be generated as import Long from 'long' instead of import * as Long from 'long'.

  • With --ts_proto_opt=env=node or browser or both, ts-proto will make environment-specific assumptions in your output. This defaults to both, which makes no environment-specific assumptions.

    Using node changes the types of bytes from Uint8Array to Buffer for easier integration with the node ecosystem which generally uses Buffer.

    Currently browser doesn't have any specific behavior other than being "not node". It probably will soon/at some point.

  • With --ts_proto_opt=useOptionals=messages (for message fields) or --ts_proto_opt=useOptionals=all (for message and scalar fields), fields are declared as optional keys, e.g. field?: Message instead of the default field: Message | undefined.

    ts-proto defaults to useOptionals=none because it:

    1. Prevents typos when initializing messages, and
    2. Provides the most consistent API to readers
    3. Ensures production messages are properly initialized with all fields.

    For typo prevention, optional fields make it easy for extra fields to slip into a message (until we get Exact Types), i.e.:

    interface SomeMessage {
      firstName: string;
      lastName: string;
    }
    // Declared with a typo
    const data = { firstName: "a", lastTypo: "b" };
    // With useOptionals=none, this correctly fails to compile; if `lastName` was optional, it would not
    const message: SomeMessage = { ...data };

    For a consistent API, if SomeMessage.lastName is optional lastName?, then readers have to check two empty conditions: a) is lastName undefined (b/c it was created in-memory and left unset), or b) is lastName empty string (b/c we read SomeMessage off the wire and, per the proto3 spec, initialized lastName to empty string)?

    For ensuring proper initialization, if later SomeMessage.middleInitial is added, but it's marked as optional middleInitial?, you may have many call sites in production code that should now be passing middleInitial to create a valid SomeMessage, but are not.

    So, between typo-prevention, reader inconsistency, and proper initialization, ts-proto recommends using useOptionals=none as the "most safe" option.

    All that said, this approach does require writers/creators to set every field (although fromPartial and create are meant to address this), so if you still want to have optional keys, you can set useOptionals=messages or useOptionals=all.

    (See this issue and this issue for discussions on useOptional.)

  • With --ts_proto_opt=exportCommonSymbols=false, utility types like DeepPartial and protobufPackage won't be exportd.

    This should make it possible to use create barrel imports of the generated output, i.e. import * from ./foo and import * from ./bar.

    Note that if you have the same message name used in multiple *.proto files, you will still get import conflicts.

  • With --ts_proto_opt=oneof=unions, oneof fields will be generated as ADTs.

    See the "OneOf Handling" section.

  • With --ts_proto_opt=unrecognizedEnumName=<NAME> enums will contain a key <NAME> with value of the unrecognizedEnumValue option.

    Defaults to UNRECOGNIZED.

  • With --ts_proto_opt=unrecognizedEnumValue=<NUMBER> enums will contain a key provided by the unrecognizedEnumName option with value of <NUMBER>.

    Defaults to -1.

  • With --ts_proto_opt=unrecognizedEnum=false enums will not contain an unrecognized enum key and value as provided by the unrecognizedEnumName and unrecognizedEnumValue options.

  • With --ts_proto_opt=removeEnumPrefix=true generated enums will have the enum name removed from members.

    FooBar.FOO_BAR_BAZ = "FOO_BAR_BAZ" will generate FooBar.BAZ = "FOO_BAR_BAZ"

  • With --ts_proto_opt=lowerCaseServiceMethods=true, the method names of service methods will be lowered/camel-case, i.e. service.findFoo instead of service.FindFoo.

  • With --ts_proto_opt=snakeToCamel=false, fields will be kept snake case in both the message keys and the toJSON / fromJSON methods.

    snakeToCamel can also be set as a _-delimited list of strings (comma is reserved as the flag delimited), i.e. --ts_proto_opt=snakeToCamel=keys_json, where including keys will make message keys be camel case and including json will make JSON keys be camel case.

    Empty string, i.e. snakeToCamel=, will keep both messages keys and JSON keys as snake case (it is the same as snakeToCamel=false).

    Note that to use the json_name attribute, you'll have to use the json.

    The default behavior is keys_json, i.e. both will be camel cased, and json_name will be used if set.

  • With --ts_proto_opt=outputEncodeMethods=false, the Message.encode and Message.decode methods for working with protobuf-encoded/binary data will not be output.

    This is useful if you want "only types".

  • With --ts_proto_opt=outputEncodeIncludeTypes=regex, the Message.encode method will only be output for types whose name matches the provided regular expression.

    This is useful if you want to limit encode methods to only select types.

  • With --ts_proto_opt=outputDecodeIncludeTypes=regex, the Message.decode method will only be output for types whose name matches the provided regular expression.

    This is useful if you want to limit decode methods to only select types.

  • With --ts_proto_opt=outputJsonMethods=false, the Message.fromJSON and Message.toJSON methods for working with JSON-coded data will not be output.

    This is also useful if you want "only types".

  • With --ts_proto_opt=outputJsonMethods=to-only and --ts_proto_opt=outputJsonMethods=from-only you will be able to export only one between the Message.toJSON and Message.fromJSON methods.

    This is useful if you're using ts-proto just to encode or decode and not for both.

  • With --ts_proto_opt=outputPartialMethods=false, the Message.fromPartial and Message.create methods for accepting partially-formed objects/object literals will not be output.

  • With --ts_proto_opt=stringEnums=true, the generated enum types will be string-based instead of int-based.

    This is useful if you want "only types" and are using a gRPC REST Gateway configured to serialize enums as strings.

    (Requires outputEncodeMethods=false.)

  • With --ts_proto_opt=outputClientImpl=false, the client implementations, i.e. FooServiceClientImpl, that implement the client-side (in Twirp, see next option for grpc-web) RPC interfaces will not be output.

  • With --ts_proto_opt=outputClientImpl=grpc-web, the client implementations, i.e. FooServiceClientImpl, will use the @improbable-eng/grpc-web library at runtime to send grpc messages to a grpc-web backend.

    (Note that this only uses the grpc-web runtime, you don't need to use any of their generated code, i.e. the ts-proto output replaces their ts-protoc-gen output.)

    You'll need to add the @improbable-eng/grpc-web and a transport to your project's package.json; see the integration/grpc-web directory for a working example. Also see #504 for integrating with grpc-web-devtools.

  • With --ts_proto_opt=returnObservable=true, the return type of service methods will be Observable<T> instead of Promise<T>.

  • With--ts_proto_opt=addGrpcMetadata=true, the last argument of service methods will accept the grpc Metadata type, which contains additional information with the call (i.e. access tokens/etc.).

    (Requires nestJs=true.)

  • With--ts_proto_opt=addNestjsRestParameter=true, the last argument of service methods will be a rest parameter with type any. This way you can use custom decorators you could normally use in nestjs.

    (Requires nestJs=true.)

  • With --ts_proto_opt=nestJs=true, the defaults will change to generate NestJS protobuf friendly types & service interfaces that can be used in both the client-side and server-side of NestJS protobuf implementations. See the nestjs readme for more information and implementation examples.

    Specifically outputEncodeMethods, outputJsonMethods, and outputClientImpl will all be false, lowerCaseServiceMethods will be true and outputServices will be ignored.

    Note that addGrpcMetadata, addNestjsRestParameter and returnObservable will still be false.

  • With --ts_proto_opt=useDate=false, fields of type google.protobuf.Timestamp will not be mapped to type Date in the generated types. See Timestamp for more details.

  • With --ts_proto_opt=useMongoObjectId=true, fields of a type called ObjectId where the message is constructed to have on field called value that is a string will be mapped to type mongodb.ObjectId in the generated types. This will require your project to install the mongodb npm package. See ObjectId for more details.

  • With --ts_proto_opt=annotateFilesWithVersion=false, the generated files will not contain the versions of protoc and ts-proto used to generate the file. This option is normally set to true, such that files list the versions used.

  • With --ts_proto_opt=outputSchema=true, meta typings will be generated that can later be used in other code generators.

  • With --ts_proto_opt=outputSchema=no-file-descriptor, meta typings will be generated, but we do not include the file descriptor in the generated schema. This is useful if you are trying to minimize the size of the generated schema.

  • With --ts_proto_opt=outputSchema=const, meta typings will be generated as const, allowing type-safe access to all its properties. (only works with TypeScript 4.9 and up, because it also uses the satisfies operator). Can be combined with the no-file-descriptor option (outputSchema=const,outputSchema=no-file-descriptor) to not include the file descriptor in the generated schema.

  • With --ts_proto_opt=outputTypeAnnotations=true, each message will be given a $type field containing its fully-qualified name. You can use --ts_proto_opt=outputTypeAnnotations=static-only to omit it from the interface declaration, or --ts_proto_opt=outputTypeAnnotations=optional to make it an optional property on the interface definition. The latter option may be useful if you want to use the $type field for runtime type checking on responses from a server.

  • With --ts_proto_opt=outputTypeRegistry=true, the type registry will be generated that can be used to resolve message types by fully-qualified name. Also, each message will be given a $type field containing its fully-qualified name.

  • With --ts_proto_opt=outputServices=grpc-js, ts-proto will output service definitions and server / client stubs in grpc-js format.

  • With --ts_proto_opt=outputServices=generic-definitions, ts-proto will output generic (framework-agnostic) service definitions. These definitions contain descriptors for each method with links to request and response types, which allows to generate server and client stubs at runtime, and also generate strong types for them at compile time. An example of a library that uses this approach is nice-grpc.

  • With --ts_proto_opt=outputServices=nice-grpc, ts-proto will output server and client stubs for nice-grpc. This should be used together with generic definitions, i.e. you should specify two options: outputServices=nice-grpc,outputServices=generic-definitions.

  • With --ts_proto_opt=metadataType=Foo@./some-file, ts-proto add a generic (framework-agnostic) metadata field to the generic service definition.

  • With --ts_proto_opt=outputServices=generic-definitions,outputServices=default, ts-proto will output both generic definitions and interfaces. This is useful if you want to rely on the interfaces, but also have some reflection capabilities at runtime.

  • With --ts_proto_opt=outputServices=false, or =none, ts-proto will output NO service definitions.

  • With --ts_proto_opt=rpcBeforeRequest=true, ts-proto will add a function definition to the Rpc interface definition with the signature: beforeRequest(service: string, message: string, request: <RequestType>). It will also automatically set outputServices=default. Each of the Service's methods will call beforeRequest before performing its request.

  • With --ts_proto_opt=rpcAfterResponse=true, ts-proto will add a function definition to the Rpc interface definition with the signature: afterResponse(service: string, message: string, response: <ResponseType>). It will also automatically set outputServices=default. Each of the Service's methods will call afterResponse before returning the response.

  • With --ts_proto_opt=rpcErrorHandler=true, ts-proto will add a function definition to the Rpc interface definition with the signature: handleError(service: string, message: string, error: Error). It will also automatically set outputServices=default.

  • With --ts_proto_opt=useAbortSignal=true, the generated services will accept an AbortSignal to cancel RPC calls.

  • With --ts_proto_opt=useAsyncIterable=true, the generated services will use AsyncIterable instead of Observable.

  • With --ts_proto_opt=emitImportedFiles=false, ts-proto will not emit google/protobuf/* files unless you explicit add files to protoc like this protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto my_message.proto google/protobuf/duration.proto

  • With --ts_proto_opt=fileSuffix=<SUFFIX>, ts-proto will emit generated files using the specified suffix. A helloworld.proto file with fileSuffix=.pb would be generated as helloworld.pb.ts. This is common behavior in other protoc plugins and provides a way to quickly glob all the generated files.

  • With --ts_proto_opt=importSuffix=<SUFFIX>, ts-proto will emit file imports using the specified suffix. An import of helloworld.ts with fileSuffix=.js would generate import "helloworld.js". The default is to import without a file extension. Supported by TypeScript 4.7.x and up.

  • With --ts_proto_opt=enumsAsLiterals=true, the generated enum types will be enum-ish object with as const.

  • With --ts_proto_opt=useExactTypes=false, the generated fromPartial and create methods will not use Exact types.

    The default behavior is useExactTypes=true, which makes fromPartial and create use Exact type for its argument to make TypeScript reject any unknown properties.

  • With --ts_proto_opt=unknownFields=true, all unknown fields will be parsed and output as arrays of buffers.

  • With --ts_proto_opt=onlyTypes=true, only types will be emitted, and imports for long and protobufjs/minimal will be excluded.

    This is the same as setting outputJsonMethods=false,outputEncodeMethods=false,outputClientImpl=false,nestJs=false

  • With --ts_proto_opt=usePrototypeForDefaults=true, the generated code will wrap new objects with Object.create.

    This allows code to do hazzer checks to detect when default values have been applied, which due to proto3's behavior of not putting default values on the wire, is typically only useful for interacting with proto2 messages.

    When enabled, default values are inherited from a prototype, and so code can use Object.keys().includes("someField") to detect if someField was actually decoded or not.

    Note that, as indicated, this means Object.keys will not include set-by-default fields, so if you have code that iterates over messages keys in a generic fashion, it will have to also iterate over keys inherited from the prototype.

  • With --ts_proto_opt=useJsonName=true, json_name defined in protofiles will be used instead of message field names.

  • With --ts_proto_opt=useJsonWireFormat=true, the generated code will reflect the JSON representation of Protobuf messages.

    Requires onlyTypes=true. Implies useDate=string and stringEnums=true. This option is to generate types that can be directly used with marshalling/unmarshalling Protobuf messages serialized as JSON. You may also want to set useOptionals=all, as gRPC gateways are not required to send default value for scalar values.

  • With --ts_proto_opt=useNumericEnumForJson=true, the JSON converter (toJSON) will encode enum values as int, rather than a string literal.

  • With --ts_proto_opt=initializeFieldsAsUndefined=false, all optional field initializers will be omitted from the generated base instances.

  • With --ts_proto_opt=disableProto2Optionals=true, all optional fields on proto2 files will not be set to be optional. Please note that this flag is primarily for preserving ts-proto's legacy handling of proto2 files, to avoid breaking changes, and as a result, it is not intended to be used moving forward.

  • With --ts_proto_opt=disableProto2DefaultValues=true, all fields in proto2 files that specify a default value will not actually use that default value. Please note that this flag is primarily for preserving ts-proto's legacy handling of proto2 files, to avoid breaking changes, and as a result, it is not intended to be used moving forward.

  • With --ts_proto_opt=Mgoogle/protobuf/empty.proto=./google3/protobuf/empty, ('M' means 'importMapping', similar to protoc-gen-go), the generated code import path for ./google/protobuf/empty.ts will reflect the overridden value:

    • Mfoo/bar.proto=@myorg/some-lib will map foo/bar.proto imports into import ... from '@myorg/some-lib'.
    • Mfoo/bar.proto=./some/local/lib will map foo/bar.proto imports into import ... from './some/local/lib'.
    • Mfoo/bar.proto=some-modules/some-lib will map foo/bar.proto imports into import ... from 'some-module/some-lib'.
    • Note: Uses are accumulated, so multiple values are expected in the form of --ts_proto_opt=M... --ts_proto_opt=M... (one ts_proto_opt per mapping).
    • Note: Proto files that match mapped imports will not be generated.
  • With --ts_proto_opt=useMapType=true, the generated code for protobuf map<key_type, value_type> will become Map<key_type, value_type> that uses JavaScript Map type.

    The default behavior is useMapType=false, which makes it generate the code for protobuf map<key_type, value_type with the key-value pair like {[key: key_type]: value_type}.

  • With --ts_proto_opt=useReadonlyTypes=true, the generated types will be declared as immutable using typescript's readonly modifier.

  • With --ts_proto_opt=useSnakeTypeName=false will remove snake casing from types.

    Example Protobuf

    message Box {
        message Element {
              message Image {
                    enum Alignment {
                          LEFT = 1;
                          CENTER = 2;
                          RIGHT = 3;
                    }
              }
          }
    }

    by default this is enabled which would generate a type of Box_Element_Image_Alignment. By disabling this option the type that is generated would be BoxElementImageAlignment.

  • With --ts_proto_opt=outputExtensions=true, the generated code will include proto2 extensions

    Extension encode/decode methods are compliant with the outputEncodeMethods option, and if unknownFields=true, the setExtension and getExtension methods will be created for extendable messages, also compliant with outputEncodeMethods (setExtension = encode, getExtension = decode).

  • With --ts_proto_opt=outputIndex=true, index files will be generated based on the proto package namespaces.

    This will disable exportCommonSymbols to avoid name collisions on the common symbols.

  • With --ts_proto_opt=emitDefaultValues=json-methods, the generated toJSON method will emit scalars like 0 and "" as json fields.

  • With --ts_proto_opt=comments=false, comments won't be copied from the proto files to the generated code.

  • With --ts_proto_opt=bigIntLiteral=false, the generated code will use BigInt("0") instead of 0n for BigInt literals. BigInt literals aren't supported by TypeScript when the "target" compiler option set to something older than "ES2020".

  • With --ts_proto_opt=useNullAsOptional=true, undefined values will be converted to null, and if you use optional label in your .proto file, the field will have undefined type as well. for example:

  • With --ts_proto_opt=typePrefix=MyPrefix, the generated interfaces, enums, and factories will have a prefix of MyPrefix in their names.

  • With --ts_proto_opt=typeSuffix=MySuffix, the generated interfaces, enums, and factories will have a suffix of MySuffix in their names.

message ProfileInfo {
    int32 id = 1;
    string bio = 2;
    string phone = 3;
}

message Department {
    int32 id = 1;
    string name = 2;
}

message User {
    int32 id = 1;
    string username = 2;
    /*
     ProfileInfo will be optional in typescript, the type will be ProfileInfo | null | undefined
     this is needed in cases where you don't wanna provide any value for the profile.
    */
    optional ProfileInfo profile = 3;

    /*
      Department only accepts a Department type or null, so this means you have to pass it null if there is no value available.
    */
    Department  department = 4;
}

the generated interfaces will be:

export interface ProfileInfo {
  id: number;
  bio: string;
  phone: string;
}

export interface Department {
  id: number;
  name: string;
}

export interface User {
  id: number;
  username: string;
  profile?: ProfileInfo | null | undefined; // check this one
  department: Department | null; // check this one
}
  • With --ts_proto_opt=noDefaultsForOptionals=true, undefined primitive values will not be defaulted as per the protobuf spec. Additionally unlike the standard behavior, when a field is set to its standard default value, it will be encoded allowing it to be sent over the wire and distinguished from undefined values. For example if a message does not set a boolean value, ordinarily this would be defaulted to false which is different to it being undefined.

This option allows the library to act in a compatible way with the Wire implementation maintained and used by Square/Block. Note: this option should only be used in combination with other client/server code generated using Wire or ts-proto with this option enabled.

NestJS Support

We have a great way of working together with nestjs. ts-proto generates interfaces and decorators for you controller, client. For more information see the nestjs readme.

Watch Mode

If you want to run ts-proto on every change of a proto file, you'll need to use a tool like chokidar-cli and use it as a script in package.json:

"proto:generate": "protoc --ts_proto_out=. ./<proto_path>/<proto_name>.proto --ts_proto_opt=esModuleInterop=true",
"proto:watch": "chokidar \"**/*.proto\" -c \"npm run proto:generate\""

Basic gRPC implementation

ts-proto is RPC framework agnostic - how you transmit your data to and from your data source is up to you. The generated client implementations all expect a rpc parameter, which type is defined like this:

interface Rpc {
  request(service: string, method: string, data: Uint8Array): Promise<Uint8Array>;
}

If you're working with gRPC, a simple implementation could look like this:

const conn = new grpc.Client(
  "localhost:8765",
  grpc.credentials.createInsecure()
);

type RpcImpl = (service: string, method: string, data: Uint8Array) => Promise<Uint8Array>;

const sendRequest: RpcImpl = (service, method, data) => {
  // Conventionally in gRPC, the request path looks like
  //   "package.names.ServiceName/MethodName",
  // we therefore construct such a string
  const path = `/${service}/${method}`;

  return new Promise((resolve, reject) => {
    // makeUnaryRequest transmits the result (and error) with a callback
    // transform this into a promise!
    const resultCallback: UnaryCallback<any> = (err, res) => {
      if (err) {
        return reject(err);
      }
      resolve(res);
    };

    function passThrough(argument: any) {
      return argument;
    }

    // Using passThrough as the deserialize functions
    conn.makeUnaryRequest(path, d => Buffer.from(d), passThrough, data, resultCallback);
  });
};

const rpc: Rpc = { request: sendRequest };

Sponsors

Kudos to our sponsors:

  • ngrok funded ts-proto's initial grpc-web support.

If you need ts-proto customizations or priority support for your company, you can ping me at via email.

Development

This section describes how to contribute directly to ts-proto, i.e. it's not required for running ts-proto in protoc or using the generated TypeScript.

Requirements

  • Docker
  • yarnnpm install -g yarn

Setup

The commands below assume you have Docker installed. If you are using OS X, install coreutils, brew install coreutils.

  • Check out the repository for the latest code.
  • Run yarn install to install the dependencies.
  • Run yarn build:test to generate the test files.

    This runs the following commands:

    • proto2ts — Runs ts-proto on the integration/**/*.proto files to generate .ts files.
    • proto2pbjs — Generates a reference implementation using pbjs for testing compatibility.
  • Run yarn test

Workflow

  • Add/update an integration test for your use case
    • Either find an existing integration/* test that is close enough to your use case, e.g. has a parameters.txt that matches the ts_proto_opt params necessary to reproduce your use case
    • If creating a new integration test:
      • Make a new integration/your-new-test/parameters.txt with the necessary ts_proto_opt params
      • Create a minimal integration/your-new-test/your-new-test.proto schema to reproduce your use case
    • After any changes to your-new-test.proto, or an existing integration/*.proto file, run yarn proto2bin
      • You can also leave yarn watch running, and it should "just do the right thing"
    • Add/update a integration/your-new-test/some-test.ts unit test, even if it's as trivial as just making sure the generated code compiles
  • Modify the ts-proto code generation logic:
    • Most important logic is found in src/main.ts.
    • After any changes to src/*.ts files, run yarn proto2ts to re-codegen all integration tests
      • Or yarn proto2ts your-new-test to re-codegen a specific test
      • Again leaving yarn watch running should "just do the right thing"
  • Run yarn test to verify your changes pass all existing tests
  • Commit and submit a PR
    • Run yarn format to format the typescript files.
    • Make sure to git add all of the *.proto, *.bin, and *.ts files in integration/your-new-test
      • Sometimes checking in generated code is frowned upon, but given ts-proto's main job is to generate code, seeing the codegen diffs in PRs is helpful

Testing in your projects

You can test your local ts-proto changes in your own projects by running yarn add ts-proto@./path/to/ts-proto, as long as you run yarn build manually.

Dockerized Protoc

The repository includes a dockerized version of protoc, which is configured in docker-compose.yml.

It can be useful in case you want to manually invoke the plugin with a known version of protoc.

Usage:

# Include the protoc alias in your shell.
. aliases.sh

# Run protoc as usual. The ts-proto directory is available in /ts-proto.
protoc --plugin=/ts-proto/protoc-gen-ts_proto --ts_proto_out=./output -I=./protos ./protoc/*.proto

# Or use the ts-protoc alias which specifies the plugin path for you.
ts-protoc --ts_proto_out=./output -I=./protos ./protoc/*.proto
  • All paths must be relative paths within the current working directory of the host. ../ is not allowed
  • Within the docker container, the absolute path to the project root is /ts-proto
  • The container mounts the current working directory in /host, and sets it as its working directory.
  • Once aliases.sh is sourced, you can use the protoc command in any folder.

Assumptions

  • TS/ES6 module name is the proto package

Todo

  • Support the string-based encoding of duration in fromJSON/toJSON
  • Make oneof=unions-value the default behavior in 2.0
  • Probably change forceLong default in 2.0, should default to forceLong=long
  • Make esModuleInterop=true the default in 2.0

OneOf Handling

By default, ts-proto models oneof fields "flatly" in the message, e.g. a message like:

message Foo {
  oneof either_field { string field_a = 1; string field_b = 2; }
}

Will generate a Foo type with two fields: field_a: string | undefined; and field_b: string | undefined.

With this output, you'll have to check both if object.field_a and if object.field_b, and if you set one, you'll have to remember to unset the other.

Instead, we recommend using the oneof=unions-value option, which will change the output to be an Algebraic Data Type/ADT like:

interface YourMessage {
  eitherField?: { $case: "field_a"; value: string } | { $case: "field_b"; value: string };
}

As this will automatically enforce only one of field_a or field_b "being set" at a time, because the values are stored in the eitherField field that can only have a single value at a time.

(Note that eitherField is optional b/c oneof in Protobuf means "at most one field" is set, and does not mean one of the fields must be set.)

In ts-proto's currently-unscheduled 2.x release, oneof=unions-value will become the default behavior.

There is also a oneof=unions option, which generates a union where the field names are included in each option:

interface YourMessage {
  eitherField?: { $case: "field_a"; field_a: string } | { $case: "field_b"; field_b: string };
}

This is no longer recommended as it can be difficult to write code and types to handle multiple oneof options:

OneOf Type Helpers

The following helper types may make it easier to work with the types generated from oneof=unions, though they are generally not needed if you use oneof=unions-value:

/** Extracts all the case names from a oneOf field. */
type OneOfCases<T> = T extends { $case: infer U extends string } ? U : never;

/** Extracts a union of all the value types from a oneOf field */
type OneOfValues<T> = T extends { $case: infer U extends string; [key: string]: unknown } ? T[U] : never;

/** Extracts the specific type of a oneOf case based on its field name */
type OneOfCase<T, K extends OneOfCases<T>> = T extends {
  $case: K;
  [key: string]: unknown;
}
  ? T
  : never;

/** Extracts the specific type of a value type from a oneOf field */
type OneOfValue<T, K extends OneOfCases<T>> = T extends {
  $case: infer U extends K;
  [key: string]: unknown;
}
  ? T[U]
  : never;

For comparison, the equivalents for oneof=unions-value:

/** Extracts all the case names from a oneOf field. */
type OneOfCases<T> = T['$case'];

/** Extracts a union of all the value types from a oneOf field */
type OneOfValues<T> = T['value'];

/** Extracts the specific type of a oneOf case based on its field name */
type OneOfCase<T, K extends OneOfCases<T>> = T extends {
  $case: K;
  [key: string]: unknown;
}
  ? T
  : never;

/** Extracts the specific type of a value type from a oneOf field */
type OneOfValue<T, K extends OneOfCases<T>> = T extends {
  $case: infer U extends K;
  value: unknown;
}
  ? T[U]
  : never;

Default values and unset fields

In core Protobuf (and so also ts-proto), values that are unset or equal to the default value are not sent over the wire.

For example, the default value of a message is undefined. Primitive types take their natural default value, e.g. string is '', number is 0, etc.

Protobuf chose/enforces this behavior because it enables forward compatibility, as primitive fields will always have a value, even when omitted by outdated agents.

This is good, but it also means default and unset values cannot be distinguished in ts-proto fields; it's just fundamentally how Protobuf works.

If you need primitive fields where you can detect set/unset, see Wrapper Types.

Encode / Decode

ts-proto follows the Protobuf rules, and always returns default values for unsets fields when decoding, while omitting them from the output when serialized in binary format.

syntax = "proto3";
message Foo {
  string bar = 1;
}
protobufBytes; // assume this is an empty Foo object, in protobuf binary format
Foo.decode(protobufBytes); // => { bar: '' }
Foo.encode({ bar: "" }); // => { }, writes an empty Foo object, in protobuf binary format

fromJSON / toJSON

Reading JSON will also initialize the default values. Since senders may either omit unset fields, or set them to the default value, use fromJSON to normalize the input.

Foo.fromJSON({}); // => { bar: '' }
Foo.fromJSON({ bar: "" }); // => { bar: '' }
Foo.fromJSON({ bar: "baz" }); // => { bar: 'baz' }

When writing JSON, ts-proto normalizes messages by omitting unset fields and fields set to their default values.

Foo.toJSON({}); // => { }
Foo.toJSON({ bar: undefined }); // => { }
Foo.toJSON({ bar: "" }); // => { } - note: omitting the default value, as expected
Foo.toJSON({ bar: "baz" }); // => { bar: 'baz' }

Well-Known Types

Protobuf comes with several predefined message definitions, called "Well-Known Types". Their interpretation is defined by the Protobuf specification, and libraries are expected to convert these messages to corresponding native types in the target language.

ts-proto currently automatically converts these messages to their corresponding native types.

Wrapper Types

Wrapper Types are messages containing a single primitive field, and can be imported in .proto files with import "google/protobuf/wrappers.proto".

Since these are messages, their default value is undefined, allowing you to distinguish unset primitives from their default values, when using Wrapper Types. ts-proto generates these fields as <primitive> | undefined.

For example:

// Protobuf
syntax = "proto3";

import "google/protobuf/wrappers.proto";

message ExampleMessage {
  google.protobuf.StringValue name = 1;
}
// TypeScript
interface ExampleMessage {
  name: string | undefined;
}

When encoding a message the primitive value is converted back to its corresponding wrapper type:

ExampleMessage.encode({ name: "foo" }); // => { name: { value: 'foo' } }, in binary

When calling toJSON, the value is not converted, because wrapper types are idiomatic in JSON.

ExampleMessage.toJSON({ name: "foo" }); // => { name: 'foo' }

JSON Types (Struct Types)

Protobuf's language and types are not sufficient to represent all possible JSON values, since JSON may contain values whose type is unknown in advance. For this reason, Protobuf offers several additional types to represent arbitrary JSON values.

These are called Struct Types, and can be imported in .proto files with import "google/protobuf/struct.proto".

ts-proto automatically converts back and forth between these Struct Types and their corresponding JSON types.

Example:

// Protobuf
syntax = "proto3";

import "google/protobuf/struct.proto";

message ExampleMessage {
  google.protobuf.Value anything = 1;
}
// TypeScript
interface ExampleMessage {
  anything: any | undefined;
}

Encoding a JSON value embedded in a message, converts it to a Struct Type:

ExampleMessage.encode({ anything: { name: "hello" } });
/* Outputs the following structure, encoded in protobuf binary format:
{
  anything: Value {
    structValue = Struct {
      fields = [
        MapEntry {
          key = "name",
          value = Value {
            stringValue = "hello"
          }
        ]
      }
    }
 }
}*/

ExampleMessage.encode({ anything: true });
/* Outputs the following structure encoded in protobuf binary format:
{
  anything: Value {
    boolValue = true
  }
}*/

Timestamp

The representation of google.protobuf.Timestamp is configurable by the useDate flag. The useJsonTimestamp flag controls precision when useDate is false.

Protobuf well-known type Default/useDate=true useDate=false useDate=string useDate=string-nano
google.protobuf.Timestamp Date { seconds: number, nanos: number } string string

When using useDate=false and useJsonTimestamp=raw timestamp is represented as { seconds: number, nanos: number }, but has nanosecond precision.

When using useDate=string-nano timestamp is represented as an ISO string with nanosecond precision 1970-01-01T14:27:59.987654321Z and relies on nano-date library for conversion. You'll need to install it in your project.

Number Types

Numbers are by default assumed to be plain JavaScript numbers.

This is fine for Protobuf types like int32 and float, but 64-bit types like int64 can't be 100% represented by JavaScript's number type, because int64 can have larger/smaller values than number.

ts-proto's default configuration (which is forceLong=number) is to still use number for 64-bit fields, and then throw an error if a value (at runtime) is larger than Number.MAX_SAFE_INTEGER.

If you expect to use 64-bit / higher-than-MAX_SAFE_INTEGER values, then you can use the ts-proto forceLong option, which uses the long npm package to support the entire range of 64-bit values.

The protobuf number types map to JavaScript types based on the forceLong config option:

Protobuf number types Default/forceLong=number forceLong=long forceLong=string
double number number number
float number number number
int32 number number number
int64 number* Long string
uint32 number number number
uint64 number* Unsigned Long string
sint32 number number number
sint64 number* Long string
fixed32 number number number
fixed64 number* Unsigned Long string
sfixed32 number number number
sfixed64 number* Long string

Where (*) indicates they might throw an error at runtime.

Current Status of Optional Values

  • Required primitives: use as-is, i.e. string name = 1.
  • Optional primitives: use wrapper types, i.e. StringValue name = 1.
  • Required messages: not available
  • Optional messages: use as-is, i.e. SubMessage message = 1.

changelog

2.6.1 (2024-12-27)

Bug Fixes

2.6.0 (2024-12-09)

Features

  • Make sure all types support prefix/suffix (#1148) (ddf2122)

2.5.1 (2024-12-09)

Bug Fixes

  • google protobuf timestamps don't properly get suffixed when useDate=false and prefix/suffix (#1146) (53f799e)

2.5.0 (2024-12-03)

Features

  • Add options to limit generation of encode and decode methods to only specific message types (#1085) (c7372fa), closes #1084

2.4.2 (2024-11-28)

Performance Improvements

  • Replacing "else if" with a "switch case" statement to improve Typescript performance (#1142) (de1a616), closes #1135 #1141

2.4.1 (2024-11-26)

Performance Improvements

2.4.0 (2024-11-25)

Features

  • Avoid adding empty trailing comments to oneof unions (#1140) (5359e8d), closes #1136

2.3.0 (2024-11-16)

Features

  • add support for comments on union fields in generateOneofProperty (#1136) (c933c9c), closes #1122

2.2.7 (2024-11-11)

Bug Fixes

  • problem with verbatimModuleSyntax for grpc-js (#1132) (bedfa31)

2.2.6 (2024-11-11)

Bug Fixes

  • Schema generation: ensure Buffer api is only used when in nodejs environment (#1134) (49035a4)

2.2.5 (2024-10-22)

Bug Fixes

2.2.4 (2024-10-15)

Bug Fixes

2.2.3 (2024-10-06)

Bug Fixes

2.2.2 (2024-10-04)

Bug Fixes

  • prefix and suffixes were not being applied to to/fromTimestamp resulting in compile error (#1118) (22c2905)

2.2.1 (2024-09-29)

Bug Fixes

  • Compilation error for nested repeated fields with useOptionals=all (#1113) (e89fc51), closes #1112

2.2.0 (2024-09-06)

Features

  • Add interface for static message methods (#1104) (faa33b6)

2.1.0 (2024-09-04)

Features

2.0.4 (2024-09-04)

Bug Fixes

2.0.3 (2024-08-21)

Bug Fixes

2.0.2 (2024-08-16)

Bug Fixes

2.0.1 (2024-08-16)

Bug Fixes

  • Fix build from typescript bump. (3ecd498)

2.0.0 (2024-08-16)

1.181.2 (2024-08-15)

Bug Fixes

  • toJSON Function with removeEnumPrefix=true and unrecognizedEnumValue=0 Options (#1089) (2401490), closes #1086 #1086

1.181.1 (2024-07-13)

Bug Fixes

  • Incorrect message names in the generated code for repeated fields (#1073) (8a95d8e), closes #1072

1.181.0 (2024-07-01)

Features

1.180.0 (2024-06-15)

Features

  • oneof=unions-value to use the same field name for oneof cases (#1062) (7493090), closes #1060

1.179.0 (2024-06-15)

Features

1.178.0 (2024-06-07)

Features

  • no-file-descriptor setting for outputSchema option (#1047) (c54f06c)

1.177.0 (2024-06-07)

Features

1.176.3 (2024-06-07)

Bug Fixes

  • Add check for lower bound with forceLong=number (#1057) (01ef3c3)

1.176.2 (2024-06-04)

Bug Fixes

1.176.1 (2024-05-25)

Bug Fixes

  • camelToSnake to respect uppercase words, such as "GetAPIValue" -> "GET_API_VALUE" (#1046) (d2e75cd)

1.176.0 (2024-05-16)

Features

1.175.1 (2024-05-15)

Bug Fixes

1.175.0 (2024-05-13)

Features

  • optionally output versions used to generate files (#1040) (53d6799)

1.174.0 (2024-05-01)

Features

1.173.0 (2024-04-30)

Features

1.172.0 (2024-04-13)

Features

1.171.0 (2024-03-30)

Features

1.170.0 (2024-03-26)

Features

  • support deprecatedOnly option to make deprecated fields optional (#1010) (db23004)

1.169.1 (2024-03-13)

Bug Fixes

1.169.0 (2024-03-12)

Features

  • support proto2 optional and default value fields (#1007) (1fa1e61), closes #973

1.168.0 (2024-03-08)

Features

1.167.9 (2024-02-28)

Bug Fixes

1.167.8 (2024-02-18)

Bug Fixes

1.167.7 (2024-02-17)

Bug Fixes

1.167.6 (2024-02-17)

Bug Fixes

1.167.5 (2024-02-15)

Bug Fixes

  • import fails when folder name overlaps with file name (#1000) (1e68e6f)

1.167.4 (2024-02-15)

Bug Fixes

  • don't reference globalThis.Buffer when env=browser (#967) (#999) (0d34612)

1.167.3 (2024-02-03)

Bug Fixes

  • ensure default service streaming methods compile when middleware methods are enabled (#996) (a9e975b)

1.167.2 (2024-01-28)

Bug Fixes

  • ensure docker-compose platform is amd64 (#990) (bdf4710)

1.167.1 (2024-01-26)

Bug Fixes

  • generate modules for empty files with esModuleInterop (#992) (f0629ab)

1.167.0 (2024-01-22)

Features

1.166.4 (2024-01-20)

Bug Fixes

1.166.3 (2024-01-18)

Bug Fixes

  • add support of importSuffix=.js for index files (#986) (183cf03)

1.166.2 (2023-12-31)

Bug Fixes

  • error handling on non-Error type errors (#983) (8c567fc)

1.166.1 (2023-12-31)

Bug Fixes

1.166.0 (2023-12-29)

Features

1.165.3 (2023-12-26)

Bug Fixes

  • add serviceName to grpc-js client constructor type (#980) (2c6682d)

1.165.2 (2023-12-20)

Bug Fixes

  • Fix generating wrong web-rpc implementation for wrapper-type method arg (#978) (063fd29)

1.165.1 (2023-12-06)

Bug Fixes

1.165.0 (2023-11-28)

Features

1.164.2 (2023-11-28)

Bug Fixes

  • Don't close client if we've already aborted (#968) (7ee1507)

1.164.1 (2023-11-24)

Bug Fixes

  • revert useDate=false behaviour; add useJsonTimestamp option (#969) (15ae516)

1.164.0 (2023-11-09)

Features

  • add before and after request methods to base service (#961) (19ba6a5)

1.163.0 (2023-11-02)

Features

  • generate type namespaces for enums as literals (#960) (e2619f6)

1.162.2 (2023-10-26)

Bug Fixes

  • return types and optional chaining in field masks when useOptionals=all (#957) (a3d7bd4)

1.162.1 (2023-10-13)

Bug Fixes

1.162.0 (2023-10-13)

Features

  • support json_name defined in a proto file (#943) (de989af)

1.161.1 (2023-10-10)

Bug Fixes

  • use optional chaining when both forceLong=long and useOptionals=all options are set in the generated fromTimestamp function (#949) (b00db6f)

1.161.0 (2023-10-10)

Features

  • add unrecognizedEnumName and unrecognizedEnumValue options (#946) (cd61e90)

1.160.0 (2023-10-05)

Features

1.159.3 (2023-10-04)

Bug Fixes

1.159.2 (2023-10-02)

Bug Fixes

  • Support using messages called String/Boolean/Number/Array (#934) (f75159b), closes #927

1.159.1 (2023-09-30)

Bug Fixes

1.159.0 (2023-09-30)

Features

  • Add globalThisPolyfill, defaults false. (#931) (085fa21)

1.158.1 (2023-09-30)

Bug Fixes

  • Use globalThis for Array/String/Boolean (#930) (9a252c3)

1.158.0 (2023-09-24)

Features

  • adds support for emitting default scalar values in json (#919) (01f529f)

1.157.1 (2023-09-18)

Bug Fixes

  • Update type imports syntax on gRPC generation (#921) (b10ab31)

1.157.0 (2023-09-03)

Features

1.156.8 (2023-09-03)

Bug Fixes

  • fixing exportCommonSymbols in nestjs (#916) (daf41f7)

1.156.7 (2023-08-18)

Bug Fixes

1.156.6 (2023-08-16)

Bug Fixes

  • use correct imports for optional fields (#904) (fa13ec7)

1.156.5 (2023-08-15)

Bug Fixes

1.156.4 (2023-08-15)

Bug Fixes

  • enum default value when remove-enum-prefix and string-enum both on (#902) (594b137)

1.156.3 (2023-08-13)

Bug Fixes

1.156.2 (2023-07-29)

Bug Fixes

1.156.1 (2023-07-22)

Bug Fixes

1.156.0 (2023-07-20)

Features

1.155.1 (2023-07-15)

Bug Fixes

1.155.0 (2023-07-15)

Features

1.154.0 (2023-07-15)

Features

  • Normalize toJSON output by omitting fields set to their default values (#878) (50958d6)

1.153.3 (2023-07-13)

Bug Fixes

  • Bump ts-proto-descriptors w/long back. (#880) (d27e19c)

1.153.2 (2023-07-12)

Bug Fixes

1.153.1 (2023-07-12)

Bug Fixes

1.153.0 (2023-07-12)

Features

  • Update protobufjs (and peer dependencies) to ^7 (#874) (7f979a7)

1.152.1 (2023-07-10)

Bug Fixes

1.152.0 (2023-07-10)

Features

  • Ensure strict(er) TS compliance for the generated code (#868) (1405d4b)

1.151.1 (2023-07-05)

Bug Fixes

  • generate different MessageType when using static-only (#863) (477e5f5), closes #861

1.151.0 (2023-07-04)

Features

  • Add static-only variant to outputTypeAnnotations option (#858) (d7c4af7)

1.150.1 (2023-06-23)

Bug Fixes

  • don't generate transitively imported files for mapped imports (#854) (edd9044)

1.150.0 (2023-06-20)

Features

  • expose service name as a separate exported constant (#851) (84a4ed6)

1.149.0 (2023-06-13)

Features

1.148.2 (2023-06-04)

Bug Fixes

  • esModuleInterop not working for object-hash and dataloader imports (#794) (9fc9632)

1.148.1 (2023-05-25)

Bug Fixes

1.148.0 (2023-05-23)

Features

1.147.3 (2023-05-16)

Bug Fixes

  • ensure generated fromTimestamp works when useOptionals=all (#832) (1f82445)

1.147.2 (2023-05-07)

Bug Fixes

1.147.1 (2023-05-02)

Bug Fixes

  • Try fixing the Buf publish step. (47ef176)

1.147.0 (2023-05-02)

Features

1.146.0 (2023-04-01)

Features

1.145.0 (2023-03-27)

Bug Fixes

Features

  • Update fromPartial and fromJson to respect initializeFieldsAsUndefined (#811) (1615ae0)

1.144.1 (2023-03-26)

Bug Fixes

  • Bump ts-proto-descriptors to restore any-less _unknownFields. (#810) (de9c307)

1.144.0 (2023-03-26)

Bug Fixes

  • Temporarily put anys back to release. (c6f189e)

Features

1.143.0 (2023-03-19)

Bug Fixes

  • initialize undefined optional fields upon use (#802) (ee52e06)

Features

Performance Improvements

  • use array.push to prevent reallocation on every field (#804) (a6aea2c)

1.142.1 (2023-03-18)

Performance Improvements

1.142.0 (2023-03-18)

Features

1.141.1 (2023-03-11)

Bug Fixes

1.141.0 (2023-03-08)

Features

1.140.0 (2023-02-24)

Features

  • removeEnumPrefix option (#779) (53733e6)
  • implementation of useAbortSignal option for grpc-web (#777) (7a3d429)

1.139.0 (2023-01-31)

Features

Performance Improvements

  • generate switch statement for oneof union encode (#767) (c3fd1e3)

1.138.0 (2023-01-10)

Features

  • add create utility function to message definitions (#760) (44fc7b2)

1.137.2 (2023-01-09)

Bug Fixes

  • repeated uint64 fields do not encode properly with bigint option (#751) (dcdd7e2)

1.137.1 (2023-01-07)

Bug Fixes

1.137.0 (2022-12-29)

Bug Fixes

  • Additional fix for structs with useMapType. (#743) (3264b0f)
  • Fix codegen for google.protobuf.Struct with useMapType=true (#740) (0647151)

Features

1.136.1 (2022-12-16)

Bug Fixes

1.136.0 (2022-12-14)

Features

1.135.3 (2022-12-12)

Bug Fixes

1.135.2 (2022-12-09)

Bug Fixes

1.135.1 (2022-12-09)

Bug Fixes

  • Add functionality for grpc camel case to respect splitting by word (#721) (4af040c), closes #722

1.135.0 (2022-11-26)

Features

1.134.0 (2022-11-25)

Features

  • conditionally add "Service" to nice-grpc's generated service interface name (#710) (7c39cc0)

1.133.0 (2022-11-20)

Features

1.132.1 (2022-11-15)

Bug Fixes

1.132.0 (2022-11-15)

Features

  • change channel options to client options in generate grpc/js (#704) (c4ac8ac)

1.131.2 (2022-11-13)

Bug Fixes

  • Adding a failing regression test for wrapper types (#689) (bde2e28)

1.131.1 (2022-11-13)

Bug Fixes

  • Extend global.Error to avoid import collisions with Error proto msgs (#699) (e9d8f91)

1.131.0 (2022-10-25)

Features

1.130.0 (2022-10-22)

Features

1.129.0 (2022-10-16)

Features

1.128.0 (2022-10-13)

Features

1.127.0 (2022-10-12)

Features

  • client: allow overriding the service identifier (#683) (10c7c99)
  • Import CallContext and CallOptions as type (#684) (8b388f6), closes #677

1.126.1 (2022-09-21)

Bug Fixes

  • options: initializes M opt to empty object (#673) (cb76c5e)

1.126.0 (2022-09-21)

Features

1.125.0 (2022-09-03)

Features

  • omit optional fields in base instance (#669) (47b60aa)

1.124.0 (2022-09-03)

Features

  • Bump ts poet for dprint perf increase (#668) (961d388)

1.123.1 (2022-08-27)

Bug Fixes

  • Bump ts-poet to use @dprint/typescript. (#662) (84b64f4)

1.123.0 (2022-08-27)

Features

  • Bump ts-poet for dprint, also use tsx (#660) (348a465)

1.122.0 (2022-08-15)

Features

  • Grpc-Web: Add & export GrpcWebError type (#593) (645987d)

1.121.6 (2022-08-14)

Bug Fixes

1.121.5 (2022-08-08)

Bug Fixes

1.121.4 (2022-08-07)

Performance Improvements

  • Faster base64FromBytes & bytesFromBase64 on Node.JS (#649) (82ab341)

1.121.3 (2022-08-06)

Bug Fixes

  • Use underscore separator in snakeToCamel. (#648) (b374910)

1.121.2 (2022-08-06)

Bug Fixes

  • Fix push_to_buf_registry check. (22ac914)

1.121.1 (2022-07-28)

Bug Fixes

1.121.0 (2022-07-28)

Features

1.120.0 (2022-07-21)

Features

1.119.0 (2022-07-21)

Features

1.118.0 (2022-07-19)

Features

1.117.1 (2022-07-16)

Bug Fixes

  • import protobufjs/minimal with importSuffix (#616) (b86291c)

1.117.0 (2022-07-05)

Features

  • add importSuffix option and remove default .js suffix (#612) (63a8895)

1.116.1 (2022-07-02)

Bug Fixes

1.116.0 (2022-07-01)

Features

1.115.5 (2022-06-22)

Bug Fixes

  • remove Long import statement when Long was unused (#599) (58dc10c)

1.115.4 (2022-06-05)

Bug Fixes

1.115.3 (2022-06-03)

Bug Fixes

1.115.2 (2022-06-03)

Bug Fixes

  • simplify handling useJsonWireFormat=true and fix onlyTypes=true (#583) (6e7f938)

1.115.1 (2022-06-02)

Bug Fixes

1.115.0 (2022-06-02)

Features

1.114.7 (2022-05-28)

Bug Fixes

  • Fix version number for Buf plugin. (dc1fb7e)

1.114.6 (2022-05-28)

Bug Fixes

  • Bump node in ts-proto.Dockerfile. (42f3cea)

1.114.5 (2022-05-28)

Bug Fixes

  • Use outputs for Buf plugin workflow. (7017d4c)

1.114.4 (2022-05-28)

Bug Fixes

  • Use env prefix for Buf plugin. (ea42caa)

1.114.3 (2022-05-28)

Bug Fixes

  • Use the npm environment. (0103443)

1.114.2 (2022-05-28)

Bug Fixes

1.114.0 (2022-05-27)

Features

1.113.0 (2022-05-27)

Features

1.112.2 (2022-05-18)

Bug Fixes

  • enum type returns 'UNRECOGNIZED' or '-1' in xxxToJSON/xxxToNumber (#566) (19911a1)

1.112.1 (2022-05-06)

Bug Fixes

  • use Long.fromValue instead of Long.fromString (#562) (c99891e)

1.112.0 (2022-05-02)

Bug Fixes

Features

  • add support for generating nice-grpc server and client stubs (#555) (8c19361), closes #545

1.111.0 (2022-05-01)

Features

  • include service and definition types with implementations (#552) (6b896f4)

next (????-??-??)

Features

  • When outputting service and service definition implementations, include types. Eg, before:

    export const TestDefinition = {
      name: 'Test',
      fullName: 'simple.Test',
      methods: {
        …
      },
    } as const;

    Now:

    export type TestDefinition = typeof TestDefinition;
    export const TestDefinition = {
      name: 'Test',
      fullName: 'simple.Test',
      methods: {
        …
      },
    } as const;

1.110.4 (2022-04-08)

Bug Fixes

  • Use Uint8Array.forEach in base64FromBytes (#544) (c7641ce)

1.110.3 (2022-04-08)

Bug Fixes

  • regression in being able to return a Date as a GRPC return value (#534) (22b76ec)

1.110.2 (2022-03-27)

Bug Fixes

  • Grpc-Web: Fix compilation failure when a service definition contains a client streaming call. (#535) (0c83892)

1.110.1 (2022-03-25)

Bug Fixes

  • Use a module star import for protobuf types. (#540) (f5b7700)

1.110.0 (2022-03-15)

Features

  • Add generic metadata parameter to the generic service definition interface. (#530) (0f5525a)

1.109.1 (2022-03-13)

Bug Fixes

1.109.0 (2022-03-13)

Features

  • import proto as type import if onlyTypes is set (25d8e8b)

1.108.0 (2022-03-07)

Features

1.107.0 (2022-03-04)

Features

  • Allow simultaneous services and generic service definitions (#512) (680831e)

1.106.2 (2022-02-27)

Bug Fixes

  • Add M1/ARM support for the test suite (#516) (7cf5625)

1.106.1 (2022-02-21)

Bug Fixes

  • support json_name containing hyphen on all field types (#521) (8d9e78e)

1.106.0 (2022-02-21)

Features

  • Support json names containing non-alphanumeric characters (#520) (ce44668)

1.105.2 (2022-02-17)

Bug Fixes

  • Fix snakeToCamel single value parsing. (#513) (e1ad866)

1.105.1 (2022-02-14)

Bug Fixes

  • generate canonical JSON encoding for FieldMasks (#510) (0ec4e97)

1.105.0 (2022-02-12)

Features

1.104.1 (2022-02-12)

Bug Fixes

  • make struct types play well with type registry (#503) (d62f854)

1.104.0 (2022-01-21)

Bug Fixes

Features

  • enable prototype for defaults for ts-proto-descriptors (#487) (2b5640f)

1.103.0 (2022-01-20)

Features

1.102.2 (2022-01-19)

Bug Fixes

  • Have snakeToCamel leave existing mixed case. (#482) (c0bf0fc), closes #478

1.102.1 (2022-01-19)

Bug Fixes

1.102.0 (2022-01-18)

Features

  • enable unknown fields for descriptor protos (#479) (824c996)

1.101.0 (2022-01-15)

Features

1.100.1 (2022-01-10)

Bug Fixes

1.100.0 (2022-01-09)

Features

  • support mapping ObjectId message as mongodb.ObjectId (#467) (8b23897)

1.99.0 (2022-01-07)

Features

  • yarn watch updates (specified) tests when source files change (#465) (275d0e7)

1.98.0 (2022-01-06)

Features

  • watch for changed integration test files (#464) (988cd7e)

1.97.2 (2022-01-06)

Performance Improvements

  • fromJSON returns object literal to allow v8 optimizations (#463) (5fcd05b)

1.97.1 (2022-01-05)

Bug Fixes

1.97.0 (2021-12-30)

Features

  • add an option to disable Exact types (#456) (9c53d7e)

1.96.1 (2021-12-28)

Performance Improvements

  • optimize object creation in decode, fromJSON and fromPartial (#457) (70832d3)

1.96.0 (2021-12-24)

Features

1.95.1 (2021-12-23)

Bug Fixes

  • Add service to the client constructor. (#455) (8c32104)

1.95.0 (2021-12-14)

Features

  • Add useOptionals=all to enable non-field members to be optional. (#402) (e7b70cb)

1.94.0 (2021-12-14)

Features

1.93.3 (2021-12-13)

Bug Fixes

  • support multiple options in snakeToCamel flag (#429) (cff6674), closes #423

1.93.2 (2021-12-09)

Bug Fixes

1.93.1 (2021-12-08)

Bug Fixes

  • Unwrap google.protobuf.BytesValue to Buffer when env=node (#439) (73aa836)

1.93.0 (2021-12-08)

Features

  • Allow optional suffix for generated files (#431) (d826966)

1.92.2 (2021-12-08)

Bug Fixes

1.92.1 (2021-12-02)

Bug Fixes

  • Respect stringEnums option in wrap function (#420) (7adf90c)

1.92.0 (2021-11-28)

Features

1.91.0 (2021-11-27)

Bug Fixes

  • use Long.fromValue instead of Long.fromString for improved robustness regarding already parsed objects (#405) (7bdc3ee)

Features

1.90.1 (2021-11-27)

Bug Fixes

  • code-generation for Services with Struct response types (#407) (f041fa1)

1.90.0 (2021-11-24)

Features

  • Add support for 'json_name' annotation (#408) (b519717)

1.89.0 (2021-11-24)

Features

  • Improve map reading (fromJSON/fromPartial) (#410) (057d438)

1.88.0 (2021-11-22)

Features

  • Support for Google.Protobuf.Value, ListValue and Struct (#396) (7dd9c16)

1.87.1 (2021-11-21)

Bug Fixes

  • code generation for int64 map values in fromPartial and fromJson (#395) (d3ea8eb)

1.87.0 (2021-11-16)

Features

  • Use ternary operator for conditional assignments (#394) (d84c084)

1.86.0 (2021-11-15)

Features

1.85.0 (2021-11-02)

Features

1.84.0 (2021-11-02)

Features

  • Reduce code size by using nullish coalescing operator in fromPartial (#376) (19d2ded)

1.83.3 (2021-10-28)

Bug Fixes

  • fix codegen for maps with wrapper value type (#370) (dd2481d)

1.83.2 (2021-10-26)

Bug Fixes

  • Add missing defaults to fromPartial if options.oneof is UNIONS (#375) (21781e9)

1.83.1 (2021-09-17)

Bug Fixes

  • deprecated grpc and replace with @grpc/grpc-js (#362) (1a11b97)

1.83.0 (2021-09-12)

Features

1.82.5 (2021-08-05)

Bug Fixes

  • Field starting with '_' generates an interface property starting with 'undefined' (#344) (fab354f)

1.82.4 (2021-08-04)

Bug Fixes

1.82.3 (2021-08-03)

Bug Fixes

1.82.2 (2021-07-11)

Bug Fixes

1.82.1 (2021-07-11)

Bug Fixes

  • Consistently apply lowerCaseServiceMethods=true (#332) (57f2473)

1.82.0 (2021-06-28)

Features

  • framework-agnostic service definitions (#316) (3d89282)

1.81.3 (2021-06-13)

Bug Fixes

  • close server stream on observer unsubscribe (#309) (4b72563)

1.81.2 (2021-06-13)

Bug Fixes

  • Fix TypeScript errors when compiling with noUncheckedIndexedAccess (#297) (f865e43)

1.81.1 (2021-05-23)

Bug Fixes

1.81.0 (2021-05-23)

Features

1.80.1 (2021-05-18)

Bug Fixes

1.80.0 (2021-05-09)

Features

1.79.8 (2021-05-09)

Bug Fixes

1.79.7 (2021-04-27)

Bug Fixes

1.79.6 (2021-04-24)

Bug Fixes

1.79.5 (2021-04-24)

Bug Fixes

1.79.4 (2021-04-23)

Bug Fixes

1.79.3 (2021-04-16)

Bug Fixes

  • Add long dep to ts-proto-descriptors. (#275) (0d20827)

1.79.2 (2021-04-07)

Bug Fixes

1.79.1 (2021-04-04)

Bug Fixes

1.79.0 (2021-04-02)

Features

1.78.1 (2021-04-02)

Bug Fixes

1.78.0 (2021-04-02)

Features

v1.77.0

  • Fix bytes initialization. Fixes #237. (willclarktech and webmaster128)
  • Better camelization for FOO_BAR to fooBar
  • Add message.$type fields and a type register. See #254. (aikoven)
  • Don't output long initialization for only types. Fixes #247.

v1.76.0

  • Always initial long when forceLong=long. Fixes #247. (daw1012345)

v1.75.0

  • Fix stringEnums combined with outputEncodeMethods

v1.74.0

  • Fix @improbable-eng imports to work with babel. (m!m)

v1.73.0

  • Fix compiler errors when strict is enabled. Fixes #235. (Graham)

v1.72.0

  • Revert the change in v1.70.0 that changed useOptionals handling of repeated fields.

Before this PR, useOptionals was purely a type system tweak, and this PR introduced a change to decoding semantics, so it needs to be re-introduced under a separate flag to avoid being a breaking change.

v1.71.0

  • Add constEnum option to enable const enums. Fixes #230. (lxgreen)

v1.70.0

  • Update useOptionals to make repeated fields optional as well. Fixes #225. (i-dot)

v1.69.0

  • Actually fix #223.

v1.68.0

  • Allow setting outputJsonMethods=true while using nestJs=true. Fixes #223.

v1.67.0

  • Add outputPartialMethods. See #207. (mharsat)

v1.66.0

  • Allow returnObservable=true when not using grpc-web. See #220. (ardyfeb)
  • Fix useDate=false in encoding/JSON methods. See #211. (willclarktech)
  • Revert back to object spread instead of Object.create for primitive default values. Fixes #218.

v1.65.0

  • Fix globalThis compilation errors with messages called Error

v1.64.0

  • Don't put default values on the wire while encoding. Fixed #213. (webmaster128)

v1.63.0

  • Qualify Object.create with globalThis to avoid collisions with message names of Object. Fixes #216.

v1.62.0

  • Use ts-proto-descriptors package to read/write the protoc stdin CodeGeneratorRequest and stdout CodeGeneratorResponse messages.

v1.61.0

  • Use Object.create in decode to create messages so that hasOwnProperty will be false for fields that are using default values.

    In theory fields being default values is not supposed to be observable (on the wire at least), but protobuf itself specifically uses this for the FieldDescriptorProto.oneofIndex field.

v1.60.0

  • New outputSchema option to include the *.proto schema/metadata in the generated output file (Vilsol)

v1.59.0

  • Fix DeepPartial imports when services and messages are in separate files

v1.58.0

  • Fix JSON parsing of long wrapper values when forceLong != long (jessebutterfield)

v1.57.0

  • Accidental duplicate publish.

v1.56.0

  • Fix import collisions for imported-only symbols (stezu)

v1.55.0

  • Fix missing fromTimestamp import in generated code, fixes #200 (jessebutterfield)

v1.54.0

  • Fix google.protobuf.BytesValue in fromPartial & fromJSON (ebakoba)

v1.53.0

  • Fix typo for method names in service output (willclarktech)

v1.52.0

  • Fix stringEnums=true in fromJSON and fromPartial output (mharsat)

v1.51.0

  • Re-publish to fix previous publish error.

v1.50.0

  • Allow setting addGrpcMetadata=true w/o using NestJS (#188)

v1.49.0

  • Add exportCommonSymbols flag (defaults true) that, when false skips exporting a few common symbols (i.e. DeepPartial) that make it more likely for multiple generated files to be imported by import * from ... and not have import conflicts, i.e. for barrel imports.

    v1.48.0

  • Tweak atob & btoa utility methods to prefix Buffer with globalThis to avoid issues in non-node envs. Fixes #77.

v1.47.0

  • Avoid import conflicts when an imported message name matches a locally-declared message name, see #36.

v1.46.0

  • Import protobufjs/minimal as a default import when using esModuleInterop
    • This should fix running in "type: module" ESM modules, see #181

v1.45.0

  • Add new esModuleInterop option to fix Long imports for projects that use esModuleInterop: true in their tsconfig.json.

v1.44.0

  • Fix DeepPartial when used with Longs (willclarktech)

v1.43.0

  • Polyfill globalThis for Node v10 support (willclarktech)

v1.42.1

  • Handle @deprecated when there are no other comments (ShakedH)

v1.42.0

  • Messages and fields that are marked as deprecated in *.proto files will have a @deprecated marker included in their JSDoc output (ShakedH)
  • Upgraded to the latest ts-poet

v1.41.1

  • [grpc-web] Remove import = to support not using synthetic default imports

v1.41.0

  • [grpc-web] Fix code generation errors introduced in v1.40.0
  • [grpc-web] Revert breaking change of unaryTransport / invokeTransport
    • Now client constructors take transport & streamingTransport, and streaming calls will use streamingTransport is set, and otherwise fallback on transport.
  • [grpc-web] Remove rxjs dependency unless streaming is actually used

v1.40.0

  • Add support for grpc-web streaming responses (PhilipMantrov)

v1.38.0

  • Add unrecognizedEnum option for disabling the UNRECOGNIZED enum values (ShakedH)

v1.37.0

  • Fix forceLong behavior when using wrapper types (Graham)
  • Add rpcDataLoaderOptions (Felix Mo)
  • Add useDate option to disable java.util.Date mapping (Graham)
    • This is primarily useful for NestJS which can only encode the original google.protobuf.Timestamp type
  • Add stringEnums option (Bastian Eicher)
    • Note this is not supported in the binary encode/decode methods yet
  • Avoid unnecessary import = usage (Graham)

v1.36.0

  • Add a protobufPackage exported const for metadata

v1.35.1

  • Fix maps of enums (@ahmadj-levelbenefits)

v1.35.0

  • Fix proto3 optional support

v1.34.0

  • Fix blobs in fromPartial and toJSON

v1.33.0

  • Automatically configure protobuf.util.Long when 64-bit numbers are used (fixes #78)

v1.32.0

  • Add support for the experimental proto3 optional keyword

v1.31.0

  • Fix oneof=unions not decoding default values correctly (@philikon)

v1.30.0

  • Accept cross-call metadata args in the GrpcWebImpl constructor
  • Accept DeepPartial request types for grpc-web calls

v1.29.0

  • Fix toJSON with maps of messages (#124 by @mscolnick)

v1.28.0

  • Use enum keyword for modeling keywords again
  • Fix maps of google.protobuf.Timestamps
  • Fix name conflicts when using google.type.Date
  • Fix maps of bytes in JSON
  • Add initial support for grpc-web using the @improbable-eng/grpc-web runtime

v1.27.1

  • Extra release to ensure the build output is correct.

v1.27.0

  • Added a addNestjsRestParameter=true that adds a ...rest: any parameter to use NestJS decorators like @CurrentUser (@ToonvanStrijp)

v1.26.0

  • Added a oneof=properties that generates oneofs as an Abstract Data Type (ADT) of each option (@philikon)

v1.25.0

  • Added a useOptionals=true option that makes non-scaler/oneof fields optional, i.e. message?: Message instead of message: Message | undefined (@philikon)

v1.24.0

  • Messages no longer use a base prototype to get default values. (@cliedeman)

v1.23.0

  • Added a env=both option and made that the default

    This restores the pre-1.22.0 behavior that bytes are Uint8Array so that the Buffer support is not a breaking change. Users have to opt-in with env=node.

    Also fixes a bug introduced in 1.22.0 that output an as Buffer without first checking env=node.

v1.22.0

  • Added a env=node/env=browser option that defaults to env=node

    Currently env=node only changes the types of bytes from Uint8Array to Buffer, as a convenience for Node programming where Buffer (which is the defacto subclass of Uint8Array) is more widely used (@dolsup)

v1.21.5

  • Drop falsey values in maps in decode and fromPartial. Fixes #79. (@timostamm)

v1.21.4

  • Repeated fields cannot be optional, fixes #80 (@philikon)

v1.21.2 and v1.21.3

  • Use globalThis.Error instead of global.Error for browsers, fix for #70

v1.21.1

  • Fix NestJS decorator for only-stream-in / only-stream-out methods

v1.21.0

  • Allow Message.decode methods to take a Uint8Array (or Buffer) directly instead of having to pass a Reader

v1.20.2

  • Another fix for NestJS-related PACKAGE_NAME consts

v1.20.1

  • Fix for NestJS-related PACKAGE_NAME consts

v1.20.0

  • Support for NestJS streams

v1.19.0

  • Added support for generating NestJS friendly output (thanks Ian Gregson!)
    • See the readme for new options nestJs, lowerCaseServiceMethods, returnObservable, etc.