Skip to content

Commit

Permalink
remove .registerEndpoints
Browse files Browse the repository at this point in the history
BREAKING CHANGE: `octokit.registerEndpoints()` has been removed.

Instead of

```js
await octokit.registerEndpoints({
  misc: {
    getRoot: {
      method: "GET",
      url: "/"
    }
  }
});
```

do

```js
octokit.misc.getRoot = octokit.request.defaults({
  method: "GET",
  url: "/"
});
```

or

```js
Object.assign(octokit.misc, {
  getRoot: octokit.request.defaults({
    method: "GET",
    url: "/"
  })
})
```
  • Loading branch information
gr2m committed Jan 31, 2020
1 parent 7177356 commit 51a85da
Show file tree
Hide file tree
Showing 8 changed files with 2,069 additions and 6,924 deletions.
128 changes: 61 additions & 67 deletions scripts/update-endpoints/code.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,98 +28,92 @@ async function generateRoutes() {
return;
}

const idName = endpoint.id;
const route = `${endpoint.method} ${endpoint.url}`;
const endpointDefaults = {};
const endpointDecorations = {};

if (!newRoutes[scope]) {
newRoutes[scope] = {};
}

const idName = endpoint.id;
const url = endpoint.url.toLowerCase().replace(/\{(\w+)\}/g, ":$1");
if (endpoint.headers.length) {
const headers = endpoint.headers.reduce((result, header) => {
// accept header is set via mediatype
if (header.name === "accept") {
return result;
}

// ignore headers with null values. THese can be required headers that must be set by the user,
// such as `headers['content-type']` for `octokit.repos.uploadReleaseAsset()`
if (header.value === null) {
return result;
}

// new route
newRoutes[scope][idName] = {
method: endpoint.method,
headers: endpoint.headers.reduce((result, header) => {
if (!result) {
result = {};
}

result[header.name] = header.value;
return result;
}, undefined),
params: endpoint.parameters.reduce((result, param) => {
result[param.name] = {
type: param.type
};
if (param.allowNull) {
result[param.name].allowNull = true;
}
if (param.required) {
result[param.name].required = true;
}
if (param.mapToData) {
result[param.name].mapTo = "data";
}
if (param.enum) {
result[param.name].enum = param.enum;
}
if (param.validation) {
result[param.name].validation = param.validation;
}
if (param.deprecated) {
result[param.name].deprecated = true;

if (param.alias) {
result[param.name].alias = param.alias;
result[param.name].type = result[param.alias].type;
} else {
result[param.name].type = param.type;
result[param.name].description = param.description;
}
}
}, undefined);

return result;
}, {}),
url,
deprecated: newRoutes[scope][idName]
? newRoutes[scope][idName].deprecated
: undefined
};

const previewHeaders = endpoint.previews
.map(preview => `application/vnd.github.${preview.name}-preview+json`)
.join(",");

if (previewHeaders) {
newRoutes[scope][idName].headers = {
accept: previewHeaders
if (headers) {
endpointDefaults.headers = headers;
}
}

if (endpoint.previews.length) {
endpointDefaults.mediaType = {
previews: endpoint.previews.map(preview => preview.name)
};
}

if (endpoint.renamed) {
const { before, after } = endpoint.renamed;
if (!newRoutes[before.scope]) {
newRoutes[before.scope] = {};
}
endpointDecorations.renamed = [
endpoint.renamed.after.scope,
endpoint.renamed.after.id
];
}

if (!newRoutes[before.scope][before.id]) {
newRoutes[before.scope][before.id] = newRoutes[scope][idName];
}
if (endpoint.isDeprecated && !endpoint.renamed) {
endpointDecorations.deprecated = `octokit.${scope}.${idName}() is deprecated, see ${endpoint.documentationUrl}`;
}

const renamedParameters = endpoint.parameters.filter(
parameter => !!parameter.alias
);

if (renamedParameters.length) {
endpointDecorations.renamedParameters = {};

newRoutes[before.scope][
before.id
].deprecated = `octokit.${before.scope}.${before.id}() has been renamed to octokit.${after.scope}.${after.id}() (${endpoint.renamed.date})`;
for (const parameter of renamedParameters) {
endpointDecorations.renamedParameters[parameter.name] = parameter.alias;
if (!parameter.deprecated) {
console.log(`parameter`);
console.log(parameter);
}
}
}

if (endpoint.isDeprecated && !newRoutes[scope][idName].deprecated) {
newRoutes[scope][
idName
].deprecated = `octokit.${scope}.${idName}() is deprecated, see ${endpoint.documentationUrl}`;
newRoutes[scope][idName] = [route];

if (Object.keys(endpointDecorations).length) {
newRoutes[scope][idName].push(endpointDefaults, endpointDecorations);
} else if (Object.keys(endpointDefaults).length) {
newRoutes[scope][idName].push(endpointDefaults);
}
});

writeFileSync(
ROUTES_PATH,
prettier.format(
`export default ` + JSON.stringify(sortKeys(newRoutes, { deep: true })),
`import { EndpointsDefaultsAndDecorations } from "../types";
const Endpoints: EndpointsDefaultsAndDecorations = ${JSON.stringify(
sortKeys(newRoutes, { deep: true })
)}
export default Endpoints`,
{ parser: "typescript" }
)
);
Expand Down
104 changes: 104 additions & 0 deletions src/endpoints-to-methods.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { Octokit } from "@octokit/core";
import {
EndpointOptions,
RequestParameters,
RequestMethod,
Route,
Url
} from "@octokit/types";
import { EndpointsDefaultsAndDecorations, EndpointDecorations } from "./types";
import { RestEndpointMethods } from "./generated/rest-endpoint-methods-types";

type EndpointMethods = {
[methodName: string]: typeof Octokit.prototype.request;
};

export function endpointsToMethods(
octokit: Octokit,
endpointsMap: EndpointsDefaultsAndDecorations
) {
const newMethods = {} as { [key: string]: object };

for (const [scope, endpoints] of Object.entries(endpointsMap)) {
for (const [methodName, endpoint] of Object.entries(endpoints)) {
const [route, defaults, decorations] = endpoint;
const [method, url] = route.split(/ /) as [RequestMethod, Url];
const endpointDefaults: EndpointOptions = Object.assign(
{ method, url },
defaults
);

if (!newMethods[scope]) {
newMethods[scope] = {};
}

const scopeMethods = newMethods[scope] as EndpointMethods;

if (decorations) {
scopeMethods[methodName] = decorate(
octokit,
scope,
methodName,
endpointDefaults,
decorations
);
continue;
}

scopeMethods[methodName] = octokit.request.defaults(endpointDefaults);
}
}

return newMethods as RestEndpointMethods;
}

function decorate(
octokit: Octokit,
scope: string,
methodName: string,
defaults: EndpointOptions,
decorations: EndpointDecorations
) {
const requestWithDefaults = octokit.request.defaults(defaults);

function withDeprecations(
...args: [Route, RequestParameters?] | [EndpointOptions]
) {
if (decorations.renamed) {
const [newScope, newMethodName] = decorations.renamed;
octokit.log.warn(
`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`
);
}

if (decorations.deprecated) {
octokit.log.warn(decorations.deprecated);
}

if (decorations.renamedParameters) {
// @ts-ignore https://github.com/microsoft/TypeScript/issues/25488
const options = requestWithDefaults.endpoint.merge(...args);

for (const [name, alias] of Object.entries(
decorations.renamedParameters
)) {
if (name in options) {
octokit.log.warn(
`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`
);
if (!(alias in options)) {
options[alias] = options[name];
}
delete options[name];
}
}

return requestWithDefaults(options);
}

// @ts-ignore https://github.com/microsoft/TypeScript/issues/25488
return requestWithDefaults(...args);
}

return Object.assign(withDeprecations, requestWithDefaults);
}

0 comments on commit 51a85da

Please sign in to comment.