Skip to content

Commit 68798e6

Browse files
authored
feat(typescript): auth strategies (#19)
1 parent efdf0b8 commit 68798e6

File tree

6 files changed

+154
-2
lines changed

6 files changed

+154
-2
lines changed

packages/types/index.d.ts

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,30 @@
11
import { RequestInterface } from "./request";
22
export { RequestInterface } from "./request";
33

4+
interface AuthStrategyInterface {
5+
(options?: any): AuthInterface;
6+
}
7+
interface AuthInterface {
8+
(options?: any): Promise<unknown>;
9+
}
10+
11+
type AuthStrategyAndOptions<AuthStrategy extends AuthStrategyInterface> = {
12+
authStrategy: AuthStrategy;
13+
auth: Parameters<AuthStrategy>[0];
14+
};
15+
416
/**
517
* Global Octokit interfaces that can be extended as needed.
618
*/
719
export namespace Octokit {
820
interface Options {
21+
/**
22+
* API version. Defaults to `"github.com"`.
23+
*
24+
* In order to set it a GitHub Enterprise Version such as "ghes-3.1",
25+
* install the according `@octokit-next/types-rest-api-ghes-*` package,
26+
* such as `@octokit-next/types-rest-api-ghes-3.1`.
27+
*/
928
version?: keyof Octokit.ApiVersions;
1029

1130
/**
@@ -22,6 +41,22 @@ export namespace Octokit {
2241
*/
2342
userAgent?: string;
2443

44+
// /**
45+
// * Auth strategy function
46+
// *
47+
// * @see https://github.com/octokit/auth.js
48+
// */
49+
// authStrategy?: AuthStrategyInterface;
50+
51+
// /**
52+
// * Auth strategy options. Can be set to an access token. If `authStrategy`
53+
// * option is set, the auth option must be set to the authentication strategy options.
54+
// */
55+
// auth?: String | Record<string, unknown>;
56+
57+
/**
58+
* Request options passed as default `{ request }` options to every request.
59+
*/
2560
request?: RequestOptions;
2661
}
2762

@@ -120,7 +155,8 @@ export namespace Octokit {
120155

121156
export declare class Octokit<
122157
TVersion extends keyof Octokit.ApiVersions = "github.com",
123-
TOptions extends Octokit.Options = Octokit.Options
158+
TOptions extends Octokit.Options = Octokit.Options,
159+
TAuthStrategy extends AuthStrategyInterface | never = never
124160
> {
125161
/**
126162
* Pass one or multiple plugin functions to extend the `Octokit` class.
@@ -216,7 +252,23 @@ export declare class Octokit<
216252
*/
217253
options: { version: TVersion } & TOptions;
218254

219-
constructor(options: { version?: TVersion } & TOptions);
255+
/**
256+
* Constructor without setting `authStrategy`
257+
*
258+
* You can optionally set the `auth` option to an access token string in order
259+
* to authenticate requests.
260+
*/
261+
constructor(options: { version?: TVersion } & { auth?: string } & TOptions);
262+
263+
/**
264+
* Constructor with setting `authStrategy`
265+
*
266+
* The `auth` option must be set to whatever the function passed as `authStrategy` accepts
267+
*/
268+
constructor(
269+
options: { version?: TVersion } & AuthStrategyAndOptions<TAuthStrategy> &
270+
TOptions
271+
);
220272

221273
request: RequestInterface<TVersion>;
222274
}

tests/js/auth/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { Octokit } from "@octokit-next/core";

tests/js/auth/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { Octokit } from "@octokit-next/core";

tests/js/auth/index.test-d.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { expectType } from "tsd";
2+
3+
import { Octokit } from "./index.js";
4+
5+
type CallbackStrategyOptions = {
6+
callback: () => string | Promise<string>;
7+
};
8+
9+
type AuthUnauthenticated = {
10+
type: "unauthenticated";
11+
};
12+
13+
type AuthToken = {
14+
type: "token";
15+
token: string;
16+
};
17+
18+
interface CallbackAuth {
19+
(options?: Record<string, unknown>): Promise<unknown>;
20+
}
21+
22+
declare function createCallbackAuth(
23+
options: CallbackStrategyOptions
24+
): CallbackAuth;
25+
26+
export async function test() {
27+
// set auth to access token
28+
new Octokit({
29+
auth: "token",
30+
});
31+
32+
// @ts-expect-error - auth is required to be set to `{ callback }`
33+
new Octokit({
34+
authStrategy: createCallbackAuth,
35+
});
36+
37+
new Octokit({
38+
authStrategy: createCallbackAuth,
39+
auth: {
40+
callback() {
41+
return "secret";
42+
},
43+
},
44+
});
45+
46+
// @ts-expect-error - invalid auth options
47+
new Octokit({
48+
authStrategy: createCallbackAuth,
49+
auth: "token",
50+
});
51+
52+
const OctokitWithCallbackAuth = Octokit.withDefaults({
53+
authStrategy: createCallbackAuth,
54+
});
55+
56+
// TODO: @ts-expect-error - auth is required to be set to `{ callback }`
57+
new OctokitWithCallbackAuth();
58+
}

tests/ts/auth/test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { Octokit } from "@octokit-next/core";
2+
3+
type CallbackStrategyOptions = {
4+
callback: () => string | Promise<string>;
5+
};
6+
7+
function createCallbackAuth(options: CallbackStrategyOptions) {
8+
return async function auth() {
9+
return options.callback();
10+
};
11+
}
12+
13+
export async function test() {
14+
// set auth to access token
15+
new Octokit({
16+
auth: "token",
17+
});
18+
19+
// @ts-expect-error - auth is required to be set to `{ callback }`
20+
new Octokit({
21+
authStrategy: createCallbackAuth,
22+
});
23+
24+
// @ts-expect-error - invalid auth options
25+
new Octokit({
26+
authStrategy: createCallbackAuth,
27+
auth: "token",
28+
});
29+
30+
new Octokit({
31+
authStrategy: createCallbackAuth,
32+
auth: {
33+
callback: () => "token",
34+
},
35+
});
36+
}

tests/ts/auth/tsconfig.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"extends": "../tsconfig.json",
3+
"include": ["*.ts"]
4+
}

0 commit comments

Comments
 (0)