-
Notifications
You must be signed in to change notification settings - Fork 206
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
Add Pub/Sub support + HTTPS testing #925
Conversation
While adding Pub/Sub support I noticed that there were now v2/ tests. Added those tests + fixes that they uncovered. Also fixed issue where 'firebase-functions/logger' wasn't working as an import in my test project.
@@ -22,6 +22,9 @@ | |||
|
|||
/** @internal */ |
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.
If this is going to be a package export, perhaps we should call it core.ts
instead of base.ts
? Base to me seems like a class that will be extended whereas this is more shared interfaces.
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.
Sure
|
||
/** The resource which published this event. */ | ||
source: string; | ||
|
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.
Shouldn't there also be a subject?: string
here? Also, have you thought about how we want to handle a replacement for context.params
in a v2 world since it won't be in the payload and isn't a part of CloudEvent?
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.
RE subject, yes. I was just documenting the fields I saw in prod and subject was missing for P/S events.
RE params, why not event.params?
src/v2/providers/https.ts
Outdated
@@ -44,12 +44,16 @@ export type HttpsHandler = ( | |||
request: Request, | |||
response: express.Response | |||
) => void | Promise<void>; | |||
export type CallableHandler = ( | |||
data: any, | |||
export type CallableHandler<T> = ( |
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.
We could make this CallableHandler<T,U>
and let both the request and response types be specified.
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.
I was going to do that in a followup conversation per Chat, but can do it now.
src/v2/providers/pubsub.ts
Outdated
* | ||
* @param data Payload of a Pub/Sub message. | ||
*/ | ||
export class Message { |
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.
Should this be generic as well, allowing folks to specify onMessagePublished<T>({data: {json: T}})
?
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.
I'm worried that this will affect readability more than it improves ergonomics, but we can try it out.
src/v2/providers/pubsub.ts
Outdated
constructor(data: any) { | ||
this.messageId = data.messageId; | ||
this.data = data.data; | ||
(this.attributes = data.attributes || {}), (this._json = data.json); |
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 line is super weird, what's going on here? I would expect the comma to be a syntax error...
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.
My fingers may have run faster than my brain and code complete probably had a hand. In this case, a comma is the same as a semicolon though the parens are necessary due to order of operations. Same with C++.
src/v2/providers/pubsub.ts
Outdated
} | ||
|
||
const func = (raw: CloudEvent<unknown>) => { | ||
const messagePublisheData = raw.data as { |
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.
Missing a d
at the end of "Published"
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.
fixed
src/v2/providers/pubsub.ts
Outdated
|
||
func.run = callback; | ||
|
||
func.__trigger = 'silencing transpiler'; |
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.
?
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.
Added comments
spec/v2/providers/pubsub.spec.ts
Outdated
|
||
it('should create a complex trigger with appropraite values', () => { | ||
const result = pubsub.onMessagePublished( | ||
{ |
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.
I wonder if we should extract out a common "kitchen sink" trigger that can be used across tests...
import { FULL_OPTIONS, FULL_TRIGGER } from "./helpers";
pubsub.onMessagePublished({ ...FULL_OPTIONS, topic: 'topic' });
expect(result.__trigger).to.deep.equal({ ...FULL_TRIGGER, eventTrigger: EVENT_TRIGGER });
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.
I can buy it
src/v2/providers/pubsub.ts
Outdated
|
||
export function onMessagePublished( | ||
topicOrOptions: string | PubSubOptions, | ||
callback: (event: CloudEvent<MessagePublishedData>) => any | Promise<any> |
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.
I'd prefer "handler" to "callback" I think
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.
Me too
src/v2/providers/https.ts
Outdated
context: CallableContext | ||
) => any | Promise<any>; | ||
|
||
export type HttpsFunction = HttpsHandler & { __trigger: unknown }; | ||
export interface CallableFunction<T> extends HttpsHandler { | ||
__trigger: unknown; | ||
run(data: T, context: CallableContext): any | Promise<any>; |
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.
I probably knew this at one point, but what's with .run
?
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.
Finally someone willing to stand up to me in code reviews! 😄
spec/v2/providers/pubsub.spec.ts
Outdated
|
||
it('should create a complex trigger with appropraite values', () => { | ||
const result = pubsub.onMessagePublished( | ||
{ |
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.
I can buy it
@@ -22,6 +22,9 @@ | |||
|
|||
/** @internal */ |
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.
Sure
|
||
/** The resource which published this event. */ | ||
source: string; | ||
|
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.
RE subject, yes. I was just documenting the fields I saw in prod and subject was missing for P/S events.
RE params, why not event.params?
src/v2/providers/https.ts
Outdated
@@ -44,12 +44,16 @@ export type HttpsHandler = ( | |||
request: Request, | |||
response: express.Response | |||
) => void | Promise<void>; | |||
export type CallableHandler = ( | |||
data: any, | |||
export type CallableHandler<T> = ( |
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.
I was going to do that in a followup conversation per Chat, but can do it now.
src/v2/providers/pubsub.ts
Outdated
* | ||
* @param data Payload of a Pub/Sub message. | ||
*/ | ||
export class Message { |
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.
I'm worried that this will affect readability more than it improves ergonomics, but we can try it out.
src/v2/providers/pubsub.ts
Outdated
*/ | ||
get json(): any { | ||
if (typeof this._json === 'undefined') { | ||
this._json = JSON.parse( |
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.
I like it.
src/v2/providers/pubsub.ts
Outdated
|
||
export function onMessagePublished( | ||
topicOrOptions: string | PubSubOptions, | ||
callback: (event: CloudEvent<MessagePublishedData>) => any | Promise<any> |
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.
Me too
} else { | ||
topic = topicOrOptions.topic; | ||
opts = { ...topicOrOptions }; | ||
delete (opts as any).topic; |
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.
I could equally easily just say opts = topicOrOptions
. optionsToTriggerAnnotations
will skip over anything that's unknown. I definitely don't want that function altering its parameters though. I just thought here that clone = {... original }; delete clone.unwanted
was a fine way of saying _.omit(original, "unwanted")
and removing the unwanted field is just defensive programming.
src/v2/providers/pubsub.ts
Outdated
} | ||
|
||
const func = (raw: CloudEvent<unknown>) => { | ||
const messagePublisheData = raw.data as { |
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.
fixed
src/v2/providers/pubsub.ts
Outdated
|
||
func.run = callback; | ||
|
||
func.__trigger = 'silencing transpiler'; |
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.
Added comments
While adding Pub/Sub support I noticed that there were now v2/ tests.
Added those tests + fixes that they uncovered.
Also fixed issue where 'firebase-functions/logger' wasn't working as
an import in my test project.