Skip to content

Commit

Permalink
feat(typescript): composePaginateRest types (#208)
Browse files Browse the repository at this point in the history
  • Loading branch information
gr2m authored Nov 1, 2020
1 parent 6716952 commit 9e9c835
Show file tree
Hide file tree
Showing 2 changed files with 239 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/compose-paginate.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { paginate } from "./paginate";
import { iterator } from "./iterator";

export const composePaginateRest = Object.assign(paginate, { iterator });
import { ComposePaginateInterface } from "./types";

export const composePaginateRest = Object.assign(paginate, {
iterator,
}) as ComposePaginateInterface;
234 changes: 234 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Octokit } from "@octokit/core";
import * as OctokitTypes from "@octokit/types";

export {
Expand Down Expand Up @@ -255,3 +256,236 @@ export interface PaginateInterface {
>;
};
}

// TODO: find a way to remove duplication between PaginateInterface & ComposePaginateInterface
// The difference is that ComposePaginateInterface accepts an `octokit` as first argument
export interface ComposePaginateInterface {
// Using object as first parameter

/**
* Paginate a request using endpoint options and map each response to a custom array
*
* @param {object} octokit Octokit instance
* @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 {function} mapFn Optional method to map each response to a custom array
*/
<T, R>(
octokit: Octokit,
options: OctokitTypes.EndpointOptions,
mapFn: MapFunction<T, R>
): Promise<PaginationResults<R>>;

/**
* Paginate a request using endpoint options
*
* @param {object} octokit Octokit instance
* @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>(octokit: Octokit, options: OctokitTypes.EndpointOptions): Promise<
PaginationResults<T>
>;

// Using route string as first parameter

/**
* Paginate a request using a known endpoint route string and map each response to a custom array
*
* @param {object} octokit Octokit instance
* @param {string} route Request method + URL. Example: `'GET /orgs/:org'`
* @param {function} mapFn Optional method to map each response to a custom array
*/
<R extends keyof PaginatingEndpoints, MR extends unknown[]>(
octokit: Octokit,
route: R,
mapFn: (
response: PaginatingEndpoints[R]["response"],
done: () => void
) => MR
): Promise<MR>;

/**
* Paginate a request using a known endpoint route string and parameters, and map each response to a custom array
*
* @param {object} octokit Octokit instance
* @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`.
* @param {function} mapFn Optional method to map each response to a custom array
*/
<R extends keyof PaginatingEndpoints, MR extends unknown[]>(
octokit: Octokit,
route: R,
parameters: PaginatingEndpoints[R]["parameters"],
mapFn: (
response: PaginatingEndpoints[R]["response"],
done: () => void
) => MR
): Promise<MR>;

/**
* Paginate a request using an known endpoint route string
*
* @param {object} octokit Octokit instance
* @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 keyof PaginatingEndpoints>(
octokit: Octokit,
route: R,
parameters?: PaginatingEndpoints[R]["parameters"]
): Promise<PaginatingEndpoints[R]["response"]["data"]>;

// I tried this version which would make the `parameters` argument required if the route has required parameters
// but it caused some weird errors
// <R extends keyof PaginatingEndpoints>(
// route: R,
// ...args: RequiredKeys<PaginatingEndpoints[R]["parameters"]> extends never
// ? [PaginatingEndpoints[R]["parameters"]?]
// : [PaginatingEndpoints[R]["parameters"]]
// ): Promise<PaginatingEndpoints[R]["response"]["data"]>;

/**
* Paginate a request using an unknown endpoint route string
*
* @param {object} octokit Octokit instance
* @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`.
*/
<T, R extends OctokitTypes.Route = OctokitTypes.Route>(
octokit: Octokit,
route: R,
parameters?: R extends keyof PaginatingEndpoints
? PaginatingEndpoints[R]["parameters"]
: OctokitTypes.RequestParameters
): Promise<T[]>;

// Using request method as first parameter

/**
* Paginate a request using an endpoint method and a map function
*
* @param {object} octokit Octokit instance
* @param {string} request Request method (`octokit.request` or `@octokit/request`)
* @param {function} mapFn? Optional method to map each response to a custom array
*/
<R extends OctokitTypes.RequestInterface, MR extends unknown[]>(
octokit: Octokit,
request: R,
mapFn: (
response: NormalizeResponse<
OctokitTypes.GetResponseTypeFromEndpointMethod<R>
>,
done: () => void
) => MR
): Promise<MR>;

/**
* Paginate a request using an endpoint method, parameters, and a map function
*
* @param {object} octokit Octokit instance
* @param {string} request Request method (`octokit.request` or `@octokit/request`)
* @param {object} parameters URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
* @param {function} mapFn? Optional method to map each response to a custom array
*/
<R extends OctokitTypes.RequestInterface, MR extends unknown[]>(
octokit: Octokit,
request: R,
parameters: Parameters<R>[0],
mapFn: (
response: NormalizeResponse<
OctokitTypes.GetResponseTypeFromEndpointMethod<R>
>,
done?: () => void
) => MR
): Promise<MR>;

/**
* Paginate a request using an endpoint method and parameters
*
* @param {object} octokit Octokit instance
* @param {string} request Request method (`octokit.request` or `@octokit/request`)
* @param {object} parameters? URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
*/
<R extends OctokitTypes.RequestInterface>(
octokit: Octokit,
request: R,
parameters?: Parameters<R>[0]
): Promise<
NormalizeResponse<OctokitTypes.GetResponseTypeFromEndpointMethod<R>>["data"]
>;

iterator: {
// Using object as first parameter

/**
* Get an async iterator to paginate a request using endpoint options
*
* @see {link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of} for await...of
*
* @param {object} octokit Octokit instance
* @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>(
octokit: Octokit,
EndpointOptions: OctokitTypes.EndpointOptions
): AsyncIterableIterator<
OctokitTypes.OctokitResponse<PaginationResults<T>>
>;

// Using route string as first parameter

/**
* Get an async iterator to paginate a request using a known endpoint route string and optional parameters
*
* @see {link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of} for await...of
*
* @param {object} octokit Octokit instance
* @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 keyof PaginatingEndpoints>(
octokit: Octokit,
route: R,
parameters?: PaginatingEndpoints[R]["parameters"]
): AsyncIterableIterator<
OctokitTypes.OctokitResponse<PaginatingEndpoints[R]["response"]["data"]>
>;

/**
* Get an async iterator to paginate a request using an unknown endpoint route string and optional parameters
*
* @see {link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of} for await...of
*
* @param {object} octokit Octokit instance
* @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`.
*/
<T, R extends OctokitTypes.Route = OctokitTypes.Route>(
octokit: Octokit,
route: R,
parameters?: R extends keyof PaginatingEndpoints
? PaginatingEndpoints[R]["parameters"]
: OctokitTypes.RequestParameters
): AsyncIterableIterator<
OctokitTypes.OctokitResponse<PaginationResults<T>>
>;

// Using request method as first parameter

/**
* Get an async iterator to paginate a request using a request method and optional parameters
*
* @see {link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of} for await...of
*
* @param {object} octokit Octokit instance
* @param {string} request `@octokit/request` or `octokit.request` method
* @param {object} [parameters] URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
*/
<R extends OctokitTypes.RequestInterface>(
octokit: Octokit,
request: R,
parameters?: Parameters<R>[0]
): AsyncIterableIterator<
NormalizeResponse<OctokitTypes.GetResponseTypeFromEndpointMethod<R>>
>;
};
}

0 comments on commit 9e9c835

Please sign in to comment.