+1
-2
@@ -1,7 +1,6 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2012 Cloud9 IDE, Inc. (Mike de Boer)
|
||||
Copyright (c) 2017-2018 Octokit contributors
|
||||
Copyright (c) 2019 Octokit contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
+270
@@ -0,0 +1,270 @@
|
||||
# auth-token.js
|
||||
|
||||
> GitHub API token authentication for browsers and Node.js
|
||||
|
||||
[](https://www.npmjs.com/package/@octokit/auth-token)
|
||||
[](https://github.com/octokit/auth-token.js/actions?query=workflow%3ATest)
|
||||
|
||||
`@octokit/auth-token` is the simplest of [GitHub’s authentication strategies](https://github.com/octokit/auth.js).
|
||||
|
||||
It is useful if you want to support multiple authentication strategies, as it’s API is compatible with its sibling packages for [basic](https://github.com/octokit/auth-basic.js), [GitHub App](https://github.com/octokit/auth-app.js) and [OAuth app](https://github.com/octokit/auth.js) authentication.
|
||||
|
||||
<!-- toc -->
|
||||
|
||||
- [Usage](#usage)
|
||||
- [`createTokenAuth(token) options`](#createtokenauthtoken-options)
|
||||
- [`auth()`](#auth)
|
||||
- [Authentication object](#authentication-object)
|
||||
- [`auth.hook(request, route, options)` or `auth.hook(request, options)`](#authhookrequest-route-options-or-authhookrequest-options)
|
||||
- [Find more information](#find-more-information)
|
||||
- [Find out what scopes are enabled for oauth tokens](#find-out-what-scopes-are-enabled-for-oauth-tokens)
|
||||
- [Find out if token is a personal access token or if it belongs to an OAuth app](#find-out-if-token-is-a-personal-access-token-or-if-it-belongs-to-an-oauth-app)
|
||||
- [Find out what permissions are enabled for a repository](#find-out-what-permissions-are-enabled-for-a-repository)
|
||||
- [Use token for git operations](#use-token-for-git-operations)
|
||||
- [License](#license)
|
||||
|
||||
<!-- tocstop -->
|
||||
|
||||
## Usage
|
||||
|
||||
<table>
|
||||
<tbody valign=top align=left>
|
||||
<tr><th>
|
||||
Browsers
|
||||
</th><td width=100%>
|
||||
|
||||
Load `@octokit/auth-token` directly from [cdn.skypack.dev](https://cdn.skypack.dev)
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import { createTokenAuth } from "https://cdn.skypack.dev/@octokit/auth-token";
|
||||
</script>
|
||||
```
|
||||
|
||||
</td></tr>
|
||||
<tr><th>
|
||||
Node
|
||||
</th><td>
|
||||
|
||||
Install with <code>npm install @octokit/auth-token</code>
|
||||
|
||||
```js
|
||||
const { createTokenAuth } = require("@octokit/auth-token");
|
||||
// or: import { createTokenAuth } from "@octokit/auth-token";
|
||||
```
|
||||
|
||||
</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
```js
|
||||
const auth = createTokenAuth("1234567890abcdef1234567890abcdef12345678");
|
||||
const authentication = await auth();
|
||||
// {
|
||||
// type: 'token',
|
||||
// token: '1234567890abcdef1234567890abcdef12345678',
|
||||
// tokenType: 'oauth'
|
||||
```
|
||||
|
||||
## `createTokenAuth(token) options`
|
||||
|
||||
The `createTokenAuth` method accepts a single argument of type string, which is the token. The passed token can be one of the following:
|
||||
|
||||
- [Personal access token](https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line)
|
||||
- [OAuth access token](https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/)
|
||||
- Installation access token ([GitHub App Installation](https://developer.github.com/apps/building-github-apps/authenticating-with-github-apps/#authenticating-as-an-installation))
|
||||
- [GITHUB_TOKEN provided to GitHub Actions](https://developer.github.com/actions/creating-github-actions/accessing-the-runtime-environment/#environment-variables)
|
||||
|
||||
Examples
|
||||
|
||||
```js
|
||||
// Personal access token or OAuth access token
|
||||
createTokenAuth("1234567890abcdef1234567890abcdef12345678");
|
||||
|
||||
// Installation access token or GitHub Action token
|
||||
createTokenAuth("v1.d3d433526f780fbcc3129004e2731b3904ad0b86");
|
||||
```
|
||||
|
||||
## `auth()`
|
||||
|
||||
The `auth()` method has no options. It returns a promise which resolves with the the authentication object.
|
||||
|
||||
## Authentication object
|
||||
|
||||
<table width="100%">
|
||||
<thead align=left>
|
||||
<tr>
|
||||
<th width=150>
|
||||
name
|
||||
</th>
|
||||
<th width=70>
|
||||
type
|
||||
</th>
|
||||
<th>
|
||||
description
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody align=left valign=top>
|
||||
<tr>
|
||||
<th>
|
||||
<code>type</code>
|
||||
</th>
|
||||
<th>
|
||||
<code>string</code>
|
||||
</th>
|
||||
<td>
|
||||
<code>"token"</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<code>token</code>
|
||||
</th>
|
||||
<th>
|
||||
<code>string</code>
|
||||
</th>
|
||||
<td>
|
||||
The provided token.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<code>tokenType</code>
|
||||
</th>
|
||||
<th>
|
||||
<code>string</code>
|
||||
</th>
|
||||
<td>
|
||||
Can be either <code>"oauth"</code> for personal access tokens and OAuth tokens, or <code>"installation"</code> for installation access tokens (includes <code>GITHUB_TOKEN</code> provided to GitHub Actions)
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## `auth.hook(request, route, options)` or `auth.hook(request, options)`
|
||||
|
||||
`auth.hook()` hooks directly into the request life cycle. It authenticates the request using the provided token.
|
||||
|
||||
The `request` option is an instance of [`@octokit/request`](https://github.com/octokit/request.js#readme). The `route`/`options` parameters are the same as for the [`request()` method](https://github.com/octokit/request.js#request).
|
||||
|
||||
`auth.hook()` can be called directly to send an authenticated request
|
||||
|
||||
```js
|
||||
const { data: authorizations } = await auth.hook(
|
||||
request,
|
||||
"GET /authorizations"
|
||||
);
|
||||
```
|
||||
|
||||
Or it can be passed as option to [`request()`](https://github.com/octokit/request.js#request).
|
||||
|
||||
```js
|
||||
const requestWithAuth = request.defaults({
|
||||
request: {
|
||||
hook: auth.hook,
|
||||
},
|
||||
});
|
||||
|
||||
const { data: authorizations } = await requestWithAuth("GET /authorizations");
|
||||
```
|
||||
|
||||
## Find more information
|
||||
|
||||
`auth()` does not send any requests, it only transforms the provided token string into an authentication object.
|
||||
|
||||
Here is a list of things you can do to retrieve further information
|
||||
|
||||
### Find out what scopes are enabled for oauth tokens
|
||||
|
||||
Note that this does not work for installations. There is no way to retrieve permissions based on an installation access tokens.
|
||||
|
||||
```js
|
||||
const TOKEN = "1234567890abcdef1234567890abcdef12345678";
|
||||
|
||||
const auth = createTokenAuth(TOKEN);
|
||||
const authentication = await auth();
|
||||
|
||||
const response = await request("HEAD /", {
|
||||
headers: authentication.headers,
|
||||
});
|
||||
const scopes = response.headers["x-oauth-scopes"].split(/,\s+/);
|
||||
|
||||
if (scopes.length) {
|
||||
console.log(
|
||||
`"${TOKEN}" has ${scopes.length} scopes enabled: ${scopes.join(", ")}`
|
||||
);
|
||||
} else {
|
||||
console.log(`"${TOKEN}" has no scopes enabled`);
|
||||
}
|
||||
```
|
||||
|
||||
### Find out if token is a personal access token or if it belongs to an OAuth app
|
||||
|
||||
```js
|
||||
const TOKEN = "1234567890abcdef1234567890abcdef12345678";
|
||||
|
||||
const auth = createTokenAuth(TOKEN);
|
||||
const authentication = await auth();
|
||||
|
||||
const response = await request("HEAD /", {
|
||||
headers: authentication.headers,
|
||||
});
|
||||
const clientId = response.headers["x-oauth-client-id"];
|
||||
|
||||
if (clientId) {
|
||||
console.log(
|
||||
`"${token}" is an OAuth token, its app’s client_id is ${clientId}.`
|
||||
);
|
||||
} else {
|
||||
console.log(`"${token}" is a personal access token`);
|
||||
}
|
||||
```
|
||||
|
||||
### Find out what permissions are enabled for a repository
|
||||
|
||||
Note that the `permissions` key is not set when authenticated using an installation access token.
|
||||
|
||||
```js
|
||||
const TOKEN = "1234567890abcdef1234567890abcdef12345678";
|
||||
|
||||
const auth = createTokenAuth(TOKEN);
|
||||
const authentication = await auth();
|
||||
|
||||
const response = await request("GET /repos/:owner/:repo", {
|
||||
owner: 'octocat',
|
||||
repo: 'hello-world'
|
||||
headers: authentication.headers
|
||||
});
|
||||
|
||||
console.log(response.data.permissions)
|
||||
// {
|
||||
// admin: true,
|
||||
// push: true,
|
||||
// pull: true
|
||||
// }
|
||||
```
|
||||
|
||||
### Use token for git operations
|
||||
|
||||
Both OAuth and installation access tokens can be used for git operations. However, when using with an installation, [the token must be prefixed with `x-access-token`](https://developer.github.com/apps/building-github-apps/authenticating-with-github-apps/#http-based-git-access-by-an-installation).
|
||||
|
||||
This example is using the [`execa`](https://github.com/sindresorhus/execa) package to run a `git push` command.
|
||||
|
||||
```js
|
||||
const TOKEN = "1234567890abcdef1234567890abcdef12345678";
|
||||
|
||||
const auth = createTokenAuth(TOKEN);
|
||||
const { token, tokenType } = await auth();
|
||||
const tokenWithPrefix =
|
||||
tokenType === "installation" ? `x-access-token:${token}` : token;
|
||||
|
||||
const repositoryUrl = `https://${tokenWithPrefix}@github.com/octocat/hello-world.git`;
|
||||
|
||||
const { stdout } = await execa("git", ["push", repositoryUrl]);
|
||||
console.log(stdout);
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
async function auth(token) {
|
||||
const tokenType = token.split(/\./).length === 3 ? "app" : /^v\d+\./.test(token) ? "installation" : "oauth";
|
||||
return {
|
||||
type: "token",
|
||||
token: token,
|
||||
tokenType
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefix token for usage in the Authorization header
|
||||
*
|
||||
* @param token OAuth token or JSON Web Token
|
||||
*/
|
||||
function withAuthorizationPrefix(token) {
|
||||
if (token.split(/\./).length === 3) {
|
||||
return `bearer ${token}`;
|
||||
}
|
||||
|
||||
return `token ${token}`;
|
||||
}
|
||||
|
||||
async function hook(token, request, route, parameters) {
|
||||
const endpoint = request.endpoint.merge(route, parameters);
|
||||
endpoint.headers.authorization = withAuthorizationPrefix(token);
|
||||
return request(endpoint);
|
||||
}
|
||||
|
||||
const createTokenAuth = function createTokenAuth(token) {
|
||||
if (!token) {
|
||||
throw new Error("[@octokit/auth-token] No token passed to createTokenAuth");
|
||||
}
|
||||
|
||||
if (typeof token !== "string") {
|
||||
throw new Error("[@octokit/auth-token] Token passed to createTokenAuth is not a string");
|
||||
}
|
||||
|
||||
token = token.replace(/^(token|bearer) +/i, "");
|
||||
return Object.assign(auth.bind(null, token), {
|
||||
hook: hook.bind(null, token)
|
||||
});
|
||||
};
|
||||
|
||||
exports.createTokenAuth = createTokenAuth;
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sources":["../dist-src/auth.js","../dist-src/with-authorization-prefix.js","../dist-src/hook.js","../dist-src/index.js"],"sourcesContent":["export async function auth(token) {\n const tokenType = token.split(/\\./).length === 3\n ? \"app\"\n : /^v\\d+\\./.test(token)\n ? \"installation\"\n : \"oauth\";\n return {\n type: \"token\",\n token: token,\n tokenType\n };\n}\n","/**\n * Prefix token for usage in the Authorization header\n *\n * @param token OAuth token or JSON Web Token\n */\nexport function withAuthorizationPrefix(token) {\n if (token.split(/\\./).length === 3) {\n return `bearer ${token}`;\n }\n return `token ${token}`;\n}\n","import { withAuthorizationPrefix } from \"./with-authorization-prefix\";\nexport async function hook(token, request, route, parameters) {\n const endpoint = request.endpoint.merge(route, parameters);\n endpoint.headers.authorization = withAuthorizationPrefix(token);\n return request(endpoint);\n}\n","import { auth } from \"./auth\";\nimport { hook } from \"./hook\";\nexport const createTokenAuth = function createTokenAuth(token) {\n if (!token) {\n throw new Error(\"[@octokit/auth-token] No token passed to createTokenAuth\");\n }\n if (typeof token !== \"string\") {\n throw new Error(\"[@octokit/auth-token] Token passed to createTokenAuth is not a string\");\n }\n token = token.replace(/^(token|bearer) +/i, \"\");\n return Object.assign(auth.bind(null, token), {\n hook: hook.bind(null, token)\n });\n};\n"],"names":["auth","token","tokenType","split","length","test","type","withAuthorizationPrefix","hook","request","route","parameters","endpoint","merge","headers","authorization","createTokenAuth","Error","replace","Object","assign","bind"],"mappings":";;;;AAAO,eAAeA,IAAf,CAAoBC,KAApB,EAA2B;AAC9B,QAAMC,SAAS,GAAGD,KAAK,CAACE,KAAN,CAAY,IAAZ,EAAkBC,MAAlB,KAA6B,CAA7B,GACZ,KADY,GAEZ,UAAUC,IAAV,CAAeJ,KAAf,IACI,cADJ,GAEI,OAJV;AAKA,SAAO;AACHK,IAAAA,IAAI,EAAE,OADH;AAEHL,IAAAA,KAAK,EAAEA,KAFJ;AAGHC,IAAAA;AAHG,GAAP;AAKH;;ACXD;;;;;AAKA,AAAO,SAASK,uBAAT,CAAiCN,KAAjC,EAAwC;AAC3C,MAAIA,KAAK,CAACE,KAAN,CAAY,IAAZ,EAAkBC,MAAlB,KAA6B,CAAjC,EAAoC;AAChC,WAAQ,UAASH,KAAM,EAAvB;AACH;;AACD,SAAQ,SAAQA,KAAM,EAAtB;AACH;;ACTM,eAAeO,IAAf,CAAoBP,KAApB,EAA2BQ,OAA3B,EAAoCC,KAApC,EAA2CC,UAA3C,EAAuD;AAC1D,QAAMC,QAAQ,GAAGH,OAAO,CAACG,QAAR,CAAiBC,KAAjB,CAAuBH,KAAvB,EAA8BC,UAA9B,CAAjB;AACAC,EAAAA,QAAQ,CAACE,OAAT,CAAiBC,aAAjB,GAAiCR,uBAAuB,CAACN,KAAD,CAAxD;AACA,SAAOQ,OAAO,CAACG,QAAD,CAAd;AACH;;MCHYI,eAAe,GAAG,SAASA,eAAT,CAAyBf,KAAzB,EAAgC;AAC3D,MAAI,CAACA,KAAL,EAAY;AACR,UAAM,IAAIgB,KAAJ,CAAU,0DAAV,CAAN;AACH;;AACD,MAAI,OAAOhB,KAAP,KAAiB,QAArB,EAA+B;AAC3B,UAAM,IAAIgB,KAAJ,CAAU,uEAAV,CAAN;AACH;;AACDhB,EAAAA,KAAK,GAAGA,KAAK,CAACiB,OAAN,CAAc,oBAAd,EAAoC,EAApC,CAAR;AACA,SAAOC,MAAM,CAACC,MAAP,CAAcpB,IAAI,CAACqB,IAAL,CAAU,IAAV,EAAgBpB,KAAhB,CAAd,EAAsC;AACzCO,IAAAA,IAAI,EAAEA,IAAI,CAACa,IAAL,CAAU,IAAV,EAAgBpB,KAAhB;AADmC,GAAtC,CAAP;AAGH,CAXM;;;;"}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
export async function auth(token) {
|
||||
const tokenType = token.split(/\./).length === 3
|
||||
? "app"
|
||||
: /^v\d+\./.test(token)
|
||||
? "installation"
|
||||
: "oauth";
|
||||
return {
|
||||
type: "token",
|
||||
token: token,
|
||||
tokenType
|
||||
};
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import { withAuthorizationPrefix } from "./with-authorization-prefix";
|
||||
export async function hook(token, request, route, parameters) {
|
||||
const endpoint = request.endpoint.merge(route, parameters);
|
||||
endpoint.headers.authorization = withAuthorizationPrefix(token);
|
||||
return request(endpoint);
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import { auth } from "./auth";
|
||||
import { hook } from "./hook";
|
||||
export const createTokenAuth = function createTokenAuth(token) {
|
||||
if (!token) {
|
||||
throw new Error("[@octokit/auth-token] No token passed to createTokenAuth");
|
||||
}
|
||||
if (typeof token !== "string") {
|
||||
throw new Error("[@octokit/auth-token] Token passed to createTokenAuth is not a string");
|
||||
}
|
||||
token = token.replace(/^(token|bearer) +/i, "");
|
||||
return Object.assign(auth.bind(null, token), {
|
||||
hook: hook.bind(null, token)
|
||||
});
|
||||
};
|
||||
Generated
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Prefix token for usage in the Authorization header
|
||||
*
|
||||
* @param token OAuth token or JSON Web Token
|
||||
*/
|
||||
export function withAuthorizationPrefix(token) {
|
||||
if (token.split(/\./).length === 3) {
|
||||
return `bearer ${token}`;
|
||||
}
|
||||
return `token ${token}`;
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import { Token, Authentication } from "./types";
|
||||
export declare function auth(token: Token): Promise<Authentication>;
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import { AnyResponse, EndpointOptions, RequestInterface, RequestParameters, Route, Token } from "./types";
|
||||
export declare function hook(token: Token, request: RequestInterface, route: Route | EndpointOptions, parameters?: RequestParameters): Promise<AnyResponse>;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import { StrategyInterface, Token, Authentication } from "./types";
|
||||
export declare type Types = {
|
||||
StrategyOptions: Token;
|
||||
AuthOptions: never;
|
||||
Authentication: Authentication;
|
||||
};
|
||||
export declare const createTokenAuth: StrategyInterface;
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import * as OctokitTypes from "@octokit/types";
|
||||
export declare type AnyResponse = OctokitTypes.OctokitResponse<any>;
|
||||
export declare type StrategyInterface = OctokitTypes.StrategyInterface<[Token], [], Authentication>;
|
||||
export declare type EndpointDefaults = OctokitTypes.EndpointDefaults;
|
||||
export declare type EndpointOptions = OctokitTypes.EndpointOptions;
|
||||
export declare type RequestParameters = OctokitTypes.RequestParameters;
|
||||
export declare type RequestInterface = OctokitTypes.RequestInterface;
|
||||
export declare type Route = OctokitTypes.Route;
|
||||
export declare type Token = string;
|
||||
export declare type OAuthTokenAuthentication = {
|
||||
type: "token";
|
||||
tokenType: "oauth";
|
||||
token: Token;
|
||||
};
|
||||
export declare type InstallationTokenAuthentication = {
|
||||
type: "token";
|
||||
tokenType: "installation";
|
||||
token: Token;
|
||||
};
|
||||
export declare type AppAuthentication = {
|
||||
type: "token";
|
||||
tokenType: "app";
|
||||
token: Token;
|
||||
};
|
||||
export declare type Authentication = OAuthTokenAuthentication | InstallationTokenAuthentication | AppAuthentication;
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Prefix token for usage in the Authorization header
|
||||
*
|
||||
* @param token OAuth token or JSON Web Token
|
||||
*/
|
||||
export declare function withAuthorizationPrefix(token: string): string;
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
async function auth(token) {
|
||||
const tokenType = token.split(/\./).length === 3
|
||||
? "app"
|
||||
: /^v\d+\./.test(token)
|
||||
? "installation"
|
||||
: "oauth";
|
||||
return {
|
||||
type: "token",
|
||||
token: token,
|
||||
tokenType
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefix token for usage in the Authorization header
|
||||
*
|
||||
* @param token OAuth token or JSON Web Token
|
||||
*/
|
||||
function withAuthorizationPrefix(token) {
|
||||
if (token.split(/\./).length === 3) {
|
||||
return `bearer ${token}`;
|
||||
}
|
||||
return `token ${token}`;
|
||||
}
|
||||
|
||||
async function hook(token, request, route, parameters) {
|
||||
const endpoint = request.endpoint.merge(route, parameters);
|
||||
endpoint.headers.authorization = withAuthorizationPrefix(token);
|
||||
return request(endpoint);
|
||||
}
|
||||
|
||||
const createTokenAuth = function createTokenAuth(token) {
|
||||
if (!token) {
|
||||
throw new Error("[@octokit/auth-token] No token passed to createTokenAuth");
|
||||
}
|
||||
if (typeof token !== "string") {
|
||||
throw new Error("[@octokit/auth-token] Token passed to createTokenAuth is not a string");
|
||||
}
|
||||
token = token.replace(/^(token|bearer) +/i, "");
|
||||
return Object.assign(auth.bind(null, token), {
|
||||
hook: hook.bind(null, token)
|
||||
});
|
||||
};
|
||||
|
||||
export { createTokenAuth };
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sources":["../dist-src/auth.js","../dist-src/with-authorization-prefix.js","../dist-src/hook.js","../dist-src/index.js"],"sourcesContent":["export async function auth(token) {\n const tokenType = token.split(/\\./).length === 3\n ? \"app\"\n : /^v\\d+\\./.test(token)\n ? \"installation\"\n : \"oauth\";\n return {\n type: \"token\",\n token: token,\n tokenType\n };\n}\n","/**\n * Prefix token for usage in the Authorization header\n *\n * @param token OAuth token or JSON Web Token\n */\nexport function withAuthorizationPrefix(token) {\n if (token.split(/\\./).length === 3) {\n return `bearer ${token}`;\n }\n return `token ${token}`;\n}\n","import { withAuthorizationPrefix } from \"./with-authorization-prefix\";\nexport async function hook(token, request, route, parameters) {\n const endpoint = request.endpoint.merge(route, parameters);\n endpoint.headers.authorization = withAuthorizationPrefix(token);\n return request(endpoint);\n}\n","import { auth } from \"./auth\";\nimport { hook } from \"./hook\";\nexport const createTokenAuth = function createTokenAuth(token) {\n if (!token) {\n throw new Error(\"[@octokit/auth-token] No token passed to createTokenAuth\");\n }\n if (typeof token !== \"string\") {\n throw new Error(\"[@octokit/auth-token] Token passed to createTokenAuth is not a string\");\n }\n token = token.replace(/^(token|bearer) +/i, \"\");\n return Object.assign(auth.bind(null, token), {\n hook: hook.bind(null, token)\n });\n};\n"],"names":[],"mappings":"AAAO,eAAe,IAAI,CAAC,KAAK,EAAE;AAClC,IAAI,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;AACpD,UAAU,KAAK;AACf,UAAU,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;AAC/B,cAAc,cAAc;AAC5B,cAAc,OAAO,CAAC;AACtB,IAAI,OAAO;AACX,QAAQ,IAAI,EAAE,OAAO;AACrB,QAAQ,KAAK,EAAE,KAAK;AACpB,QAAQ,SAAS;AACjB,KAAK,CAAC;AACN;;ACXA;AACA;AACA;AACA;AACA;AACA,AAAO,SAAS,uBAAuB,CAAC,KAAK,EAAE;AAC/C,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE;AACxC,QAAQ,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;AACjC,KAAK;AACL,IAAI,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AAC5B,CAAC;;ACTM,eAAe,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE;AAC9D,IAAI,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;AAC/D,IAAI,QAAQ,CAAC,OAAO,CAAC,aAAa,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;AACpE,IAAI,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC;AAC7B,CAAC;;ACHW,MAAC,eAAe,GAAG,SAAS,eAAe,CAAC,KAAK,EAAE;AAC/D,IAAI,IAAI,CAAC,KAAK,EAAE;AAChB,QAAQ,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;AACpF,KAAK;AACL,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;AACnC,QAAQ,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;AACjG,KAAK;AACL,IAAI,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;AACpD,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;AACjD,QAAQ,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC;AACpC,KAAK,CAAC,CAAC;AACP,CAAC;;;;"}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"_from": "@octokit/auth-token@^2.4.0",
|
||||
"_id": "@octokit/auth-token@2.4.3",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-fdGoOQ3kQJh+hrilc0Plg50xSfaCKOeYN9t6dpJKXN9BxhhfquL0OzoQXg3spLYymL5rm29uPeI3KEXRaZQ9zg==",
|
||||
"_location": "/@octokit/auth-token",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "@octokit/auth-token@^2.4.0",
|
||||
"name": "@octokit/auth-token",
|
||||
"escapedName": "@octokit%2fauth-token",
|
||||
"scope": "@octokit",
|
||||
"rawSpec": "^2.4.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^2.4.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/@octokit/core"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.3.tgz",
|
||||
"_shasum": "b868b5f2366533a7e62933eaa1181a8924228cc4",
|
||||
"_spec": "@octokit/auth-token@^2.4.0",
|
||||
"_where": "/workspace/setup-ossutil/node_modules/@octokit/core",
|
||||
"bugs": {
|
||||
"url": "https://github.com/octokit/auth-token.js/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"@octokit/types": "^5.0.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "GitHub API token authentication for browsers and Node.js",
|
||||
"devDependencies": {
|
||||
"@octokit/core": "^3.0.0",
|
||||
"@octokit/request": "^5.3.0",
|
||||
"@pika/pack": "^0.5.0",
|
||||
"@pika/plugin-build-node": "^0.9.0",
|
||||
"@pika/plugin-build-web": "^0.9.0",
|
||||
"@pika/plugin-ts-standard-pkg": "^0.9.0",
|
||||
"@types/fetch-mock": "^7.3.1",
|
||||
"@types/jest": "^26.0.0",
|
||||
"fetch-mock": "^9.0.0",
|
||||
"jest": "^25.1.0",
|
||||
"semantic-release": "^17.0.0",
|
||||
"ts-jest": "^25.1.0",
|
||||
"typescript": "^3.7.2"
|
||||
},
|
||||
"files": [
|
||||
"dist-*/",
|
||||
"bin/"
|
||||
],
|
||||
"homepage": "https://github.com/octokit/auth-token.js#readme",
|
||||
"keywords": [
|
||||
"github",
|
||||
"octokit",
|
||||
"authentication",
|
||||
"api"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "dist-node/index.js",
|
||||
"module": "dist-web/index.js",
|
||||
"name": "@octokit/auth-token",
|
||||
"pika": true,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/octokit/auth-token.js.git"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"source": "dist-src/index.js",
|
||||
"types": "dist-types/index.d.ts",
|
||||
"version": "2.4.3"
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2019 Octokit contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+438
@@ -0,0 +1,438 @@
|
||||
# core.js
|
||||
|
||||
> Extendable client for GitHub's REST & GraphQL APIs
|
||||
|
||||
[](https://www.npmjs.com/package/@octokit/core)
|
||||
[](https://github.com/octokit/core.js/actions?query=workflow%3ATest+branch%3Amaster)
|
||||
|
||||
<!-- toc -->
|
||||
|
||||
- [Usage](#usage)
|
||||
- [REST API example](#rest-api-example)
|
||||
- [GraphQL example](#graphql-example)
|
||||
- [Options](#options)
|
||||
- [Defaults](#defaults)
|
||||
- [Authentication](#authentication)
|
||||
- [Logging](#logging)
|
||||
- [Hooks](#hooks)
|
||||
- [Plugins](#plugins)
|
||||
- [Build your own Octokit with Plugins and Defaults](#build-your-own-octokit-with-plugins-and-defaults)
|
||||
- [LICENSE](#license)
|
||||
|
||||
<!-- tocstop -->
|
||||
|
||||
If you need a minimalistic library to utilize GitHub's [REST API](https://developer.github.com/v3/) and [GraphQL API](https://developer.github.com/v4/) which you can extend with plugins as needed, then `@octokit/core` is a great starting point.
|
||||
|
||||
If you don't need the Plugin API then using [`@octokit/request`](https://github.com/octokit/request.js/) or [`@octokit/graphql`](https://github.com/octokit/graphql.js/) directly is a good alternative.
|
||||
|
||||
## Usage
|
||||
|
||||
<table>
|
||||
<tbody valign=top align=left>
|
||||
<tr><th>
|
||||
Browsers
|
||||
</th><td width=100%>
|
||||
Load <code>@octokit/core</code> directly from <a href="https://cdn.skypack.dev">cdn.skypack.dev</a>
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import { Octokit } from "https://cdn.skypack.dev/@octokit/core";
|
||||
</script>
|
||||
```
|
||||
|
||||
</td></tr>
|
||||
<tr><th>
|
||||
Node
|
||||
</th><td>
|
||||
|
||||
Install with <code>npm install @octokit/core</code>
|
||||
|
||||
```js
|
||||
const { Octokit } = require("@octokit/core");
|
||||
// or: import { Octokit } from "@octokit/core";
|
||||
```
|
||||
|
||||
</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### REST API example
|
||||
|
||||
```js
|
||||
// Create a personal access token at https://github.com/settings/tokens/new?scopes=repo
|
||||
const octokit = new Octokit({ auth: `personal-access-token123` });
|
||||
|
||||
const response = await octokit.request("GET /orgs/:org/repos", {
|
||||
org: "octokit",
|
||||
type: "private",
|
||||
});
|
||||
```
|
||||
|
||||
See [`@octokit/request`](https://github.com/octokit/request.js) for full documentation of the `.request` method.
|
||||
|
||||
### GraphQL example
|
||||
|
||||
```js
|
||||
const octokit = new Octokit({ auth: `secret123` });
|
||||
|
||||
const response = await octokit.graphql(
|
||||
`query ($login: String!) {
|
||||
organization(login: $login) {
|
||||
repositories(privacy: PRIVATE) {
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
}`,
|
||||
{ login: "octokit" }
|
||||
);
|
||||
```
|
||||
|
||||
See [`@octokit/graphql`](https://github.com/octokit/graphql.js) for full documentation of the `.graphql` method.
|
||||
|
||||
## Options
|
||||
|
||||
<table>
|
||||
<thead align=left>
|
||||
<tr>
|
||||
<th>
|
||||
name
|
||||
</th>
|
||||
<th>
|
||||
type
|
||||
</th>
|
||||
<th width=100%>
|
||||
description
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody align=left valign=top>
|
||||
<tr>
|
||||
<th>
|
||||
<code>options.authStrategy</code>
|
||||
</th>
|
||||
<td>
|
||||
<code>Function<code>
|
||||
</td>
|
||||
<td>
|
||||
Defaults to <a href="https://github.com/octokit/auth-token.js#readme"><code>@octokit/auth-token</code></a>. See <a href="#authentication">Authentication</a> below for examples.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<code>options.auth</code>
|
||||
</th>
|
||||
<td>
|
||||
<code>String</code> or <code>Object</code>
|
||||
</td>
|
||||
<td>
|
||||
See <a href="#authentication">Authentication</a> below for examples.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<code>options.baseUrl</code>
|
||||
</th>
|
||||
<td>
|
||||
<code>String</code>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
When using with GitHub Enterprise Server, set `options.baseUrl` to the root URL of the API. For example, if your GitHub Enterprise Server's hostname is `github.acme-inc.com`, then set `options.baseUrl` to `https://github.acme-inc.com/api/v3`. Example
|
||||
|
||||
```js
|
||||
const octokit = new Octokit({
|
||||
baseUrl: "https://github.acme-inc.com/api/v3",
|
||||
});
|
||||
```
|
||||
|
||||
</td></tr>
|
||||
<tr>
|
||||
<th>
|
||||
<code>options.previews</code>
|
||||
</th>
|
||||
<td>
|
||||
<code>Array of Strings</code>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Some REST API endpoints require preview headers to be set, or enable
|
||||
additional features. Preview headers can be set on a per-request basis, e.g.
|
||||
|
||||
```js
|
||||
octokit.request("POST /repos/:owner/:repo/pulls", {
|
||||
mediaType: {
|
||||
previews: ["shadow-cat"],
|
||||
},
|
||||
owner,
|
||||
repo,
|
||||
title: "My pull request",
|
||||
base: "master",
|
||||
head: "my-feature",
|
||||
draft: true,
|
||||
});
|
||||
```
|
||||
|
||||
You can also set previews globally, by setting the `options.previews` option on the constructor. Example:
|
||||
|
||||
```js
|
||||
const octokit = new Octokit({
|
||||
previews: ["shadow-cat"],
|
||||
});
|
||||
```
|
||||
|
||||
</td></tr>
|
||||
<tr>
|
||||
<th>
|
||||
<code>options.request</code>
|
||||
</th>
|
||||
<td>
|
||||
<code>Object</code>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Set a default request timeout (`options.request.timeout`) or an [`http(s).Agent`](https://nodejs.org/api/http.html#http_class_http_agent) e.g. for proxy usage (Node only, `options.request.agent`).
|
||||
|
||||
There are more `options.request.*` options, see [`@octokit/request` options](https://github.com/octokit/request.js#request). `options.request` can also be set on a per-request basis.
|
||||
|
||||
</td></tr>
|
||||
<tr>
|
||||
<th>
|
||||
<code>options.timeZone</code>
|
||||
</th>
|
||||
<td>
|
||||
<code>String</code>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Sets the `Time-Zone` header which defines a timezone according to the [list of names from the Olson database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
|
||||
|
||||
```js
|
||||
const octokit = new Octokit({
|
||||
timeZone: "America/Los_Angeles",
|
||||
});
|
||||
```
|
||||
|
||||
The time zone header will determine the timezone used for generating the timestamp when creating commits. See [GitHub's Timezones documentation](https://developer.github.com/v3/#timezones).
|
||||
|
||||
</td></tr>
|
||||
<tr>
|
||||
<th>
|
||||
<code>options.userAgent</code>
|
||||
</th>
|
||||
<td>
|
||||
<code>String</code>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
A custom user agent string for your app or library. Example
|
||||
|
||||
```js
|
||||
const octokit = new Octokit({
|
||||
userAgent: "my-app/v1.2.3",
|
||||
});
|
||||
```
|
||||
|
||||
</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Defaults
|
||||
|
||||
You can create a new Octokit class with customized default options.
|
||||
|
||||
```js
|
||||
const MyOctokit = Octokit.defaults({
|
||||
auth: "personal-access-token123",
|
||||
baseUrl: "https://github.acme-inc.com/api/v3",
|
||||
userAgent: "my-app/v1.2.3",
|
||||
});
|
||||
const octokit1 = new MyOctokit();
|
||||
const octokit2 = new MyOctokit();
|
||||
```
|
||||
|
||||
If you pass additional options to your new constructor, the options will be merged shallowly.
|
||||
|
||||
```js
|
||||
const MyOctokit = Octokit.defaults({
|
||||
foo: {
|
||||
opt1: 1,
|
||||
},
|
||||
});
|
||||
const octokit = new MyOctokit({
|
||||
foo: {
|
||||
opt2: 1,
|
||||
},
|
||||
});
|
||||
// options will be { foo: { opt2: 1 }}
|
||||
```
|
||||
|
||||
If you need a deep or conditional merge, you can pass a function instead.
|
||||
|
||||
```js
|
||||
const MyOctokit = Octokit.defaults((options) => {
|
||||
return {
|
||||
foo: Object.assign({}, options.foo, { opt2: 1 }),
|
||||
};
|
||||
});
|
||||
const octokit = new MyOctokit({
|
||||
foo: { opt2: 1 },
|
||||
});
|
||||
// options will be { foo: { opt1: 1, opt2: 1 }}
|
||||
```
|
||||
|
||||
Be careful about mutating the `options` object in the `Octokit.defaults` callback, as it can have unforeseen consequences.
|
||||
|
||||
## Authentication
|
||||
|
||||
Authentication is optional for some REST API endpoints accessing public data, but is required for GraphQL queries. Using authentication also increases your [API rate limit](https://developer.github.com/v3/#rate-limiting).
|
||||
|
||||
By default, Octokit authenticates using the [token authentication strategy](https://github.com/octokit/auth-token.js). Pass in a token using `options.auth`. It can be a personal access token, an OAuth token, an installation access token or a JSON Web Token for GitHub App authentication. The `Authorization` header will be set according to the type of token.
|
||||
|
||||
```js
|
||||
import { Octokit } from "@octokit/core";
|
||||
|
||||
const octokit = new Octokit({
|
||||
auth: "mypersonalaccesstoken123",
|
||||
});
|
||||
|
||||
const { data } = await octokit.request("/user");
|
||||
```
|
||||
|
||||
To use a different authentication strategy, set `options.authStrategy`. A set of officially supported authentication strategies can be retrieved from [`@octokit/auth`](https://github.com/octokit/auth-app.js#readme). Example
|
||||
|
||||
```js
|
||||
import { Octokit } from "@octokit/core";
|
||||
import { createAppAuth } from "@octokit/auth-app";
|
||||
|
||||
const appOctokit = new Octokit({
|
||||
authStrategy: createAppAuth,
|
||||
auth: {
|
||||
appId: 123,
|
||||
privateKey: process.env.PRIVATE_KEY,
|
||||
},
|
||||
});
|
||||
|
||||
const { data } = await appOctokit.request("/app");
|
||||
```
|
||||
|
||||
The `.auth()` method returned by the current authentication strategy can be accessed at `octokit.auth()`. Example
|
||||
|
||||
```js
|
||||
const { token } = await appOctokit.auth({
|
||||
type: "installation",
|
||||
installationId: 123,
|
||||
});
|
||||
```
|
||||
|
||||
## Logging
|
||||
|
||||
There are four built-in log methods
|
||||
|
||||
1. `octokit.log.debug(message[, additionalInfo])`
|
||||
1. `octokit.log.info(message[, additionalInfo])`
|
||||
1. `octokit.log.warn(message[, additionalInfo])`
|
||||
1. `octokit.log.error(message[, additionalInfo])`
|
||||
|
||||
They can be configured using the [`log` client option](client-options). By default, `octokit.log.debug()` and `octokit.log.info()` are no-ops, while the other two call `console.warn()` and `console.error()` respectively.
|
||||
|
||||
This is useful if you build reusable [plugins](#plugins).
|
||||
|
||||
If you would like to make the log level configurable using an environment variable or external option, we recommend the [console-log-level](https://github.com/watson/console-log-level) package. Example
|
||||
|
||||
```js
|
||||
const octokit = new Octokit({
|
||||
log: require("console-log-level")({ level: "info" }),
|
||||
});
|
||||
```
|
||||
|
||||
## Hooks
|
||||
|
||||
You can customize Octokit's request lifecycle with hooks.
|
||||
|
||||
```js
|
||||
octokit.hook.before("request", async (options) => {
|
||||
validate(options);
|
||||
});
|
||||
octokit.hook.after("request", async (response, options) => {
|
||||
console.log(`${options.method} ${options.url}: ${response.status}`);
|
||||
});
|
||||
octokit.hook.error("request", async (error, options) => {
|
||||
if (error.status === 304) {
|
||||
return findInCache(error.headers.etag);
|
||||
}
|
||||
|
||||
throw error;
|
||||
});
|
||||
octokit.hook.wrap("request", async (request, options) => {
|
||||
// add logic before, after, catch errors or replace the request altogether
|
||||
return request(options);
|
||||
});
|
||||
```
|
||||
|
||||
See [before-after-hook](https://github.com/gr2m/before-after-hook#readme) for more documentation on hooks.
|
||||
|
||||
## Plugins
|
||||
|
||||
Octokit’s functionality can be extended using plugins. The `Octokit.plugin()` method accepts a plugin (or many) and returns a new constructor.
|
||||
|
||||
A plugin is a function which gets two arguments:
|
||||
|
||||
1. the current instance
|
||||
2. the options passed to the constructor.
|
||||
|
||||
In order to extend `octokit`'s API, the plugin must return an object with the new methods.
|
||||
|
||||
```js
|
||||
// index.js
|
||||
const { Octokit } = require("@octokit/core")
|
||||
const MyOctokit = Octokit.plugin(
|
||||
require("./lib/my-plugin"),
|
||||
require("octokit-plugin-example")
|
||||
);
|
||||
|
||||
const octokit = new MyOctokit({ greeting: "Moin moin" });
|
||||
octokit.helloWorld(); // logs "Moin moin, world!"
|
||||
octokit.request("GET /"); // logs "GET / - 200 in 123ms"
|
||||
|
||||
// lib/my-plugin.js
|
||||
module.exports = (octokit, options = { greeting: "Hello" }) => {
|
||||
// hook into the request lifecycle
|
||||
octokit.hook.wrap("request", async (request, options) => {
|
||||
const time = Date.now();
|
||||
const response = await request(options);
|
||||
console.log(
|
||||
`${options.method} ${options.url} – ${response.status} in ${Date.now() -
|
||||
time}ms`
|
||||
);
|
||||
return response;
|
||||
});
|
||||
|
||||
// add a custom method
|
||||
return {
|
||||
helloWorld: () => console.log(`${options.greeting}, world!`);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Build your own Octokit with Plugins and Defaults
|
||||
|
||||
You can build your own Octokit class with preset default options and plugins. In fact, this is mostly how the `@octokit/<context>` modules work, such as [`@octokit/action`](https://github.com/octokit/action.js):
|
||||
|
||||
```js
|
||||
const { Octokit } = require("@octokit/core");
|
||||
const MyActionOctokit = Octokit.plugin(
|
||||
require("@octokit/plugin-paginate-rest"),
|
||||
require("@octokit/plugin-throttling"),
|
||||
require("@octokit/plugin-retry")
|
||||
).defaults({
|
||||
authStrategy: require("@octokit/auth-action"),
|
||||
userAgent: `my-octokit-action/v1.2.3`,
|
||||
});
|
||||
|
||||
const octokit = new MyActionOctokit();
|
||||
const installations = await octokit.paginate("GET /app/installations");
|
||||
```
|
||||
|
||||
## LICENSE
|
||||
|
||||
[MIT](LICENSE)
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
var universalUserAgent = require('universal-user-agent');
|
||||
var beforeAfterHook = require('before-after-hook');
|
||||
var request = require('@octokit/request');
|
||||
var graphql = require('@octokit/graphql');
|
||||
var authToken = require('@octokit/auth-token');
|
||||
|
||||
function _objectWithoutPropertiesLoose(source, excluded) {
|
||||
if (source == null) return {};
|
||||
var target = {};
|
||||
var sourceKeys = Object.keys(source);
|
||||
var key, i;
|
||||
|
||||
for (i = 0; i < sourceKeys.length; i++) {
|
||||
key = sourceKeys[i];
|
||||
if (excluded.indexOf(key) >= 0) continue;
|
||||
target[key] = source[key];
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
function _objectWithoutProperties(source, excluded) {
|
||||
if (source == null) return {};
|
||||
|
||||
var target = _objectWithoutPropertiesLoose(source, excluded);
|
||||
|
||||
var key, i;
|
||||
|
||||
if (Object.getOwnPropertySymbols) {
|
||||
var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
|
||||
|
||||
for (i = 0; i < sourceSymbolKeys.length; i++) {
|
||||
key = sourceSymbolKeys[i];
|
||||
if (excluded.indexOf(key) >= 0) continue;
|
||||
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
const VERSION = "3.2.1";
|
||||
|
||||
class Octokit {
|
||||
constructor(options = {}) {
|
||||
const hook = new beforeAfterHook.Collection();
|
||||
const requestDefaults = {
|
||||
baseUrl: request.request.endpoint.DEFAULTS.baseUrl,
|
||||
headers: {},
|
||||
request: Object.assign({}, options.request, {
|
||||
hook: hook.bind(null, "request")
|
||||
}),
|
||||
mediaType: {
|
||||
previews: [],
|
||||
format: ""
|
||||
}
|
||||
}; // prepend default user agent with `options.userAgent` if set
|
||||
|
||||
requestDefaults.headers["user-agent"] = [options.userAgent, `octokit-core.js/${VERSION} ${universalUserAgent.getUserAgent()}`].filter(Boolean).join(" ");
|
||||
|
||||
if (options.baseUrl) {
|
||||
requestDefaults.baseUrl = options.baseUrl;
|
||||
}
|
||||
|
||||
if (options.previews) {
|
||||
requestDefaults.mediaType.previews = options.previews;
|
||||
}
|
||||
|
||||
if (options.timeZone) {
|
||||
requestDefaults.headers["time-zone"] = options.timeZone;
|
||||
}
|
||||
|
||||
this.request = request.request.defaults(requestDefaults);
|
||||
this.graphql = graphql.withCustomRequest(this.request).defaults(requestDefaults);
|
||||
this.log = Object.assign({
|
||||
debug: () => {},
|
||||
info: () => {},
|
||||
warn: console.warn.bind(console),
|
||||
error: console.error.bind(console)
|
||||
}, options.log);
|
||||
this.hook = hook; // (1) If neither `options.authStrategy` nor `options.auth` are set, the `octokit` instance
|
||||
// is unauthenticated. The `this.auth()` method is a no-op and no request hook is registered.
|
||||
// (2) If only `options.auth` is set, use the default token authentication strategy.
|
||||
// (3) If `options.authStrategy` is set then use it and pass in `options.auth`. Always pass own request as many strategies accept a custom request instance.
|
||||
// TODO: type `options.auth` based on `options.authStrategy`.
|
||||
|
||||
if (!options.authStrategy) {
|
||||
if (!options.auth) {
|
||||
// (1)
|
||||
this.auth = async () => ({
|
||||
type: "unauthenticated"
|
||||
});
|
||||
} else {
|
||||
// (2)
|
||||
const auth = authToken.createTokenAuth(options.auth); // @ts-ignore ¯\_(ツ)_/¯
|
||||
|
||||
hook.wrap("request", auth.hook);
|
||||
this.auth = auth;
|
||||
}
|
||||
} else {
|
||||
const {
|
||||
authStrategy
|
||||
} = options,
|
||||
otherOptions = _objectWithoutProperties(options, ["authStrategy"]);
|
||||
|
||||
const auth = authStrategy(Object.assign({
|
||||
request: this.request,
|
||||
log: this.log,
|
||||
// we pass the current octokit instance as well as its constructor options
|
||||
// to allow for authentication strategies that return a new octokit instance
|
||||
// that shares the same internal state as the current one. The original
|
||||
// requirement for this was the "event-octokit" authentication strategy
|
||||
// of https://github.com/probot/octokit-auth-probot.
|
||||
octokit: this,
|
||||
octokitOptions: otherOptions
|
||||
}, options.auth)); // @ts-ignore ¯\_(ツ)_/¯
|
||||
|
||||
hook.wrap("request", auth.hook);
|
||||
this.auth = auth;
|
||||
} // apply plugins
|
||||
// https://stackoverflow.com/a/16345172
|
||||
|
||||
|
||||
const classConstructor = this.constructor;
|
||||
classConstructor.plugins.forEach(plugin => {
|
||||
Object.assign(this, plugin(this, options));
|
||||
});
|
||||
}
|
||||
|
||||
static defaults(defaults) {
|
||||
const OctokitWithDefaults = class extends this {
|
||||
constructor(...args) {
|
||||
const options = args[0] || {};
|
||||
|
||||
if (typeof defaults === "function") {
|
||||
super(defaults(options));
|
||||
return;
|
||||
}
|
||||
|
||||
super(Object.assign({}, defaults, options, options.userAgent && defaults.userAgent ? {
|
||||
userAgent: `${options.userAgent} ${defaults.userAgent}`
|
||||
} : null));
|
||||
}
|
||||
|
||||
};
|
||||
return OctokitWithDefaults;
|
||||
}
|
||||
/**
|
||||
* Attach a plugin (or many) to your Octokit instance.
|
||||
*
|
||||
* @example
|
||||
* const API = Octokit.plugin(plugin1, plugin2, plugin3, ...)
|
||||
*/
|
||||
|
||||
|
||||
static plugin(...newPlugins) {
|
||||
var _a;
|
||||
|
||||
const currentPlugins = this.plugins;
|
||||
const NewOctokit = (_a = class extends this {}, _a.plugins = currentPlugins.concat(newPlugins.filter(plugin => !currentPlugins.includes(plugin))), _a);
|
||||
return NewOctokit;
|
||||
}
|
||||
|
||||
}
|
||||
Octokit.VERSION = VERSION;
|
||||
Octokit.plugins = [];
|
||||
|
||||
exports.Octokit = Octokit;
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+124
@@ -0,0 +1,124 @@
|
||||
import { getUserAgent } from "universal-user-agent";
|
||||
import { Collection } from "before-after-hook";
|
||||
import { request } from "@octokit/request";
|
||||
import { withCustomRequest } from "@octokit/graphql";
|
||||
import { createTokenAuth } from "@octokit/auth-token";
|
||||
import { VERSION } from "./version";
|
||||
export class Octokit {
|
||||
constructor(options = {}) {
|
||||
const hook = new Collection();
|
||||
const requestDefaults = {
|
||||
baseUrl: request.endpoint.DEFAULTS.baseUrl,
|
||||
headers: {},
|
||||
request: Object.assign({}, options.request, {
|
||||
hook: hook.bind(null, "request"),
|
||||
}),
|
||||
mediaType: {
|
||||
previews: [],
|
||||
format: "",
|
||||
},
|
||||
};
|
||||
// prepend default user agent with `options.userAgent` if set
|
||||
requestDefaults.headers["user-agent"] = [
|
||||
options.userAgent,
|
||||
`octokit-core.js/${VERSION} ${getUserAgent()}`,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ");
|
||||
if (options.baseUrl) {
|
||||
requestDefaults.baseUrl = options.baseUrl;
|
||||
}
|
||||
if (options.previews) {
|
||||
requestDefaults.mediaType.previews = options.previews;
|
||||
}
|
||||
if (options.timeZone) {
|
||||
requestDefaults.headers["time-zone"] = options.timeZone;
|
||||
}
|
||||
this.request = request.defaults(requestDefaults);
|
||||
this.graphql = withCustomRequest(this.request).defaults(requestDefaults);
|
||||
this.log = Object.assign({
|
||||
debug: () => { },
|
||||
info: () => { },
|
||||
warn: console.warn.bind(console),
|
||||
error: console.error.bind(console),
|
||||
}, options.log);
|
||||
this.hook = hook;
|
||||
// (1) If neither `options.authStrategy` nor `options.auth` are set, the `octokit` instance
|
||||
// is unauthenticated. The `this.auth()` method is a no-op and no request hook is registered.
|
||||
// (2) If only `options.auth` is set, use the default token authentication strategy.
|
||||
// (3) If `options.authStrategy` is set then use it and pass in `options.auth`. Always pass own request as many strategies accept a custom request instance.
|
||||
// TODO: type `options.auth` based on `options.authStrategy`.
|
||||
if (!options.authStrategy) {
|
||||
if (!options.auth) {
|
||||
// (1)
|
||||
this.auth = async () => ({
|
||||
type: "unauthenticated",
|
||||
});
|
||||
}
|
||||
else {
|
||||
// (2)
|
||||
const auth = createTokenAuth(options.auth);
|
||||
// @ts-ignore ¯\_(ツ)_/¯
|
||||
hook.wrap("request", auth.hook);
|
||||
this.auth = auth;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const { authStrategy, ...otherOptions } = options;
|
||||
const auth = authStrategy(Object.assign({
|
||||
request: this.request,
|
||||
log: this.log,
|
||||
// we pass the current octokit instance as well as its constructor options
|
||||
// to allow for authentication strategies that return a new octokit instance
|
||||
// that shares the same internal state as the current one. The original
|
||||
// requirement for this was the "event-octokit" authentication strategy
|
||||
// of https://github.com/probot/octokit-auth-probot.
|
||||
octokit: this,
|
||||
octokitOptions: otherOptions,
|
||||
}, options.auth));
|
||||
// @ts-ignore ¯\_(ツ)_/¯
|
||||
hook.wrap("request", auth.hook);
|
||||
this.auth = auth;
|
||||
}
|
||||
// apply plugins
|
||||
// https://stackoverflow.com/a/16345172
|
||||
const classConstructor = this.constructor;
|
||||
classConstructor.plugins.forEach((plugin) => {
|
||||
Object.assign(this, plugin(this, options));
|
||||
});
|
||||
}
|
||||
static defaults(defaults) {
|
||||
const OctokitWithDefaults = class extends this {
|
||||
constructor(...args) {
|
||||
const options = args[0] || {};
|
||||
if (typeof defaults === "function") {
|
||||
super(defaults(options));
|
||||
return;
|
||||
}
|
||||
super(Object.assign({}, defaults, options, options.userAgent && defaults.userAgent
|
||||
? {
|
||||
userAgent: `${options.userAgent} ${defaults.userAgent}`,
|
||||
}
|
||||
: null));
|
||||
}
|
||||
};
|
||||
return OctokitWithDefaults;
|
||||
}
|
||||
/**
|
||||
* Attach a plugin (or many) to your Octokit instance.
|
||||
*
|
||||
* @example
|
||||
* const API = Octokit.plugin(plugin1, plugin2, plugin3, ...)
|
||||
*/
|
||||
static plugin(...newPlugins) {
|
||||
var _a;
|
||||
const currentPlugins = this.plugins;
|
||||
const NewOctokit = (_a = class extends this {
|
||||
},
|
||||
_a.plugins = currentPlugins.concat(newPlugins.filter((plugin) => !currentPlugins.includes(plugin))),
|
||||
_a);
|
||||
return NewOctokit;
|
||||
}
|
||||
}
|
||||
Octokit.VERSION = VERSION;
|
||||
Octokit.plugins = [];
|
||||
+1
@@ -0,0 +1 @@
|
||||
export {};
|
||||
+1
@@ -0,0 +1 @@
|
||||
export const VERSION = "3.2.1";
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
import { HookCollection } from "before-after-hook";
|
||||
import { request } from "@octokit/request";
|
||||
import { graphql } from "@octokit/graphql";
|
||||
import { Constructor, OctokitOptions, OctokitPlugin, ReturnTypeOf, UnionToIntersection } from "./types";
|
||||
export declare class Octokit {
|
||||
static VERSION: string;
|
||||
static defaults<S extends Constructor<any>>(this: S, defaults: OctokitOptions | Function): {
|
||||
new (...args: any[]): {
|
||||
[x: string]: any;
|
||||
};
|
||||
} & S;
|
||||
static plugins: OctokitPlugin[];
|
||||
/**
|
||||
* Attach a plugin (or many) to your Octokit instance.
|
||||
*
|
||||
* @example
|
||||
* const API = Octokit.plugin(plugin1, plugin2, plugin3, ...)
|
||||
*/
|
||||
static plugin<S extends Constructor<any> & {
|
||||
plugins: any[];
|
||||
}, T extends OctokitPlugin[]>(this: S, ...newPlugins: T): {
|
||||
new (...args: any[]): {
|
||||
[x: string]: any;
|
||||
};
|
||||
plugins: any[];
|
||||
} & S & Constructor<UnionToIntersection<ReturnTypeOf<T>>>;
|
||||
constructor(options?: OctokitOptions);
|
||||
request: typeof request;
|
||||
graphql: typeof graphql;
|
||||
log: {
|
||||
debug: (message: string, additionalInfo?: object) => any;
|
||||
info: (message: string, additionalInfo?: object) => any;
|
||||
warn: (message: string, additionalInfo?: object) => any;
|
||||
error: (message: string, additionalInfo?: object) => any;
|
||||
[key: string]: any;
|
||||
};
|
||||
hook: HookCollection;
|
||||
auth: (...args: unknown[]) => Promise<unknown>;
|
||||
[key: string]: any;
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import * as OctokitTypes from "@octokit/types";
|
||||
import { Octokit } from ".";
|
||||
export declare type RequestParameters = OctokitTypes.RequestParameters;
|
||||
export declare type OctokitOptions = {
|
||||
authStrategy?: any;
|
||||
auth?: any;
|
||||
userAgent?: string;
|
||||
previews?: string[];
|
||||
baseUrl?: string;
|
||||
log?: {
|
||||
debug: (message: string) => unknown;
|
||||
info: (message: string) => unknown;
|
||||
warn: (message: string) => unknown;
|
||||
error: (message: string) => unknown;
|
||||
};
|
||||
request?: OctokitTypes.RequestRequestOptions;
|
||||
timeZone?: string;
|
||||
[option: string]: any;
|
||||
};
|
||||
export declare type Constructor<T> = new (...args: any[]) => T;
|
||||
export declare type ReturnTypeOf<T extends AnyFunction | AnyFunction[]> = T extends AnyFunction ? ReturnType<T> : T extends AnyFunction[] ? UnionToIntersection<ReturnType<T[number]>> : never;
|
||||
/**
|
||||
* @author https://stackoverflow.com/users/2887218/jcalz
|
||||
* @see https://stackoverflow.com/a/50375286/10325032
|
||||
*/
|
||||
export declare type UnionToIntersection<Union> = (Union extends any ? (argument: Union) => void : never) extends (argument: infer Intersection) => void ? Intersection : never;
|
||||
declare type AnyFunction = (...args: any) => any;
|
||||
export declare type OctokitPlugin = (octokit: Octokit, options: OctokitOptions) => {
|
||||
[key: string]: any;
|
||||
} | void;
|
||||
export {};
|
||||
+1
@@ -0,0 +1 @@
|
||||
export declare const VERSION = "3.2.1";
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
import { getUserAgent } from 'universal-user-agent';
|
||||
import { Collection } from 'before-after-hook';
|
||||
import { request } from '@octokit/request';
|
||||
import { withCustomRequest } from '@octokit/graphql';
|
||||
import { createTokenAuth } from '@octokit/auth-token';
|
||||
|
||||
const VERSION = "3.2.1";
|
||||
|
||||
class Octokit {
|
||||
constructor(options = {}) {
|
||||
const hook = new Collection();
|
||||
const requestDefaults = {
|
||||
baseUrl: request.endpoint.DEFAULTS.baseUrl,
|
||||
headers: {},
|
||||
request: Object.assign({}, options.request, {
|
||||
hook: hook.bind(null, "request"),
|
||||
}),
|
||||
mediaType: {
|
||||
previews: [],
|
||||
format: "",
|
||||
},
|
||||
};
|
||||
// prepend default user agent with `options.userAgent` if set
|
||||
requestDefaults.headers["user-agent"] = [
|
||||
options.userAgent,
|
||||
`octokit-core.js/${VERSION} ${getUserAgent()}`,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ");
|
||||
if (options.baseUrl) {
|
||||
requestDefaults.baseUrl = options.baseUrl;
|
||||
}
|
||||
if (options.previews) {
|
||||
requestDefaults.mediaType.previews = options.previews;
|
||||
}
|
||||
if (options.timeZone) {
|
||||
requestDefaults.headers["time-zone"] = options.timeZone;
|
||||
}
|
||||
this.request = request.defaults(requestDefaults);
|
||||
this.graphql = withCustomRequest(this.request).defaults(requestDefaults);
|
||||
this.log = Object.assign({
|
||||
debug: () => { },
|
||||
info: () => { },
|
||||
warn: console.warn.bind(console),
|
||||
error: console.error.bind(console),
|
||||
}, options.log);
|
||||
this.hook = hook;
|
||||
// (1) If neither `options.authStrategy` nor `options.auth` are set, the `octokit` instance
|
||||
// is unauthenticated. The `this.auth()` method is a no-op and no request hook is registered.
|
||||
// (2) If only `options.auth` is set, use the default token authentication strategy.
|
||||
// (3) If `options.authStrategy` is set then use it and pass in `options.auth`. Always pass own request as many strategies accept a custom request instance.
|
||||
// TODO: type `options.auth` based on `options.authStrategy`.
|
||||
if (!options.authStrategy) {
|
||||
if (!options.auth) {
|
||||
// (1)
|
||||
this.auth = async () => ({
|
||||
type: "unauthenticated",
|
||||
});
|
||||
}
|
||||
else {
|
||||
// (2)
|
||||
const auth = createTokenAuth(options.auth);
|
||||
// @ts-ignore ¯\_(ツ)_/¯
|
||||
hook.wrap("request", auth.hook);
|
||||
this.auth = auth;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const { authStrategy, ...otherOptions } = options;
|
||||
const auth = authStrategy(Object.assign({
|
||||
request: this.request,
|
||||
log: this.log,
|
||||
// we pass the current octokit instance as well as its constructor options
|
||||
// to allow for authentication strategies that return a new octokit instance
|
||||
// that shares the same internal state as the current one. The original
|
||||
// requirement for this was the "event-octokit" authentication strategy
|
||||
// of https://github.com/probot/octokit-auth-probot.
|
||||
octokit: this,
|
||||
octokitOptions: otherOptions,
|
||||
}, options.auth));
|
||||
// @ts-ignore ¯\_(ツ)_/¯
|
||||
hook.wrap("request", auth.hook);
|
||||
this.auth = auth;
|
||||
}
|
||||
// apply plugins
|
||||
// https://stackoverflow.com/a/16345172
|
||||
const classConstructor = this.constructor;
|
||||
classConstructor.plugins.forEach((plugin) => {
|
||||
Object.assign(this, plugin(this, options));
|
||||
});
|
||||
}
|
||||
static defaults(defaults) {
|
||||
const OctokitWithDefaults = class extends this {
|
||||
constructor(...args) {
|
||||
const options = args[0] || {};
|
||||
if (typeof defaults === "function") {
|
||||
super(defaults(options));
|
||||
return;
|
||||
}
|
||||
super(Object.assign({}, defaults, options, options.userAgent && defaults.userAgent
|
||||
? {
|
||||
userAgent: `${options.userAgent} ${defaults.userAgent}`,
|
||||
}
|
||||
: null));
|
||||
}
|
||||
};
|
||||
return OctokitWithDefaults;
|
||||
}
|
||||
/**
|
||||
* Attach a plugin (or many) to your Octokit instance.
|
||||
*
|
||||
* @example
|
||||
* const API = Octokit.plugin(plugin1, plugin2, plugin3, ...)
|
||||
*/
|
||||
static plugin(...newPlugins) {
|
||||
var _a;
|
||||
const currentPlugins = this.plugins;
|
||||
const NewOctokit = (_a = class extends this {
|
||||
},
|
||||
_a.plugins = currentPlugins.concat(newPlugins.filter((plugin) => !currentPlugins.includes(plugin))),
|
||||
_a);
|
||||
return NewOctokit;
|
||||
}
|
||||
}
|
||||
Octokit.VERSION = VERSION;
|
||||
Octokit.plugins = [];
|
||||
|
||||
export { Octokit };
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+90
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"_from": "@octokit/core@^3.0.0",
|
||||
"_id": "@octokit/core@3.2.1",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-XfFSDDwv6tclUenS0EmB6iA7u+4aOHBT1Lz4PtQNQQg3hBbNaR/+Uv5URU+egeIuuGAiMRiDyY92G4GBOWOqDA==",
|
||||
"_location": "/@octokit/core",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "@octokit/core@^3.0.0",
|
||||
"name": "@octokit/core",
|
||||
"escapedName": "@octokit%2fcore",
|
||||
"scope": "@octokit",
|
||||
"rawSpec": "^3.0.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^3.0.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/@actions/github"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.2.1.tgz",
|
||||
"_shasum": "9e04df3f4e7f825ac0559327490ce34299140af5",
|
||||
"_spec": "@octokit/core@^3.0.0",
|
||||
"_where": "/workspace/setup-ossutil/node_modules/@actions/github",
|
||||
"bugs": {
|
||||
"url": "https://github.com/octokit/core.js/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^2.4.0",
|
||||
"@octokit/graphql": "^4.3.1",
|
||||
"@octokit/request": "^5.4.0",
|
||||
"@octokit/types": "^5.0.0",
|
||||
"before-after-hook": "^2.1.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Extendable client for GitHub's REST & GraphQL APIs",
|
||||
"devDependencies": {
|
||||
"@octokit/auth": "^2.0.0",
|
||||
"@pika/pack": "^0.5.0",
|
||||
"@pika/plugin-build-node": "^0.9.0",
|
||||
"@pika/plugin-build-web": "^0.9.0",
|
||||
"@pika/plugin-ts-standard-pkg": "^0.9.0",
|
||||
"@types/fetch-mock": "^7.3.1",
|
||||
"@types/jest": "^26.0.0",
|
||||
"@types/lolex": "^5.1.0",
|
||||
"@types/node": "^14.0.4",
|
||||
"@types/node-fetch": "^2.5.0",
|
||||
"fetch-mock": "^9.0.0",
|
||||
"http-proxy-agent": "^4.0.1",
|
||||
"jest": "^26.1.0",
|
||||
"lolex": "^6.0.0",
|
||||
"prettier": "^2.0.4",
|
||||
"proxy": "^1.0.1",
|
||||
"semantic-release": "^17.0.0",
|
||||
"semantic-release-plugin-update-version-in-files": "^1.0.0",
|
||||
"ts-jest": "^26.1.3",
|
||||
"typescript": "^4.0.2"
|
||||
},
|
||||
"files": [
|
||||
"dist-*/",
|
||||
"bin/"
|
||||
],
|
||||
"homepage": "https://github.com/octokit/core.js#readme",
|
||||
"keywords": [
|
||||
"octokit",
|
||||
"github",
|
||||
"api",
|
||||
"sdk",
|
||||
"toolkit"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "dist-node/index.js",
|
||||
"module": "dist-web/index.js",
|
||||
"name": "@octokit/core",
|
||||
"pika": true,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/octokit/core.js.git"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"source": "dist-src/index.js",
|
||||
"types": "dist-types/index.d.ts",
|
||||
"version": "3.2.1"
|
||||
}
|
||||
+27
-27
@@ -3,21 +3,21 @@
|
||||
> Turns GitHub REST API endpoints into generic request options
|
||||
|
||||
[](https://www.npmjs.com/package/@octokit/endpoint)
|
||||
[](https://travis-ci.org/octokit/endpoint.js)
|
||||
[](https://greenkeeper.io/)
|
||||

|
||||
|
||||
`@octokit/endpoint` combines [GitHub REST API routes](https://developer.github.com/v3/) with your parameters and turns them into generic request options that can be used in any request library.
|
||||
|
||||
<!-- update table of contents by running `npx markdown-toc README.md -i` -->
|
||||
|
||||
<!-- toc -->
|
||||
|
||||
- [Usage](#usage)
|
||||
- [API](#api)
|
||||
- [endpoint()](#endpoint)
|
||||
- [endpoint.defaults()](#endpointdefaults)
|
||||
- [endpoint.DEFAULTS](#endpointdefaults)
|
||||
- [endpoint.merge()](#endpointmerge)
|
||||
- [endpoint.parse()](#endpointparse)
|
||||
- [`endpoint(route, options)` or `endpoint(options)`](#endpointroute-options-or-endpointoptions)
|
||||
- [`endpoint.defaults()`](#endpointdefaults)
|
||||
- [`endpoint.DEFAULTS`](#endpointdefaults)
|
||||
- [`endpoint.merge(route, options)` or `endpoint.merge(options)`](#endpointmergeroute-options-or-endpointmergeoptions)
|
||||
- [`endpoint.parse()`](#endpointparse)
|
||||
- [Special cases](#special-cases)
|
||||
- [The `data` parameter – set request body directly](#the-data-parameter-%E2%80%93-set-request-body-directly)
|
||||
- [Set parameters for both the URL/query and the request body](#set-parameters-for-both-the-urlquery-and-the-request-body)
|
||||
@@ -32,11 +32,11 @@
|
||||
<tr><th>
|
||||
Browsers
|
||||
</th><td width=100%>
|
||||
Load <code>@octokit/endpoint</code> directly from <a href="https://cdn.pika.dev">cdn.pika.dev</a>
|
||||
Load <code>@octokit/endpoint</code> directly from <a href="https://cdn.skypack.dev">cdn.skypack.dev</a>
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import { endpoint } from "https://cdn.pika.dev/@octokit/endpoint";
|
||||
import { endpoint } from "https://cdn.skypack.dev/@octokit/endpoint";
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -61,10 +61,10 @@ Example for [List organization repositories](https://developer.github.com/v3/rep
|
||||
```js
|
||||
const requestOptions = endpoint("GET /orgs/:org/repos", {
|
||||
headers: {
|
||||
authorization: "token 0000000000000000000000000000000000000001"
|
||||
authorization: "token 0000000000000000000000000000000000000001",
|
||||
},
|
||||
org: "octokit",
|
||||
type: "private"
|
||||
type: "private",
|
||||
});
|
||||
```
|
||||
|
||||
@@ -82,7 +82,7 @@ The resulting `requestOptions` looks as follows
|
||||
}
|
||||
```
|
||||
|
||||
You can pass `requestOptions` to commen request libraries
|
||||
You can pass `requestOptions` to common request libraries
|
||||
|
||||
```js
|
||||
const { url, ...options } = requestOptions;
|
||||
@@ -283,10 +283,10 @@ const myEndpoint = require("@octokit/endpoint").defaults({
|
||||
baseUrl: "https://github-enterprise.acme-inc.com/api/v3",
|
||||
headers: {
|
||||
"user-agent": "myApp/1.2.3",
|
||||
authorization: `token 0000000000000000000000000000000000000001`
|
||||
authorization: `token 0000000000000000000000000000000000000001`,
|
||||
},
|
||||
org: "my-project",
|
||||
per_page: 100
|
||||
per_page: 100,
|
||||
});
|
||||
|
||||
request(myEndpoint(`GET /orgs/:org/repos`));
|
||||
@@ -298,14 +298,14 @@ You can call `.defaults()` again on the returned method, the defaults will casca
|
||||
const myProjectEndpoint = endpoint.defaults({
|
||||
baseUrl: "https://github-enterprise.acme-inc.com/api/v3",
|
||||
headers: {
|
||||
"user-agent": "myApp/1.2.3"
|
||||
"user-agent": "myApp/1.2.3",
|
||||
},
|
||||
org: "my-project"
|
||||
org: "my-project",
|
||||
});
|
||||
const myProjectEndpointWithAuth = myProjectEndpoint.defaults({
|
||||
headers: {
|
||||
authorization: `token 0000000000000000000000000000000000000001`
|
||||
}
|
||||
authorization: `token 0000000000000000000000000000000000000001`,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
@@ -320,7 +320,7 @@ The current default options.
|
||||
```js
|
||||
endpoint.DEFAULTS.baseUrl; // https://api.github.com
|
||||
const myEndpoint = endpoint.defaults({
|
||||
baseUrl: "https://github-enterprise.acme-inc.com/api/v3"
|
||||
baseUrl: "https://github-enterprise.acme-inc.com/api/v3",
|
||||
});
|
||||
myEndpoint.DEFAULTS.baseUrl; // https://github-enterprise.acme-inc.com/api/v3
|
||||
```
|
||||
@@ -333,16 +333,16 @@ Get the defaulted endpoint options, but without parsing them into request option
|
||||
const myProjectEndpoint = endpoint.defaults({
|
||||
baseUrl: "https://github-enterprise.acme-inc.com/api/v3",
|
||||
headers: {
|
||||
"user-agent": "myApp/1.2.3"
|
||||
"user-agent": "myApp/1.2.3",
|
||||
},
|
||||
org: "my-project"
|
||||
org: "my-project",
|
||||
});
|
||||
myProjectEndpoint.merge("GET /orgs/:org/repos", {
|
||||
headers: {
|
||||
authorization: `token 0000000000000000000000000000000000000001`
|
||||
authorization: `token 0000000000000000000000000000000000000001`,
|
||||
},
|
||||
org: "my-secret-project",
|
||||
type: "private"
|
||||
type: "private",
|
||||
});
|
||||
|
||||
// {
|
||||
@@ -377,8 +377,8 @@ const options = endpoint("POST /markdown/raw", {
|
||||
data: "Hello world github/linguist#1 **cool**, and #1!",
|
||||
headers: {
|
||||
accept: "text/html;charset=utf-8",
|
||||
"content-type": "text/plain"
|
||||
}
|
||||
"content-type": "text/plain",
|
||||
},
|
||||
});
|
||||
|
||||
// options is
|
||||
@@ -409,9 +409,9 @@ endpoint(
|
||||
headers: {
|
||||
"content-type": "text/plain",
|
||||
"content-length": 14,
|
||||
authorization: `token 0000000000000000000000000000000000000001`
|
||||
authorization: `token 0000000000000000000000000000000000000001`,
|
||||
},
|
||||
data: "Hello, world!"
|
||||
data: "Hello, world!",
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
+23
-10
@@ -2,9 +2,7 @@
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
||||
|
||||
var isPlainObject = _interopDefault(require('is-plain-object'));
|
||||
var isPlainObject = require('is-plain-object');
|
||||
var universalUserAgent = require('universal-user-agent');
|
||||
|
||||
function lowercaseKeys(object) {
|
||||
@@ -21,7 +19,7 @@ function lowercaseKeys(object) {
|
||||
function mergeDeep(defaults, options) {
|
||||
const result = Object.assign({}, defaults);
|
||||
Object.keys(options).forEach(key => {
|
||||
if (isPlainObject(options[key])) {
|
||||
if (isPlainObject.isPlainObject(options[key])) {
|
||||
if (!(key in defaults)) Object.assign(result, {
|
||||
[key]: options[key]
|
||||
});else result[key] = mergeDeep(defaults[key], options[key]);
|
||||
@@ -34,6 +32,16 @@ function mergeDeep(defaults, options) {
|
||||
return result;
|
||||
}
|
||||
|
||||
function removeUndefinedProperties(obj) {
|
||||
for (const key in obj) {
|
||||
if (obj[key] === undefined) {
|
||||
delete obj[key];
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
function merge(defaults, route, options) {
|
||||
if (typeof route === "string") {
|
||||
let [method, url] = route.split(" ");
|
||||
@@ -48,7 +56,10 @@ function merge(defaults, route, options) {
|
||||
} // lowercase header names before merging with defaults to avoid duplicates
|
||||
|
||||
|
||||
options.headers = lowercaseKeys(options.headers);
|
||||
options.headers = lowercaseKeys(options.headers); // remove properties with undefined values before merging
|
||||
|
||||
removeUndefinedProperties(options);
|
||||
removeUndefinedProperties(options.headers);
|
||||
const mergedOptions = mergeDeep(defaults || {}, options); // mediaType.previews arrays are merged, instead of overwritten
|
||||
|
||||
if (defaults && defaults.mediaType.previews.length) {
|
||||
@@ -270,7 +281,7 @@ function parse(options) {
|
||||
// https://fetch.spec.whatwg.org/#methods
|
||||
let method = options.method.toUpperCase(); // replace :varname with {varname} to make it RFC 6570 compatible
|
||||
|
||||
let url = options.url.replace(/:([a-z]\w+)/g, "{+$1}");
|
||||
let url = (options.url || "/").replace(/:([a-z]\w+)/g, "{$1}");
|
||||
let headers = Object.assign({}, options.headers);
|
||||
let body;
|
||||
let parameters = omit(options, ["method", "baseUrl", "url", "headers", "request", "mediaType"]); // extract variable names from URL to calculate remaining variables later
|
||||
@@ -284,9 +295,9 @@ function parse(options) {
|
||||
|
||||
const omittedParameters = Object.keys(options).filter(option => urlVariableNames.includes(option)).concat("baseUrl");
|
||||
const remainingParameters = omit(parameters, omittedParameters);
|
||||
const isBinaryRequset = /application\/octet-stream/i.test(headers.accept);
|
||||
const isBinaryRequest = /application\/octet-stream/i.test(headers.accept);
|
||||
|
||||
if (!isBinaryRequset) {
|
||||
if (!isBinaryRequest) {
|
||||
if (options.mediaType.format) {
|
||||
// e.g. application/vnd.github.v3+json => application/vnd.github.v3.raw
|
||||
headers.accept = headers.accept.split(/,/).map(preview => preview.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/, `application/vnd$1$2.${options.mediaType.format}`)).join(",");
|
||||
@@ -355,9 +366,11 @@ function withDefaults(oldDefaults, newDefaults) {
|
||||
});
|
||||
}
|
||||
|
||||
const VERSION = "0.0.0-development";
|
||||
const VERSION = "6.0.9";
|
||||
|
||||
const userAgent = `octokit-endpoint.js/${VERSION} ${universalUserAgent.getUserAgent()}`; // DEFAULTS has all properties set that EndpointOptions has, except url.
|
||||
// So we use RequestParameters and add method as additional required property.
|
||||
|
||||
const userAgent = `octokit-endpoint.js/${VERSION} ${universalUserAgent.getUserAgent()}`;
|
||||
const DEFAULTS = {
|
||||
method: "GET",
|
||||
baseUrl: "https://api.github.com",
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+5
-3
@@ -1,15 +1,17 @@
|
||||
import { getUserAgent } from "universal-user-agent";
|
||||
import { VERSION } from "./version";
|
||||
const userAgent = `octokit-endpoint.js/${VERSION} ${getUserAgent()}`;
|
||||
// DEFAULTS has all properties set that EndpointOptions has, except url.
|
||||
// So we use RequestParameters and add method as additional required property.
|
||||
export const DEFAULTS = {
|
||||
method: "GET",
|
||||
baseUrl: "https://api.github.com",
|
||||
headers: {
|
||||
accept: "application/vnd.github.v3+json",
|
||||
"user-agent": userAgent
|
||||
"user-agent": userAgent,
|
||||
},
|
||||
mediaType: {
|
||||
format: "",
|
||||
previews: []
|
||||
}
|
||||
previews: [],
|
||||
},
|
||||
};
|
||||
|
||||
+5
-1
@@ -1,5 +1,6 @@
|
||||
import { lowercaseKeys } from "./util/lowercase-keys";
|
||||
import { mergeDeep } from "./util/merge-deep";
|
||||
import { removeUndefinedProperties } from "./util/remove-undefined-properties";
|
||||
export function merge(defaults, route, options) {
|
||||
if (typeof route === "string") {
|
||||
let [method, url] = route.split(" ");
|
||||
@@ -10,11 +11,14 @@ export function merge(defaults, route, options) {
|
||||
}
|
||||
// lowercase header names before merging with defaults to avoid duplicates
|
||||
options.headers = lowercaseKeys(options.headers);
|
||||
// remove properties with undefined values before merging
|
||||
removeUndefinedProperties(options);
|
||||
removeUndefinedProperties(options.headers);
|
||||
const mergedOptions = mergeDeep(defaults || {}, options);
|
||||
// mediaType.previews arrays are merged, instead of overwritten
|
||||
if (defaults && defaults.mediaType.previews.length) {
|
||||
mergedOptions.mediaType.previews = defaults.mediaType.previews
|
||||
.filter(preview => !mergedOptions.mediaType.previews.includes(preview))
|
||||
.filter((preview) => !mergedOptions.mediaType.previews.includes(preview))
|
||||
.concat(mergedOptions.mediaType.previews);
|
||||
}
|
||||
mergedOptions.mediaType.previews = mergedOptions.mediaType.previews.map((preview) => preview.replace(/-preview/, ""));
|
||||
|
||||
+7
-7
@@ -6,7 +6,7 @@ export function parse(options) {
|
||||
// https://fetch.spec.whatwg.org/#methods
|
||||
let method = options.method.toUpperCase();
|
||||
// replace :varname with {varname} to make it RFC 6570 compatible
|
||||
let url = options.url.replace(/:([a-z]\w+)/g, "{+$1}");
|
||||
let url = (options.url || "/").replace(/:([a-z]\w+)/g, "{$1}");
|
||||
let headers = Object.assign({}, options.headers);
|
||||
let body;
|
||||
let parameters = omit(options, [
|
||||
@@ -15,7 +15,7 @@ export function parse(options) {
|
||||
"url",
|
||||
"headers",
|
||||
"request",
|
||||
"mediaType"
|
||||
"mediaType",
|
||||
]);
|
||||
// extract variable names from URL to calculate remaining variables later
|
||||
const urlVariableNames = extractUrlVariableNames(url);
|
||||
@@ -24,23 +24,23 @@ export function parse(options) {
|
||||
url = options.baseUrl + url;
|
||||
}
|
||||
const omittedParameters = Object.keys(options)
|
||||
.filter(option => urlVariableNames.includes(option))
|
||||
.filter((option) => urlVariableNames.includes(option))
|
||||
.concat("baseUrl");
|
||||
const remainingParameters = omit(parameters, omittedParameters);
|
||||
const isBinaryRequset = /application\/octet-stream/i.test(headers.accept);
|
||||
if (!isBinaryRequset) {
|
||||
const isBinaryRequest = /application\/octet-stream/i.test(headers.accept);
|
||||
if (!isBinaryRequest) {
|
||||
if (options.mediaType.format) {
|
||||
// e.g. application/vnd.github.v3+json => application/vnd.github.v3.raw
|
||||
headers.accept = headers.accept
|
||||
.split(/,/)
|
||||
.map(preview => preview.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/, `application/vnd$1$2.${options.mediaType.format}`))
|
||||
.map((preview) => preview.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/, `application/vnd$1$2.${options.mediaType.format}`))
|
||||
.join(",");
|
||||
}
|
||||
if (options.mediaType.previews.length) {
|
||||
const previewsFromAcceptHeader = headers.accept.match(/[\w-]+(?=-preview)/g) || [];
|
||||
headers.accept = previewsFromAcceptHeader
|
||||
.concat(options.mediaType.previews)
|
||||
.map(preview => {
|
||||
.map((preview) => {
|
||||
const format = options.mediaType.format
|
||||
? `.${options.mediaType.format}`
|
||||
: "+json";
|
||||
|
||||
+2
-6
@@ -7,13 +7,9 @@ export function addQueryParameters(url, parameters) {
|
||||
return (url +
|
||||
separator +
|
||||
names
|
||||
.map(name => {
|
||||
.map((name) => {
|
||||
if (name === "q") {
|
||||
return ("q=" +
|
||||
parameters
|
||||
.q.split("+")
|
||||
.map(encodeURIComponent)
|
||||
.join("+"));
|
||||
return ("q=" + parameters.q.split("+").map(encodeURIComponent).join("+"));
|
||||
}
|
||||
return `${name}=${encodeURIComponent(parameters[name])}`;
|
||||
})
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import isPlainObject from "is-plain-object";
|
||||
import { isPlainObject } from "is-plain-object";
|
||||
export function mergeDeep(defaults, options) {
|
||||
const result = Object.assign({}, defaults);
|
||||
Object.keys(options).forEach(key => {
|
||||
Object.keys(options).forEach((key) => {
|
||||
if (isPlainObject(options[key])) {
|
||||
if (!(key in defaults))
|
||||
Object.assign(result, { [key]: options[key] });
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
export function omit(object, keysToOmit) {
|
||||
return Object.keys(object)
|
||||
.filter(option => !keysToOmit.includes(option))
|
||||
.filter((option) => !keysToOmit.includes(option))
|
||||
.reduce((obj, key) => {
|
||||
obj[key] = object[key];
|
||||
return obj;
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
export function removeUndefinedProperties(obj) {
|
||||
for (const key in obj) {
|
||||
if (obj[key] === undefined) {
|
||||
delete obj[key];
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
+3
-9
@@ -29,9 +29,7 @@ function encodeReserved(str) {
|
||||
.split(/(%[0-9A-Fa-f]{2})/g)
|
||||
.map(function (part) {
|
||||
if (!/%[0-9A-Fa-f]/.test(part)) {
|
||||
part = encodeURI(part)
|
||||
.replace(/%5B/g, "[")
|
||||
.replace(/%5D/g, "]");
|
||||
part = encodeURI(part).replace(/%5B/g, "[").replace(/%5D/g, "]");
|
||||
}
|
||||
return part;
|
||||
})
|
||||
@@ -39,11 +37,7 @@ function encodeReserved(str) {
|
||||
}
|
||||
function encodeUnreserved(str) {
|
||||
return encodeURIComponent(str).replace(/[!'()*]/g, function (c) {
|
||||
return ("%" +
|
||||
c
|
||||
.charCodeAt(0)
|
||||
.toString(16)
|
||||
.toUpperCase());
|
||||
return "%" + c.charCodeAt(0).toString(16).toUpperCase();
|
||||
});
|
||||
}
|
||||
function encodeValue(operator, value, key) {
|
||||
@@ -132,7 +126,7 @@ function getValues(context, operator, key, modifier) {
|
||||
}
|
||||
export function parseUrl(template) {
|
||||
return {
|
||||
expand: expand.bind(null, template)
|
||||
expand: expand.bind(null, template),
|
||||
};
|
||||
}
|
||||
function expand(template, context) {
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
export const VERSION = "0.0.0-development";
|
||||
export const VERSION = "6.0.9";
|
||||
|
||||
+1
-1
@@ -8,6 +8,6 @@ export function withDefaults(oldDefaults, newDefaults) {
|
||||
DEFAULTS,
|
||||
defaults: withDefaults.bind(null, DEFAULTS),
|
||||
merge: merge.bind(null, DEFAULTS),
|
||||
parse
|
||||
parse,
|
||||
});
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,2 +1,2 @@
|
||||
import { Defaults } from "./types";
|
||||
export declare const DEFAULTS: Defaults;
|
||||
import { EndpointDefaults } from "@octokit/types";
|
||||
export declare const DEFAULTS: EndpointDefaults;
|
||||
|
||||
+3
-2
@@ -1,2 +1,3 @@
|
||||
import { Defaults, Endpoint, RequestOptions, Route, Parameters } from "./types";
|
||||
export declare function endpointWithDefaults(defaults: Defaults, route: Route | Endpoint, options?: Parameters): RequestOptions;
|
||||
import { EndpointOptions, RequestParameters, Route } from "@octokit/types";
|
||||
import { DEFAULTS } from "./defaults";
|
||||
export declare function endpointWithDefaults(defaults: typeof DEFAULTS, route: Route | EndpointOptions, options?: RequestParameters): import("@octokit/types").RequestOptions;
|
||||
|
||||
-4284
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -1 +1 @@
|
||||
export declare const endpoint: import("./types").endpoint;
|
||||
export declare const endpoint: import("@octokit/types").EndpointInterface<object>;
|
||||
|
||||
+2
-2
@@ -1,2 +1,2 @@
|
||||
import { Defaults, Route, Parameters } from "./types";
|
||||
export declare function merge(defaults: Defaults | null, route?: Route | Parameters, options?: Parameters): Defaults;
|
||||
import { EndpointDefaults, RequestParameters, Route } from "@octokit/types";
|
||||
export declare function merge(defaults: EndpointDefaults | null, route?: Route | RequestParameters, options?: RequestParameters): EndpointDefaults;
|
||||
|
||||
+2
-2
@@ -1,2 +1,2 @@
|
||||
import { Defaults, RequestOptions } from "./types";
|
||||
export declare function parse(options: Defaults): RequestOptions;
|
||||
import { EndpointDefaults, RequestOptions } from "@octokit/types";
|
||||
export declare function parse(options: EndpointDefaults): RequestOptions;
|
||||
|
||||
-150
@@ -1,150 +0,0 @@
|
||||
import { Routes as KnownRoutes } from "./generated/routes";
|
||||
export interface endpoint {
|
||||
/**
|
||||
* 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`.
|
||||
*/
|
||||
(options: Endpoint): 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 KnownRoutes | R, options?: R extends keyof KnownRoutes ? KnownRoutes[R][0] & Parameters : Parameters): R extends keyof KnownRoutes ? KnownRoutes[R][1] : RequestOptions;
|
||||
/**
|
||||
* Object with current default route and parameters
|
||||
*/
|
||||
DEFAULTS: Defaults;
|
||||
/**
|
||||
* Returns a new `endpoint` with updated route and parameters
|
||||
*/
|
||||
defaults: (newDefaults: Parameters) => endpoint;
|
||||
merge: {
|
||||
/**
|
||||
* Merges current endpoint defaults with passed route and parameters,
|
||||
* without transforming them into 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`.
|
||||
*
|
||||
*/
|
||||
(route: Route, parameters?: Parameters): Defaults;
|
||||
/**
|
||||
* 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: Parameters): Defaults;
|
||||
/**
|
||||
* Returns current default options.
|
||||
*
|
||||
* @deprecated use endpoint.DEFAULTS instead
|
||||
*/
|
||||
(): Defaults;
|
||||
};
|
||||
/**
|
||||
* Stateless method to turn endpoint options into request options.
|
||||
* Calling `endpoint(options)` is the same as calling `endpoint.parse(endpoint.merge(options))`.
|
||||
*
|
||||
* @param {object} options `method`, `url`. Plus URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
|
||||
*/
|
||||
parse: (options: Defaults) => RequestOptions;
|
||||
}
|
||||
/**
|
||||
* Request method + URL. Example: `'GET /orgs/:org'`
|
||||
*/
|
||||
export declare type Route = string;
|
||||
/**
|
||||
* Relative or absolute URL. Examples: `'/orgs/:org'`, `https://example.com/foo/bar`
|
||||
*/
|
||||
export declare type Url = string;
|
||||
/**
|
||||
* Request method
|
||||
*/
|
||||
export declare type Method = "DELETE" | "GET" | "HEAD" | "PATCH" | "POST" | "PUT";
|
||||
/**
|
||||
* Endpoint parameters
|
||||
*/
|
||||
export declare type Parameters = {
|
||||
/**
|
||||
* Base URL to be used when a relative URL is passed, such as `/orgs/:org`.
|
||||
* If `baseUrl` is `https://enterprise.acme-inc.com/api/v3`, then the resulting
|
||||
* `RequestOptions.url` will be `https://enterprise.acme-inc.com/api/v3/orgs/:org`.
|
||||
*/
|
||||
baseUrl?: string;
|
||||
/**
|
||||
* HTTP headers. Use lowercase keys.
|
||||
*/
|
||||
headers?: Headers;
|
||||
/**
|
||||
* Media type options, see {@link https://developer.github.com/v3/media/|GitHub Developer Guide}
|
||||
*/
|
||||
mediaType?: {
|
||||
/**
|
||||
* `json` by default. Can be `raw`, `text`, `html`, `full`, `diff`, `patch`, `sha`, `base64`. Depending on endpoint
|
||||
*/
|
||||
format?: string;
|
||||
/**
|
||||
* Custom media type names of {@link https://developer.github.com/v3/media/|API Previews} without the `-preview` suffix.
|
||||
* Example for single preview: `['squirrel-girl']`.
|
||||
* Example for multiple previews: `['squirrel-girl', 'mister-fantastic']`.
|
||||
*/
|
||||
previews?: string[];
|
||||
};
|
||||
/**
|
||||
* Pass custom meta information for the request. The `request` object will be returned as is.
|
||||
*/
|
||||
request?: EndpointRequestOptions;
|
||||
/**
|
||||
* Any additional parameter will be passed as follows
|
||||
* 1. URL parameter if `':parameter'` or `{parameter}` is part of `url`
|
||||
* 2. Query parameter if `method` is `'GET'` or `'HEAD'`
|
||||
* 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;
|
||||
};
|
||||
export declare type Endpoint = Parameters & {
|
||||
method: Method;
|
||||
url: Url;
|
||||
};
|
||||
export declare type Defaults = Parameters & {
|
||||
method: Method;
|
||||
baseUrl: string;
|
||||
headers: Headers & {
|
||||
accept: string;
|
||||
"user-agent": string;
|
||||
};
|
||||
mediaType: {
|
||||
format: string;
|
||||
previews: string[];
|
||||
};
|
||||
};
|
||||
export declare type RequestOptions = {
|
||||
method: Method;
|
||||
url: Url;
|
||||
headers: Headers;
|
||||
body?: any;
|
||||
request?: EndpointRequestOptions;
|
||||
};
|
||||
export declare type Headers = {
|
||||
/**
|
||||
* Avoid setting `accept`, use `mediaFormat.{format|previews}` instead.
|
||||
*/
|
||||
accept?: string;
|
||||
/**
|
||||
* Use `authorization` to send authenticated request, remember `token ` / `bearer ` prefixes. Example: `token 1234567890abcdef1234567890abcdef12345678`
|
||||
*/
|
||||
authorization?: string;
|
||||
/**
|
||||
* `user-agent` is set do a default and can be overwritten as needed.
|
||||
*/
|
||||
"user-agent"?: string;
|
||||
[header: string]: string | number | undefined;
|
||||
};
|
||||
export declare type EndpointRequestOptions = {
|
||||
[option: string]: any;
|
||||
};
|
||||
+1
@@ -0,0 +1 @@
|
||||
export declare function removeUndefinedProperties(obj: any): any;
|
||||
+1
-1
@@ -1 +1 @@
|
||||
export declare const VERSION = "0.0.0-development";
|
||||
export declare const VERSION = "6.0.9";
|
||||
|
||||
+2
-2
@@ -1,2 +1,2 @@
|
||||
import { Defaults, endpoint, Parameters } from "./types";
|
||||
export declare function withDefaults(oldDefaults: Defaults | null, newDefaults: Parameters): endpoint;
|
||||
import { EndpointInterface, RequestParameters, EndpointDefaults } from "@octokit/types";
|
||||
export declare function withDefaults(oldDefaults: EndpointDefaults | null, newDefaults: RequestParameters): EndpointInterface;
|
||||
|
||||
+35
-31
@@ -1,4 +1,4 @@
|
||||
import isPlainObject from 'is-plain-object';
|
||||
import { isPlainObject } from 'is-plain-object';
|
||||
import { getUserAgent } from 'universal-user-agent';
|
||||
|
||||
function lowercaseKeys(object) {
|
||||
@@ -13,7 +13,7 @@ function lowercaseKeys(object) {
|
||||
|
||||
function mergeDeep(defaults, options) {
|
||||
const result = Object.assign({}, defaults);
|
||||
Object.keys(options).forEach(key => {
|
||||
Object.keys(options).forEach((key) => {
|
||||
if (isPlainObject(options[key])) {
|
||||
if (!(key in defaults))
|
||||
Object.assign(result, { [key]: options[key] });
|
||||
@@ -27,6 +27,15 @@ function mergeDeep(defaults, options) {
|
||||
return result;
|
||||
}
|
||||
|
||||
function removeUndefinedProperties(obj) {
|
||||
for (const key in obj) {
|
||||
if (obj[key] === undefined) {
|
||||
delete obj[key];
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
function merge(defaults, route, options) {
|
||||
if (typeof route === "string") {
|
||||
let [method, url] = route.split(" ");
|
||||
@@ -37,11 +46,14 @@ function merge(defaults, route, options) {
|
||||
}
|
||||
// lowercase header names before merging with defaults to avoid duplicates
|
||||
options.headers = lowercaseKeys(options.headers);
|
||||
// remove properties with undefined values before merging
|
||||
removeUndefinedProperties(options);
|
||||
removeUndefinedProperties(options.headers);
|
||||
const mergedOptions = mergeDeep(defaults || {}, options);
|
||||
// mediaType.previews arrays are merged, instead of overwritten
|
||||
if (defaults && defaults.mediaType.previews.length) {
|
||||
mergedOptions.mediaType.previews = defaults.mediaType.previews
|
||||
.filter(preview => !mergedOptions.mediaType.previews.includes(preview))
|
||||
.filter((preview) => !mergedOptions.mediaType.previews.includes(preview))
|
||||
.concat(mergedOptions.mediaType.previews);
|
||||
}
|
||||
mergedOptions.mediaType.previews = mergedOptions.mediaType.previews.map((preview) => preview.replace(/-preview/, ""));
|
||||
@@ -57,13 +69,9 @@ function addQueryParameters(url, parameters) {
|
||||
return (url +
|
||||
separator +
|
||||
names
|
||||
.map(name => {
|
||||
.map((name) => {
|
||||
if (name === "q") {
|
||||
return ("q=" +
|
||||
parameters
|
||||
.q.split("+")
|
||||
.map(encodeURIComponent)
|
||||
.join("+"));
|
||||
return ("q=" + parameters.q.split("+").map(encodeURIComponent).join("+"));
|
||||
}
|
||||
return `${name}=${encodeURIComponent(parameters[name])}`;
|
||||
})
|
||||
@@ -84,7 +92,7 @@ function extractUrlVariableNames(url) {
|
||||
|
||||
function omit(object, keysToOmit) {
|
||||
return Object.keys(object)
|
||||
.filter(option => !keysToOmit.includes(option))
|
||||
.filter((option) => !keysToOmit.includes(option))
|
||||
.reduce((obj, key) => {
|
||||
obj[key] = object[key];
|
||||
return obj;
|
||||
@@ -122,9 +130,7 @@ function encodeReserved(str) {
|
||||
.split(/(%[0-9A-Fa-f]{2})/g)
|
||||
.map(function (part) {
|
||||
if (!/%[0-9A-Fa-f]/.test(part)) {
|
||||
part = encodeURI(part)
|
||||
.replace(/%5B/g, "[")
|
||||
.replace(/%5D/g, "]");
|
||||
part = encodeURI(part).replace(/%5B/g, "[").replace(/%5D/g, "]");
|
||||
}
|
||||
return part;
|
||||
})
|
||||
@@ -132,11 +138,7 @@ function encodeReserved(str) {
|
||||
}
|
||||
function encodeUnreserved(str) {
|
||||
return encodeURIComponent(str).replace(/[!'()*]/g, function (c) {
|
||||
return ("%" +
|
||||
c
|
||||
.charCodeAt(0)
|
||||
.toString(16)
|
||||
.toUpperCase());
|
||||
return "%" + c.charCodeAt(0).toString(16).toUpperCase();
|
||||
});
|
||||
}
|
||||
function encodeValue(operator, value, key) {
|
||||
@@ -225,7 +227,7 @@ function getValues(context, operator, key, modifier) {
|
||||
}
|
||||
function parseUrl(template) {
|
||||
return {
|
||||
expand: expand.bind(null, template)
|
||||
expand: expand.bind(null, template),
|
||||
};
|
||||
}
|
||||
function expand(template, context) {
|
||||
@@ -266,7 +268,7 @@ function parse(options) {
|
||||
// https://fetch.spec.whatwg.org/#methods
|
||||
let method = options.method.toUpperCase();
|
||||
// replace :varname with {varname} to make it RFC 6570 compatible
|
||||
let url = options.url.replace(/:([a-z]\w+)/g, "{+$1}");
|
||||
let url = (options.url || "/").replace(/:([a-z]\w+)/g, "{$1}");
|
||||
let headers = Object.assign({}, options.headers);
|
||||
let body;
|
||||
let parameters = omit(options, [
|
||||
@@ -275,7 +277,7 @@ function parse(options) {
|
||||
"url",
|
||||
"headers",
|
||||
"request",
|
||||
"mediaType"
|
||||
"mediaType",
|
||||
]);
|
||||
// extract variable names from URL to calculate remaining variables later
|
||||
const urlVariableNames = extractUrlVariableNames(url);
|
||||
@@ -284,23 +286,23 @@ function parse(options) {
|
||||
url = options.baseUrl + url;
|
||||
}
|
||||
const omittedParameters = Object.keys(options)
|
||||
.filter(option => urlVariableNames.includes(option))
|
||||
.filter((option) => urlVariableNames.includes(option))
|
||||
.concat("baseUrl");
|
||||
const remainingParameters = omit(parameters, omittedParameters);
|
||||
const isBinaryRequset = /application\/octet-stream/i.test(headers.accept);
|
||||
if (!isBinaryRequset) {
|
||||
const isBinaryRequest = /application\/octet-stream/i.test(headers.accept);
|
||||
if (!isBinaryRequest) {
|
||||
if (options.mediaType.format) {
|
||||
// e.g. application/vnd.github.v3+json => application/vnd.github.v3.raw
|
||||
headers.accept = headers.accept
|
||||
.split(/,/)
|
||||
.map(preview => preview.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/, `application/vnd$1$2.${options.mediaType.format}`))
|
||||
.map((preview) => preview.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/, `application/vnd$1$2.${options.mediaType.format}`))
|
||||
.join(",");
|
||||
}
|
||||
if (options.mediaType.previews.length) {
|
||||
const previewsFromAcceptHeader = headers.accept.match(/[\w-]+(?=-preview)/g) || [];
|
||||
headers.accept = previewsFromAcceptHeader
|
||||
.concat(options.mediaType.previews)
|
||||
.map(preview => {
|
||||
.map((preview) => {
|
||||
const format = options.mediaType.format
|
||||
? `.${options.mediaType.format}`
|
||||
: "+json";
|
||||
@@ -351,24 +353,26 @@ function withDefaults(oldDefaults, newDefaults) {
|
||||
DEFAULTS,
|
||||
defaults: withDefaults.bind(null, DEFAULTS),
|
||||
merge: merge.bind(null, DEFAULTS),
|
||||
parse
|
||||
parse,
|
||||
});
|
||||
}
|
||||
|
||||
const VERSION = "0.0.0-development";
|
||||
const VERSION = "6.0.9";
|
||||
|
||||
const userAgent = `octokit-endpoint.js/${VERSION} ${getUserAgent()}`;
|
||||
// DEFAULTS has all properties set that EndpointOptions has, except url.
|
||||
// So we use RequestParameters and add method as additional required property.
|
||||
const DEFAULTS = {
|
||||
method: "GET",
|
||||
baseUrl: "https://api.github.com",
|
||||
headers: {
|
||||
accept: "application/vnd.github.v3+json",
|
||||
"user-agent": userAgent
|
||||
"user-agent": userAgent,
|
||||
},
|
||||
mediaType: {
|
||||
format: "",
|
||||
previews: []
|
||||
}
|
||||
previews: [],
|
||||
},
|
||||
};
|
||||
|
||||
const endpoint = withDefaults(null, DEFAULTS);
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
-7
@@ -1,7 +0,0 @@
|
||||
# [ISC License](https://spdx.org/licenses/ISC)
|
||||
|
||||
Copyright (c) 2018, Gregor Martynus (https://github.com/gr2m)
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
# universal-user-agent
|
||||
|
||||
> Get a user agent string in both browser and node
|
||||
|
||||
[](https://www.npmjs.com/package/universal-user-agent)
|
||||
[](https://travis-ci.com/gr2m/universal-user-agent)
|
||||
[](https://greenkeeper.io/)
|
||||
|
||||
```js
|
||||
const { getUserAgent } = require("universal-user-agent");
|
||||
// or import { getUserAgent } from "universal-user-agent";
|
||||
|
||||
const userAgent = getUserAgent();
|
||||
// userAgent will look like this
|
||||
// in browser: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:61.0) Gecko/20100101 Firefox/61.0"
|
||||
// in node: Node.js/v8.9.4 (macOS High Sierra; x64)
|
||||
```
|
||||
|
||||
## Credits
|
||||
|
||||
The Node implementation was originally inspired by [default-user-agent](https://www.npmjs.com/package/default-user-agent).
|
||||
|
||||
## License
|
||||
|
||||
[ISC](LICENSE.md)
|
||||
Generated
Vendored
-22
@@ -1,22 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
||||
|
||||
var osName = _interopDefault(require('os-name'));
|
||||
|
||||
function getUserAgent() {
|
||||
try {
|
||||
return `Node.js/${process.version.substr(1)} (${osName()}; ${process.arch})`;
|
||||
} catch (error) {
|
||||
if (/wmic os get Caption/.test(error.message)) {
|
||||
return "Windows <version undetectable>";
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
exports.getUserAgent = getUserAgent;
|
||||
//# sourceMappingURL=index.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"index.js","sources":["../dist-src/node.js"],"sourcesContent":["import osName from \"os-name\";\nexport function getUserAgent() {\n try {\n return `Node.js/${process.version.substr(1)} (${osName()}; ${process.arch})`;\n }\n catch (error) {\n if (/wmic os get Caption/.test(error.message)) {\n return \"Windows <version undetectable>\";\n }\n throw error;\n }\n}\n"],"names":["getUserAgent","process","version","substr","osName","arch","error","test","message"],"mappings":";;;;;;;;AACO,SAASA,YAAT,GAAwB;MACvB;WACQ,WAAUC,OAAO,CAACC,OAAR,CAAgBC,MAAhB,CAAuB,CAAvB,CAA0B,KAAIC,MAAM,EAAG,KAAIH,OAAO,CAACI,IAAK,GAA1E;GADJ,CAGA,OAAOC,KAAP,EAAc;QACN,sBAAsBC,IAAtB,CAA2BD,KAAK,CAACE,OAAjC,CAAJ,EAA+C;aACpC,gCAAP;;;UAEEF,KAAN;;;;;;"}
|
||||
Generated
Vendored
-3
@@ -1,3 +0,0 @@
|
||||
export function getUserAgent() {
|
||||
return navigator.userAgent;
|
||||
}
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
export { getUserAgent } from "./node";
|
||||
Generated
Vendored
-12
@@ -1,12 +0,0 @@
|
||||
import osName from "os-name";
|
||||
export function getUserAgent() {
|
||||
try {
|
||||
return `Node.js/${process.version.substr(1)} (${osName()}; ${process.arch})`;
|
||||
}
|
||||
catch (error) {
|
||||
if (/wmic os get Caption/.test(error.message)) {
|
||||
return "Windows <version undetectable>";
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
export declare function getUserAgent(): string;
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
export { getUserAgent } from "./node";
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
export declare function getUserAgent(): string;
|
||||
Generated
Vendored
-6
@@ -1,6 +0,0 @@
|
||||
function getUserAgent() {
|
||||
return navigator.userAgent;
|
||||
}
|
||||
|
||||
export { getUserAgent };
|
||||
//# sourceMappingURL=index.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"index.js","sources":["../dist-src/browser.js"],"sourcesContent":["export function getUserAgent() {\n return navigator.userAgent;\n}\n"],"names":[],"mappings":"AAAO,SAAS,YAAY,GAAG;IAC3B,OAAO,SAAS,CAAC,SAAS,CAAC;CAC9B;;;;"}
|
||||
-65
@@ -1,65 +0,0 @@
|
||||
{
|
||||
"_from": "universal-user-agent@^4.0.0",
|
||||
"_id": "universal-user-agent@4.0.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==",
|
||||
"_location": "/@octokit/endpoint/universal-user-agent",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "universal-user-agent@^4.0.0",
|
||||
"name": "universal-user-agent",
|
||||
"escapedName": "universal-user-agent",
|
||||
"rawSpec": "^4.0.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^4.0.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/@octokit/endpoint"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz",
|
||||
"_shasum": "27da2ec87e32769619f68a14996465ea1cb9df16",
|
||||
"_spec": "universal-user-agent@^4.0.0",
|
||||
"_where": "/Users/yuanrong.man/projects/setup-ossutil/node_modules/@octokit/endpoint",
|
||||
"bugs": {
|
||||
"url": "https://github.com/gr2m/universal-user-agent/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"os-name": "^3.1.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Get a user agent string in both browser and node",
|
||||
"devDependencies": {
|
||||
"@gr2m/pika-plugin-build-web": "^0.6.0-issue-84.1",
|
||||
"@pika/pack": "^0.5.0",
|
||||
"@pika/plugin-build-node": "^0.6.0",
|
||||
"@pika/plugin-ts-standard-pkg": "^0.6.0",
|
||||
"@types/jest": "^24.0.18",
|
||||
"jest": "^24.9.0",
|
||||
"prettier": "^1.18.2",
|
||||
"semantic-release": "^15.9.15",
|
||||
"ts-jest": "^24.0.2",
|
||||
"typescript": "^3.6.2"
|
||||
},
|
||||
"files": [
|
||||
"dist-*/",
|
||||
"bin/"
|
||||
],
|
||||
"homepage": "https://github.com/gr2m/universal-user-agent#readme",
|
||||
"keywords": [],
|
||||
"license": "ISC",
|
||||
"main": "dist-node/index.js",
|
||||
"module": "dist-web/index.js",
|
||||
"name": "universal-user-agent",
|
||||
"pika": true,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/gr2m/universal-user-agent.git"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"source": "dist-src/index.js",
|
||||
"types": "dist-types/index.d.ts",
|
||||
"version": "4.0.0"
|
||||
}
|
||||
+24
-32
@@ -1,59 +1,51 @@
|
||||
{
|
||||
"_from": "@octokit/endpoint@^5.1.0",
|
||||
"_id": "@octokit/endpoint@5.4.0",
|
||||
"_from": "@octokit/endpoint@^6.0.1",
|
||||
"_id": "@octokit/endpoint@6.0.9",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-DWTNgEKg5KXzvNjKTzcFTnkZiL7te6pQxxumvxPjyjDpcY5V3xzywnNu1WVqySY3Ct1flF/kAoyDdZos6acq3Q==",
|
||||
"_integrity": "sha512-3VPLbcCuqji4IFTclNUtGdp9v7g+nspWdiCUbK3+iPMjJCZ6LEhn1ts626bWLOn0GiDb6j+uqGvPpqLnY7pBgw==",
|
||||
"_location": "/@octokit/endpoint",
|
||||
"_phantomChildren": {
|
||||
"os-name": "3.1.0"
|
||||
},
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "@octokit/endpoint@^5.1.0",
|
||||
"raw": "@octokit/endpoint@^6.0.1",
|
||||
"name": "@octokit/endpoint",
|
||||
"escapedName": "@octokit%2fendpoint",
|
||||
"scope": "@octokit",
|
||||
"rawSpec": "^5.1.0",
|
||||
"rawSpec": "^6.0.1",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^5.1.0"
|
||||
"fetchSpec": "^6.0.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/@octokit/request"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-5.4.0.tgz",
|
||||
"_shasum": "5b44b3e8e92d88765daf127e1501174ecbca7bce",
|
||||
"_spec": "@octokit/endpoint@^5.1.0",
|
||||
"_where": "/Users/yuanrong.man/projects/setup-ossutil/node_modules/@octokit/request",
|
||||
"_resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.9.tgz",
|
||||
"_shasum": "c6a772e024202b1bd19ab69f90e0536a2598b13e",
|
||||
"_spec": "@octokit/endpoint@^6.0.1",
|
||||
"_where": "/workspace/setup-ossutil/node_modules/@octokit/request",
|
||||
"bugs": {
|
||||
"url": "https://github.com/octokit/endpoint.js/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"is-plain-object": "^3.0.0",
|
||||
"universal-user-agent": "^4.0.0"
|
||||
"@octokit/types": "^5.0.0",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Turns REST API endpoints into generic request options",
|
||||
"devDependencies": {
|
||||
"@octokit/graphql": "^4.2.0",
|
||||
"@pika/pack": "^0.5.0",
|
||||
"@pika/plugin-build-node": "^0.6.0",
|
||||
"@pika/plugin-build-web": "^0.6.0",
|
||||
"@pika/plugin-ts-standard-pkg": "^0.6.0",
|
||||
"@types/jest": "^24.0.11",
|
||||
"handlebars": "^4.4.2",
|
||||
"jest": "^24.7.1",
|
||||
"lodash.set": "^4.3.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"pascal-case": "^2.0.1",
|
||||
"prettier": "1.18.2",
|
||||
"semantic-release": "^15.13.8",
|
||||
"@pika/plugin-build-node": "^0.9.0",
|
||||
"@pika/plugin-build-web": "^0.9.0",
|
||||
"@pika/plugin-ts-standard-pkg": "^0.9.0",
|
||||
"@types/jest": "^26.0.0",
|
||||
"jest": "^26.0.1",
|
||||
"prettier": "2.1.2",
|
||||
"semantic-release": "^17.0.0",
|
||||
"semantic-release-plugin-update-version-in-files": "^1.0.0",
|
||||
"sort-keys": "^4.0.0",
|
||||
"string-to-jsdoc-comment": "^1.0.0",
|
||||
"ts-jest": "^24.0.2",
|
||||
"typescript": "^3.4.5"
|
||||
"ts-jest": "^26.0.0",
|
||||
"typescript": "^4.0.2"
|
||||
},
|
||||
"files": [
|
||||
"dist-*/",
|
||||
@@ -81,5 +73,5 @@
|
||||
"sideEffects": false,
|
||||
"source": "dist-src/index.js",
|
||||
"types": "dist-types/index.d.ts",
|
||||
"version": "5.4.0"
|
||||
"version": "6.0.9"
|
||||
}
|
||||
|
||||
+241
-149
@@ -3,14 +3,19 @@
|
||||
> GitHub GraphQL API client for browsers and Node
|
||||
|
||||
[](https://www.npmjs.com/package/@octokit/graphql)
|
||||
[](https://travis-ci.com/octokit/graphql.js)
|
||||
[](https://coveralls.io/github/octokit/graphql.js)
|
||||
[](https://greenkeeper.io/)
|
||||
[](https://github.com/octokit/graphql.js/actions?query=workflow%3ATest+branch%3Amaster)
|
||||
|
||||
<!-- toc -->
|
||||
|
||||
- [Usage](#usage)
|
||||
- [Send a simple query](#send-a-simple-query)
|
||||
- [Authentication](#authentication)
|
||||
- [Variables](#variables)
|
||||
- [Pass query together with headers and variables](#pass-query-together-with-headers-and-variables)
|
||||
- [Use with GitHub Enterprise](#use-with-github-enterprise)
|
||||
- [Use custom `@octokit/request` instance](#use-custom-octokitrequest-instance)
|
||||
- [Errors](#errors)
|
||||
- [Partial responses](#partial-responses)
|
||||
- [Writing tests](#writing-tests)
|
||||
- [License](#license)
|
||||
|
||||
@@ -18,34 +23,75 @@
|
||||
|
||||
## Usage
|
||||
|
||||
Send a simple query
|
||||
<table>
|
||||
<tbody valign=top align=left>
|
||||
<tr><th>
|
||||
Browsers
|
||||
</th><td width=100%>
|
||||
|
||||
Load `@octokit/graphql` directly from [cdn.skypack.dev](https://cdn.skypack.dev)
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import { endpoint } from "https://cdn.skypack.dev/@octokit/graphql";
|
||||
</script>
|
||||
```
|
||||
|
||||
</td></tr>
|
||||
<tr><th>
|
||||
Node
|
||||
</th><td>
|
||||
|
||||
Install with <code>npm install @octokit/graphql</code>
|
||||
|
||||
```js
|
||||
const graphql = require('@octokit/graphql')
|
||||
const { repository } = await graphql(`{
|
||||
repository(owner:"octokit", name:"graphql.js") {
|
||||
issues(last:3) {
|
||||
edges {
|
||||
node {
|
||||
title
|
||||
const { graphql } = require("@octokit/graphql");
|
||||
// or: import { graphql } from "@octokit/graphql";
|
||||
```
|
||||
|
||||
</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Send a simple query
|
||||
|
||||
```js
|
||||
const { repository } = await graphql(
|
||||
`
|
||||
{
|
||||
repository(owner: "octokit", name: "graphql.js") {
|
||||
issues(last: 3) {
|
||||
edges {
|
||||
node {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
{
|
||||
headers: {
|
||||
authorization: `token secret123`,
|
||||
},
|
||||
}
|
||||
}`, {
|
||||
headers: {
|
||||
authorization: `token secret123`
|
||||
}
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
⚠️ Do not use [template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) in the query strings as they make your code vulnerable to query injection attacks (see [#2](https://github.com/octokit/graphql.js/issues/2)). Use variables instead:
|
||||
### Authentication
|
||||
|
||||
The simplest way to authenticate a request is to set the `Authorization` header, e.g. to a [personal access token](https://github.com/settings/tokens/).
|
||||
|
||||
```js
|
||||
const graphql = require('@octokit/graphql')
|
||||
const { lastIssues } = await graphql(`query lastIssues($owner: String!, $repo: String!, $num: Int = 3) {
|
||||
repository(owner:$owner, name:$repo) {
|
||||
issues(last:$num) {
|
||||
const graphqlWithAuth = graphql.defaults({
|
||||
headers: {
|
||||
authorization: `token secret123`,
|
||||
},
|
||||
});
|
||||
const { repository } = await graphqlWithAuth(`
|
||||
{
|
||||
repository(owner: "octokit", name: "graphql.js") {
|
||||
issues(last: 3) {
|
||||
edges {
|
||||
node {
|
||||
title
|
||||
@@ -53,73 +99,73 @@ const { lastIssues } = await graphql(`query lastIssues($owner: String!, $repo: S
|
||||
}
|
||||
}
|
||||
}
|
||||
}`, {
|
||||
owner: 'octokit',
|
||||
repo: 'graphql.js'
|
||||
headers: {
|
||||
authorization: `token secret123`
|
||||
}
|
||||
}
|
||||
})
|
||||
`);
|
||||
```
|
||||
|
||||
Create two new clients and set separate default configs for them.
|
||||
For more complex authentication strategies such as GitHub Apps or Basic, we recommend the according authentication library exported by [`@octokit/auth`](https://github.com/octokit/auth.js).
|
||||
|
||||
```js
|
||||
const graphql1 = require('@octokit/graphql').defaults({
|
||||
headers: {
|
||||
authorization: `token secret123`
|
||||
}
|
||||
})
|
||||
const { createAppAuth } = require("@octokit/auth-app");
|
||||
const auth = createAppAuth({
|
||||
id: process.env.APP_ID,
|
||||
privateKey: process.env.PRIVATE_KEY,
|
||||
installationId: 123,
|
||||
});
|
||||
const graphqlWithAuth = graphql.defaults({
|
||||
request: {
|
||||
hook: auth.hook,
|
||||
},
|
||||
});
|
||||
|
||||
const graphql2 = require('@octokit/graphql').defaults({
|
||||
headers: {
|
||||
authorization: `token foobar`
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Create two clients, the second inherits config from the first.
|
||||
|
||||
```js
|
||||
const graphql1 = require('@octokit/graphql').defaults({
|
||||
headers: {
|
||||
authorization: `token secret123`
|
||||
}
|
||||
})
|
||||
|
||||
const graphql2 = graphql1.defaults({
|
||||
headers: {
|
||||
'user-agent': 'my-user-agent/v1.2.3'
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Create a new client with default options and run query
|
||||
|
||||
```js
|
||||
const graphql = require('@octokit/graphql').defaults({
|
||||
headers: {
|
||||
authorization: `token secret123`
|
||||
}
|
||||
})
|
||||
const { repository } = await graphql(`{
|
||||
repository(owner:"octokit", name:"graphql.js") {
|
||||
issues(last:3) {
|
||||
edges {
|
||||
node {
|
||||
title
|
||||
const { repository } = await graphqlWithAuth(
|
||||
`{
|
||||
repository(owner: "octokit", name: "graphql.js") {
|
||||
issues(last: 3) {
|
||||
edges {
|
||||
node {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`)
|
||||
}`
|
||||
);
|
||||
```
|
||||
|
||||
Pass query together with headers and variables
|
||||
### Variables
|
||||
|
||||
⚠️ Do not use [template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) in the query strings as they make your code vulnerable to query injection attacks (see [#2](https://github.com/octokit/graphql.js/issues/2)). Use variables instead:
|
||||
|
||||
```js
|
||||
const graphql = require('@octokit/graphql')
|
||||
const { lastIssues } = await graphql(
|
||||
`
|
||||
query lastIssues($owner: String!, $repo: String!, $num: Int = 3) {
|
||||
repository(owner: $owner, name: $repo) {
|
||||
issues(last: $num) {
|
||||
edges {
|
||||
node {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
{
|
||||
owner: "octokit",
|
||||
repo: "graphql.js",
|
||||
headers: {
|
||||
authorization: `token secret123`,
|
||||
},
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
### Pass query together with headers and variables
|
||||
|
||||
```js
|
||||
const { graphql } = require("@octokit/graphql");
|
||||
const { lastIssues } = await graphql({
|
||||
query: `query lastIssues($owner: String!, $repo: String!, $num: Int = 3) {
|
||||
repository(owner:$owner, name:$repo) {
|
||||
@@ -132,34 +178,73 @@ const { lastIssues } = await graphql({
|
||||
}
|
||||
}
|
||||
}`,
|
||||
owner: 'octokit',
|
||||
repo: 'graphql.js'
|
||||
owner: "octokit",
|
||||
repo: "graphql.js",
|
||||
headers: {
|
||||
authorization: `token secret123`
|
||||
}
|
||||
})
|
||||
authorization: `token secret123`,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Use with GitHub Enterprise
|
||||
### Use with GitHub Enterprise
|
||||
|
||||
```js
|
||||
const graphql = require('@octokit/graphql').defaults({
|
||||
baseUrl: 'https://github-enterprise.acme-inc.com/api',
|
||||
let { graphql } = require("@octokit/graphql");
|
||||
graphql = graphql.defaults({
|
||||
baseUrl: "https://github-enterprise.acme-inc.com/api",
|
||||
headers: {
|
||||
authorization: `token secret123`
|
||||
}
|
||||
})
|
||||
const { repository } = await graphql(`{
|
||||
repository(owner:"acme-project", name:"acme-repo") {
|
||||
issues(last:3) {
|
||||
edges {
|
||||
node {
|
||||
title
|
||||
authorization: `token secret123`,
|
||||
},
|
||||
});
|
||||
const { repository } = await graphql(`
|
||||
{
|
||||
repository(owner: "acme-project", name: "acme-repo") {
|
||||
issues(last: 3) {
|
||||
edges {
|
||||
node {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`)
|
||||
`);
|
||||
```
|
||||
|
||||
### Use custom `@octokit/request` instance
|
||||
|
||||
```js
|
||||
const { request } = require("@octokit/request");
|
||||
const { withCustomRequest } = require("@octokit/graphql");
|
||||
|
||||
let requestCounter = 0;
|
||||
const myRequest = request.defaults({
|
||||
headers: {
|
||||
authentication: "token secret123",
|
||||
},
|
||||
request: {
|
||||
hook(request, options) {
|
||||
requestCounter++;
|
||||
return request(options);
|
||||
},
|
||||
},
|
||||
});
|
||||
const myGraphql = withCustomRequest(myRequest);
|
||||
await request("/");
|
||||
await myGraphql(`
|
||||
{
|
||||
repository(owner: "acme-project", name: "acme-repo") {
|
||||
issues(last: 3) {
|
||||
edges {
|
||||
node {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
// requestCounter is now 2
|
||||
```
|
||||
|
||||
## Errors
|
||||
@@ -167,19 +252,20 @@ const { repository } = await graphql(`{
|
||||
In case of a GraphQL error, `error.message` is set to the first error from the response’s `errors` array. All errors can be accessed at `error.errors`. `error.request` has the request options such as query, variables and headers set for easier debugging.
|
||||
|
||||
```js
|
||||
const graphql = require('@octokit/graphql').defaults({
|
||||
let { graphql } = require("@octokit/graphql");
|
||||
graphqlt = graphql.defaults({
|
||||
headers: {
|
||||
authorization: `token secret123`
|
||||
}
|
||||
})
|
||||
authorization: `token secret123`,
|
||||
},
|
||||
});
|
||||
const query = `{
|
||||
viewer {
|
||||
bioHtml
|
||||
}
|
||||
}`
|
||||
}`;
|
||||
|
||||
try {
|
||||
const result = await graphql(query)
|
||||
const result = await graphql(query);
|
||||
} catch (error) {
|
||||
// server responds with
|
||||
// {
|
||||
@@ -193,8 +279,8 @@ try {
|
||||
// }]
|
||||
// }
|
||||
|
||||
console.log('Request failed:', error.request) // { query, variables: {}, headers: { authorization: 'token secret123' } }
|
||||
console.log(error.message) // Field 'bioHtml' doesn't exist on type 'User'
|
||||
console.log("Request failed:", error.request); // { query, variables: {}, headers: { authorization: 'token secret123' } }
|
||||
console.log(error.message); // Field 'bioHtml' doesn't exist on type 'User'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -203,11 +289,12 @@ try {
|
||||
A GraphQL query may respond with partial data accompanied by errors. In this case we will throw an error but the partial data will still be accessible through `error.data`
|
||||
|
||||
```js
|
||||
const graphql = require('@octokit/graphql').defaults({
|
||||
let { graphql } = require("@octokit/graphql");
|
||||
graphql = graphql.defaults({
|
||||
headers: {
|
||||
authorization: `token secret123`
|
||||
}
|
||||
})
|
||||
authorization: `token secret123`,
|
||||
},
|
||||
});
|
||||
const query = `{
|
||||
repository(name: "probot", owner: "probot") {
|
||||
name
|
||||
@@ -223,42 +310,42 @@ const query = `{
|
||||
}
|
||||
}
|
||||
}
|
||||
}`
|
||||
}`;
|
||||
|
||||
try {
|
||||
const result = await graphql(query)
|
||||
const result = await graphql(query);
|
||||
} catch (error) {
|
||||
// server responds with
|
||||
// {
|
||||
// "data": {
|
||||
// "repository": {
|
||||
// "name": "probot",
|
||||
// "ref": null
|
||||
// }
|
||||
// },
|
||||
// "errors": [
|
||||
// {
|
||||
// "type": "INVALID_CURSOR_ARGUMENTS",
|
||||
// "path": [
|
||||
// "repository",
|
||||
// "ref",
|
||||
// "target",
|
||||
// "history"
|
||||
// ],
|
||||
// "locations": [
|
||||
// {
|
||||
// "line": 7,
|
||||
// "column": 11
|
||||
// }
|
||||
// ],
|
||||
// "message": "`invalid cursor` does not appear to be a valid cursor."
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// {
|
||||
// "data": {
|
||||
// "repository": {
|
||||
// "name": "probot",
|
||||
// "ref": null
|
||||
// }
|
||||
// },
|
||||
// "errors": [
|
||||
// {
|
||||
// "type": "INVALID_CURSOR_ARGUMENTS",
|
||||
// "path": [
|
||||
// "repository",
|
||||
// "ref",
|
||||
// "target",
|
||||
// "history"
|
||||
// ],
|
||||
// "locations": [
|
||||
// {
|
||||
// "line": 7,
|
||||
// "column": 11
|
||||
// }
|
||||
// ],
|
||||
// "message": "`invalid cursor` does not appear to be a valid cursor."
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
|
||||
console.log('Request failed:', error.request) // { query, variables: {}, headers: { authorization: 'token secret123' } }
|
||||
console.log(error.message) // `invalid cursor` does not appear to be a valid cursor.
|
||||
console.log(error.data) // { repository: { name: 'probot', ref: null } }
|
||||
console.log("Request failed:", error.request); // { query, variables: {}, headers: { authorization: 'token secret123' } }
|
||||
console.log(error.message); // `invalid cursor` does not appear to be a valid cursor.
|
||||
console.log(error.data); // { repository: { name: 'probot', ref: null } }
|
||||
}
|
||||
```
|
||||
|
||||
@@ -267,24 +354,29 @@ try {
|
||||
You can pass a replacement for [the built-in fetch implementation](https://github.com/bitinn/node-fetch) as `request.fetch` option. For example, using [fetch-mock](http://www.wheresrhys.co.uk/fetch-mock/) works great to write tests
|
||||
|
||||
```js
|
||||
const assert = require('assert')
|
||||
const fetchMock = require('fetch-mock/es5/server')
|
||||
const assert = require("assert");
|
||||
const fetchMock = require("fetch-mock/es5/server");
|
||||
|
||||
const graphql = require('@octokit/graphql')
|
||||
const { graphql } = require("@octokit/graphql");
|
||||
|
||||
graphql('{ viewer { login } }', {
|
||||
graphql("{ viewer { login } }", {
|
||||
headers: {
|
||||
authorization: 'token secret123'
|
||||
authorization: "token secret123",
|
||||
},
|
||||
request: {
|
||||
fetch: fetchMock.sandbox()
|
||||
.post('https://api.github.com/graphql', (url, options) => {
|
||||
assert.strictEqual(options.headers.authorization, 'token secret123')
|
||||
assert.strictEqual(options.body, '{"query":"{ viewer { login } }"}', 'Sends correct query')
|
||||
return { data: {} }
|
||||
})
|
||||
}
|
||||
})
|
||||
fetch: fetchMock
|
||||
.sandbox()
|
||||
.post("https://api.github.com/graphql", (url, options) => {
|
||||
assert.strictEqual(options.headers.authorization, "token secret123");
|
||||
assert.strictEqual(
|
||||
options.body,
|
||||
'{"query":"{ viewer { login } }"}',
|
||||
"Sends correct query"
|
||||
);
|
||||
return { data: {} };
|
||||
}),
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
var request = require('@octokit/request');
|
||||
var universalUserAgent = require('universal-user-agent');
|
||||
|
||||
const VERSION = "4.5.7";
|
||||
|
||||
class GraphqlError extends Error {
|
||||
constructor(request, response) {
|
||||
const message = response.data.errors[0].message;
|
||||
super(message);
|
||||
Object.assign(this, response.data);
|
||||
Object.assign(this, {
|
||||
headers: response.headers
|
||||
});
|
||||
this.name = "GraphqlError";
|
||||
this.request = request; // Maintains proper stack trace (only available on V8)
|
||||
|
||||
/* istanbul ignore next */
|
||||
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, this.constructor);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const NON_VARIABLE_OPTIONS = ["method", "baseUrl", "url", "headers", "request", "query", "mediaType"];
|
||||
const GHES_V3_SUFFIX_REGEX = /\/api\/v3\/?$/;
|
||||
function graphql(request, query, options) {
|
||||
if (typeof query === "string" && options && "query" in options) {
|
||||
return Promise.reject(new Error(`[@octokit/graphql] "query" cannot be used as variable name`));
|
||||
}
|
||||
|
||||
const parsedOptions = typeof query === "string" ? Object.assign({
|
||||
query
|
||||
}, options) : query;
|
||||
const requestOptions = Object.keys(parsedOptions).reduce((result, key) => {
|
||||
if (NON_VARIABLE_OPTIONS.includes(key)) {
|
||||
result[key] = parsedOptions[key];
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!result.variables) {
|
||||
result.variables = {};
|
||||
}
|
||||
|
||||
result.variables[key] = parsedOptions[key];
|
||||
return result;
|
||||
}, {}); // workaround for GitHub Enterprise baseUrl set with /api/v3 suffix
|
||||
// https://github.com/octokit/auth-app.js/issues/111#issuecomment-657610451
|
||||
|
||||
const baseUrl = parsedOptions.baseUrl || request.endpoint.DEFAULTS.baseUrl;
|
||||
|
||||
if (GHES_V3_SUFFIX_REGEX.test(baseUrl)) {
|
||||
requestOptions.url = baseUrl.replace(GHES_V3_SUFFIX_REGEX, "/api/graphql");
|
||||
}
|
||||
|
||||
return request(requestOptions).then(response => {
|
||||
if (response.data.errors) {
|
||||
const headers = {};
|
||||
|
||||
for (const key of Object.keys(response.headers)) {
|
||||
headers[key] = response.headers[key];
|
||||
}
|
||||
|
||||
throw new GraphqlError(requestOptions, {
|
||||
headers,
|
||||
data: response.data
|
||||
});
|
||||
}
|
||||
|
||||
return response.data.data;
|
||||
});
|
||||
}
|
||||
|
||||
function withDefaults(request$1, newDefaults) {
|
||||
const newRequest = request$1.defaults(newDefaults);
|
||||
|
||||
const newApi = (query, options) => {
|
||||
return graphql(newRequest, query, options);
|
||||
};
|
||||
|
||||
return Object.assign(newApi, {
|
||||
defaults: withDefaults.bind(null, newRequest),
|
||||
endpoint: request.request.endpoint
|
||||
});
|
||||
}
|
||||
|
||||
const graphql$1 = withDefaults(request.request, {
|
||||
headers: {
|
||||
"user-agent": `octokit-graphql.js/${VERSION} ${universalUserAgent.getUserAgent()}`
|
||||
},
|
||||
method: "POST",
|
||||
url: "/graphql"
|
||||
});
|
||||
function withCustomRequest(customRequest) {
|
||||
return withDefaults(customRequest, {
|
||||
method: "POST",
|
||||
url: "/graphql"
|
||||
});
|
||||
}
|
||||
|
||||
exports.graphql = graphql$1;
|
||||
exports.withCustomRequest = withCustomRequest;
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+15
@@ -0,0 +1,15 @@
|
||||
export class GraphqlError extends Error {
|
||||
constructor(request, response) {
|
||||
const message = response.data.errors[0].message;
|
||||
super(message);
|
||||
Object.assign(this, response.data);
|
||||
Object.assign(this, { headers: response.headers });
|
||||
this.name = "GraphqlError";
|
||||
this.request = request;
|
||||
// Maintains proper stack trace (only available on V8)
|
||||
/* istanbul ignore next */
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, this.constructor);
|
||||
}
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
import { GraphqlError } from "./error";
|
||||
const NON_VARIABLE_OPTIONS = [
|
||||
"method",
|
||||
"baseUrl",
|
||||
"url",
|
||||
"headers",
|
||||
"request",
|
||||
"query",
|
||||
"mediaType",
|
||||
];
|
||||
const GHES_V3_SUFFIX_REGEX = /\/api\/v3\/?$/;
|
||||
export function graphql(request, query, options) {
|
||||
if (typeof query === "string" && options && "query" in options) {
|
||||
return Promise.reject(new Error(`[@octokit/graphql] "query" cannot be used as variable name`));
|
||||
}
|
||||
const parsedOptions = typeof query === "string" ? Object.assign({ query }, options) : query;
|
||||
const requestOptions = Object.keys(parsedOptions).reduce((result, key) => {
|
||||
if (NON_VARIABLE_OPTIONS.includes(key)) {
|
||||
result[key] = parsedOptions[key];
|
||||
return result;
|
||||
}
|
||||
if (!result.variables) {
|
||||
result.variables = {};
|
||||
}
|
||||
result.variables[key] = parsedOptions[key];
|
||||
return result;
|
||||
}, {});
|
||||
// workaround for GitHub Enterprise baseUrl set with /api/v3 suffix
|
||||
// https://github.com/octokit/auth-app.js/issues/111#issuecomment-657610451
|
||||
const baseUrl = parsedOptions.baseUrl || request.endpoint.DEFAULTS.baseUrl;
|
||||
if (GHES_V3_SUFFIX_REGEX.test(baseUrl)) {
|
||||
requestOptions.url = baseUrl.replace(GHES_V3_SUFFIX_REGEX, "/api/graphql");
|
||||
}
|
||||
return request(requestOptions).then((response) => {
|
||||
if (response.data.errors) {
|
||||
const headers = {};
|
||||
for (const key of Object.keys(response.headers)) {
|
||||
headers[key] = response.headers[key];
|
||||
}
|
||||
throw new GraphqlError(requestOptions, {
|
||||
headers,
|
||||
data: response.data,
|
||||
});
|
||||
}
|
||||
return response.data.data;
|
||||
});
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import { request } from "@octokit/request";
|
||||
import { getUserAgent } from "universal-user-agent";
|
||||
import { VERSION } from "./version";
|
||||
import { withDefaults } from "./with-defaults";
|
||||
export const graphql = withDefaults(request, {
|
||||
headers: {
|
||||
"user-agent": `octokit-graphql.js/${VERSION} ${getUserAgent()}`,
|
||||
},
|
||||
method: "POST",
|
||||
url: "/graphql",
|
||||
});
|
||||
export function withCustomRequest(customRequest) {
|
||||
return withDefaults(customRequest, {
|
||||
method: "POST",
|
||||
url: "/graphql",
|
||||
});
|
||||
}
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
export const VERSION = "4.5.7";
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import { request as Request } from "@octokit/request";
|
||||
import { graphql } from "./graphql";
|
||||
export function withDefaults(request, newDefaults) {
|
||||
const newRequest = request.defaults(newDefaults);
|
||||
const newApi = (query, options) => {
|
||||
return graphql(newRequest, query, options);
|
||||
};
|
||||
return Object.assign(newApi, {
|
||||
defaults: withDefaults.bind(null, newRequest),
|
||||
endpoint: Request.endpoint,
|
||||
});
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import { ResponseHeaders } from "@octokit/types";
|
||||
import { GraphQlEndpointOptions, GraphQlQueryResponse } from "./types";
|
||||
export declare class GraphqlError<ResponseData> extends Error {
|
||||
request: GraphQlEndpointOptions;
|
||||
constructor(request: GraphQlEndpointOptions, response: {
|
||||
headers: ResponseHeaders;
|
||||
data: Required<GraphQlQueryResponse<ResponseData>>;
|
||||
});
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import { request as Request } from "@octokit/request";
|
||||
import { RequestParameters, GraphQlQueryResponseData } from "./types";
|
||||
export declare function graphql<ResponseData = GraphQlQueryResponseData>(request: typeof Request, query: string | RequestParameters, options?: RequestParameters): Promise<ResponseData>;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import { request } from "@octokit/request";
|
||||
export declare const graphql: import("./types").graphql;
|
||||
export declare function withCustomRequest(customRequest: typeof request): import("./types").graphql;
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
import { EndpointOptions, RequestParameters as RequestParametersType, EndpointInterface } from "@octokit/types";
|
||||
export declare type GraphQlEndpointOptions = EndpointOptions & {
|
||||
variables?: {
|
||||
[key: string]: unknown;
|
||||
};
|
||||
};
|
||||
export declare type RequestParameters = RequestParametersType;
|
||||
export declare type Query = string;
|
||||
export interface graphql {
|
||||
/**
|
||||
* Sends a GraphQL query request based on endpoint options
|
||||
* The GraphQL query must be specified in `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`.
|
||||
*/
|
||||
<ResponseData>(options: RequestParameters): GraphQlResponse<ResponseData>;
|
||||
/**
|
||||
* Sends a GraphQL query request based on endpoint options
|
||||
*
|
||||
* @param {string} query GraphQL query. Example: `'query { viewer { login } }'`.
|
||||
* @param {object} [parameters] URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
|
||||
*/
|
||||
<ResponseData>(query: Query, parameters?: RequestParameters): GraphQlResponse<ResponseData>;
|
||||
/**
|
||||
* Returns a new `endpoint` with updated route and parameters
|
||||
*/
|
||||
defaults: (newDefaults: RequestParameters) => graphql;
|
||||
/**
|
||||
* Octokit endpoint API, see {@link https://github.com/octokit/endpoint.js|@octokit/endpoint}
|
||||
*/
|
||||
endpoint: EndpointInterface;
|
||||
}
|
||||
export declare type GraphQlResponse<ResponseData> = Promise<ResponseData>;
|
||||
export declare type GraphQlQueryResponseData = {
|
||||
[key: string]: any;
|
||||
};
|
||||
export declare type GraphQlQueryResponse<ResponseData> = {
|
||||
data: ResponseData;
|
||||
errors?: [{
|
||||
message: string;
|
||||
path: [string];
|
||||
extensions: {
|
||||
[key: string]: any;
|
||||
};
|
||||
locations: [{
|
||||
line: number;
|
||||
column: number;
|
||||
}];
|
||||
}];
|
||||
};
|
||||
+1
@@ -0,0 +1 @@
|
||||
export declare const VERSION = "4.5.7";
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import { request as Request } from "@octokit/request";
|
||||
import { graphql as ApiInterface, RequestParameters } from "./types";
|
||||
export declare function withDefaults(request: typeof Request, newDefaults: RequestParameters): ApiInterface;
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
import { request } from '@octokit/request';
|
||||
import { getUserAgent } from 'universal-user-agent';
|
||||
|
||||
const VERSION = "4.5.7";
|
||||
|
||||
class GraphqlError extends Error {
|
||||
constructor(request, response) {
|
||||
const message = response.data.errors[0].message;
|
||||
super(message);
|
||||
Object.assign(this, response.data);
|
||||
Object.assign(this, { headers: response.headers });
|
||||
this.name = "GraphqlError";
|
||||
this.request = request;
|
||||
// Maintains proper stack trace (only available on V8)
|
||||
/* istanbul ignore next */
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, this.constructor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const NON_VARIABLE_OPTIONS = [
|
||||
"method",
|
||||
"baseUrl",
|
||||
"url",
|
||||
"headers",
|
||||
"request",
|
||||
"query",
|
||||
"mediaType",
|
||||
];
|
||||
const GHES_V3_SUFFIX_REGEX = /\/api\/v3\/?$/;
|
||||
function graphql(request, query, options) {
|
||||
if (typeof query === "string" && options && "query" in options) {
|
||||
return Promise.reject(new Error(`[@octokit/graphql] "query" cannot be used as variable name`));
|
||||
}
|
||||
const parsedOptions = typeof query === "string" ? Object.assign({ query }, options) : query;
|
||||
const requestOptions = Object.keys(parsedOptions).reduce((result, key) => {
|
||||
if (NON_VARIABLE_OPTIONS.includes(key)) {
|
||||
result[key] = parsedOptions[key];
|
||||
return result;
|
||||
}
|
||||
if (!result.variables) {
|
||||
result.variables = {};
|
||||
}
|
||||
result.variables[key] = parsedOptions[key];
|
||||
return result;
|
||||
}, {});
|
||||
// workaround for GitHub Enterprise baseUrl set with /api/v3 suffix
|
||||
// https://github.com/octokit/auth-app.js/issues/111#issuecomment-657610451
|
||||
const baseUrl = parsedOptions.baseUrl || request.endpoint.DEFAULTS.baseUrl;
|
||||
if (GHES_V3_SUFFIX_REGEX.test(baseUrl)) {
|
||||
requestOptions.url = baseUrl.replace(GHES_V3_SUFFIX_REGEX, "/api/graphql");
|
||||
}
|
||||
return request(requestOptions).then((response) => {
|
||||
if (response.data.errors) {
|
||||
const headers = {};
|
||||
for (const key of Object.keys(response.headers)) {
|
||||
headers[key] = response.headers[key];
|
||||
}
|
||||
throw new GraphqlError(requestOptions, {
|
||||
headers,
|
||||
data: response.data,
|
||||
});
|
||||
}
|
||||
return response.data.data;
|
||||
});
|
||||
}
|
||||
|
||||
function withDefaults(request$1, newDefaults) {
|
||||
const newRequest = request$1.defaults(newDefaults);
|
||||
const newApi = (query, options) => {
|
||||
return graphql(newRequest, query, options);
|
||||
};
|
||||
return Object.assign(newApi, {
|
||||
defaults: withDefaults.bind(null, newRequest),
|
||||
endpoint: request.endpoint,
|
||||
});
|
||||
}
|
||||
|
||||
const graphql$1 = withDefaults(request, {
|
||||
headers: {
|
||||
"user-agent": `octokit-graphql.js/${VERSION} ${getUserAgent()}`,
|
||||
},
|
||||
method: "POST",
|
||||
url: "/graphql",
|
||||
});
|
||||
function withCustomRequest(customRequest) {
|
||||
return withDefaults(customRequest, {
|
||||
method: "POST",
|
||||
url: "/graphql",
|
||||
});
|
||||
}
|
||||
|
||||
export { graphql$1 as graphql, withCustomRequest };
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
-15
@@ -1,15 +0,0 @@
|
||||
const { request } = require('@octokit/request')
|
||||
const getUserAgent = require('universal-user-agent')
|
||||
|
||||
const version = require('./package.json').version
|
||||
const userAgent = `octokit-graphql.js/${version} ${getUserAgent()}`
|
||||
|
||||
const withDefaults = require('./lib/with-defaults')
|
||||
|
||||
module.exports = withDefaults(request, {
|
||||
method: 'POST',
|
||||
url: '/graphql',
|
||||
headers: {
|
||||
'user-agent': userAgent
|
||||
}
|
||||
})
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
module.exports = class GraphqlError extends Error {
|
||||
constructor (request, response) {
|
||||
const message = response.data.errors[0].message
|
||||
super(message)
|
||||
|
||||
Object.assign(this, response.data)
|
||||
this.name = 'GraphqlError'
|
||||
this.request = request
|
||||
|
||||
// Maintains proper stack trace (only available on V8)
|
||||
/* istanbul ignore next */
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, this.constructor)
|
||||
}
|
||||
}
|
||||
}
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
module.exports = graphql
|
||||
|
||||
const GraphqlError = require('./error')
|
||||
|
||||
const NON_VARIABLE_OPTIONS = ['method', 'baseUrl', 'url', 'headers', 'request', 'query']
|
||||
|
||||
function graphql (request, query, options) {
|
||||
if (typeof query === 'string') {
|
||||
options = Object.assign({ query }, options)
|
||||
} else {
|
||||
options = query
|
||||
}
|
||||
|
||||
const requestOptions = Object.keys(options).reduce((result, key) => {
|
||||
if (NON_VARIABLE_OPTIONS.includes(key)) {
|
||||
result[key] = options[key]
|
||||
return result
|
||||
}
|
||||
|
||||
if (!result.variables) {
|
||||
result.variables = {}
|
||||
}
|
||||
|
||||
result.variables[key] = options[key]
|
||||
return result
|
||||
}, {})
|
||||
|
||||
return request(requestOptions)
|
||||
.then(response => {
|
||||
if (response.data.errors) {
|
||||
throw new GraphqlError(requestOptions, response)
|
||||
}
|
||||
|
||||
return response.data.data
|
||||
})
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
module.exports = withDefaults
|
||||
|
||||
const graphql = require('./graphql')
|
||||
|
||||
function withDefaults (request, newDefaults) {
|
||||
const newRequest = request.defaults(newDefaults)
|
||||
const newApi = function (query, options) {
|
||||
return graphql(newRequest, query, options)
|
||||
}
|
||||
|
||||
newApi.defaults = withDefaults.bind(null, newRequest)
|
||||
return newApi
|
||||
}
|
||||
+37
-76
@@ -1,67 +1,58 @@
|
||||
{
|
||||
"_from": "@octokit/graphql@^2.0.1",
|
||||
"_id": "@octokit/graphql@2.1.3",
|
||||
"_from": "@octokit/graphql@^4.3.1",
|
||||
"_id": "@octokit/graphql@4.5.7",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-XoXJqL2ondwdnMIW3wtqJWEwcBfKk37jO/rYkoxNPEVeLBDGsGO1TCWggrAlq3keGt/O+C/7VepXnukUxwt5vA==",
|
||||
"_integrity": "sha512-Gk0AR+DcwIK/lK/GX+OQ99UqtenQhcbrhHHfOYlrCQe17ADnX3EKAOKRsAZ9qZvpi5MuwWm/Nm+9aO2kTDSdyA==",
|
||||
"_location": "/@octokit/graphql",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "@octokit/graphql@^2.0.1",
|
||||
"raw": "@octokit/graphql@^4.3.1",
|
||||
"name": "@octokit/graphql",
|
||||
"escapedName": "@octokit%2fgraphql",
|
||||
"scope": "@octokit",
|
||||
"rawSpec": "^2.0.1",
|
||||
"rawSpec": "^4.3.1",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^2.0.1"
|
||||
"fetchSpec": "^4.3.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/@actions/github"
|
||||
"/@octokit/core"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-2.1.3.tgz",
|
||||
"_shasum": "60c058a0ed5fa242eca6f938908d95fd1a2f4b92",
|
||||
"_spec": "@octokit/graphql@^2.0.1",
|
||||
"_where": "/Users/yuanrong.man/projects/setup-ossutil/node_modules/@actions/github",
|
||||
"author": {
|
||||
"name": "Gregor Martynus",
|
||||
"url": "https://github.com/gr2m"
|
||||
},
|
||||
"_resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.5.7.tgz",
|
||||
"_shasum": "f4562dcd9e80ea94602068e85aefac19a88f8578",
|
||||
"_spec": "@octokit/graphql@^4.3.1",
|
||||
"_where": "/workspace/setup-ossutil/node_modules/@octokit/core",
|
||||
"bugs": {
|
||||
"url": "https://github.com/octokit/graphql.js/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"bundlesize": [
|
||||
{
|
||||
"path": "./dist/octokit-graphql.min.js.gz",
|
||||
"maxSize": "5KB"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"@octokit/request": "^5.0.0",
|
||||
"universal-user-agent": "^2.0.3"
|
||||
"@octokit/request": "^5.3.0",
|
||||
"@octokit/types": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "GitHub GraphQL API client for browsers and Node",
|
||||
"devDependencies": {
|
||||
"chai": "^4.2.0",
|
||||
"compression-webpack-plugin": "^2.0.0",
|
||||
"coveralls": "^3.0.3",
|
||||
"cypress": "^3.1.5",
|
||||
"fetch-mock": "^7.3.1",
|
||||
"mkdirp": "^0.5.1",
|
||||
"mocha": "^6.0.0",
|
||||
"npm-run-all": "^4.1.3",
|
||||
"nyc": "^14.0.0",
|
||||
"semantic-release": "^15.13.3",
|
||||
"simple-mock": "^0.8.0",
|
||||
"standard": "^12.0.1",
|
||||
"webpack": "^4.29.6",
|
||||
"webpack-bundle-analyzer": "^3.1.0",
|
||||
"webpack-cli": "^3.2.3"
|
||||
"@pika/pack": "^0.5.0",
|
||||
"@pika/plugin-build-node": "^0.9.0",
|
||||
"@pika/plugin-build-web": "^0.9.0",
|
||||
"@pika/plugin-ts-standard-pkg": "^0.9.0",
|
||||
"@types/fetch-mock": "^7.2.5",
|
||||
"@types/jest": "^26.0.0",
|
||||
"@types/node": "^14.0.4",
|
||||
"fetch-mock": "^9.0.0",
|
||||
"jest": "^25.1.0",
|
||||
"prettier": "^2.0.0",
|
||||
"semantic-release": "^17.0.0",
|
||||
"semantic-release-plugin-update-version-in-files": "^1.0.0",
|
||||
"ts-jest": "^25.1.0",
|
||||
"typescript": "^3.4.5"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
"dist-*/",
|
||||
"bin/"
|
||||
],
|
||||
"homepage": "https://github.com/octokit/graphql.js#readme",
|
||||
"keywords": [
|
||||
@@ -71,49 +62,19 @@
|
||||
"graphql"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"main": "dist-node/index.js",
|
||||
"module": "dist-web/index.js",
|
||||
"name": "@octokit/graphql",
|
||||
"pika": true,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"release": {
|
||||
"publish": [
|
||||
"@semantic-release/npm",
|
||||
{
|
||||
"path": "@semantic-release/github",
|
||||
"assets": [
|
||||
"dist/*",
|
||||
"!dist/*.map.gz"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/octokit/graphql.js.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npm-run-all build:*",
|
||||
"build:development": "webpack --mode development --entry . --output-library=octokitGraphql --output=./dist/octokit-graphql.js --profile --json > dist/bundle-stats.json",
|
||||
"build:production": "webpack --mode production --entry . --plugin=compression-webpack-plugin --output-library=octokitGraphql --output-path=./dist --output-filename=octokit-graphql.min.js --devtool source-map",
|
||||
"bundle-report": "webpack-bundle-analyzer dist/bundle-stats.json --mode=static --no-open --report dist/bundle-report.html",
|
||||
"coverage": "nyc report --reporter=html && open coverage/index.html",
|
||||
"coverage:upload": "nyc report --reporter=text-lcov | coveralls",
|
||||
"prebuild": "mkdirp dist/",
|
||||
"pretest": "standard",
|
||||
"test": "nyc mocha test/*-test.js",
|
||||
"test:browser": "cypress run --browser chrome"
|
||||
},
|
||||
"standard": {
|
||||
"globals": [
|
||||
"describe",
|
||||
"before",
|
||||
"beforeEach",
|
||||
"afterEach",
|
||||
"after",
|
||||
"it",
|
||||
"expect"
|
||||
]
|
||||
},
|
||||
"version": "2.1.3"
|
||||
"sideEffects": false,
|
||||
"source": "dist-src/index.js",
|
||||
"types": "dist-types/index.d.ts",
|
||||
"version": "4.5.7"
|
||||
}
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
MIT License Copyright (c) 2019 Octokit contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
# plugin-paginate-rest.js
|
||||
|
||||
> Octokit plugin to paginate REST API endpoint responses
|
||||
|
||||
[](https://www.npmjs.com/package/@octokit/plugin-paginate-rest)
|
||||
[](https://github.com/octokit/plugin-paginate-rest.js/actions?workflow=Test)
|
||||
|
||||
## Usage
|
||||
|
||||
<table>
|
||||
<tbody valign=top align=left>
|
||||
<tr><th>
|
||||
Browsers
|
||||
</th><td width=100%>
|
||||
|
||||
Load `@octokit/plugin-paginate-rest` and [`@octokit/core`](https://github.com/octokit/core.js) (or core-compatible module) directly from [cdn.skypack.dev](https://cdn.skypack.dev)
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import { Octokit } from "https://cdn.skypack.dev/@octokit/core";
|
||||
import { paginateRest } from "https://cdn.skypack.dev/@octokit/plugin-paginate-rest";
|
||||
</script>
|
||||
```
|
||||
|
||||
</td></tr>
|
||||
<tr><th>
|
||||
Node
|
||||
</th><td>
|
||||
|
||||
Install with `npm install @octokit/core @octokit/plugin-paginate-rest`. Optionally replace `@octokit/core` with a core-compatible module
|
||||
|
||||
```js
|
||||
const { Octokit } = require("@octokit/core");
|
||||
const { paginateRest } = require("@octokit/plugin-paginate-rest");
|
||||
```
|
||||
|
||||
</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
```js
|
||||
const MyOctokit = Octokit.plugin(paginateRest);
|
||||
const octokit = new MyOctokit({ auth: "secret123" });
|
||||
|
||||
// See https://developer.github.com/v3/issues/#list-issues-for-a-repository
|
||||
const issues = await octokit.paginate("GET /repos/:owner/:repo/issues", {
|
||||
owner: "octocat",
|
||||
repo: "hello-world",
|
||||
since: "2010-10-01",
|
||||
per_page: 100,
|
||||
});
|
||||
```
|
||||
|
||||
## `octokit.paginate()`
|
||||
|
||||
The `paginateRest` plugin adds a new `octokit.paginate()` method which accepts the same parameters as [`octokit.request`](https://github.com/octokit/request.js#request). Only "List ..." endpoints such as [List issues for a repository](https://developer.github.com/v3/issues/#list-issues-for-a-repository) are supporting pagination. Their [response includes a Link header](https://developer.github.com/v3/issues/#response-1). For other endpoints, `octokit.paginate()` behaves the same as `octokit.request()`.
|
||||
|
||||
The `per_page` parameter is usually defaulting to `30`, and can be set to up to `100`, which helps retrieving a big amount of data without hitting the rate limits too soon.
|
||||
|
||||
An optional `mapFunction` can be passed to map each page response to a new value, usually an array with only the data you need. This can help to reduce memory usage, as only the relevant data has to be kept in memory until the pagination is complete.
|
||||
|
||||
```js
|
||||
const issueTitles = await octokit.paginate(
|
||||
"GET /repos/:owner/:repo/issues",
|
||||
{
|
||||
owner: "octocat",
|
||||
repo: "hello-world",
|
||||
since: "2010-10-01",
|
||||
per_page: 100,
|
||||
},
|
||||
(response) => response.data.map((issue) => issue.title)
|
||||
);
|
||||
```
|
||||
|
||||
The `mapFunction` gets a 2nd argument `done` which can be called to end the pagination early.
|
||||
|
||||
```js
|
||||
const issues = await octokit.paginate(
|
||||
"GET /repos/:owner/:repo/issues",
|
||||
{
|
||||
owner: "octocat",
|
||||
repo: "hello-world",
|
||||
since: "2010-10-01",
|
||||
per_page: 100,
|
||||
},
|
||||
(response, done) => {
|
||||
if (response.data.find((issues) => issue.title.includes("something"))) {
|
||||
done();
|
||||
}
|
||||
return response.data;
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
Alternatively you can pass a `request` method as first argument. This is great when using in combination with [`@octokit/plugin-rest-endpoint-methods`](https://github.com/octokit/plugin-rest-endpoint-methods.js/):
|
||||
|
||||
```js
|
||||
const issues = await octokit.paginate(octokit.issues.listForRepo, {
|
||||
owner: "octocat",
|
||||
repo: "hello-world",
|
||||
since: "2010-10-01",
|
||||
per_page: 100,
|
||||
});
|
||||
```
|
||||
|
||||
## `octokit.paginate.iterator()`
|
||||
|
||||
If your target runtime environments supports async iterators (such as most modern browsers and Node 10+), you can iterate through each response
|
||||
|
||||
```js
|
||||
const parameters = {
|
||||
owner: "octocat",
|
||||
repo: "hello-world",
|
||||
since: "2010-10-01",
|
||||
per_page: 100,
|
||||
};
|
||||
for await (const response of octokit.paginate.iterator(
|
||||
"GET /repos/:owner/:repo/issues",
|
||||
parameters
|
||||
)) {
|
||||
// do whatever you want with each response, break out of the loop, etc.
|
||||
console.log(response.data.title);
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively you can pass a `request` method as first argument. This is great when using in combination with [`@octokit/plugin-rest-endpoint-methods`](https://github.com/octokit/plugin-rest-endpoint-methods.js/):
|
||||
|
||||
```js
|
||||
const parameters = {
|
||||
owner: "octocat",
|
||||
repo: "hello-world",
|
||||
since: "2010-10-01",
|
||||
per_page: 100,
|
||||
};
|
||||
for await (const response of octokit.paginate.iterator(
|
||||
octokit.issues.listForRepo,
|
||||
parameters
|
||||
)) {
|
||||
// do whatever you want with each response, break out of the loop, etc.
|
||||
console.log(response.data.title);
|
||||
}
|
||||
```
|
||||
|
||||
## How it works
|
||||
|
||||
`octokit.paginate()` wraps `octokit.request()`. As long as a `rel="next"` link value is present in the response's `Link` header, it sends another request for that URL, and so on.
|
||||
|
||||
Most of GitHub's paginating REST API endpoints return an array, but there are a few exceptions which return an object with a key that includes the items array. For example:
|
||||
|
||||
- [Search repositories](https://developer.github.com/v3/search/#example) (key `items`)
|
||||
- [List check runs for a specific ref](https://developer.github.com/v3/checks/runs/#response-3) (key: `check_runs`)
|
||||
- [List check suites for a specific ref](https://developer.github.com/v3/checks/suites/#response-1) (key: `check_suites`)
|
||||
- [List repositories](https://developer.github.com/v3/apps/installations/#list-repositories) for an installation (key: `repositories`)
|
||||
- [List installations for a user](https://developer.github.com/v3/apps/installations/#response-1) (key `installations`)
|
||||
|
||||
`octokit.paginate()` is working around these inconsistencies so you don't have to worry about it.
|
||||
|
||||
If a response is lacking the `Link` header, `octokit.paginate()` still resolves with an array, even if the response returns a single object.
|
||||
|
||||
## Contributing
|
||||
|
||||
See [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
const VERSION = "2.6.0";
|
||||
|
||||
/**
|
||||
* Some “list” response that can be paginated have a different response structure
|
||||
*
|
||||
* They have a `total_count` key in the response (search also has `incomplete_results`,
|
||||
* /installation/repositories also has `repository_selection`), as well as a key with
|
||||
* the list of the items which name varies from endpoint to endpoint.
|
||||
*
|
||||
* Octokit normalizes these responses so that paginated results are always returned following
|
||||
* the same structure. One challenge is that if the list response has only one page, no Link
|
||||
* header is provided, so this header alone is not sufficient to check wether a response is
|
||||
* paginated or not.
|
||||
*
|
||||
* We check if a "total_count" key is present in the response data, but also make sure that
|
||||
* a "url" property is not, as the "Get the combined status for a specific ref" endpoint would
|
||||
* otherwise match: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref
|
||||
*/
|
||||
function normalizePaginatedListResponse(response) {
|
||||
const responseNeedsNormalization = "total_count" in response.data && !("url" in response.data);
|
||||
if (!responseNeedsNormalization) return response; // keep the additional properties intact as there is currently no other way
|
||||
// to retrieve the same information.
|
||||
|
||||
const incompleteResults = response.data.incomplete_results;
|
||||
const repositorySelection = response.data.repository_selection;
|
||||
const totalCount = response.data.total_count;
|
||||
delete response.data.incomplete_results;
|
||||
delete response.data.repository_selection;
|
||||
delete response.data.total_count;
|
||||
const namespaceKey = Object.keys(response.data)[0];
|
||||
const data = response.data[namespaceKey];
|
||||
response.data = data;
|
||||
|
||||
if (typeof incompleteResults !== "undefined") {
|
||||
response.data.incomplete_results = incompleteResults;
|
||||
}
|
||||
|
||||
if (typeof repositorySelection !== "undefined") {
|
||||
response.data.repository_selection = repositorySelection;
|
||||
}
|
||||
|
||||
response.data.total_count = totalCount;
|
||||
return response;
|
||||
}
|
||||
|
||||
function iterator(octokit, route, parameters) {
|
||||
const options = typeof route === "function" ? route.endpoint(parameters) : octokit.request.endpoint(route, parameters);
|
||||
const requestMethod = typeof route === "function" ? route : octokit.request;
|
||||
const method = options.method;
|
||||
const headers = options.headers;
|
||||
let url = options.url;
|
||||
return {
|
||||
[Symbol.asyncIterator]: () => ({
|
||||
async next() {
|
||||
if (!url) return {
|
||||
done: true
|
||||
};
|
||||
const response = await requestMethod({
|
||||
method,
|
||||
url,
|
||||
headers
|
||||
});
|
||||
const normalizedResponse = normalizePaginatedListResponse(response); // `response.headers.link` format:
|
||||
// '<https://api.github.com/users/aseemk/followers?page=2>; rel="next", <https://api.github.com/users/aseemk/followers?page=2>; rel="last"'
|
||||
// sets `url` to undefined if "next" URL is not present or `link` header is not set
|
||||
|
||||
url = ((normalizedResponse.headers.link || "").match(/<([^>]+)>;\s*rel="next"/) || [])[1];
|
||||
return {
|
||||
value: normalizedResponse
|
||||
};
|
||||
}
|
||||
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
function paginate(octokit, route, parameters, mapFn) {
|
||||
if (typeof parameters === "function") {
|
||||
mapFn = parameters;
|
||||
parameters = undefined;
|
||||
}
|
||||
|
||||
return gather(octokit, [], iterator(octokit, route, parameters)[Symbol.asyncIterator](), mapFn);
|
||||
}
|
||||
|
||||
function gather(octokit, results, iterator, mapFn) {
|
||||
return iterator.next().then(result => {
|
||||
if (result.done) {
|
||||
return results;
|
||||
}
|
||||
|
||||
let earlyExit = false;
|
||||
|
||||
function done() {
|
||||
earlyExit = true;
|
||||
}
|
||||
|
||||
results = results.concat(mapFn ? mapFn(result.value, done) : result.value.data);
|
||||
|
||||
if (earlyExit) {
|
||||
return results;
|
||||
}
|
||||
|
||||
return gather(octokit, results, iterator, mapFn);
|
||||
});
|
||||
}
|
||||
|
||||
const composePaginateRest = Object.assign(paginate, {
|
||||
iterator
|
||||
});
|
||||
|
||||
/**
|
||||
* @param octokit Octokit instance
|
||||
* @param options Options passed to Octokit constructor
|
||||
*/
|
||||
|
||||
function paginateRest(octokit) {
|
||||
return {
|
||||
paginate: Object.assign(paginate.bind(null, octokit), {
|
||||
iterator: iterator.bind(null, octokit)
|
||||
})
|
||||
};
|
||||
}
|
||||
paginateRest.VERSION = VERSION;
|
||||
|
||||
exports.composePaginateRest = composePaginateRest;
|
||||
exports.paginateRest = paginateRest;
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+5
@@ -0,0 +1,5 @@
|
||||
import { paginate } from "./paginate";
|
||||
import { iterator } from "./iterator";
|
||||
export const composePaginateRest = Object.assign(paginate, {
|
||||
iterator,
|
||||
});
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
export {};
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import { VERSION } from "./version";
|
||||
import { paginate } from "./paginate";
|
||||
import { iterator } from "./iterator";
|
||||
export { composePaginateRest } from "./compose-paginate";
|
||||
/**
|
||||
* @param octokit Octokit instance
|
||||
* @param options Options passed to Octokit constructor
|
||||
*/
|
||||
export function paginateRest(octokit) {
|
||||
return {
|
||||
paginate: Object.assign(paginate.bind(null, octokit), {
|
||||
iterator: iterator.bind(null, octokit),
|
||||
}),
|
||||
};
|
||||
}
|
||||
paginateRest.VERSION = VERSION;
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { normalizePaginatedListResponse } from "./normalize-paginated-list-response";
|
||||
export function iterator(octokit, route, parameters) {
|
||||
const options = typeof route === "function"
|
||||
? route.endpoint(parameters)
|
||||
: octokit.request.endpoint(route, parameters);
|
||||
const requestMethod = typeof route === "function" ? route : octokit.request;
|
||||
const method = options.method;
|
||||
const headers = options.headers;
|
||||
let url = options.url;
|
||||
return {
|
||||
[Symbol.asyncIterator]: () => ({
|
||||
async next() {
|
||||
if (!url)
|
||||
return { done: true };
|
||||
const response = await requestMethod({ method, url, headers });
|
||||
const normalizedResponse = normalizePaginatedListResponse(response);
|
||||
// `response.headers.link` format:
|
||||
// '<https://api.github.com/users/aseemk/followers?page=2>; rel="next", <https://api.github.com/users/aseemk/followers?page=2>; rel="last"'
|
||||
// sets `url` to undefined if "next" URL is not present or `link` header is not set
|
||||
url = ((normalizedResponse.headers.link || "").match(/<([^>]+)>;\s*rel="next"/) || [])[1];
|
||||
return { value: normalizedResponse };
|
||||
},
|
||||
}),
|
||||
};
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user