Skip to content

Commit db3a136

Browse files
authored
feat(typescript): export types for strategy options, auth options, and the resulting authentication object (#5)
1 parent f1454df commit db3a136

File tree

8 files changed

+297
-84
lines changed

8 files changed

+297
-84
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
- [GitHub APP user authentication token with expiring disabled](#github-app-user-authentication-token-with-expiring-disabled)
2929
- [GitHub APP user authentication token with expiring enabled](#github-app-user-authentication-token-with-expiring-enabled)
3030
- [`auth.hook(request, route, parameters)` or `auth.hook(request, options)`](#authhookrequest-route-parameters-or-authhookrequest-options)
31+
- [Types](#types)
3132
- [Contributing](#contributing)
3233
- [License](#license)
3334

@@ -977,6 +978,27 @@ const requestWithAuth = request.defaults({
977978
const { data: user } = await requestWithAuth("GET /user");
978979
```
979980

981+
## Types
982+
983+
```ts
984+
import {
985+
GitHubAppAuthentication,
986+
GitHubAppAuthenticationWithExpiration,
987+
GitHubAppAuthOptions,
988+
GitHubAppStrategyOptions,
989+
GitHubAppStrategyOptionsDeviceFlow,
990+
GitHubAppStrategyOptionsExistingAuthentication,
991+
GitHubAppStrategyOptionsExistingAuthenticationWithExpiration,
992+
GitHubAppStrategyOptionsWebFlow,
993+
OAuthAppAuthentication,
994+
OAuthAppAuthOptions,
995+
OAuthAppStrategyOptions,
996+
OAuthAppStrategyOptionsDeviceFlow,
997+
OAuthAppStrategyOptionsExistingAuthentication,
998+
OAuthAppStrategyOptionsWebFlow,
999+
} from "@octokit/auth-oauth-user";
1000+
```
1001+
9801002
## Contributing
9811003

9821004
See [CONTRIBUTING.md](CONTRIBUTING.md)

src/auth.ts

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
import { AuthOptions, Authentication, State, ClientType } from "./types";
1+
import {
2+
OAuthAppAuthOptions,
3+
GitHubAppAuthOptions,
4+
OAuthAppAuthentication,
5+
GitHubAppAuthentication,
6+
GitHubAppAuthenticationWithExpiration,
7+
OAuthAppState,
8+
GitHubAppState,
9+
} from "./types";
210
import { getAuthentication } from "./get-authentication";
311
import {
412
checkToken,
@@ -8,32 +16,48 @@ import {
816
resetToken,
917
} from "@octokit/oauth-methods";
1018

11-
export async function auth<TClientType extends ClientType>(
12-
state: State,
13-
options: AuthOptions = {}
14-
): Promise<Authentication<TClientType>> {
19+
export async function auth(
20+
state: OAuthAppState,
21+
options?: OAuthAppAuthOptions
22+
): Promise<OAuthAppAuthentication>;
23+
24+
export async function auth(
25+
state: GitHubAppState,
26+
options?: GitHubAppAuthOptions
27+
): Promise<GitHubAppAuthentication | GitHubAppAuthenticationWithExpiration>;
28+
29+
export async function auth(
30+
state: OAuthAppState | GitHubAppState,
31+
options: OAuthAppAuthOptions | GitHubAppAuthOptions = {}
32+
): Promise<
33+
| OAuthAppAuthentication
34+
| GitHubAppAuthentication
35+
| GitHubAppAuthenticationWithExpiration
36+
> {
1537
if (!state.authentication) {
16-
state.authentication = await getAuthentication(state);
38+
// This is what TS makes us do ¯\_(ツ)_/¯
39+
state.authentication =
40+
state.clientType === "oauth-app"
41+
? await getAuthentication(state)
42+
: await getAuthentication(state);
1743
}
1844

1945
if (state.authentication.invalid) {
2046
throw new Error("[@octokit/auth-oauth-user] Token is invalid");
2147
}
2248

23-
const currentAuthentication = (state.authentication as unknown) as Authentication<TClientType>;
49+
const currentAuthentication = state.authentication;
2450

2551
// (auto) refresh for user-to-server tokens
2652
if ("expiresAt" in currentAuthentication) {
2753
if (
2854
options.type === "refresh" ||
29-
// @ts-expect-error TBD
3055
new Date(currentAuthentication.expiresAt) < new Date()
3156
) {
3257
const { authentication } = await refreshToken({
3358
clientType: "github-app",
3459
clientId: state.clientId,
3560
clientSecret: state.clientSecret,
36-
// @ts-expect-error TBD
3761
refreshToken: currentAuthentication.refreshToken,
3862
request: state.request,
3963
});
@@ -77,6 +101,11 @@ export async function auth<TClientType extends ClientType>(
77101
// @ts-expect-error TBD
78102
...authentication,
79103
};
104+
105+
return state.authentication as
106+
| OAuthAppAuthentication
107+
| GitHubAppAuthentication
108+
| GitHubAppAuthenticationWithExpiration;
80109
} catch (error) {
81110
// istanbul ignore else
82111
if (error.status === 404) {
@@ -88,8 +117,6 @@ export async function auth<TClientType extends ClientType>(
88117

89118
throw error;
90119
}
91-
92-
return state.authentication as Authentication<TClientType>;
93120
}
94121

95122
// invalidate
@@ -111,8 +138,8 @@ export async function auth<TClientType extends ClientType>(
111138
}
112139

113140
state.authentication.invalid = true;
114-
return state.authentication as Authentication<TClientType>;
141+
return state.authentication;
115142
}
116143

117-
return state.authentication as Authentication<TClientType>;
144+
return state.authentication;
118145
}

src/get-authentication.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,31 @@
11
// @ts-nocheck there is only place for one of us in this file. And it's not you, TS
22

3-
import { State, ClientType, Authentication } from "./types";
3+
import {
4+
OAuthAppState,
5+
GitHubAppState,
6+
OAuthAppAuthentication,
7+
GitHubAppAuthentication,
8+
GitHubAppAuthenticationWithExpiration,
9+
Authentication,
10+
} from "./types";
411

512
import { createOAuthDeviceAuth } from "@octokit/auth-oauth-device";
613
import { exchangeWebFlowCode } from "@octokit/oauth-methods";
714

8-
export async function getAuthentication<TClientType extends ClientType>(
9-
state: State
10-
): Promise<Authentication<TClientType>> {
15+
export async function getAuthentication(
16+
state: OAuthAppState
17+
): Promise<OAuthAppAuthentication>;
18+
export async function getAuthentication(
19+
state: GitHubAppState
20+
): Promise<GitHubAppAuthentication | GitHubAppAuthenticationWithExpiration>;
21+
22+
export async function getAuthentication(
23+
state: OAuthAppState | GitHubAppState
24+
): Promise<
25+
| OAuthAppAuthentication
26+
| GitHubAppAuthentication
27+
| GitHubAppAuthenticationWithExpiration
28+
> {
1129
// handle code exchange form OAuth Web Flow
1230
if ("code" in state.strategyOptions) {
1331
const { authentication } = await exchangeWebFlowCode({

src/hook.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,36 @@ import {
66
RequestParameters,
77
Route,
88
} from "@octokit/types";
9-
import { State } from "./types";
9+
import { OAuthAppState, GitHubAppState } from "./types";
1010
import { auth } from "./auth";
1111

1212
type AnyResponse = OctokitResponse<any>;
1313

1414
export async function hook(
15-
state: State,
15+
state: OAuthAppState,
16+
request: RequestInterface,
17+
route: Route | EndpointOptions,
18+
parameters: RequestParameters
19+
): Promise<AnyResponse>;
20+
21+
export async function hook(
22+
state: GitHubAppState,
23+
request: RequestInterface,
24+
route: Route | EndpointOptions,
25+
parameters: RequestParameters
26+
): Promise<AnyResponse>;
27+
28+
export async function hook(
29+
state: OAuthAppState | GitHubAppState,
1630
request: RequestInterface,
1731
route: Route | EndpointOptions,
1832
parameters: RequestParameters = {}
1933
): Promise<AnyResponse> {
20-
const { token } = await auth({
21-
...state,
22-
request,
23-
});
34+
// TS makes us do this ¯\_(ツ)_/¯
35+
const { token } =
36+
state.clientType === "oauth-app"
37+
? await auth({ ...state, request })
38+
: await auth({ ...state, request });
2439

2540
const endpoint = request.endpoint.merge(
2641
route as string,

src/index.ts

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,38 @@ import { request as octokitRequest } from "@octokit/request";
44
import { VERSION } from "./version";
55
import { auth } from "./auth";
66
import { hook } from "./hook";
7-
import { StrategyOptions, State, ClientType, AuthInterface } from "./types";
7+
import {
8+
State,
9+
OAuthAppStrategyOptions,
10+
GitHubAppStrategyOptions,
11+
OAuthAppAuthInterface,
12+
GitHubAppAuthInterface,
13+
} from "./types";
14+
export {
15+
OAuthAppStrategyOptionsWebFlow,
16+
GitHubAppStrategyOptionsWebFlow,
17+
OAuthAppStrategyOptionsDeviceFlow,
18+
GitHubAppStrategyOptionsDeviceFlow,
19+
OAuthAppStrategyOptionsExistingAuthentication,
20+
GitHubAppStrategyOptionsExistingAuthentication,
21+
GitHubAppStrategyOptionsExistingAuthenticationWithExpiration,
22+
OAuthAppStrategyOptions,
23+
GitHubAppStrategyOptions,
24+
OAuthAppAuthOptions,
25+
GitHubAppAuthOptions,
26+
OAuthAppAuthentication,
27+
GitHubAppAuthentication,
28+
GitHubAppAuthenticationWithExpiration,
29+
} from "./types";
830

9-
export function createOAuthUserAuth<
10-
TClientType extends ClientType = "oauth-app"
11-
>({
31+
export function createOAuthUserAuth(
32+
options: OAuthAppStrategyOptions
33+
): OAuthAppAuthInterface;
34+
export function createOAuthUserAuth(
35+
options: GitHubAppStrategyOptions
36+
): GitHubAppAuthInterface;
37+
38+
export function createOAuthUserAuth({
1239
clientId,
1340
clientSecret,
1441
clientType = "oauth-app",
@@ -18,7 +45,9 @@ export function createOAuthUserAuth<
1845
},
1946
}),
2047
...strategyOptions
21-
}: StrategyOptions<TClientType>): AuthInterface<TClientType> {
48+
}: OAuthAppStrategyOptions | GitHubAppStrategyOptions):
49+
| OAuthAppAuthInterface
50+
| GitHubAppAuthInterface {
2251
const state: State = Object.assign({
2352
clientType,
2453
clientId,
@@ -27,8 +56,9 @@ export function createOAuthUserAuth<
2756
request,
2857
});
2958

30-
// @ts-expect-error the extra code is not worth it just to make TS happpy
59+
// @ts-expect-error not worth the extra code needed to appease TS
3160
return Object.assign(auth.bind(null, state), {
61+
// @ts-expect-error not worth the extra code needed to appease TS
3262
hook: hook.bind(null, state),
3363
});
3464
}

0 commit comments

Comments
 (0)