Skip to content

Commit

Permalink
feat: Add optional defaults type parameter to EndpointInterface & Req…
Browse files Browse the repository at this point in the history
…uestInterface, pass on option types from `.defaults(options)` (#48)
  • Loading branch information
gr2m committed Apr 19, 2020
1 parent 7b35b72 commit 17acf10
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 61 deletions.
21 changes: 17 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,24 @@
[![Build Status](https://github.com/octokit/types.ts/workflows/Test/badge.svg)](https://github.com/octokit/types.ts/actions?workflow=Test)
[![Greenkeeper](https://badges.greenkeeper.io/octokit/types.ts.svg)](https://greenkeeper.io/)

<!-- toc -->

- [Usage](#usage)
- [Examples](#examples)
- [Get parameter and response data types for a REST API endpoint](#get-parameter-and-response-data-types-for-a-rest-api-endpoint)
- [Get response types from endpoint methods](#get-response-types-from-endpoint-methods)
- [Contributing](#contributing)
- [License](#license)

<!-- tocstop -->

## Usage

Get parameter and response data types for a REST API endpoint
See all exported types at https://octokit.github.io/types.ts

## Examples

### Get parameter and response data types for a REST API endpoint

```ts
import { Endpoints } from "./src";
Expand All @@ -23,7 +38,7 @@ async function listRepos(
}
```

Get response types from endpoint methods
### Get response types from endpoint methods

```ts
import {
Expand All @@ -41,8 +56,6 @@ type CreateLabelResponseDataType = GetResponseDataTypeFromEndpointMethod<
>;
```

See https://octokit.github.io/types.ts for all exported types

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"lint": "prettier --check '{src,test,scripts}/**/*.{js,ts,json}' README.md package.json !src/generated/* !scripts/update-endpoints/generated/*",
"lint:fix": "prettier --write '{src,test,scripts}/**/*.{js,ts,json}' README.md package.json !src/generated/* !scripts/update-endpoints/generated/*",
"pretest": "npm run -s lint",
"test": "npx tsc --noEmit --declaration src/index.ts",
"test": "npx tsc --noEmit --declaration src/index.ts test.ts",
"update-endpoints": "npm-run-all update-endpoints:*",
"update-endpoints:fetch-json": "node scripts/update-endpoints/fetch-json",
"update-endpoints:typescript": "node scripts/update-endpoints/typescript"
Expand Down
2 changes: 1 addition & 1 deletion scripts/update-endpoints/templates/endpoints.ts.template
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type {{request.name}} = {
{{/each}}

{{#childParams}}
export type {{paramTypeName}} = {
type {{paramTypeName}} = {
{{#params}}
{{{name this}}}: {{{type this}}}
{{/params}}
Expand Down
55 changes: 40 additions & 15 deletions src/EndpointInterface.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,50 @@
import { EndpointDefaults } from "./EndpointDefaults";
import { EndpointOptions } from "./EndpointOptions";
import { RequestOptions } from "./RequestOptions";
import { RequestParameters } from "./RequestParameters";
import { Route } from "./Route";

import { Endpoints } from "./generated/Endpoints";

export interface EndpointInterface {
export interface EndpointInterface<D extends object = object> {
/**
* Transforms a GitHub REST API endpoint into generic request options
*
* @param {object} endpoint Must set `method` and `url`. Plus URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
* @param {object} endpoint Must set `url` unless it's set defaults. Plus URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
*/
(options: EndpointOptions): RequestOptions;
<O extends RequestParameters = RequestParameters>(
options: O & { method?: string } & ("url" extends keyof D
? { url?: string }
: { url: string })
): RequestOptions & Pick<D & O, keyof RequestOptions>;

/**
* Transforms a GitHub REST API endpoint into generic request options
*
* @param {string} route Request method + URL. Example: `'GET /orgs/:org'`
* @param {object} [parameters] URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
*/
<R extends Route>(
route: keyof Endpoints | R,
options?: R extends keyof Endpoints
<
R extends Route,
P extends RequestParameters = R extends keyof Endpoints
? Endpoints[R]["parameters"] & RequestParameters
: RequestParameters
): R extends keyof Endpoints ? Endpoints[R]["request"] : RequestOptions;
>(
route: keyof Endpoints | R,
parameters?: P
): (R extends keyof Endpoints ? Endpoints[R]["request"] : RequestOptions) &
Pick<P, keyof RequestOptions>;

/**
* Object with current default route and parameters
*/
DEFAULTS: EndpointDefaults;
DEFAULTS: D & EndpointDefaults;

/**
* Returns a new `endpoint` with updated route and parameters
* Returns a new `endpoint` interface with new defaults
*/
defaults: (newDefaults: RequestParameters) => EndpointInterface;
defaults: <O extends RequestParameters = RequestParameters>(
newDefaults: O
) => EndpointInterface<D & O>;

merge: {
/**
Expand All @@ -46,22 +55,36 @@ export interface EndpointInterface {
* @param {object} [parameters] URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
*
*/
(route: Route, parameters?: RequestParameters): EndpointDefaults;
<
R extends Route,
P extends RequestParameters = R extends keyof Endpoints
? Endpoints[R]["parameters"] & RequestParameters
: RequestParameters
>(
route: keyof Endpoints | R,
parameters?: P
): D &
(R extends keyof Endpoints
? Endpoints[R]["request"] & Endpoints[R]["parameters"]
: EndpointDefaults) &
P;

/**
* Merges current endpoint defaults with passed route and parameters,
* without transforming them into request options.
*
* @param {object} endpoint Must set `method` and `url`. Plus URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
*/
(options: RequestParameters): EndpointDefaults;
<P extends RequestParameters = RequestParameters>(
options: P
): EndpointDefaults & D & P;

/**
* Returns current default options.
*
* @deprecated use endpoint.DEFAULTS instead
*/
(): EndpointDefaults;
(): D & EndpointDefaults;
};

/**
Expand All @@ -70,5 +93,7 @@ export interface EndpointInterface {
*
* @param {object} options `method`, `url`. Plus URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
*/
parse: (options: EndpointDefaults) => RequestOptions;
parse: <O extends EndpointDefaults = EndpointDefaults>(
options: O
) => RequestOptions & Pick<O, keyof RequestOptions>;
}
16 changes: 11 additions & 5 deletions src/RequestInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ import { Route } from "./Route";

import { Endpoints } from "./generated/Endpoints";

export interface RequestInterface {
export interface RequestInterface<D extends object = object> {
/**
* Sends a request based on endpoint options
*
* @param {object} endpoint Must set `method` and `url`. Plus URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
*/
<T = any>(options: EndpointOptions): Promise<OctokitResponse<T>>;
<T = any, O extends RequestParameters = RequestParameters>(
options: O & { method?: string } & ("url" extends keyof D
? { url?: string }
: { url: string })
): Promise<OctokitResponse<T>>;

/**
* Sends a request based on endpoint options
Expand All @@ -30,12 +34,14 @@ export interface RequestInterface {
: Promise<OctokitResponse<any>>;

/**
* Returns a new `endpoint` with updated route and parameters
* Returns a new `request` with updated route and parameters
*/
defaults: (newDefaults: RequestParameters) => RequestInterface;
defaults: <O extends RequestParameters = RequestParameters>(
newDefaults: O
) => RequestInterface<D & O>;

/**
* Octokit endpoint API, see {@link https://github.com/octokit/endpoint.js|@octokit/endpoint}
*/
endpoint: EndpointInterface;
endpoint: EndpointInterface<D>;
}
2 changes: 1 addition & 1 deletion src/RequestParameters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,5 @@ export type RequestParameters = {
* 3. Request body if `parameter` is `'data'`
* 4. JSON in the request body in the form of `body[parameter]` unless `parameter` key is `'data'`
*/
[parameter: string]: any;
[parameter: string]: unknown;
};

0 comments on commit 17acf10

Please sign in to comment.