Skip to content

Commit

Permalink
feat: add option noDefaultsForOptionals (#1051)
Browse files Browse the repository at this point in the history
Adds a new option - `noDefaultsForOptionals` that allows for
compatibility with [Square/Block's Wire Protobuf
implementation](https://square.github.io/wire/) with respect to
defaulting of optional fields.

Note: As per the documentation added to the readme, this option provides
non-standard protobuf behaviour so it would be understandable if this
isn't something you'd like in the library. I'm hoping with the
appropriate warning in the docs that you'll consider this as as option.
  • Loading branch information
robmonie authored Jun 7, 2024
1 parent e61deab commit 41d1020
Show file tree
Hide file tree
Showing 21 changed files with 1,262 additions and 13 deletions.
5 changes: 5 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,11 @@ export interface User {
}
```

- 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 it's 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](https://square.github.io/wire/) 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](https://docs.nestjs.com/microservices/grpc). `ts-proto` generates `interfaces` and `decorators` for you controller, client. For more information see the [nestjs readme](NESTJS.markdown).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Proto2TestMessage } from './proto-2';

describe('proto2', () => {
it('preserves null values on optional fields', () => {
const message = Proto2TestMessage.fromJSON({
intValue: null,
stringValue: null,
boolValue: null,
mapValue: {},
});

const data = Proto2TestMessage.encode(message).finish();
const result = Proto2TestMessage.decode(data);

expect(result).toEqual(message);
});

it('encodes/decodes non-null values on optional fields', () => {
const message = Proto2TestMessage.fromJSON({
intValue: 100,
stringValue: 'string',
boolValue: true,
mapValue: {
v1:'1',
v2:'2',
}
});

const data = Proto2TestMessage.encode(message).finish();
const result = Proto2TestMessage.decode(data);

expect(result).toEqual(message);
});

it('encodes/decodes non-null values set to standard protobuf defaults', () => {
const message = Proto2TestMessage.fromJSON({
intValue: 0,
stringValue: '',
boolValue: false,
mapValue: {},
});

const data = Proto2TestMessage.encode(message).finish();
const result = Proto2TestMessage.decode(data);

expect(result).toEqual(message);
});
})
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
noDefaultsForOptionals=true,useNullAsOptional=true
Binary file not shown.
11 changes: 11 additions & 0 deletions integration/no-defaults-for-optionals-with-nulls/proto-2.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
syntax = "proto2";

package omit;

message Proto2TestMessage {
optional bool boolValue = 1;
optional int32 intValue = 2;
optional string stringValue = 3;

map<string, string> mapValue = 4;
}
238 changes: 238 additions & 0 deletions integration/no-defaults-for-optionals-with-nulls/proto-2.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
15 changes: 15 additions & 0 deletions integration/no-defaults-for-optionals-with-nulls/proto-3.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
syntax = "proto3";

package omit;

message Proto3TestMessage {
bool boolValue = 1;
int32 intValue = 2;
string stringValue = 3;

optional bool optionalBoolValue = 4;
optional int32 optionalIntValue = 5;
optional string optionalStringValue = 6;

map<string, string> mapValue = 7;
}
Loading

0 comments on commit 41d1020

Please sign in to comment.