-
Notifications
You must be signed in to change notification settings - Fork 351
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: regression in being able to return a Date as a GRPC return value #534
Changes from 1 commit
bc31222
fa545a2
21b0024
0df959a
2c8a4ea
bd00e98
b251971
b762bde
12b185a
db169c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* eslint-disable */ | ||
import { util, configure, Writer, Reader } from 'protobufjs/minimal'; | ||
import * as Long from 'long'; | ||
|
||
export const protobufPackage = 'google.protobuf'; | ||
|
||
/** | ||
* A generic empty message that you can re-use to avoid defining duplicated | ||
* empty messages in your APIs. A typical example is to use it as the request | ||
* or the response type of an API method. For instance: | ||
* | ||
* service Foo { | ||
* rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); | ||
* } | ||
* | ||
* The JSON representation for `Empty` is empty JSON object `{}`. | ||
*/ | ||
export interface Empty {} | ||
|
||
function createBaseEmpty(): Empty { | ||
return {}; | ||
} | ||
|
||
export const Empty = { | ||
encode(_: Empty, writer: Writer = Writer.create()): Writer { | ||
return writer; | ||
}, | ||
|
||
decode(input: Reader | Uint8Array, length?: number): Empty { | ||
const reader = input instanceof Reader ? input : new Reader(input); | ||
let end = length === undefined ? reader.len : reader.pos + length; | ||
const message = createBaseEmpty(); | ||
while (reader.pos < end) { | ||
const tag = reader.uint32(); | ||
switch (tag >>> 3) { | ||
default: | ||
reader.skipType(tag & 7); | ||
break; | ||
} | ||
} | ||
return message; | ||
}, | ||
|
||
fromJSON(_: any): Empty { | ||
return {}; | ||
}, | ||
|
||
toJSON(_: Empty): unknown { | ||
const obj: any = {}; | ||
return obj; | ||
}, | ||
|
||
fromPartial<I extends Exact<DeepPartial<Empty>, I>>(_: I): Empty { | ||
const message = createBaseEmpty(); | ||
return message; | ||
}, | ||
}; | ||
|
||
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; | ||
|
||
export type DeepPartial<T> = T extends Builtin | ||
? T | ||
: T extends Array<infer U> | ||
? Array<DeepPartial<U>> | ||
: T extends ReadonlyArray<infer U> | ||
? ReadonlyArray<DeepPartial<U>> | ||
: T extends {} | ||
? { [K in keyof T]?: DeepPartial<T[K]> } | ||
: Partial<T>; | ||
|
||
type KeysOfUnion<T> = T extends T ? keyof T : never; | ||
export type Exact<P, I extends P> = P extends Builtin | ||
? P | ||
: P & { [K in keyof P]: Exact<P[K], I[K]> } & Record<Exclude<keyof I, KeysOfUnion<P>>, never>; | ||
|
||
// If you get a compile-error about 'Constructor<Long> and ... have no overlap', | ||
// add '--ts_proto_opt=esModuleInterop=true' as a flag when calling 'protoc'. | ||
if (util.Long !== Long) { | ||
util.Long = Long as any; | ||
configure(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
useDate=true | ||
useDate=true,outputServices=generic-definitions,outputServices=default |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -106,18 +106,22 @@ function generateRegularRpcMethod( | |
methodDesc: MethodDescriptorProto | ||
): Code { | ||
assertInstanceOf(methodDesc, FormattedMethodDescriptor); | ||
const { options } = ctx; | ||
const { options, utils } = ctx; | ||
const Reader = imp('Reader@protobufjs/minimal'); | ||
const rawInputType = rawRequestType(ctx, methodDesc); | ||
const inputType = requestType(ctx, methodDesc); | ||
const outputType = responseType(ctx, methodDesc); | ||
const rawOutputType = responseType(ctx, methodDesc, { keepValueType: true }); | ||
|
||
const params = [...(options.context ? [code`ctx: Context`] : []), code`request: ${inputType}`]; | ||
const maybeCtx = options.context ? 'ctx,' : ''; | ||
|
||
let encode = code`${rawInputType}.encode(request).finish()`; | ||
let decode = code`data => ${outputType}.decode(new ${Reader}(data))`; | ||
|
||
console.error(); | ||
if (options.useDate && rawOutputType.toString().includes('Timestamp')) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's check |
||
decode = code`data => ${utils.fromTimestamp}(${rawOutputType}.decode(new ${Reader}(data)))`; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yeah... this makes sense, and I see what you mean by this is a slippery slope to just re-coding ~all of our well known/use date/etc. special type handling that we currently have ~quite a few of here: https://github.com/stephenh/ts-proto/blob/main/src/main.ts#L839 Yeah, it'd be great to re-use code, but dunno, I'm pretty comfortable with what you have as a point/incremental solution to a use case that's covered by a test case, and we will magically refactor things at some point in the future (...probably... :-)). |
||
} | ||
if (methodDesc.clientStreaming) { | ||
encode = code`request.pipe(${imp('map@rxjs/operators')}(request => ${encode}))`; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This snuck in :-)