Skip to content

Commit

Permalink
WIP: workaround for "Expression produces a union type that is too com…
Browse files Browse the repository at this point in the history
…plex to represent" error
  • Loading branch information
gr2m committed Apr 19, 2020
1 parent 5f51108 commit cf2782a
Show file tree
Hide file tree
Showing 4 changed files with 3,072 additions and 3,122 deletions.
18 changes: 13 additions & 5 deletions scripts/update-endpoints/templates/endpoints.ts.template
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,31 @@
import { OctokitResponse } from "../OctokitResponse";
import { RequestHeaders } from "../RequestHeaders";
import { RequestRequestOptions } from "../RequestRequestOptions";
import { RequestParameters } from "../RequestParameters";
import { RequestOptions } from "../RequestOptions";

type RequiredPreview<T> = {
mediaType: {
previews: [T, ...string[]];
};
};

type Endpoint<
Parameters extends RequestParameters,
Request extends RequestOptions,
Response extends OctokitResponse<any>
> = {
parameters: Parameters;
request: Request;
response: Response;
};

export interface Endpoints {
{{#each endpointsByRoute}}
/**
* @see {{documentationUrl}}
*/
"{{@key}}": {
parameters: {{optionsTypeName}},
request: {{requestOptionsTypeName}},
response: OctokitResponse<{{responseTypeName}}>,
},
"{{@key}}": Endpoint<{{optionsTypeName}}, {{requestOptionsTypeName}}, OctokitResponse<{{responseTypeName}}>>,
{{/each}}
}

Expand Down
58 changes: 43 additions & 15 deletions src/EndpointInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { EndpointDefaults } from "./EndpointDefaults";
import { RequestOptions } from "./RequestOptions";
import { RequestParameters } from "./RequestParameters";
import { Route } from "./Route";
import { Url } from "./Url";
import { RequestMethod } from "./RequestMethod";

import { Endpoints } from "./generated/Endpoints";
Expand All @@ -21,33 +22,35 @@ type EndpointsByUrlAndMethod = UnionToIntersection<
url: TUrl;
method: TMethod;
};
options: Endpoints[K]["parameters"] & {
url: TUrl;
method: TMethod;
};
parameters: Endpoints[K]["parameters"];
request: Endpoints[K]["request"];
};
};
};
}[keyof Endpoints]
>;

type UnknownEndpointParameters = RequestParameters & {
type UnknownRouteObject = {
method?: RequestMethod;
url: string;
};
type UnknownEndpointParameters = RequestParameters & UnknownRouteObject;

type KnownOrUnknownEndpointParameters<
type KnownOrUnknownEndpointsByUrlAndMethod<
T extends UnknownEndpointParameters
> = T["url"] extends keyof EndpointsByUrlAndMethod
? T["method"] extends keyof EndpointsByUrlAndMethod[T["url"]]
? EndpointsByUrlAndMethod[T["url"]][T["method"]] extends {
parameters: infer TOpt;
parameters: infer TParams;
request: infer TRequest;
}
? TOpt
? { parameters: TParams; request: TRequest }
: never
: never
: UnknownEndpointParameters;
: {
parameters: UnknownEndpointParameters;
request: RequestOptions;
};

// https://stackoverflow.com/a/61281317/206879
type KnownOptions<T> = T extends {
Expand All @@ -58,19 +61,44 @@ type KnownOptions<T> = T extends {
? OptionValue
: never;

type KnownEndpoints = KnownOptions<EndpointsByUrlAndMethod>["route"];
type KnownRouteObjects = KnownOptions<EndpointsByUrlAndMethod>["route"];
type KnownRouteObject = { method: RequestMethod; url: Url };
type RouteObjectFrom<T extends KnownRouteObject> = {
method: T["method"];
url: T["url"];
};

export interface EndpointInterface<D extends object = object> {
/**
* Transforms a GitHub REST API endpoint into generic request options
*
* @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`.
*/
<O extends KnownEndpoints | UnknownEndpointParameters>(
options: O & KnownOrUnknownEndpointParameters<O>
): O extends KnownEndpoints
? EndpointsByUrlAndMethod[O["url"]][O["method"]]["request"]
: RequestOptions;
// WIP: does not allow optionsk for unknown routes, does not respect `D`
<O extends KnownRouteObjects>(
options: O &
KnownOrUnknownEndpointsByUrlAndMethod<O>["parameters"] &
RequestParameters
): KnownOrUnknownEndpointsByUrlAndMethod<O>["request"];

// WIP: does not validate required parameters for known route:
// <O extends RequestParameters>(
// options: O extends KnownRouteObject
// ? RouteObjectFrom<D & O> extends KnownRouteObjects
// ? KnownOrUnknownEndpointsByUrlAndMethod<
// RouteObjectFrom<D & O>
// >["parameters"]
// : O & { method?: string } & ("url" extends keyof D
// ? { url?: string }
// : { url: string })
// : O & { method?: string } & ("url" extends keyof D
// ? { url?: string }
// : { url: string })
// ): O extends KnownRouteObject
// ? RouteObjectFrom<D & O> extends KnownRouteObjects
// ? KnownOrUnknownEndpointsByUrlAndMethod<RouteObjectFrom<D & O>>["request"]
// : RequestOptions & Pick<D & O, keyof RequestOptions>
// : RequestOptions & Pick<D & O, keyof RequestOptions>;

/**
* Transforms a GitHub REST API endpoint into generic request options
Expand Down
Loading

0 comments on commit cf2782a

Please sign in to comment.