-
Notifications
You must be signed in to change notification settings - Fork 105
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
Rework framework adapters, and add new ones #61
Conversation
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.
The http and https adapters correspond to the native Node modules. They are not intended to behave differently per platform.
Thanks for adding support for the std/http
server of Deno! Rather than making the existing http identifier ambiguous, we should add a new name for the adapter. Pick any you like.
Your PR starts dividing the supported platforms into the platform-specific code. This used not to be the case. I don't have strong opinions on the matter, but here are pros and cons of platform-specific code.
Pro:
- no superfluous entries in autocomplete
Con:
missing Node adapters in API reference(edit: they don't show up there)- increases dependency on
platform.{deno,node}.ts
Now that I think about it, it does indeed make a lot of sense to keep runtime-specific adapters in runtime-specific files. Feel free to restructure It would still be preferable if there were no name clashes, i.e. that no framework adapter appears in both environments. |
89b2c2b
to
4e6f075
Compare
@kraftwerk28 awaiting your review. |
src/convenience/frameworks.deno.ts
Outdated
const reqUrl = new URL(req.url); | ||
return { | ||
update: (req.method !== "POST" || reqUrl.pathname !== secretPath) | ||
? Promise.resolve(undefined) |
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.
Why resolving undefined
? I'd expect a rejection here.
src/convenience/webhook.ts
Outdated
timeoutMilliseconds = 10_000, | ||
) { | ||
const server = frameworkAdapters[framework] ?? standard; | ||
adapter?: A, |
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 missed this. This is a breaking change so we either have to wait with merging until 2.0 (some time later next year maybe?), or it has to be reverted.
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.
Alternatively, we could introduce a union type. This would still permit string identifiers (non-breaking) but optionally allow people to pass their own adapter. May make it hard to find good types, not sure.
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, this should be in the next major. Thought I feel that giving a choice among predefined frameworks has less flexibility than allowing to put either a custom one or import from grammY's code. I'll add a temporary union
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 don't see why users would have to access the predefined objects. How about not exposing them, and simply allowing string identifiers as well as custom objects? One could pass a string to use a predefined one, or an object to define a custom one.
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.
Is there a reason for exposing them?
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.
That's also what I have in mind. Plus, letting the adapters become implementation details that aren't exported.
f30722f
to
680358e
Compare
Why the force-push? Did anything else change? |
I did a pull-rebase from |
Is it OK to disable |
I see. Now I'll need to go through all old commits again. Merge commits are usually much easier to review. Now that we're squash-merging PRs, so having a few merges on the feature branches isn't problematic. |
Yes. |
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.
IIRC we agreed on proceeding like this.
- Do not support path matching for now, introduce this with a breaking change in the next major version which can perform more substantial refactoring.
- Do not expose all config objects. Instead, let them be identified via strings. It is still allowed to pass your own config object, which effectively allows you to do path matching manually.
- The current organisation of files (separating Deno/Node) can stay that way, as long as 2 is applied.
Make sure the identifier of the adapters do not change. This is currently the case for at least awsLambda
.
src/convenience/frameworks.node.ts
Outdated
req.method !== "POST" || | ||
!safeStringCompare(secretPath, req.url ?? "") | ||
) { | ||
reject(); |
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.
Please reject with an error that has a helpful error message
src/convenience/frameworks.node.ts
Outdated
const raw = Buffer.concat(chunks).toString("utf-8"); | ||
resolve(JSON.parse(raw)); | ||
}) | ||
.once("error", (e) => reject(e)); |
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.
nit:
.once("error", (e) => reject(e)); | |
.once("error", reject); |
src/convenience/webhook.ts
Outdated
try { | ||
await timeoutIfNecessary( | ||
bot.handleUpdate(await update, webhookReplyEnvelope), | ||
typeof onTimeout === "function" | ||
? () => onTimeout(...args) | ||
: onTimeout, | ||
timeoutMilliseconds, | ||
); | ||
if (end !== undefined && !usedWebhookReply) end(); | ||
} catch { | ||
// Adapter rejected processing an update | ||
} |
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.
Also, we should not suppress errors, but throw them instead.
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.
Does it mean an error occured if the adapter just rejected the request from Telegram (e.g. requrst.url !== secretPath
)? Or we can create an class UpdateRejected extends Error
and throw iif !(error instanceof UpdateRejected)
.
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 are not going to support secret path matching in this iteration. If an adapter throws, something is wrong.
If we later implement adapters that choose not to process some requests, they must integrate with their respective web frameworks, and e.g. call next()
.
71da33a
to
80650c3
Compare
80650c3
to
79efe98
Compare
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.
LGTM now.
As stated in the conversation above, we need to change the call signature of webhookCallback
in order to support more complex options objects in a usable and convenient way. This is a breaking change that will be introduced in the next major release.
Until then, users must route their updates manually, and perform necessary path matching themselves if they decide to go for a low-level framework that does not support this out of the box.
Thank you for this contribution, and my apologies that it took so long to get this through. @all-contributors add @kraftwerk28 for code, ideas, and review! |
I've put up a pull request to add @kraftwerk28! 🎉 |
No description provided.