Skip to content
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

Web API Type Safety #1673

Merged
merged 125 commits into from
Jan 15, 2024
Merged

Web API Type Safety #1673

merged 125 commits into from
Jan 15, 2024

Conversation

filmaj
Copy link
Contributor

@filmaj filmaj commented Oct 5, 2023

This work builds off #1670. Web API arguments are worked on to make type safe, though responses were not closely validated as that would require a lot more work. I am also leaving notes on API arguments and responses as I test them out, with breadcrumbs on future improvements / breaking changes.

Once merged, this PR intends to fix #1323.

USEFUL WHEN ASSEMBLING CHANGELOG: For the list of breaking changes introduced, best to look at the src/methods.ts file in this commit and search for "TODO".

Open Questions

  • How deeply do we want to type the Manifest schema? The answer here determines changes to still apply to the apps.manifest.* APIs in this PR.
    • Answer: somewhat reasonably deeply. Will do my best!

Deprecations being removed

While here, and since this PR is in prep for a new major release, also took the opportunity to remove methods that were marked as deprecated:

  • channels.*
  • groups.*
  • im.*
  • mpim.*

New Deprecations

We will deprecate the following method groups, given they are mentioned as such in their reference docs.

  • oauth.access (superseded by the new oauth.v2.* methods)
  • stars.* (docs specifically mention end-users cant interact with them in the client anymore, presumably will be replaced with the Later feature at some point)
  • workflows.* (legacy steps-from-apps related workflow methods)

Updates/Testing

Documenting, DRYing up and type-safety-ifying arguments for all the methods against the documentation. Also writing type tests for the arguments as I go.

  • admin.*:
    • refactored request shapes argument w/ docs
    • type tests
  • admin.analytics.getFile (need to get unblocked on specific enterprise org setup, should be able to get access to that Monday Nov 27):
    • refactored request shapes argument w/ docs
    • type tests
  • api.test
    • refactored request shapes argument w/ docs
    • type tests
  • apps.manifest.* (see open questions above)
    • refactored request shapes argument w/ docs
    • type tests
  • auth.*
    • refactored request shapes argument w/ docs
    • type tests
  • bookmarks.*
    • refactored request shapes argument w/ docs
    • type tests
  • calls.*
    • refactored request shapes argument w/ docs
    • type tests
  • chat.*
    • refactored request shapes argument w/ docs
    • type tests
  • conversations.*
    • refactored request shapes argument w/ docs
    • type tests
  • dialog.open
    • refactored request shapes argument w/ docs
    • type tests
  • dnd.*
    • refactored request shapes argument w/ docs
    • type tests
  • emoji.list
    • refactored request shapes argument w/ docs
    • type tests
  • files.*
    • refactored request shapes argument w/ docs
    • type tests
  • migration.exchange
    • refactored request shapes argument w/ docs
    • type tests
  • oauth.*
    • refactored request shapes argument w/ docs
    • type tests
  • openid.*
    • refactored request shapes argument w/ docs
    • type tests
  • pins.*
    • refactored request shapes argument w/ docs
    • type tests
  • reactions.*
    • refactored request shapes argument w/ docs
    • type tests
  • reminders.*
    • refactored request shapes argument w/ docs
    • type tests
  • rtm.*
    • refactored request shapes argument w/ docs
    • type tests
  • search.*
    • refactored request shapes argument w/ docs
    • type tests
  • stars.*
    • refactored request shapes argument w/ docs
  • team.*
    • refactored request shapes argument w/ docs
    • type tests
  • tooling.*
    • refactored request shapes argument w/ docs
    • type tests
  • usergroups.*
    • refactored request shapes argument w/ docs
    • type tests
  • users.*
    • refactored request shapes argument w/ docs
    • type tests
  • views.*
    • refactored request shapes argument w/ docs
    • type tests
  • workflows.*
    • refactored request shapes argument w/ docs

@filmaj filmaj added semver:major enhancement M-T: A feature request for new functionality pkg:web-api applies to `@slack/web-api` draft labels Oct 5, 2023
@filmaj filmaj added this to the [email protected] milestone Oct 5, 2023
@filmaj filmaj self-assigned this Oct 5, 2023
…g, unknown>`. Remove unneeded disabling of no-trailing-space rule. Replace use of `headers: any` in private `serializeApiCallOptions` method with `Record<string, string>`.
…allResult. Tweak fileUploadV2 return type as a result.
@filmaj filmaj marked this pull request as ready for review December 13, 2023 20:45
Copy link
Member

@seratch seratch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't guarantee everything works as with before but I am confident that this PR is carefully crafted. Great work!

shouldStop?: PaginatePredicate,
reduce?: PageReducer<A>,
): (Promise<A> | AsyncIterable<WebAPICallResult>) {
if (!cursorPaginationEnabledMethods.has(method)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this check is not a big deal at all but did you have to do so due to some changes in this PR? Also, the pagnation method does not provide type-safety for arguments: https://slack.dev/node-slack-sdk/web-api#pagination Do you have any possible ideas to improve it? (not necessarily work on it in this PR)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I removed this as I removed the cursorPaginationEnabledMethods variable altogether. I did not find it gave much value (its only use was to issue the warning below). I believe I brought this up in an early discussion internally two months ago or so (search for "from:fil paginate" in our #team-devrel-tools channel internally).

As for ideas on how to improve it, perhaps the API could be changed so that each API method supporting pagination could optionally return an iterator? This way the developer doesn't have to provide the method name string as that would be known by the framework, and the type safety for method arguments provided by this PR would apply as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for clarifying. Makes sense!

* @param options
*/
public async filesUploadV2(options: FilesUploadV2Arguments): Promise<WebAPICallResult> {
public async filesUploadV2(options: FilesUploadV2Arguments): Promise<
WebAPICallResult & { files: FilesCompleteUploadExternalResponse[] }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch!

packages/web-api/src/types/request/bots.ts Outdated Show resolved Hide resolved
@@ -0,0 +1,224 @@
import type { KnownBlock, Block, MessageAttachment, LinkUnfurls, MessageMetadata } from '@slack/types';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am still not 100% confident that all the patterns here are correct ... but well done!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I think this is a risky area.. all possible combinations of Block elements, etc, may be hard to verify... but I think as long as we are OK to tell developers that find a problem, "please use // @ts-expect-error as a workaround until we release a patch", it should be OK.

app_home?: ManifestAppHome;
/**
* @description A subgroup of settings that describe {@link https://api.slack.com/legacy/enabling-bot-users bot user} configuration.
* @see {@link https://api.slack.com/legacy/enabling-bot-users Legacy bots}.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like linking this "legacy" document here but indeed there is no other document for this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took this from the Manifest fields documentation here: https://api.slack.com/reference/manifests#features

The link originally links to api.slack.com/bot-user which redirects to the above link.

@@ -24,6 +16,7 @@ export interface ResponseMetadata {

export interface AdminAnalyticsMemberDetails {
enterprise_id: string;
team_id: string;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch

@@ -0,0 +1,45 @@
import { expectAssignable, expectError } from 'tsd';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding these tests!

@@ -5,7 +5,7 @@

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect!

filmaj and others added 3 commits December 14, 2023 08:10
@filmaj filmaj removed the draft label Dec 14, 2023
@filmaj filmaj merged commit d53ef02 into main Jan 15, 2024
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement M-T: A feature request for new functionality pkg:web-api applies to `@slack/web-api` semver:major
Projects
None yet
Development

Successfully merging this pull request may close these issues.

WebClient arguments and responses are not type safe in TypeScript
2 participants