new toolkit and scoped registries
This commit is contained in:
parent
a9f1343a9a
commit
feb12fe291
|
@ -7,6 +7,8 @@ inputs:
|
|||
default: '10.x'
|
||||
registry-url:
|
||||
description: 'Optional registry to set up for auth. Will set the registry in a project level .npmrc and .yarnrc file, and set up auth to read in from env.NODE_AUTH_TOKEN'
|
||||
scope:
|
||||
description: 'Optional scope for authenticating against scoped registries'
|
||||
runs:
|
||||
using: 'node12'
|
||||
main: 'lib/setup-node.js'
|
||||
|
|
|
@ -11,12 +11,20 @@ const fs = __importStar(require("fs"));
|
|||
const os = __importStar(require("os"));
|
||||
const path = __importStar(require("path"));
|
||||
const core = __importStar(require("@actions/core"));
|
||||
const github = __importStar(require("@actions/github"));
|
||||
function configAuthentication(registryUrl) {
|
||||
const npmrc = path.resolve(process.cwd(), '.npmrc');
|
||||
writeRegistryToFile(registryUrl, npmrc);
|
||||
}
|
||||
exports.configAuthentication = configAuthentication;
|
||||
function writeRegistryToFile(registryUrl, fileLocation) {
|
||||
let scope = core.getInput('scope');
|
||||
if (!scope && registryUrl.indexOf('npm.pkg.github.com') > -1) {
|
||||
scope = github.context.repo.owner;
|
||||
}
|
||||
if (scope && scope[0] != '@') {
|
||||
scope = '@' + scope;
|
||||
}
|
||||
core.debug(`Setting auth in ${fileLocation}`);
|
||||
let newContents = '';
|
||||
if (fs.existsSync(fileLocation)) {
|
||||
|
@ -28,13 +36,9 @@ function writeRegistryToFile(registryUrl, fileLocation) {
|
|||
}
|
||||
});
|
||||
}
|
||||
newContents +=
|
||||
'registry=' +
|
||||
registryUrl +
|
||||
os.EOL +
|
||||
'always-auth=true' +
|
||||
os.EOL +
|
||||
registryUrl.replace(/(^\w+:|^)/, '') + // Remove http: or https: from front of registry.
|
||||
':_authToken=${NODE_AUTH_TOKEN}';
|
||||
// Remove http: or https: from front of registry.
|
||||
const authString = registryUrl.replace(/(^\w+:|^)/, '') + ':_authToken=${NODE_AUTH_TOKEN}';
|
||||
const registryString = scope ? `${scope}:registry=${registryUrl}` : `registry=${registryUrl}`;
|
||||
newContents += `${registryString}${os.EOL}always-auth=true${os.EOL}${authString}`;
|
||||
fs.writeFileSync(fileLocation, newContents);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
"$basedir/node" "$basedir/../which/bin/which" "$@"
|
||||
ret=$?
|
||||
else
|
||||
node "$basedir/../which/bin/which" "$@"
|
||||
ret=$?
|
||||
fi
|
||||
exit $ret
|
|
@ -0,0 +1,7 @@
|
|||
@IF EXIST "%~dp0\node.exe" (
|
||||
"%~dp0\node.exe" "%~dp0\..\which\bin\which" %*
|
||||
) ELSE (
|
||||
@SETLOCAL
|
||||
@SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
node "%~dp0\..\which\bin\which" %*
|
||||
)
|
|
@ -1,7 +1,7 @@
|
|||
# `@actions/exec`
|
||||
|
||||
> Functions necessary for running tools on the command line
|
||||
|
||||
## Usage
|
||||
|
||||
# `@actions/exec`
|
||||
|
||||
> Functions necessary for running tools on the command line
|
||||
|
||||
## Usage
|
||||
|
||||
See [src/exec.ts](src/exec.ts).
|
|
@ -1,12 +1,12 @@
|
|||
import * as im from './interfaces';
|
||||
/**
|
||||
* Exec a command.
|
||||
* Output will be streamed to the live console.
|
||||
* Returns promise with return code
|
||||
*
|
||||
* @param commandLine command to execute (can include additional args). Must be correctly escaped.
|
||||
* @param args optional arguments for tool. Escaping is handled by the lib.
|
||||
* @param options optional exec options. See ExecOptions
|
||||
* @returns Promise<number> exit code
|
||||
*/
|
||||
export declare function exec(commandLine: string, args?: string[], options?: im.ExecOptions): Promise<number>;
|
||||
import * as im from './interfaces';
|
||||
/**
|
||||
* Exec a command.
|
||||
* Output will be streamed to the live console.
|
||||
* Returns promise with return code
|
||||
*
|
||||
* @param commandLine command to execute (can include additional args). Must be correctly escaped.
|
||||
* @param args optional arguments for tool. Escaping is handled by the lib.
|
||||
* @param options optional exec options. See ExecOptions
|
||||
* @returns Promise<number> exit code
|
||||
*/
|
||||
export declare function exec(commandLine: string, args?: string[], options?: im.ExecOptions): Promise<number>;
|
||||
|
|
|
@ -1,36 +1,36 @@
|
|||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const tr = require("./toolrunner");
|
||||
/**
|
||||
* Exec a command.
|
||||
* Output will be streamed to the live console.
|
||||
* Returns promise with return code
|
||||
*
|
||||
* @param commandLine command to execute (can include additional args). Must be correctly escaped.
|
||||
* @param args optional arguments for tool. Escaping is handled by the lib.
|
||||
* @param options optional exec options. See ExecOptions
|
||||
* @returns Promise<number> exit code
|
||||
*/
|
||||
function exec(commandLine, args, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const commandArgs = tr.argStringToArray(commandLine);
|
||||
if (commandArgs.length === 0) {
|
||||
throw new Error(`Parameter 'commandLine' cannot be null or empty.`);
|
||||
}
|
||||
// Path to tool to execute should be first arg
|
||||
const toolPath = commandArgs[0];
|
||||
args = commandArgs.slice(1).concat(args || []);
|
||||
const runner = new tr.ToolRunner(toolPath, args, options);
|
||||
return runner.exec();
|
||||
});
|
||||
}
|
||||
exports.exec = exec;
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const tr = require("./toolrunner");
|
||||
/**
|
||||
* Exec a command.
|
||||
* Output will be streamed to the live console.
|
||||
* Returns promise with return code
|
||||
*
|
||||
* @param commandLine command to execute (can include additional args). Must be correctly escaped.
|
||||
* @param args optional arguments for tool. Escaping is handled by the lib.
|
||||
* @param options optional exec options. See ExecOptions
|
||||
* @returns Promise<number> exit code
|
||||
*/
|
||||
function exec(commandLine, args, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const commandArgs = tr.argStringToArray(commandLine);
|
||||
if (commandArgs.length === 0) {
|
||||
throw new Error(`Parameter 'commandLine' cannot be null or empty.`);
|
||||
}
|
||||
// Path to tool to execute should be first arg
|
||||
const toolPath = commandArgs[0];
|
||||
args = commandArgs.slice(1).concat(args || []);
|
||||
const runner = new tr.ToolRunner(toolPath, args, options);
|
||||
return runner.exec();
|
||||
});
|
||||
}
|
||||
exports.exec = exec;
|
||||
//# sourceMappingURL=exec.js.map
|
|
@ -1,35 +1,35 @@
|
|||
/// <reference types="node" />
|
||||
import * as stream from 'stream';
|
||||
/**
|
||||
* Interface for exec options
|
||||
*/
|
||||
export interface ExecOptions {
|
||||
/** optional working directory. defaults to current */
|
||||
cwd?: string;
|
||||
/** optional envvar dictionary. defaults to current process's env */
|
||||
env?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
/** optional. defaults to false */
|
||||
silent?: boolean;
|
||||
/** optional out stream to use. Defaults to process.stdout */
|
||||
outStream?: stream.Writable;
|
||||
/** optional err stream to use. Defaults to process.stderr */
|
||||
errStream?: stream.Writable;
|
||||
/** optional. whether to skip quoting/escaping arguments if needed. defaults to false. */
|
||||
windowsVerbatimArguments?: boolean;
|
||||
/** optional. whether to fail if output to stderr. defaults to false */
|
||||
failOnStdErr?: boolean;
|
||||
/** optional. defaults to failing on non zero. ignore will not fail leaving it up to the caller */
|
||||
ignoreReturnCode?: boolean;
|
||||
/** optional. How long in ms to wait for STDIO streams to close after the exit event of the process before terminating. defaults to 10000 */
|
||||
delay?: number;
|
||||
/** optional. Listeners for output. Callback functions that will be called on these events */
|
||||
listeners?: {
|
||||
stdout?: (data: Buffer) => void;
|
||||
stderr?: (data: Buffer) => void;
|
||||
stdline?: (data: string) => void;
|
||||
errline?: (data: string) => void;
|
||||
debug?: (data: string) => void;
|
||||
};
|
||||
}
|
||||
/// <reference types="node" />
|
||||
import * as stream from 'stream';
|
||||
/**
|
||||
* Interface for exec options
|
||||
*/
|
||||
export interface ExecOptions {
|
||||
/** optional working directory. defaults to current */
|
||||
cwd?: string;
|
||||
/** optional envvar dictionary. defaults to current process's env */
|
||||
env?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
/** optional. defaults to false */
|
||||
silent?: boolean;
|
||||
/** optional out stream to use. Defaults to process.stdout */
|
||||
outStream?: stream.Writable;
|
||||
/** optional err stream to use. Defaults to process.stderr */
|
||||
errStream?: stream.Writable;
|
||||
/** optional. whether to skip quoting/escaping arguments if needed. defaults to false. */
|
||||
windowsVerbatimArguments?: boolean;
|
||||
/** optional. whether to fail if output to stderr. defaults to false */
|
||||
failOnStdErr?: boolean;
|
||||
/** optional. defaults to failing on non zero. ignore will not fail leaving it up to the caller */
|
||||
ignoreReturnCode?: boolean;
|
||||
/** optional. How long in ms to wait for STDIO streams to close after the exit event of the process before terminating. defaults to 10000 */
|
||||
delay?: number;
|
||||
/** optional. Listeners for output. Callback functions that will be called on these events */
|
||||
listeners?: {
|
||||
stdout?: (data: Buffer) => void;
|
||||
stderr?: (data: Buffer) => void;
|
||||
stdline?: (data: string) => void;
|
||||
errline?: (data: string) => void;
|
||||
debug?: (data: string) => void;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=interfaces.js.map
|
|
@ -1,37 +1,37 @@
|
|||
/// <reference types="node" />
|
||||
import * as events from 'events';
|
||||
import * as im from './interfaces';
|
||||
export declare class ToolRunner extends events.EventEmitter {
|
||||
constructor(toolPath: string, args?: string[], options?: im.ExecOptions);
|
||||
private toolPath;
|
||||
private args;
|
||||
private options;
|
||||
private _debug;
|
||||
private _getCommandString;
|
||||
private _processLineBuffer;
|
||||
private _getSpawnFileName;
|
||||
private _getSpawnArgs;
|
||||
private _endsWith;
|
||||
private _isCmdFile;
|
||||
private _windowsQuoteCmdArg;
|
||||
private _uvQuoteCmdArg;
|
||||
private _cloneExecOptions;
|
||||
private _getSpawnOptions;
|
||||
/**
|
||||
* Exec a tool.
|
||||
* Output will be streamed to the live console.
|
||||
* Returns promise with return code
|
||||
*
|
||||
* @param tool path to tool to exec
|
||||
* @param options optional exec options. See ExecOptions
|
||||
* @returns number
|
||||
*/
|
||||
exec(): Promise<number>;
|
||||
}
|
||||
/**
|
||||
* Convert an arg string to an array of args. Handles escaping
|
||||
*
|
||||
* @param argString string of arguments
|
||||
* @returns string[] array of arguments
|
||||
*/
|
||||
export declare function argStringToArray(argString: string): string[];
|
||||
/// <reference types="node" />
|
||||
import * as events from 'events';
|
||||
import * as im from './interfaces';
|
||||
export declare class ToolRunner extends events.EventEmitter {
|
||||
constructor(toolPath: string, args?: string[], options?: im.ExecOptions);
|
||||
private toolPath;
|
||||
private args;
|
||||
private options;
|
||||
private _debug;
|
||||
private _getCommandString;
|
||||
private _processLineBuffer;
|
||||
private _getSpawnFileName;
|
||||
private _getSpawnArgs;
|
||||
private _endsWith;
|
||||
private _isCmdFile;
|
||||
private _windowsQuoteCmdArg;
|
||||
private _uvQuoteCmdArg;
|
||||
private _cloneExecOptions;
|
||||
private _getSpawnOptions;
|
||||
/**
|
||||
* Exec a tool.
|
||||
* Output will be streamed to the live console.
|
||||
* Returns promise with return code
|
||||
*
|
||||
* @param tool path to tool to exec
|
||||
* @param options optional exec options. See ExecOptions
|
||||
* @returns number
|
||||
*/
|
||||
exec(): Promise<number>;
|
||||
}
|
||||
/**
|
||||
* Convert an arg string to an array of args. Handles escaping
|
||||
*
|
||||
* @param argString string of arguments
|
||||
* @returns string[] array of arguments
|
||||
*/
|
||||
export declare function argStringToArray(argString: string): string[];
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
Copyright 2019 GitHub
|
||||
|
||||
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.
|
||||
|
||||
Copyright 2019 GitHub
|
||||
|
||||
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.
|
|
@ -1,7 +1,7 @@
|
|||
# `@actions/exit`
|
||||
|
||||
> TODO: description
|
||||
|
||||
## Usage
|
||||
|
||||
# `@actions/exit`
|
||||
|
||||
> TODO: description
|
||||
|
||||
## Usage
|
||||
|
||||
See [src/exit.ts](src/exit.ts).
|
|
@ -1,29 +1,29 @@
|
|||
/**
|
||||
* The code to exit an action
|
||||
*/
|
||||
export declare enum ExitCode {
|
||||
/**
|
||||
* A code indicating that the action was successful
|
||||
*/
|
||||
Success = 0,
|
||||
/**
|
||||
* A code indicating that the action was a failure
|
||||
*/
|
||||
Failure = 1,
|
||||
/**
|
||||
* A code indicating that the action is complete, but neither succeeded nor failed
|
||||
*/
|
||||
Neutral = 78
|
||||
}
|
||||
/**
|
||||
* Exit the action as a success.
|
||||
*/
|
||||
export declare function success(): void;
|
||||
/**
|
||||
* Exit the action as a failure.
|
||||
*/
|
||||
export declare function failure(): void;
|
||||
/**
|
||||
* Exit the action neither a success or a failure
|
||||
*/
|
||||
export declare function neutral(): void;
|
||||
/**
|
||||
* The code to exit an action
|
||||
*/
|
||||
export declare enum ExitCode {
|
||||
/**
|
||||
* A code indicating that the action was successful
|
||||
*/
|
||||
Success = 0,
|
||||
/**
|
||||
* A code indicating that the action was a failure
|
||||
*/
|
||||
Failure = 1,
|
||||
/**
|
||||
* A code indicating that the action is complete, but neither succeeded nor failed
|
||||
*/
|
||||
Neutral = 78
|
||||
}
|
||||
/**
|
||||
* Exit the action as a success.
|
||||
*/
|
||||
export declare function success(): void;
|
||||
/**
|
||||
* Exit the action as a failure.
|
||||
*/
|
||||
export declare function failure(): void;
|
||||
/**
|
||||
* Exit the action neither a success or a failure
|
||||
*/
|
||||
export declare function neutral(): void;
|
||||
|
|
|
@ -1,44 +1,44 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/**
|
||||
* The code to exit an action
|
||||
*/
|
||||
var ExitCode;
|
||||
(function (ExitCode) {
|
||||
/**
|
||||
* A code indicating that the action was successful
|
||||
*/
|
||||
ExitCode[ExitCode["Success"] = 0] = "Success";
|
||||
/**
|
||||
* A code indicating that the action was a failure
|
||||
*/
|
||||
ExitCode[ExitCode["Failure"] = 1] = "Failure";
|
||||
/**
|
||||
* A code indicating that the action is complete, but neither succeeded nor failed
|
||||
*/
|
||||
ExitCode[ExitCode["Neutral"] = 78] = "Neutral";
|
||||
})(ExitCode = exports.ExitCode || (exports.ExitCode = {}));
|
||||
// TODO: These exit codes may not behave as expected on the new runtime, due to
|
||||
// complexities of async logging and sync exiting.
|
||||
/**
|
||||
* Exit the action as a success.
|
||||
*/
|
||||
function success() {
|
||||
process.exit(ExitCode.Success);
|
||||
}
|
||||
exports.success = success;
|
||||
/**
|
||||
* Exit the action as a failure.
|
||||
*/
|
||||
function failure() {
|
||||
process.exit(ExitCode.Failure);
|
||||
}
|
||||
exports.failure = failure;
|
||||
/**
|
||||
* Exit the action neither a success or a failure
|
||||
*/
|
||||
function neutral() {
|
||||
process.exit(ExitCode.Neutral);
|
||||
}
|
||||
exports.neutral = neutral;
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/**
|
||||
* The code to exit an action
|
||||
*/
|
||||
var ExitCode;
|
||||
(function (ExitCode) {
|
||||
/**
|
||||
* A code indicating that the action was successful
|
||||
*/
|
||||
ExitCode[ExitCode["Success"] = 0] = "Success";
|
||||
/**
|
||||
* A code indicating that the action was a failure
|
||||
*/
|
||||
ExitCode[ExitCode["Failure"] = 1] = "Failure";
|
||||
/**
|
||||
* A code indicating that the action is complete, but neither succeeded nor failed
|
||||
*/
|
||||
ExitCode[ExitCode["Neutral"] = 78] = "Neutral";
|
||||
})(ExitCode = exports.ExitCode || (exports.ExitCode = {}));
|
||||
// TODO: These exit codes may not behave as expected on the new runtime, due to
|
||||
// complexities of async logging and sync exiting.
|
||||
/**
|
||||
* Exit the action as a success.
|
||||
*/
|
||||
function success() {
|
||||
process.exit(ExitCode.Success);
|
||||
}
|
||||
exports.success = success;
|
||||
/**
|
||||
* Exit the action as a failure.
|
||||
*/
|
||||
function failure() {
|
||||
process.exit(ExitCode.Failure);
|
||||
}
|
||||
exports.failure = failure;
|
||||
/**
|
||||
* Exit the action neither a success or a failure
|
||||
*/
|
||||
function neutral() {
|
||||
process.exit(ExitCode.Neutral);
|
||||
}
|
||||
exports.neutral = neutral;
|
||||
//# sourceMappingURL=exit.js.map
|
|
@ -0,0 +1,48 @@
|
|||
# `@actions/github`
|
||||
|
||||
> A hydrated Octokit client.
|
||||
|
||||
## Usage
|
||||
|
||||
Returns an [Octokit SDK] client. See https://octokit.github.io/rest.js for the API.
|
||||
|
||||
```
|
||||
const github = require('@actions/github');
|
||||
const core = require('@actions/core');
|
||||
|
||||
// This should be a token with access to your repository scoped in as a secret.
|
||||
const myToken = core.getInput('myToken');
|
||||
|
||||
const octokit = new github.GitHub(myToken);
|
||||
|
||||
const pulls = await octokit.pulls.get({
|
||||
owner: 'octokit',
|
||||
repo: 'rest.js',
|
||||
pull_number: 123,
|
||||
mediaType: {
|
||||
format: 'diff'
|
||||
}
|
||||
});
|
||||
|
||||
console.log(pulls);
|
||||
```
|
||||
|
||||
You can also make GraphQL requests:
|
||||
|
||||
```
|
||||
const result = await octokit.graphql(query, variables);
|
||||
```
|
||||
|
||||
Finally, you can get the context of the current action:
|
||||
|
||||
```
|
||||
const github = require('@actions/github');
|
||||
|
||||
const context = github.context;
|
||||
|
||||
const newIssue = await octokit.issues.create({
|
||||
...context.repo,
|
||||
title: 'New issue!',
|
||||
body: 'Hello Universe!'
|
||||
});
|
||||
```
|
|
@ -0,0 +1,26 @@
|
|||
import { WebhookPayload } from './interfaces';
|
||||
export declare class Context {
|
||||
/**
|
||||
* Webhook payload object that triggered the workflow
|
||||
*/
|
||||
payload: WebhookPayload;
|
||||
eventName: string;
|
||||
sha: string;
|
||||
ref: string;
|
||||
workflow: string;
|
||||
action: string;
|
||||
actor: string;
|
||||
/**
|
||||
* Hydrate the context from the environment
|
||||
*/
|
||||
constructor();
|
||||
readonly issue: {
|
||||
owner: string;
|
||||
repo: string;
|
||||
number: number;
|
||||
};
|
||||
readonly repo: {
|
||||
owner: string;
|
||||
repo: string;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/* eslint-disable @typescript-eslint/no-require-imports */
|
||||
class Context {
|
||||
/**
|
||||
* Hydrate the context from the environment
|
||||
*/
|
||||
constructor() {
|
||||
this.payload = process.env.GITHUB_EVENT_PATH
|
||||
? require(process.env.GITHUB_EVENT_PATH)
|
||||
: {};
|
||||
this.eventName = process.env.GITHUB_EVENT_NAME;
|
||||
this.sha = process.env.GITHUB_SHA;
|
||||
this.ref = process.env.GITHUB_REF;
|
||||
this.workflow = process.env.GITHUB_WORKFLOW;
|
||||
this.action = process.env.GITHUB_ACTION;
|
||||
this.actor = process.env.GITHUB_ACTOR;
|
||||
}
|
||||
get issue() {
|
||||
const payload = this.payload;
|
||||
return Object.assign({}, this.repo, { number: (payload.issue || payload.pullRequest || payload).number });
|
||||
}
|
||||
get repo() {
|
||||
if (process.env.GITHUB_REPOSITORY) {
|
||||
const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/');
|
||||
return { owner, repo };
|
||||
}
|
||||
if (this.payload.repository) {
|
||||
return {
|
||||
owner: this.payload.repository.owner.login,
|
||||
repo: this.payload.repository.name
|
||||
};
|
||||
}
|
||||
throw new Error("context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'");
|
||||
}
|
||||
}
|
||||
exports.Context = Context;
|
||||
//# sourceMappingURL=context.js.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":";;AAGA,0DAA0D;AAE1D,MAAa,OAAO;IAalB;;OAEG;IACH;QACE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB;YAC1C,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;YACxC,CAAC,CAAC,EAAE,CAAA;QACN,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,iBAA2B,CAAA;QACxD,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,UAAoB,CAAA;QAC3C,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,UAAoB,CAAA;QAC3C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,eAAyB,CAAA;QACrD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAuB,CAAA;QACjD,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,YAAsB,CAAA;IACjD,CAAC;IAED,IAAI,KAAK;QACP,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;QAE5B,yBACK,IAAI,CAAC,IAAI,IACZ,MAAM,EAAE,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,CAAC,MAAM,IACjE;IACH,CAAC;IAED,IAAI,IAAI;QACN,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE;YACjC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAC9D,OAAO,EAAC,KAAK,EAAE,IAAI,EAAC,CAAA;SACrB;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;YAC3B,OAAO;gBACL,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK;gBAC1C,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI;aACnC,CAAA;SACF;QAED,MAAM,IAAI,KAAK,CACb,kFAAkF,CACnF,CAAA;IACH,CAAC;CACF;AAtDD,0BAsDC"}
|
|
@ -0,0 +1,8 @@
|
|||
import { GraphQlQueryResponse, Variables } from '@octokit/graphql';
|
||||
import Octokit from '@octokit/rest';
|
||||
import * as Context from './context';
|
||||
export declare const context: Context.Context;
|
||||
export declare class GitHub extends Octokit {
|
||||
graphql: (query: string, variables?: Variables) => Promise<GraphQlQueryResponse>;
|
||||
constructor(token: string);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
// Originally pulled from https://github.com/JasonEtco/actions-toolkit/blob/master/src/github.ts
|
||||
const graphql_1 = require("@octokit/graphql");
|
||||
const rest_1 = __importDefault(require("@octokit/rest"));
|
||||
const Context = __importStar(require("./context"));
|
||||
// We need this in order to extend Octokit
|
||||
rest_1.default.prototype = new rest_1.default();
|
||||
exports.context = new Context.Context();
|
||||
class GitHub extends rest_1.default {
|
||||
constructor(token) {
|
||||
super({ auth: `token ${token}` });
|
||||
this.graphql = graphql_1.defaults({
|
||||
headers: { authorization: `token ${token}` }
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.GitHub = GitHub;
|
||||
//# sourceMappingURL=github.js.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"github.js","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,gGAAgG;AAChG,8CAA0E;AAC1E,yDAAmC;AACnC,mDAAoC;AAEpC,0CAA0C;AAC1C,cAAO,CAAC,SAAS,GAAG,IAAI,cAAO,EAAE,CAAA;AAEpB,QAAA,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,CAAA;AAE5C,MAAa,MAAO,SAAQ,cAAO;IAMjC,YAAY,KAAa;QACvB,KAAK,CAAC,EAAC,IAAI,EAAE,SAAS,KAAK,EAAE,EAAC,CAAC,CAAA;QAC/B,IAAI,CAAC,OAAO,GAAG,kBAAQ,CAAC;YACtB,OAAO,EAAE,EAAC,aAAa,EAAE,SAAS,KAAK,EAAE,EAAC;SAC3C,CAAC,CAAA;IACJ,CAAC;CACF;AAZD,wBAYC"}
|
|
@ -0,0 +1,36 @@
|
|||
export interface PayloadRepository {
|
||||
[key: string]: any;
|
||||
full_name?: string;
|
||||
name: string;
|
||||
owner: {
|
||||
[key: string]: any;
|
||||
login: string;
|
||||
name?: string;
|
||||
};
|
||||
html_url?: string;
|
||||
}
|
||||
export interface WebhookPayload {
|
||||
[key: string]: any;
|
||||
repository?: PayloadRepository;
|
||||
issue?: {
|
||||
[key: string]: any;
|
||||
number: number;
|
||||
html_url?: string;
|
||||
body?: string;
|
||||
};
|
||||
pull_request?: {
|
||||
[key: string]: any;
|
||||
number: number;
|
||||
html_url?: string;
|
||||
body?: string;
|
||||
};
|
||||
sender?: {
|
||||
[key: string]: any;
|
||||
type: string;
|
||||
};
|
||||
action?: string;
|
||||
installation?: {
|
||||
id: number;
|
||||
[key: string]: any;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
"use strict";
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=interfaces.js.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":";AAAA,uDAAuD"}
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"_from": "file:toolkit\\actions-github-0.0.0.tgz",
|
||||
"_id": "@actions/github@0.0.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-CByX5VIagC5BqGwsHD9Qt5MfN+H6GDC9qQl+MIUipaHTc89sUG/vAY/xQDS9vxuuRwrxbdERwKO3dR6U1BSziw==",
|
||||
"_location": "/@actions/github",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "file",
|
||||
"where": "C:\\Users\\Administrator\\Documents\\setup-node",
|
||||
"raw": "@actions/github@file:toolkit/actions-github-0.0.0.tgz",
|
||||
"name": "@actions/github",
|
||||
"escapedName": "@actions%2fgithub",
|
||||
"scope": "@actions",
|
||||
"rawSpec": "file:toolkit/actions-github-0.0.0.tgz",
|
||||
"saveSpec": "file:toolkit\\actions-github-0.0.0.tgz",
|
||||
"fetchSpec": "C:\\Users\\Administrator\\Documents\\setup-node\\toolkit\\actions-github-0.0.0.tgz"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/"
|
||||
],
|
||||
"_resolved": "C:\\Users\\Administrator\\Documents\\setup-node\\toolkit\\actions-github-0.0.0.tgz",
|
||||
"_shasum": "d9a87b3682d66d032fffcaff1adcdb2decd92b81",
|
||||
"_spec": "@actions/github@file:toolkit/actions-github-0.0.0.tgz",
|
||||
"_where": "C:\\Users\\Administrator\\Documents\\setup-node",
|
||||
"bugs": {
|
||||
"url": "https://github.com/actions/toolkit/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"@octokit/graphql": "^2.0.1",
|
||||
"@octokit/rest": "^16.15.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Actions github lib",
|
||||
"devDependencies": {
|
||||
"jest": "^24.7.1"
|
||||
},
|
||||
"directories": {
|
||||
"lib": "lib",
|
||||
"test": "__tests__"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"homepage": "https://github.com/actions/toolkit/tree/master/packages/github",
|
||||
"keywords": [
|
||||
"github",
|
||||
"actions"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "lib/github.js",
|
||||
"name": "@actions/github",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/actions/toolkit.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"test": "jest",
|
||||
"tsc": "tsc"
|
||||
},
|
||||
"version": "0.0.0"
|
||||
}
|
|
@ -1,49 +1,49 @@
|
|||
# `@actions/io`
|
||||
|
||||
> Core functions for cli filesystem scenarios
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/**
|
||||
* Copies a file or folder.
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See CopyOptions.
|
||||
*/
|
||||
export function cp(source: string, dest: string, options?: CopyOptions): Promise<void>
|
||||
|
||||
/**
|
||||
* Remove a path recursively with force
|
||||
*
|
||||
* @param path path to remove
|
||||
*/
|
||||
export function rmRF(path: string): Promise<void>
|
||||
|
||||
/**
|
||||
* Make a directory. Creates the full path with folders in between
|
||||
*
|
||||
* @param p path to create
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
export function mkdirP(p: string): Promise<void>
|
||||
|
||||
/**
|
||||
* Moves a path.
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See CopyOptions.
|
||||
*/
|
||||
export function mv(source: string, dest: string, options?: CopyOptions): Promise<void>
|
||||
|
||||
/**
|
||||
* Returns path of a tool had the tool actually been invoked. Resolves via paths.
|
||||
*
|
||||
* @param tool name of the tool
|
||||
* @param options optional. See WhichOptions.
|
||||
* @returns Promise<string> path to tool
|
||||
*/
|
||||
export function which(tool: string, options?: WhichOptions): Promise<string>
|
||||
# `@actions/io`
|
||||
|
||||
> Core functions for cli filesystem scenarios
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/**
|
||||
* Copies a file or folder.
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See CopyOptions.
|
||||
*/
|
||||
export function cp(source: string, dest: string, options?: CopyOptions): Promise<void>
|
||||
|
||||
/**
|
||||
* Remove a path recursively with force
|
||||
*
|
||||
* @param path path to remove
|
||||
*/
|
||||
export function rmRF(path: string): Promise<void>
|
||||
|
||||
/**
|
||||
* Make a directory. Creates the full path with folders in between
|
||||
*
|
||||
* @param p path to create
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
export function mkdirP(p: string): Promise<void>
|
||||
|
||||
/**
|
||||
* Moves a path.
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See CopyOptions.
|
||||
*/
|
||||
export function mv(source: string, dest: string, options?: CopyOptions): Promise<void>
|
||||
|
||||
/**
|
||||
* Returns path of a tool had the tool actually been invoked. Resolves via paths.
|
||||
*
|
||||
* @param tool name of the tool
|
||||
* @param options optional. See WhichOptions.
|
||||
* @returns Promise<string> path to tool
|
||||
*/
|
||||
export function which(tool: string, options?: WhichOptions): Promise<string>
|
||||
```
|
|
@ -1,29 +1,29 @@
|
|||
/// <reference types="node" />
|
||||
import * as fs from 'fs';
|
||||
export declare const copyFile: typeof fs.promises.copyFile, lstat: typeof fs.promises.lstat, mkdir: typeof fs.promises.mkdir, readdir: typeof fs.promises.readdir, rmdir: typeof fs.promises.rmdir, stat: typeof fs.promises.stat, unlink: typeof fs.promises.unlink;
|
||||
export declare const IS_WINDOWS: boolean;
|
||||
export declare function exists(fsPath: string): Promise<boolean>;
|
||||
export declare function isDirectory(fsPath: string, useStat?: boolean): Promise<boolean>;
|
||||
/**
|
||||
* On OSX/Linux, true if path starts with '/'. On Windows, true for paths like:
|
||||
* \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases).
|
||||
*/
|
||||
export declare function isRooted(p: string): boolean;
|
||||
/**
|
||||
* Recursively create a directory at `fsPath`.
|
||||
*
|
||||
* This implementation is optimistic, meaning it attempts to create the full
|
||||
* path first, and backs up the path stack from there.
|
||||
*
|
||||
* @param fsPath The path to create
|
||||
* @param maxDepth The maximum recursion depth
|
||||
* @param depth The current recursion depth
|
||||
*/
|
||||
export declare function mkdirP(fsPath: string, maxDepth?: number, depth?: number): Promise<void>;
|
||||
/**
|
||||
* Best effort attempt to determine whether a file exists and is executable.
|
||||
* @param filePath file path to check
|
||||
* @param extensions additional file extensions to try
|
||||
* @return if file exists and is executable, returns the file path. otherwise empty string.
|
||||
*/
|
||||
export declare function tryGetExecutablePath(filePath: string, extensions: string[]): Promise<string>;
|
||||
/// <reference types="node" />
|
||||
import * as fs from 'fs';
|
||||
export declare const copyFile: typeof fs.promises.copyFile, lstat: typeof fs.promises.lstat, mkdir: typeof fs.promises.mkdir, readdir: typeof fs.promises.readdir, rmdir: typeof fs.promises.rmdir, stat: typeof fs.promises.stat, unlink: typeof fs.promises.unlink;
|
||||
export declare const IS_WINDOWS: boolean;
|
||||
export declare function exists(fsPath: string): Promise<boolean>;
|
||||
export declare function isDirectory(fsPath: string, useStat?: boolean): Promise<boolean>;
|
||||
/**
|
||||
* On OSX/Linux, true if path starts with '/'. On Windows, true for paths like:
|
||||
* \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases).
|
||||
*/
|
||||
export declare function isRooted(p: string): boolean;
|
||||
/**
|
||||
* Recursively create a directory at `fsPath`.
|
||||
*
|
||||
* This implementation is optimistic, meaning it attempts to create the full
|
||||
* path first, and backs up the path stack from there.
|
||||
*
|
||||
* @param fsPath The path to create
|
||||
* @param maxDepth The maximum recursion depth
|
||||
* @param depth The current recursion depth
|
||||
*/
|
||||
export declare function mkdirP(fsPath: string, maxDepth?: number, depth?: number): Promise<void>;
|
||||
/**
|
||||
* Best effort attempt to determine whether a file exists and is executable.
|
||||
* @param filePath file path to check
|
||||
* @param extensions additional file extensions to try
|
||||
* @return if file exists and is executable, returns the file path. otherwise empty string.
|
||||
*/
|
||||
export declare function tryGetExecutablePath(filePath: string, extensions: string[]): Promise<string>;
|
||||
|
|
|
@ -1,194 +1,194 @@
|
|||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var _a;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const assert_1 = require("assert");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
_a = fs.promises, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.readdir = _a.readdir, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.unlink = _a.unlink;
|
||||
exports.IS_WINDOWS = process.platform === 'win32';
|
||||
function exists(fsPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
yield exports.stat(fsPath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
return false;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
exports.exists = exists;
|
||||
function isDirectory(fsPath, useStat = false) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath);
|
||||
return stats.isDirectory();
|
||||
});
|
||||
}
|
||||
exports.isDirectory = isDirectory;
|
||||
/**
|
||||
* On OSX/Linux, true if path starts with '/'. On Windows, true for paths like:
|
||||
* \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases).
|
||||
*/
|
||||
function isRooted(p) {
|
||||
p = normalizeSeparators(p);
|
||||
if (!p) {
|
||||
throw new Error('isRooted() parameter "p" cannot be empty');
|
||||
}
|
||||
if (exports.IS_WINDOWS) {
|
||||
return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello
|
||||
); // e.g. C: or C:\hello
|
||||
}
|
||||
return p.startsWith('/');
|
||||
}
|
||||
exports.isRooted = isRooted;
|
||||
/**
|
||||
* Recursively create a directory at `fsPath`.
|
||||
*
|
||||
* This implementation is optimistic, meaning it attempts to create the full
|
||||
* path first, and backs up the path stack from there.
|
||||
*
|
||||
* @param fsPath The path to create
|
||||
* @param maxDepth The maximum recursion depth
|
||||
* @param depth The current recursion depth
|
||||
*/
|
||||
function mkdirP(fsPath, maxDepth = 1000, depth = 1) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
assert_1.ok(fsPath, 'a path argument must be provided');
|
||||
fsPath = path.resolve(fsPath);
|
||||
if (depth >= maxDepth)
|
||||
return exports.mkdir(fsPath);
|
||||
try {
|
||||
yield exports.mkdir(fsPath);
|
||||
return;
|
||||
}
|
||||
catch (err) {
|
||||
switch (err.code) {
|
||||
case 'ENOENT': {
|
||||
yield mkdirP(path.dirname(fsPath), maxDepth, depth + 1);
|
||||
yield exports.mkdir(fsPath);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
let stats;
|
||||
try {
|
||||
stats = yield exports.stat(fsPath);
|
||||
}
|
||||
catch (err2) {
|
||||
throw err;
|
||||
}
|
||||
if (!stats.isDirectory())
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.mkdirP = mkdirP;
|
||||
/**
|
||||
* Best effort attempt to determine whether a file exists and is executable.
|
||||
* @param filePath file path to check
|
||||
* @param extensions additional file extensions to try
|
||||
* @return if file exists and is executable, returns the file path. otherwise empty string.
|
||||
*/
|
||||
function tryGetExecutablePath(filePath, extensions) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let stats = undefined;
|
||||
try {
|
||||
// test file exists
|
||||
stats = yield exports.stat(filePath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
|
||||
}
|
||||
}
|
||||
if (stats && stats.isFile()) {
|
||||
if (exports.IS_WINDOWS) {
|
||||
// on Windows, test for valid extension
|
||||
const upperExt = path.extname(filePath).toUpperCase();
|
||||
if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isUnixExecutable(stats)) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
// try each extension
|
||||
const originalFilePath = filePath;
|
||||
for (const extension of extensions) {
|
||||
filePath = originalFilePath + extension;
|
||||
stats = undefined;
|
||||
try {
|
||||
stats = yield exports.stat(filePath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
|
||||
}
|
||||
}
|
||||
if (stats && stats.isFile()) {
|
||||
if (exports.IS_WINDOWS) {
|
||||
// preserve the case of the actual file (since an extension was appended)
|
||||
try {
|
||||
const directory = path.dirname(filePath);
|
||||
const upperName = path.basename(filePath).toUpperCase();
|
||||
for (const actualName of yield exports.readdir(directory)) {
|
||||
if (upperName === actualName.toUpperCase()) {
|
||||
filePath = path.join(directory, actualName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`);
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
else {
|
||||
if (isUnixExecutable(stats)) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
});
|
||||
}
|
||||
exports.tryGetExecutablePath = tryGetExecutablePath;
|
||||
function normalizeSeparators(p) {
|
||||
p = p || '';
|
||||
if (exports.IS_WINDOWS) {
|
||||
// convert slashes on Windows
|
||||
p = p.replace(/\//g, '\\');
|
||||
// remove redundant slashes
|
||||
return p.replace(/\\\\+/g, '\\');
|
||||
}
|
||||
// remove redundant slashes
|
||||
return p.replace(/\/\/+/g, '/');
|
||||
}
|
||||
// on Mac/Linux, test the execute bit
|
||||
// R W X R W X R W X
|
||||
// 256 128 64 32 16 8 4 2 1
|
||||
function isUnixExecutable(stats) {
|
||||
return ((stats.mode & 1) > 0 ||
|
||||
((stats.mode & 8) > 0 && stats.gid === process.getgid()) ||
|
||||
((stats.mode & 64) > 0 && stats.uid === process.getuid()));
|
||||
}
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var _a;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const assert_1 = require("assert");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
_a = fs.promises, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.readdir = _a.readdir, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.unlink = _a.unlink;
|
||||
exports.IS_WINDOWS = process.platform === 'win32';
|
||||
function exists(fsPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
yield exports.stat(fsPath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
return false;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
exports.exists = exists;
|
||||
function isDirectory(fsPath, useStat = false) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath);
|
||||
return stats.isDirectory();
|
||||
});
|
||||
}
|
||||
exports.isDirectory = isDirectory;
|
||||
/**
|
||||
* On OSX/Linux, true if path starts with '/'. On Windows, true for paths like:
|
||||
* \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases).
|
||||
*/
|
||||
function isRooted(p) {
|
||||
p = normalizeSeparators(p);
|
||||
if (!p) {
|
||||
throw new Error('isRooted() parameter "p" cannot be empty');
|
||||
}
|
||||
if (exports.IS_WINDOWS) {
|
||||
return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello
|
||||
); // e.g. C: or C:\hello
|
||||
}
|
||||
return p.startsWith('/');
|
||||
}
|
||||
exports.isRooted = isRooted;
|
||||
/**
|
||||
* Recursively create a directory at `fsPath`.
|
||||
*
|
||||
* This implementation is optimistic, meaning it attempts to create the full
|
||||
* path first, and backs up the path stack from there.
|
||||
*
|
||||
* @param fsPath The path to create
|
||||
* @param maxDepth The maximum recursion depth
|
||||
* @param depth The current recursion depth
|
||||
*/
|
||||
function mkdirP(fsPath, maxDepth = 1000, depth = 1) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
assert_1.ok(fsPath, 'a path argument must be provided');
|
||||
fsPath = path.resolve(fsPath);
|
||||
if (depth >= maxDepth)
|
||||
return exports.mkdir(fsPath);
|
||||
try {
|
||||
yield exports.mkdir(fsPath);
|
||||
return;
|
||||
}
|
||||
catch (err) {
|
||||
switch (err.code) {
|
||||
case 'ENOENT': {
|
||||
yield mkdirP(path.dirname(fsPath), maxDepth, depth + 1);
|
||||
yield exports.mkdir(fsPath);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
let stats;
|
||||
try {
|
||||
stats = yield exports.stat(fsPath);
|
||||
}
|
||||
catch (err2) {
|
||||
throw err;
|
||||
}
|
||||
if (!stats.isDirectory())
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.mkdirP = mkdirP;
|
||||
/**
|
||||
* Best effort attempt to determine whether a file exists and is executable.
|
||||
* @param filePath file path to check
|
||||
* @param extensions additional file extensions to try
|
||||
* @return if file exists and is executable, returns the file path. otherwise empty string.
|
||||
*/
|
||||
function tryGetExecutablePath(filePath, extensions) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let stats = undefined;
|
||||
try {
|
||||
// test file exists
|
||||
stats = yield exports.stat(filePath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
|
||||
}
|
||||
}
|
||||
if (stats && stats.isFile()) {
|
||||
if (exports.IS_WINDOWS) {
|
||||
// on Windows, test for valid extension
|
||||
const upperExt = path.extname(filePath).toUpperCase();
|
||||
if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isUnixExecutable(stats)) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
// try each extension
|
||||
const originalFilePath = filePath;
|
||||
for (const extension of extensions) {
|
||||
filePath = originalFilePath + extension;
|
||||
stats = undefined;
|
||||
try {
|
||||
stats = yield exports.stat(filePath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
|
||||
}
|
||||
}
|
||||
if (stats && stats.isFile()) {
|
||||
if (exports.IS_WINDOWS) {
|
||||
// preserve the case of the actual file (since an extension was appended)
|
||||
try {
|
||||
const directory = path.dirname(filePath);
|
||||
const upperName = path.basename(filePath).toUpperCase();
|
||||
for (const actualName of yield exports.readdir(directory)) {
|
||||
if (upperName === actualName.toUpperCase()) {
|
||||
filePath = path.join(directory, actualName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`);
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
else {
|
||||
if (isUnixExecutable(stats)) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
});
|
||||
}
|
||||
exports.tryGetExecutablePath = tryGetExecutablePath;
|
||||
function normalizeSeparators(p) {
|
||||
p = p || '';
|
||||
if (exports.IS_WINDOWS) {
|
||||
// convert slashes on Windows
|
||||
p = p.replace(/\//g, '\\');
|
||||
// remove redundant slashes
|
||||
return p.replace(/\\\\+/g, '\\');
|
||||
}
|
||||
// remove redundant slashes
|
||||
return p.replace(/\/\/+/g, '/');
|
||||
}
|
||||
// on Mac/Linux, test the execute bit
|
||||
// R W X R W X R W X
|
||||
// 256 128 64 32 16 8 4 2 1
|
||||
function isUnixExecutable(stats) {
|
||||
return ((stats.mode & 1) > 0 ||
|
||||
((stats.mode & 8) > 0 && stats.gid === process.getgid()) ||
|
||||
((stats.mode & 64) > 0 && stats.uid === process.getuid()));
|
||||
}
|
||||
//# sourceMappingURL=io-util.js.map
|
|
@ -1,48 +1,48 @@
|
|||
/**
|
||||
* Interface for cp/mv options
|
||||
*/
|
||||
export interface CopyOptions {
|
||||
/** Optional. Whether to recursively copy all subdirectories. Defaults to false */
|
||||
recursive?: boolean;
|
||||
/** Optional. Whether to overwrite existing files in the destination. Defaults to true */
|
||||
force?: boolean;
|
||||
}
|
||||
/**
|
||||
* Copies a file or folder.
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See CopyOptions.
|
||||
*/
|
||||
export declare function cp(source: string, dest: string, options?: CopyOptions): Promise<void>;
|
||||
/**
|
||||
* Moves a path.
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See CopyOptions.
|
||||
*/
|
||||
export declare function mv(source: string, dest: string, options?: CopyOptions): Promise<void>;
|
||||
/**
|
||||
* Remove a path recursively with force
|
||||
*
|
||||
* @param inputPath path to remove
|
||||
*/
|
||||
export declare function rmRF(inputPath: string): Promise<void>;
|
||||
/**
|
||||
* Make a directory. Creates the full path with folders in between
|
||||
* Will throw if it fails
|
||||
*
|
||||
* @param fsPath path to create
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
export declare function mkdirP(fsPath: string): Promise<void>;
|
||||
/**
|
||||
* Returns path of a tool had the tool actually been invoked. Resolves via paths.
|
||||
* If you check and the tool does not exist, it will throw.
|
||||
*
|
||||
* @param tool name of the tool
|
||||
* @param check whether to check if tool exists
|
||||
* @returns Promise<string> path to tool
|
||||
*/
|
||||
export declare function which(tool: string, check?: boolean): Promise<string>;
|
||||
/**
|
||||
* Interface for cp/mv options
|
||||
*/
|
||||
export interface CopyOptions {
|
||||
/** Optional. Whether to recursively copy all subdirectories. Defaults to false */
|
||||
recursive?: boolean;
|
||||
/** Optional. Whether to overwrite existing files in the destination. Defaults to true */
|
||||
force?: boolean;
|
||||
}
|
||||
/**
|
||||
* Copies a file or folder.
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See CopyOptions.
|
||||
*/
|
||||
export declare function cp(source: string, dest: string, options?: CopyOptions): Promise<void>;
|
||||
/**
|
||||
* Moves a path.
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See CopyOptions.
|
||||
*/
|
||||
export declare function mv(source: string, dest: string, options?: CopyOptions): Promise<void>;
|
||||
/**
|
||||
* Remove a path recursively with force
|
||||
*
|
||||
* @param inputPath path to remove
|
||||
*/
|
||||
export declare function rmRF(inputPath: string): Promise<void>;
|
||||
/**
|
||||
* Make a directory. Creates the full path with folders in between
|
||||
* Will throw if it fails
|
||||
*
|
||||
* @param fsPath path to create
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
export declare function mkdirP(fsPath: string): Promise<void>;
|
||||
/**
|
||||
* Returns path of a tool had the tool actually been invoked. Resolves via paths.
|
||||
* If you check and the tool does not exist, it will throw.
|
||||
*
|
||||
* @param tool name of the tool
|
||||
* @param check whether to check if tool exists
|
||||
* @returns Promise<string> path to tool
|
||||
*/
|
||||
export declare function which(tool: string, check?: boolean): Promise<string>;
|
||||
|
|
|
@ -1,262 +1,262 @@
|
|||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const childProcess = require("child_process");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const util_1 = require("util");
|
||||
const ioUtil = require("./io-util");
|
||||
const exec = util_1.promisify(childProcess.exec);
|
||||
/**
|
||||
* Copies a file or folder.
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See CopyOptions.
|
||||
*/
|
||||
function cp(source, dest, options = {}) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield move(source, dest, options, { deleteOriginal: false });
|
||||
});
|
||||
}
|
||||
exports.cp = cp;
|
||||
/**
|
||||
* Moves a path.
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See CopyOptions.
|
||||
*/
|
||||
function mv(source, dest, options = {}) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield move(source, dest, options, { deleteOriginal: true });
|
||||
});
|
||||
}
|
||||
exports.mv = mv;
|
||||
/**
|
||||
* Remove a path recursively with force
|
||||
*
|
||||
* @param inputPath path to remove
|
||||
*/
|
||||
function rmRF(inputPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (ioUtil.IS_WINDOWS) {
|
||||
// Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another
|
||||
// program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del.
|
||||
try {
|
||||
if (yield ioUtil.isDirectory(inputPath, true)) {
|
||||
yield exec(`rd /s /q "${inputPath}"`);
|
||||
}
|
||||
else {
|
||||
yield exec(`del /f /a "${inputPath}"`);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
// if you try to delete a file that doesn't exist, desired result is achieved
|
||||
// other errors are valid
|
||||
if (err.code !== 'ENOENT')
|
||||
throw err;
|
||||
}
|
||||
// Shelling out fails to remove a symlink folder with missing source, this unlink catches that
|
||||
try {
|
||||
yield ioUtil.unlink(inputPath);
|
||||
}
|
||||
catch (err) {
|
||||
// if you try to delete a file that doesn't exist, desired result is achieved
|
||||
// other errors are valid
|
||||
if (err.code !== 'ENOENT')
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
else {
|
||||
let isDir = false;
|
||||
try {
|
||||
isDir = yield ioUtil.isDirectory(inputPath);
|
||||
}
|
||||
catch (err) {
|
||||
// if you try to delete a file that doesn't exist, desired result is achieved
|
||||
// other errors are valid
|
||||
if (err.code !== 'ENOENT')
|
||||
throw err;
|
||||
return;
|
||||
}
|
||||
if (isDir) {
|
||||
yield exec(`rm -rf "${inputPath}"`);
|
||||
}
|
||||
else {
|
||||
yield ioUtil.unlink(inputPath);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.rmRF = rmRF;
|
||||
/**
|
||||
* Make a directory. Creates the full path with folders in between
|
||||
* Will throw if it fails
|
||||
*
|
||||
* @param fsPath path to create
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
function mkdirP(fsPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield ioUtil.mkdirP(fsPath);
|
||||
});
|
||||
}
|
||||
exports.mkdirP = mkdirP;
|
||||
/**
|
||||
* Returns path of a tool had the tool actually been invoked. Resolves via paths.
|
||||
* If you check and the tool does not exist, it will throw.
|
||||
*
|
||||
* @param tool name of the tool
|
||||
* @param check whether to check if tool exists
|
||||
* @returns Promise<string> path to tool
|
||||
*/
|
||||
function which(tool, check) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (!tool) {
|
||||
throw new Error("parameter 'tool' is required");
|
||||
}
|
||||
// recursive when check=true
|
||||
if (check) {
|
||||
const result = yield which(tool, false);
|
||||
if (!result) {
|
||||
if (ioUtil.IS_WINDOWS) {
|
||||
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`);
|
||||
}
|
||||
else {
|
||||
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
// build the list of extensions to try
|
||||
const extensions = [];
|
||||
if (ioUtil.IS_WINDOWS && process.env.PATHEXT) {
|
||||
for (const extension of process.env.PATHEXT.split(path.delimiter)) {
|
||||
if (extension) {
|
||||
extensions.push(extension);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if it's rooted, return it if exists. otherwise return empty.
|
||||
if (ioUtil.isRooted(tool)) {
|
||||
const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions);
|
||||
if (filePath) {
|
||||
return filePath;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
// if any path separators, return empty
|
||||
if (tool.includes('/') || (ioUtil.IS_WINDOWS && tool.includes('\\'))) {
|
||||
return '';
|
||||
}
|
||||
// build the list of directories
|
||||
//
|
||||
// Note, technically "where" checks the current directory on Windows. From a task lib perspective,
|
||||
// it feels like we should not do this. Checking the current directory seems like more of a use
|
||||
// case of a shell, and the which() function exposed by the task lib should strive for consistency
|
||||
// across platforms.
|
||||
const directories = [];
|
||||
if (process.env.PATH) {
|
||||
for (const p of process.env.PATH.split(path.delimiter)) {
|
||||
if (p) {
|
||||
directories.push(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
// return the first match
|
||||
for (const directory of directories) {
|
||||
const filePath = yield ioUtil.tryGetExecutablePath(directory + path.sep + tool, extensions);
|
||||
if (filePath) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
catch (err) {
|
||||
throw new Error(`which failed with message ${err.message}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.which = which;
|
||||
// Copies contents of source into dest, making any necessary folders along the way.
|
||||
// Deletes the original copy if deleteOriginal is true
|
||||
function copyDirectoryContents(source, dest, force, deleteOriginal = false) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (yield ioUtil.isDirectory(source)) {
|
||||
if (yield ioUtil.exists(dest)) {
|
||||
if (!(yield ioUtil.isDirectory(dest))) {
|
||||
throw new Error(`${dest} is not a directory`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
yield mkdirP(dest);
|
||||
}
|
||||
// Copy all child files, and directories recursively
|
||||
const sourceChildren = yield ioUtil.readdir(source);
|
||||
for (const newSource of sourceChildren) {
|
||||
const newDest = path.join(dest, path.basename(newSource));
|
||||
yield copyDirectoryContents(path.resolve(source, newSource), newDest, force, deleteOriginal);
|
||||
}
|
||||
if (deleteOriginal) {
|
||||
yield ioUtil.rmdir(source);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (force) {
|
||||
yield ioUtil.copyFile(source, dest);
|
||||
}
|
||||
else {
|
||||
yield ioUtil.copyFile(source, dest, fs.constants.COPYFILE_EXCL);
|
||||
}
|
||||
if (deleteOriginal) {
|
||||
yield ioUtil.unlink(source);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function move(source, dest, options = {}, moveOptions) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const { force, recursive } = readCopyOptions(options);
|
||||
if (yield ioUtil.isDirectory(source)) {
|
||||
if (!recursive) {
|
||||
throw new Error(`non-recursive cp failed, ${source} is a directory`);
|
||||
}
|
||||
// If directory exists, move source inside it. Otherwise, create it and move contents of source inside.
|
||||
if (yield ioUtil.exists(dest)) {
|
||||
if (!(yield ioUtil.isDirectory(dest))) {
|
||||
throw new Error(`${dest} is not a directory`);
|
||||
}
|
||||
dest = path.join(dest, path.basename(source));
|
||||
}
|
||||
yield copyDirectoryContents(source, dest, force, moveOptions.deleteOriginal);
|
||||
}
|
||||
else {
|
||||
if ((yield ioUtil.exists(dest)) && (yield ioUtil.isDirectory(dest))) {
|
||||
dest = path.join(dest, path.basename(source));
|
||||
}
|
||||
if (force) {
|
||||
yield ioUtil.copyFile(source, dest);
|
||||
}
|
||||
else {
|
||||
yield ioUtil.copyFile(source, dest, fs.constants.COPYFILE_EXCL);
|
||||
}
|
||||
if (moveOptions.deleteOriginal) {
|
||||
yield ioUtil.unlink(source);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function readCopyOptions(options) {
|
||||
const force = options.force == null ? true : options.force;
|
||||
const recursive = Boolean(options.recursive);
|
||||
return { force, recursive };
|
||||
}
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const childProcess = require("child_process");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const util_1 = require("util");
|
||||
const ioUtil = require("./io-util");
|
||||
const exec = util_1.promisify(childProcess.exec);
|
||||
/**
|
||||
* Copies a file or folder.
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See CopyOptions.
|
||||
*/
|
||||
function cp(source, dest, options = {}) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield move(source, dest, options, { deleteOriginal: false });
|
||||
});
|
||||
}
|
||||
exports.cp = cp;
|
||||
/**
|
||||
* Moves a path.
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See CopyOptions.
|
||||
*/
|
||||
function mv(source, dest, options = {}) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield move(source, dest, options, { deleteOriginal: true });
|
||||
});
|
||||
}
|
||||
exports.mv = mv;
|
||||
/**
|
||||
* Remove a path recursively with force
|
||||
*
|
||||
* @param inputPath path to remove
|
||||
*/
|
||||
function rmRF(inputPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (ioUtil.IS_WINDOWS) {
|
||||
// Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another
|
||||
// program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del.
|
||||
try {
|
||||
if (yield ioUtil.isDirectory(inputPath, true)) {
|
||||
yield exec(`rd /s /q "${inputPath}"`);
|
||||
}
|
||||
else {
|
||||
yield exec(`del /f /a "${inputPath}"`);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
// if you try to delete a file that doesn't exist, desired result is achieved
|
||||
// other errors are valid
|
||||
if (err.code !== 'ENOENT')
|
||||
throw err;
|
||||
}
|
||||
// Shelling out fails to remove a symlink folder with missing source, this unlink catches that
|
||||
try {
|
||||
yield ioUtil.unlink(inputPath);
|
||||
}
|
||||
catch (err) {
|
||||
// if you try to delete a file that doesn't exist, desired result is achieved
|
||||
// other errors are valid
|
||||
if (err.code !== 'ENOENT')
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
else {
|
||||
let isDir = false;
|
||||
try {
|
||||
isDir = yield ioUtil.isDirectory(inputPath);
|
||||
}
|
||||
catch (err) {
|
||||
// if you try to delete a file that doesn't exist, desired result is achieved
|
||||
// other errors are valid
|
||||
if (err.code !== 'ENOENT')
|
||||
throw err;
|
||||
return;
|
||||
}
|
||||
if (isDir) {
|
||||
yield exec(`rm -rf "${inputPath}"`);
|
||||
}
|
||||
else {
|
||||
yield ioUtil.unlink(inputPath);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.rmRF = rmRF;
|
||||
/**
|
||||
* Make a directory. Creates the full path with folders in between
|
||||
* Will throw if it fails
|
||||
*
|
||||
* @param fsPath path to create
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
function mkdirP(fsPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield ioUtil.mkdirP(fsPath);
|
||||
});
|
||||
}
|
||||
exports.mkdirP = mkdirP;
|
||||
/**
|
||||
* Returns path of a tool had the tool actually been invoked. Resolves via paths.
|
||||
* If you check and the tool does not exist, it will throw.
|
||||
*
|
||||
* @param tool name of the tool
|
||||
* @param check whether to check if tool exists
|
||||
* @returns Promise<string> path to tool
|
||||
*/
|
||||
function which(tool, check) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (!tool) {
|
||||
throw new Error("parameter 'tool' is required");
|
||||
}
|
||||
// recursive when check=true
|
||||
if (check) {
|
||||
const result = yield which(tool, false);
|
||||
if (!result) {
|
||||
if (ioUtil.IS_WINDOWS) {
|
||||
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`);
|
||||
}
|
||||
else {
|
||||
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
// build the list of extensions to try
|
||||
const extensions = [];
|
||||
if (ioUtil.IS_WINDOWS && process.env.PATHEXT) {
|
||||
for (const extension of process.env.PATHEXT.split(path.delimiter)) {
|
||||
if (extension) {
|
||||
extensions.push(extension);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if it's rooted, return it if exists. otherwise return empty.
|
||||
if (ioUtil.isRooted(tool)) {
|
||||
const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions);
|
||||
if (filePath) {
|
||||
return filePath;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
// if any path separators, return empty
|
||||
if (tool.includes('/') || (ioUtil.IS_WINDOWS && tool.includes('\\'))) {
|
||||
return '';
|
||||
}
|
||||
// build the list of directories
|
||||
//
|
||||
// Note, technically "where" checks the current directory on Windows. From a task lib perspective,
|
||||
// it feels like we should not do this. Checking the current directory seems like more of a use
|
||||
// case of a shell, and the which() function exposed by the task lib should strive for consistency
|
||||
// across platforms.
|
||||
const directories = [];
|
||||
if (process.env.PATH) {
|
||||
for (const p of process.env.PATH.split(path.delimiter)) {
|
||||
if (p) {
|
||||
directories.push(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
// return the first match
|
||||
for (const directory of directories) {
|
||||
const filePath = yield ioUtil.tryGetExecutablePath(directory + path.sep + tool, extensions);
|
||||
if (filePath) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
catch (err) {
|
||||
throw new Error(`which failed with message ${err.message}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.which = which;
|
||||
// Copies contents of source into dest, making any necessary folders along the way.
|
||||
// Deletes the original copy if deleteOriginal is true
|
||||
function copyDirectoryContents(source, dest, force, deleteOriginal = false) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (yield ioUtil.isDirectory(source)) {
|
||||
if (yield ioUtil.exists(dest)) {
|
||||
if (!(yield ioUtil.isDirectory(dest))) {
|
||||
throw new Error(`${dest} is not a directory`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
yield mkdirP(dest);
|
||||
}
|
||||
// Copy all child files, and directories recursively
|
||||
const sourceChildren = yield ioUtil.readdir(source);
|
||||
for (const newSource of sourceChildren) {
|
||||
const newDest = path.join(dest, path.basename(newSource));
|
||||
yield copyDirectoryContents(path.resolve(source, newSource), newDest, force, deleteOriginal);
|
||||
}
|
||||
if (deleteOriginal) {
|
||||
yield ioUtil.rmdir(source);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (force) {
|
||||
yield ioUtil.copyFile(source, dest);
|
||||
}
|
||||
else {
|
||||
yield ioUtil.copyFile(source, dest, fs.constants.COPYFILE_EXCL);
|
||||
}
|
||||
if (deleteOriginal) {
|
||||
yield ioUtil.unlink(source);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function move(source, dest, options = {}, moveOptions) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const { force, recursive } = readCopyOptions(options);
|
||||
if (yield ioUtil.isDirectory(source)) {
|
||||
if (!recursive) {
|
||||
throw new Error(`non-recursive cp failed, ${source} is a directory`);
|
||||
}
|
||||
// If directory exists, move source inside it. Otherwise, create it and move contents of source inside.
|
||||
if (yield ioUtil.exists(dest)) {
|
||||
if (!(yield ioUtil.isDirectory(dest))) {
|
||||
throw new Error(`${dest} is not a directory`);
|
||||
}
|
||||
dest = path.join(dest, path.basename(source));
|
||||
}
|
||||
yield copyDirectoryContents(source, dest, force, moveOptions.deleteOriginal);
|
||||
}
|
||||
else {
|
||||
if ((yield ioUtil.exists(dest)) && (yield ioUtil.isDirectory(dest))) {
|
||||
dest = path.join(dest, path.basename(source));
|
||||
}
|
||||
if (force) {
|
||||
yield ioUtil.copyFile(source, dest);
|
||||
}
|
||||
else {
|
||||
yield ioUtil.copyFile(source, dest, fs.constants.COPYFILE_EXCL);
|
||||
}
|
||||
if (moveOptions.deleteOriginal) {
|
||||
yield ioUtil.unlink(source);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function readCopyOptions(options) {
|
||||
const force = options.force == null ? true : options.force;
|
||||
const recursive = Boolean(options.recursive);
|
||||
return { force, recursive };
|
||||
}
|
||||
//# sourceMappingURL=io.js.map
|
|
@ -1,7 +1,7 @@
|
|||
# `@actions/tool-cache`
|
||||
|
||||
> Functions necessary for downloading and caching tools.
|
||||
|
||||
## Usage
|
||||
|
||||
# `@actions/tool-cache`
|
||||
|
||||
> Functions necessary for downloading and caching tools.
|
||||
|
||||
## Usage
|
||||
|
||||
See [src/tool-cache.ts](src/tool-cache.ts).
|
|
@ -1,78 +1,78 @@
|
|||
export declare class HTTPError extends Error {
|
||||
readonly httpStatusCode: number | undefined;
|
||||
constructor(httpStatusCode: number | undefined);
|
||||
}
|
||||
/**
|
||||
* Download a tool from an url and stream it into a file
|
||||
*
|
||||
* @param url url of tool to download
|
||||
* @returns path to downloaded tool
|
||||
*/
|
||||
export declare function downloadTool(url: string): Promise<string>;
|
||||
/**
|
||||
* Extract a .7z file
|
||||
*
|
||||
* @param file path to the .7z file
|
||||
* @param dest destination directory. Optional.
|
||||
* @param _7zPath path to 7zr.exe. Optional, for long path support. Most .7z archives do not have this
|
||||
* problem. If your .7z archive contains very long paths, you can pass the path to 7zr.exe which will
|
||||
* gracefully handle long paths. By default 7zdec.exe is used because it is a very small program and is
|
||||
* bundled with the tool lib. However it does not support long paths. 7zr.exe is the reduced command line
|
||||
* interface, it is smaller than the full command line interface, and it does support long paths. At the
|
||||
* time of this writing, it is freely available from the LZMA SDK that is available on the 7zip website.
|
||||
* Be sure to check the current license agreement. If 7zr.exe is bundled with your action, then the path
|
||||
* to 7zr.exe can be pass to this function.
|
||||
* @returns path to the destination directory
|
||||
*/
|
||||
export declare function extract7z(file: string, dest?: string, _7zPath?: string): Promise<string>;
|
||||
/**
|
||||
* Extract a tar
|
||||
*
|
||||
* @param file path to the tar
|
||||
* @param dest destination directory. Optional.
|
||||
* @returns path to the destination directory
|
||||
*/
|
||||
export declare function extractTar(file: string, dest?: string): Promise<string>;
|
||||
/**
|
||||
* Extract a zip
|
||||
*
|
||||
* @param file path to the zip
|
||||
* @param dest destination directory. Optional.
|
||||
* @returns path to the destination directory
|
||||
*/
|
||||
export declare function extractZip(file: string, dest?: string): Promise<string>;
|
||||
/**
|
||||
* Caches a directory and installs it into the tool cacheDir
|
||||
*
|
||||
* @param sourceDir the directory to cache into tools
|
||||
* @param tool tool name
|
||||
* @param version version of the tool. semver format
|
||||
* @param arch architecture of the tool. Optional. Defaults to machine architecture
|
||||
*/
|
||||
export declare function cacheDir(sourceDir: string, tool: string, version: string, arch?: string): Promise<string>;
|
||||
/**
|
||||
* Caches a downloaded file (GUID) and installs it
|
||||
* into the tool cache with a given targetName
|
||||
*
|
||||
* @param sourceFile the file to cache into tools. Typically a result of downloadTool which is a guid.
|
||||
* @param targetFile the name of the file name in the tools directory
|
||||
* @param tool tool name
|
||||
* @param version version of the tool. semver format
|
||||
* @param arch architecture of the tool. Optional. Defaults to machine architecture
|
||||
*/
|
||||
export declare function cacheFile(sourceFile: string, targetFile: string, tool: string, version: string, arch?: string): Promise<string>;
|
||||
/**
|
||||
* Finds the path to a tool version in the local installed tool cache
|
||||
*
|
||||
* @param toolName name of the tool
|
||||
* @param versionSpec version of the tool
|
||||
* @param arch optional arch. defaults to arch of computer
|
||||
*/
|
||||
export declare function find(toolName: string, versionSpec: string, arch?: string): string;
|
||||
/**
|
||||
* Finds the paths to all versions of a tool that are installed in the local tool cache
|
||||
*
|
||||
* @param toolName name of the tool
|
||||
* @param arch optional arch. defaults to arch of computer
|
||||
*/
|
||||
export declare function findAllVersions(toolName: string, arch?: string): string[];
|
||||
export declare class HTTPError extends Error {
|
||||
readonly httpStatusCode: number | undefined;
|
||||
constructor(httpStatusCode: number | undefined);
|
||||
}
|
||||
/**
|
||||
* Download a tool from an url and stream it into a file
|
||||
*
|
||||
* @param url url of tool to download
|
||||
* @returns path to downloaded tool
|
||||
*/
|
||||
export declare function downloadTool(url: string): Promise<string>;
|
||||
/**
|
||||
* Extract a .7z file
|
||||
*
|
||||
* @param file path to the .7z file
|
||||
* @param dest destination directory. Optional.
|
||||
* @param _7zPath path to 7zr.exe. Optional, for long path support. Most .7z archives do not have this
|
||||
* problem. If your .7z archive contains very long paths, you can pass the path to 7zr.exe which will
|
||||
* gracefully handle long paths. By default 7zdec.exe is used because it is a very small program and is
|
||||
* bundled with the tool lib. However it does not support long paths. 7zr.exe is the reduced command line
|
||||
* interface, it is smaller than the full command line interface, and it does support long paths. At the
|
||||
* time of this writing, it is freely available from the LZMA SDK that is available on the 7zip website.
|
||||
* Be sure to check the current license agreement. If 7zr.exe is bundled with your action, then the path
|
||||
* to 7zr.exe can be pass to this function.
|
||||
* @returns path to the destination directory
|
||||
*/
|
||||
export declare function extract7z(file: string, dest?: string, _7zPath?: string): Promise<string>;
|
||||
/**
|
||||
* Extract a tar
|
||||
*
|
||||
* @param file path to the tar
|
||||
* @param dest destination directory. Optional.
|
||||
* @returns path to the destination directory
|
||||
*/
|
||||
export declare function extractTar(file: string, dest?: string): Promise<string>;
|
||||
/**
|
||||
* Extract a zip
|
||||
*
|
||||
* @param file path to the zip
|
||||
* @param dest destination directory. Optional.
|
||||
* @returns path to the destination directory
|
||||
*/
|
||||
export declare function extractZip(file: string, dest?: string): Promise<string>;
|
||||
/**
|
||||
* Caches a directory and installs it into the tool cacheDir
|
||||
*
|
||||
* @param sourceDir the directory to cache into tools
|
||||
* @param tool tool name
|
||||
* @param version version of the tool. semver format
|
||||
* @param arch architecture of the tool. Optional. Defaults to machine architecture
|
||||
*/
|
||||
export declare function cacheDir(sourceDir: string, tool: string, version: string, arch?: string): Promise<string>;
|
||||
/**
|
||||
* Caches a downloaded file (GUID) and installs it
|
||||
* into the tool cache with a given targetName
|
||||
*
|
||||
* @param sourceFile the file to cache into tools. Typically a result of downloadTool which is a guid.
|
||||
* @param targetFile the name of the file name in the tools directory
|
||||
* @param tool tool name
|
||||
* @param version version of the tool. semver format
|
||||
* @param arch architecture of the tool. Optional. Defaults to machine architecture
|
||||
*/
|
||||
export declare function cacheFile(sourceFile: string, targetFile: string, tool: string, version: string, arch?: string): Promise<string>;
|
||||
/**
|
||||
* Finds the path to a tool version in the local installed tool cache
|
||||
*
|
||||
* @param toolName name of the tool
|
||||
* @param versionSpec version of the tool
|
||||
* @param arch optional arch. defaults to arch of computer
|
||||
*/
|
||||
export declare function find(toolName: string, versionSpec: string, arch?: string): string;
|
||||
/**
|
||||
* Finds the paths to all versions of a tool that are installed in the local tool cache
|
||||
*
|
||||
* @param toolName name of the tool
|
||||
* @param arch optional arch. defaults to arch of computer
|
||||
*/
|
||||
export declare function findAllVersions(toolName: string, arch?: string): string[];
|
||||
|
|
|
@ -1,437 +1,437 @@
|
|||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const core = require("@actions/core");
|
||||
const io = require("@actions/io");
|
||||
const fs = require("fs");
|
||||
const os = require("os");
|
||||
const path = require("path");
|
||||
const httpm = require("typed-rest-client/HttpClient");
|
||||
const semver = require("semver");
|
||||
const shell = require("shelljs");
|
||||
const uuidV4 = require("uuid/v4");
|
||||
const exec_1 = require("@actions/exec/lib/exec");
|
||||
const assert_1 = require("assert");
|
||||
class HTTPError extends Error {
|
||||
constructor(httpStatusCode) {
|
||||
super(`Unexpected HTTP response: ${httpStatusCode}`);
|
||||
this.httpStatusCode = httpStatusCode;
|
||||
Object.setPrototypeOf(this, new.target.prototype);
|
||||
}
|
||||
}
|
||||
exports.HTTPError = HTTPError;
|
||||
const IS_WINDOWS = process.platform === 'win32';
|
||||
const userAgent = 'actions/tool-cache';
|
||||
// On load grab temp directory and cache directory and remove them from env (currently don't want to expose this)
|
||||
let tempDirectory = process.env['RUNNER_TEMP'] || '';
|
||||
let cacheRoot = process.env['RUNNER_TOOL_CACHE'] || '';
|
||||
// If directories not found, place them in common temp locations
|
||||
if (!tempDirectory || !cacheRoot) {
|
||||
let baseLocation;
|
||||
if (IS_WINDOWS) {
|
||||
// On windows use the USERPROFILE env variable
|
||||
baseLocation = process.env['USERPROFILE'] || 'C:\\';
|
||||
}
|
||||
else {
|
||||
if (process.platform === 'darwin') {
|
||||
baseLocation = '/Users';
|
||||
}
|
||||
else {
|
||||
baseLocation = '/home';
|
||||
}
|
||||
}
|
||||
if (!tempDirectory) {
|
||||
tempDirectory = path.join(baseLocation, 'actions', 'temp');
|
||||
}
|
||||
if (!cacheRoot) {
|
||||
cacheRoot = path.join(baseLocation, 'actions', 'cache');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Download a tool from an url and stream it into a file
|
||||
*
|
||||
* @param url url of tool to download
|
||||
* @returns path to downloaded tool
|
||||
*/
|
||||
function downloadTool(url) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// Wrap in a promise so that we can resolve from within stream callbacks
|
||||
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
const http = new httpm.HttpClient(userAgent, [], {
|
||||
allowRetries: true,
|
||||
maxRetries: 3
|
||||
});
|
||||
const destPath = path.join(tempDirectory, uuidV4());
|
||||
yield io.mkdirP(tempDirectory);
|
||||
core.debug(`Downloading ${url}`);
|
||||
core.debug(`Downloading ${destPath}`);
|
||||
if (fs.existsSync(destPath)) {
|
||||
throw new Error(`Destination file path ${destPath} already exists`);
|
||||
}
|
||||
const response = yield http.get(url);
|
||||
if (response.message.statusCode !== 200) {
|
||||
const err = new HTTPError(response.message.statusCode);
|
||||
core.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`);
|
||||
throw err;
|
||||
}
|
||||
const file = fs.createWriteStream(destPath);
|
||||
file.on('open', () => __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
const stream = response.message.pipe(file);
|
||||
stream.on('close', () => {
|
||||
core.debug('download complete');
|
||||
resolve(destPath);
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
core.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`);
|
||||
reject(err);
|
||||
}
|
||||
}));
|
||||
file.on('error', err => {
|
||||
file.end();
|
||||
reject(err);
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
exports.downloadTool = downloadTool;
|
||||
/**
|
||||
* Extract a .7z file
|
||||
*
|
||||
* @param file path to the .7z file
|
||||
* @param dest destination directory. Optional.
|
||||
* @param _7zPath path to 7zr.exe. Optional, for long path support. Most .7z archives do not have this
|
||||
* problem. If your .7z archive contains very long paths, you can pass the path to 7zr.exe which will
|
||||
* gracefully handle long paths. By default 7zdec.exe is used because it is a very small program and is
|
||||
* bundled with the tool lib. However it does not support long paths. 7zr.exe is the reduced command line
|
||||
* interface, it is smaller than the full command line interface, and it does support long paths. At the
|
||||
* time of this writing, it is freely available from the LZMA SDK that is available on the 7zip website.
|
||||
* Be sure to check the current license agreement. If 7zr.exe is bundled with your action, then the path
|
||||
* to 7zr.exe can be pass to this function.
|
||||
* @returns path to the destination directory
|
||||
*/
|
||||
function extract7z(file, dest, _7zPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
assert_1.ok(IS_WINDOWS, 'extract7z() not supported on current OS');
|
||||
assert_1.ok(file, 'parameter "file" is required');
|
||||
dest = dest || (yield _createExtractFolder(dest));
|
||||
const originalCwd = process.cwd();
|
||||
process.chdir(dest);
|
||||
if (_7zPath) {
|
||||
try {
|
||||
const args = [
|
||||
'x',
|
||||
'-bb1',
|
||||
'-bd',
|
||||
'-sccUTF-8',
|
||||
file
|
||||
];
|
||||
const options = {
|
||||
silent: true
|
||||
};
|
||||
yield exec_1.exec(`"${_7zPath}"`, args, options);
|
||||
}
|
||||
finally {
|
||||
process.chdir(originalCwd);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const escapedScript = path
|
||||
.join(__dirname, '..', 'scripts', 'Invoke-7zdec.ps1')
|
||||
.replace(/'/g, "''")
|
||||
.replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines
|
||||
const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, '');
|
||||
const escapedTarget = dest.replace(/'/g, "''").replace(/"|\n|\r/g, '');
|
||||
const command = `& '${escapedScript}' -Source '${escapedFile}' -Target '${escapedTarget}'`;
|
||||
const args = [
|
||||
'-NoLogo',
|
||||
'-Sta',
|
||||
'-NoProfile',
|
||||
'-NonInteractive',
|
||||
'-ExecutionPolicy',
|
||||
'Unrestricted',
|
||||
'-Command',
|
||||
command
|
||||
];
|
||||
const options = {
|
||||
silent: true
|
||||
};
|
||||
try {
|
||||
const powershellPath = yield io.which('powershell', true);
|
||||
yield exec_1.exec(`"${powershellPath}"`, args, options);
|
||||
}
|
||||
finally {
|
||||
process.chdir(originalCwd);
|
||||
}
|
||||
}
|
||||
return dest;
|
||||
});
|
||||
}
|
||||
exports.extract7z = extract7z;
|
||||
/**
|
||||
* Extract a tar
|
||||
*
|
||||
* @param file path to the tar
|
||||
* @param dest destination directory. Optional.
|
||||
* @returns path to the destination directory
|
||||
*/
|
||||
function extractTar(file, dest) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (!file) {
|
||||
throw new Error("parameter 'file' is required");
|
||||
}
|
||||
dest = dest || (yield _createExtractFolder(dest));
|
||||
const tarPath = yield io.which('tar', true);
|
||||
yield exec_1.exec(`"${tarPath}"`, ['xzC', dest, '-f', file]);
|
||||
return dest;
|
||||
});
|
||||
}
|
||||
exports.extractTar = extractTar;
|
||||
/**
|
||||
* Extract a zip
|
||||
*
|
||||
* @param file path to the zip
|
||||
* @param dest destination directory. Optional.
|
||||
* @returns path to the destination directory
|
||||
*/
|
||||
function extractZip(file, dest) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (!file) {
|
||||
throw new Error("parameter 'file' is required");
|
||||
}
|
||||
dest = dest || (yield _createExtractFolder(dest));
|
||||
if (IS_WINDOWS) {
|
||||
yield extractZipWin(file, dest);
|
||||
}
|
||||
else {
|
||||
yield extractZipNix(file, dest);
|
||||
}
|
||||
return dest;
|
||||
});
|
||||
}
|
||||
exports.extractZip = extractZip;
|
||||
function extractZipWin(file, dest) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// build the powershell command
|
||||
const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines
|
||||
const escapedDest = dest.replace(/'/g, "''").replace(/"|\n|\r/g, '');
|
||||
const command = `$ErrorActionPreference = 'Stop' ; try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}')`;
|
||||
// run powershell
|
||||
const powershellPath = yield io.which('powershell');
|
||||
const args = [
|
||||
'-NoLogo',
|
||||
'-Sta',
|
||||
'-NoProfile',
|
||||
'-NonInteractive',
|
||||
'-ExecutionPolicy',
|
||||
'Unrestricted',
|
||||
'-Command',
|
||||
command
|
||||
];
|
||||
yield exec_1.exec(`"${powershellPath}"`, args);
|
||||
});
|
||||
}
|
||||
function extractZipNix(file, dest) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const unzipPath = path.join(__dirname, '..', 'scripts', 'externals', 'unzip');
|
||||
yield exec_1.exec(`"${unzipPath}"`, [file], { cwd: dest });
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Caches a directory and installs it into the tool cacheDir
|
||||
*
|
||||
* @param sourceDir the directory to cache into tools
|
||||
* @param tool tool name
|
||||
* @param version version of the tool. semver format
|
||||
* @param arch architecture of the tool. Optional. Defaults to machine architecture
|
||||
*/
|
||||
function cacheDir(sourceDir, tool, version, arch) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
version = semver.clean(version) || version;
|
||||
arch = arch || os.arch();
|
||||
core.debug(`Caching tool ${tool} ${version} ${arch}`);
|
||||
core.debug(`source dir: ${sourceDir}`);
|
||||
if (!fs.statSync(sourceDir).isDirectory()) {
|
||||
throw new Error('sourceDir is not a directory');
|
||||
}
|
||||
// Create the tool dir
|
||||
const destPath = yield _createToolPath(tool, version, arch);
|
||||
// copy each child item. do not move. move can fail on Windows
|
||||
// due to anti-virus software having an open handle on a file.
|
||||
for (const itemName of fs.readdirSync(sourceDir)) {
|
||||
const s = path.join(sourceDir, itemName);
|
||||
shell.cp('-R', s, destPath);
|
||||
}
|
||||
// write .complete
|
||||
_completeToolPath(tool, version, arch);
|
||||
return destPath;
|
||||
});
|
||||
}
|
||||
exports.cacheDir = cacheDir;
|
||||
/**
|
||||
* Caches a downloaded file (GUID) and installs it
|
||||
* into the tool cache with a given targetName
|
||||
*
|
||||
* @param sourceFile the file to cache into tools. Typically a result of downloadTool which is a guid.
|
||||
* @param targetFile the name of the file name in the tools directory
|
||||
* @param tool tool name
|
||||
* @param version version of the tool. semver format
|
||||
* @param arch architecture of the tool. Optional. Defaults to machine architecture
|
||||
*/
|
||||
function cacheFile(sourceFile, targetFile, tool, version, arch) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
version = semver.clean(version) || version;
|
||||
arch = arch || os.arch();
|
||||
core.debug(`Caching tool ${tool} ${version} ${arch}`);
|
||||
core.debug(`source file: ${sourceFile}`);
|
||||
if (!fs.statSync(sourceFile).isFile()) {
|
||||
throw new Error('sourceFile is not a file');
|
||||
}
|
||||
// create the tool dir
|
||||
const destFolder = yield _createToolPath(tool, version, arch);
|
||||
// copy instead of move. move can fail on Windows due to
|
||||
// anti-virus software having an open handle on a file.
|
||||
const destPath = path.join(destFolder, targetFile);
|
||||
core.debug(`destination file ${destPath}`);
|
||||
yield io.cp(sourceFile, destPath);
|
||||
// write .complete
|
||||
_completeToolPath(tool, version, arch);
|
||||
return destFolder;
|
||||
});
|
||||
}
|
||||
exports.cacheFile = cacheFile;
|
||||
/**
|
||||
* Finds the path to a tool version in the local installed tool cache
|
||||
*
|
||||
* @param toolName name of the tool
|
||||
* @param versionSpec version of the tool
|
||||
* @param arch optional arch. defaults to arch of computer
|
||||
*/
|
||||
function find(toolName, versionSpec, arch) {
|
||||
if (!toolName) {
|
||||
throw new Error('toolName parameter is required');
|
||||
}
|
||||
if (!versionSpec) {
|
||||
throw new Error('versionSpec parameter is required');
|
||||
}
|
||||
arch = arch || os.arch();
|
||||
// attempt to resolve an explicit version
|
||||
if (!_isExplicitVersion(versionSpec)) {
|
||||
const localVersions = findAllVersions(toolName, arch);
|
||||
const match = _evaluateVersions(localVersions, versionSpec);
|
||||
versionSpec = match;
|
||||
}
|
||||
// check for the explicit version in the cache
|
||||
let toolPath = '';
|
||||
if (versionSpec) {
|
||||
versionSpec = semver.clean(versionSpec) || '';
|
||||
const cachePath = path.join(cacheRoot, toolName, versionSpec, arch);
|
||||
core.debug(`checking cache: ${cachePath}`);
|
||||
if (fs.existsSync(cachePath) && fs.existsSync(`${cachePath}.complete`)) {
|
||||
core.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch}`);
|
||||
toolPath = cachePath;
|
||||
}
|
||||
else {
|
||||
core.debug('not found');
|
||||
}
|
||||
}
|
||||
return toolPath;
|
||||
}
|
||||
exports.find = find;
|
||||
/**
|
||||
* Finds the paths to all versions of a tool that are installed in the local tool cache
|
||||
*
|
||||
* @param toolName name of the tool
|
||||
* @param arch optional arch. defaults to arch of computer
|
||||
*/
|
||||
function findAllVersions(toolName, arch) {
|
||||
const versions = [];
|
||||
arch = arch || os.arch();
|
||||
const toolPath = path.join(cacheRoot, toolName);
|
||||
if (fs.existsSync(toolPath)) {
|
||||
const children = fs.readdirSync(toolPath);
|
||||
for (const child of children) {
|
||||
if (_isExplicitVersion(child)) {
|
||||
const fullPath = path.join(toolPath, child, arch || '');
|
||||
if (fs.existsSync(fullPath) && fs.existsSync(`${fullPath}.complete`)) {
|
||||
versions.push(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return versions;
|
||||
}
|
||||
exports.findAllVersions = findAllVersions;
|
||||
function _createExtractFolder(dest) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (!dest) {
|
||||
// create a temp dir
|
||||
dest = path.join(tempDirectory, uuidV4());
|
||||
}
|
||||
yield io.mkdirP(dest);
|
||||
return dest;
|
||||
});
|
||||
}
|
||||
function _createToolPath(tool, version, arch) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const folderPath = path.join(cacheRoot, tool, semver.clean(version) || version, arch || '');
|
||||
core.debug(`destination ${folderPath}`);
|
||||
const markerPath = `${folderPath}.complete`;
|
||||
yield io.rmRF(folderPath);
|
||||
yield io.rmRF(markerPath);
|
||||
yield io.mkdirP(folderPath);
|
||||
return folderPath;
|
||||
});
|
||||
}
|
||||
function _completeToolPath(tool, version, arch) {
|
||||
const folderPath = path.join(cacheRoot, tool, semver.clean(version) || version, arch || '');
|
||||
const markerPath = `${folderPath}.complete`;
|
||||
fs.writeFileSync(markerPath, '');
|
||||
core.debug('finished caching tool');
|
||||
}
|
||||
function _isExplicitVersion(versionSpec) {
|
||||
const c = semver.clean(versionSpec) || '';
|
||||
core.debug(`isExplicit: ${c}`);
|
||||
const valid = semver.valid(c) != null;
|
||||
core.debug(`explicit? ${valid}`);
|
||||
return valid;
|
||||
}
|
||||
function _evaluateVersions(versions, versionSpec) {
|
||||
let version = '';
|
||||
core.debug(`evaluating ${versions.length} versions`);
|
||||
versions = versions.sort((a, b) => {
|
||||
if (semver.gt(a, b)) {
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
});
|
||||
for (let i = versions.length - 1; i >= 0; i--) {
|
||||
const potential = versions[i];
|
||||
const satisfied = semver.satisfies(potential, versionSpec);
|
||||
if (satisfied) {
|
||||
version = potential;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (version) {
|
||||
core.debug(`matched: ${version}`);
|
||||
}
|
||||
else {
|
||||
core.debug('match not found');
|
||||
}
|
||||
return version;
|
||||
}
|
||||
//# sourceMappingURL=tool-cache.js.map
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const core = require("@actions/core");
|
||||
const io = require("@actions/io");
|
||||
const fs = require("fs");
|
||||
const os = require("os");
|
||||
const path = require("path");
|
||||
const httpm = require("typed-rest-client/HttpClient");
|
||||
const semver = require("semver");
|
||||
const shell = require("shelljs");
|
||||
const uuidV4 = require("uuid/v4");
|
||||
const exec_1 = require("@actions/exec/lib/exec");
|
||||
const assert_1 = require("assert");
|
||||
class HTTPError extends Error {
|
||||
constructor(httpStatusCode) {
|
||||
super(`Unexpected HTTP response: ${httpStatusCode}`);
|
||||
this.httpStatusCode = httpStatusCode;
|
||||
Object.setPrototypeOf(this, new.target.prototype);
|
||||
}
|
||||
}
|
||||
exports.HTTPError = HTTPError;
|
||||
const IS_WINDOWS = process.platform === 'win32';
|
||||
const userAgent = 'actions/tool-cache';
|
||||
// On load grab temp directory and cache directory and remove them from env (currently don't want to expose this)
|
||||
let tempDirectory = process.env['RUNNER_TEMP'] || '';
|
||||
let cacheRoot = process.env['RUNNER_TOOL_CACHE'] || '';
|
||||
// If directories not found, place them in common temp locations
|
||||
if (!tempDirectory || !cacheRoot) {
|
||||
let baseLocation;
|
||||
if (IS_WINDOWS) {
|
||||
// On windows use the USERPROFILE env variable
|
||||
baseLocation = process.env['USERPROFILE'] || 'C:\\';
|
||||
}
|
||||
else {
|
||||
if (process.platform === 'darwin') {
|
||||
baseLocation = '/Users';
|
||||
}
|
||||
else {
|
||||
baseLocation = '/home';
|
||||
}
|
||||
}
|
||||
if (!tempDirectory) {
|
||||
tempDirectory = path.join(baseLocation, 'actions', 'temp');
|
||||
}
|
||||
if (!cacheRoot) {
|
||||
cacheRoot = path.join(baseLocation, 'actions', 'cache');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Download a tool from an url and stream it into a file
|
||||
*
|
||||
* @param url url of tool to download
|
||||
* @returns path to downloaded tool
|
||||
*/
|
||||
function downloadTool(url) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// Wrap in a promise so that we can resolve from within stream callbacks
|
||||
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
const http = new httpm.HttpClient(userAgent, [], {
|
||||
allowRetries: true,
|
||||
maxRetries: 3
|
||||
});
|
||||
const destPath = path.join(tempDirectory, uuidV4());
|
||||
yield io.mkdirP(tempDirectory);
|
||||
core.debug(`Downloading ${url}`);
|
||||
core.debug(`Downloading ${destPath}`);
|
||||
if (fs.existsSync(destPath)) {
|
||||
throw new Error(`Destination file path ${destPath} already exists`);
|
||||
}
|
||||
const response = yield http.get(url);
|
||||
if (response.message.statusCode !== 200) {
|
||||
const err = new HTTPError(response.message.statusCode);
|
||||
core.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`);
|
||||
throw err;
|
||||
}
|
||||
const file = fs.createWriteStream(destPath);
|
||||
file.on('open', () => __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
const stream = response.message.pipe(file);
|
||||
stream.on('close', () => {
|
||||
core.debug('download complete');
|
||||
resolve(destPath);
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
core.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`);
|
||||
reject(err);
|
||||
}
|
||||
}));
|
||||
file.on('error', err => {
|
||||
file.end();
|
||||
reject(err);
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
exports.downloadTool = downloadTool;
|
||||
/**
|
||||
* Extract a .7z file
|
||||
*
|
||||
* @param file path to the .7z file
|
||||
* @param dest destination directory. Optional.
|
||||
* @param _7zPath path to 7zr.exe. Optional, for long path support. Most .7z archives do not have this
|
||||
* problem. If your .7z archive contains very long paths, you can pass the path to 7zr.exe which will
|
||||
* gracefully handle long paths. By default 7zdec.exe is used because it is a very small program and is
|
||||
* bundled with the tool lib. However it does not support long paths. 7zr.exe is the reduced command line
|
||||
* interface, it is smaller than the full command line interface, and it does support long paths. At the
|
||||
* time of this writing, it is freely available from the LZMA SDK that is available on the 7zip website.
|
||||
* Be sure to check the current license agreement. If 7zr.exe is bundled with your action, then the path
|
||||
* to 7zr.exe can be pass to this function.
|
||||
* @returns path to the destination directory
|
||||
*/
|
||||
function extract7z(file, dest, _7zPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
assert_1.ok(IS_WINDOWS, 'extract7z() not supported on current OS');
|
||||
assert_1.ok(file, 'parameter "file" is required');
|
||||
dest = dest || (yield _createExtractFolder(dest));
|
||||
const originalCwd = process.cwd();
|
||||
process.chdir(dest);
|
||||
if (_7zPath) {
|
||||
try {
|
||||
const args = [
|
||||
'x',
|
||||
'-bb1',
|
||||
'-bd',
|
||||
'-sccUTF-8',
|
||||
file
|
||||
];
|
||||
const options = {
|
||||
silent: true
|
||||
};
|
||||
yield exec_1.exec(`"${_7zPath}"`, args, options);
|
||||
}
|
||||
finally {
|
||||
process.chdir(originalCwd);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const escapedScript = path
|
||||
.join(__dirname, '..', 'scripts', 'Invoke-7zdec.ps1')
|
||||
.replace(/'/g, "''")
|
||||
.replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines
|
||||
const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, '');
|
||||
const escapedTarget = dest.replace(/'/g, "''").replace(/"|\n|\r/g, '');
|
||||
const command = `& '${escapedScript}' -Source '${escapedFile}' -Target '${escapedTarget}'`;
|
||||
const args = [
|
||||
'-NoLogo',
|
||||
'-Sta',
|
||||
'-NoProfile',
|
||||
'-NonInteractive',
|
||||
'-ExecutionPolicy',
|
||||
'Unrestricted',
|
||||
'-Command',
|
||||
command
|
||||
];
|
||||
const options = {
|
||||
silent: true
|
||||
};
|
||||
try {
|
||||
const powershellPath = yield io.which('powershell', true);
|
||||
yield exec_1.exec(`"${powershellPath}"`, args, options);
|
||||
}
|
||||
finally {
|
||||
process.chdir(originalCwd);
|
||||
}
|
||||
}
|
||||
return dest;
|
||||
});
|
||||
}
|
||||
exports.extract7z = extract7z;
|
||||
/**
|
||||
* Extract a tar
|
||||
*
|
||||
* @param file path to the tar
|
||||
* @param dest destination directory. Optional.
|
||||
* @returns path to the destination directory
|
||||
*/
|
||||
function extractTar(file, dest) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (!file) {
|
||||
throw new Error("parameter 'file' is required");
|
||||
}
|
||||
dest = dest || (yield _createExtractFolder(dest));
|
||||
const tarPath = yield io.which('tar', true);
|
||||
yield exec_1.exec(`"${tarPath}"`, ['xzC', dest, '-f', file]);
|
||||
return dest;
|
||||
});
|
||||
}
|
||||
exports.extractTar = extractTar;
|
||||
/**
|
||||
* Extract a zip
|
||||
*
|
||||
* @param file path to the zip
|
||||
* @param dest destination directory. Optional.
|
||||
* @returns path to the destination directory
|
||||
*/
|
||||
function extractZip(file, dest) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (!file) {
|
||||
throw new Error("parameter 'file' is required");
|
||||
}
|
||||
dest = dest || (yield _createExtractFolder(dest));
|
||||
if (IS_WINDOWS) {
|
||||
yield extractZipWin(file, dest);
|
||||
}
|
||||
else {
|
||||
yield extractZipNix(file, dest);
|
||||
}
|
||||
return dest;
|
||||
});
|
||||
}
|
||||
exports.extractZip = extractZip;
|
||||
function extractZipWin(file, dest) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// build the powershell command
|
||||
const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines
|
||||
const escapedDest = dest.replace(/'/g, "''").replace(/"|\n|\r/g, '');
|
||||
const command = `$ErrorActionPreference = 'Stop' ; try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}')`;
|
||||
// run powershell
|
||||
const powershellPath = yield io.which('powershell');
|
||||
const args = [
|
||||
'-NoLogo',
|
||||
'-Sta',
|
||||
'-NoProfile',
|
||||
'-NonInteractive',
|
||||
'-ExecutionPolicy',
|
||||
'Unrestricted',
|
||||
'-Command',
|
||||
command
|
||||
];
|
||||
yield exec_1.exec(`"${powershellPath}"`, args);
|
||||
});
|
||||
}
|
||||
function extractZipNix(file, dest) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const unzipPath = path.join(__dirname, '..', 'scripts', 'externals', 'unzip');
|
||||
yield exec_1.exec(`"${unzipPath}"`, [file], { cwd: dest });
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Caches a directory and installs it into the tool cacheDir
|
||||
*
|
||||
* @param sourceDir the directory to cache into tools
|
||||
* @param tool tool name
|
||||
* @param version version of the tool. semver format
|
||||
* @param arch architecture of the tool. Optional. Defaults to machine architecture
|
||||
*/
|
||||
function cacheDir(sourceDir, tool, version, arch) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
version = semver.clean(version) || version;
|
||||
arch = arch || os.arch();
|
||||
core.debug(`Caching tool ${tool} ${version} ${arch}`);
|
||||
core.debug(`source dir: ${sourceDir}`);
|
||||
if (!fs.statSync(sourceDir).isDirectory()) {
|
||||
throw new Error('sourceDir is not a directory');
|
||||
}
|
||||
// Create the tool dir
|
||||
const destPath = yield _createToolPath(tool, version, arch);
|
||||
// copy each child item. do not move. move can fail on Windows
|
||||
// due to anti-virus software having an open handle on a file.
|
||||
for (const itemName of fs.readdirSync(sourceDir)) {
|
||||
const s = path.join(sourceDir, itemName);
|
||||
shell.cp('-R', s, destPath);
|
||||
}
|
||||
// write .complete
|
||||
_completeToolPath(tool, version, arch);
|
||||
return destPath;
|
||||
});
|
||||
}
|
||||
exports.cacheDir = cacheDir;
|
||||
/**
|
||||
* Caches a downloaded file (GUID) and installs it
|
||||
* into the tool cache with a given targetName
|
||||
*
|
||||
* @param sourceFile the file to cache into tools. Typically a result of downloadTool which is a guid.
|
||||
* @param targetFile the name of the file name in the tools directory
|
||||
* @param tool tool name
|
||||
* @param version version of the tool. semver format
|
||||
* @param arch architecture of the tool. Optional. Defaults to machine architecture
|
||||
*/
|
||||
function cacheFile(sourceFile, targetFile, tool, version, arch) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
version = semver.clean(version) || version;
|
||||
arch = arch || os.arch();
|
||||
core.debug(`Caching tool ${tool} ${version} ${arch}`);
|
||||
core.debug(`source file: ${sourceFile}`);
|
||||
if (!fs.statSync(sourceFile).isFile()) {
|
||||
throw new Error('sourceFile is not a file');
|
||||
}
|
||||
// create the tool dir
|
||||
const destFolder = yield _createToolPath(tool, version, arch);
|
||||
// copy instead of move. move can fail on Windows due to
|
||||
// anti-virus software having an open handle on a file.
|
||||
const destPath = path.join(destFolder, targetFile);
|
||||
core.debug(`destination file ${destPath}`);
|
||||
yield io.cp(sourceFile, destPath);
|
||||
// write .complete
|
||||
_completeToolPath(tool, version, arch);
|
||||
return destFolder;
|
||||
});
|
||||
}
|
||||
exports.cacheFile = cacheFile;
|
||||
/**
|
||||
* Finds the path to a tool version in the local installed tool cache
|
||||
*
|
||||
* @param toolName name of the tool
|
||||
* @param versionSpec version of the tool
|
||||
* @param arch optional arch. defaults to arch of computer
|
||||
*/
|
||||
function find(toolName, versionSpec, arch) {
|
||||
if (!toolName) {
|
||||
throw new Error('toolName parameter is required');
|
||||
}
|
||||
if (!versionSpec) {
|
||||
throw new Error('versionSpec parameter is required');
|
||||
}
|
||||
arch = arch || os.arch();
|
||||
// attempt to resolve an explicit version
|
||||
if (!_isExplicitVersion(versionSpec)) {
|
||||
const localVersions = findAllVersions(toolName, arch);
|
||||
const match = _evaluateVersions(localVersions, versionSpec);
|
||||
versionSpec = match;
|
||||
}
|
||||
// check for the explicit version in the cache
|
||||
let toolPath = '';
|
||||
if (versionSpec) {
|
||||
versionSpec = semver.clean(versionSpec) || '';
|
||||
const cachePath = path.join(cacheRoot, toolName, versionSpec, arch);
|
||||
core.debug(`checking cache: ${cachePath}`);
|
||||
if (fs.existsSync(cachePath) && fs.existsSync(`${cachePath}.complete`)) {
|
||||
core.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch}`);
|
||||
toolPath = cachePath;
|
||||
}
|
||||
else {
|
||||
core.debug('not found');
|
||||
}
|
||||
}
|
||||
return toolPath;
|
||||
}
|
||||
exports.find = find;
|
||||
/**
|
||||
* Finds the paths to all versions of a tool that are installed in the local tool cache
|
||||
*
|
||||
* @param toolName name of the tool
|
||||
* @param arch optional arch. defaults to arch of computer
|
||||
*/
|
||||
function findAllVersions(toolName, arch) {
|
||||
const versions = [];
|
||||
arch = arch || os.arch();
|
||||
const toolPath = path.join(cacheRoot, toolName);
|
||||
if (fs.existsSync(toolPath)) {
|
||||
const children = fs.readdirSync(toolPath);
|
||||
for (const child of children) {
|
||||
if (_isExplicitVersion(child)) {
|
||||
const fullPath = path.join(toolPath, child, arch || '');
|
||||
if (fs.existsSync(fullPath) && fs.existsSync(`${fullPath}.complete`)) {
|
||||
versions.push(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return versions;
|
||||
}
|
||||
exports.findAllVersions = findAllVersions;
|
||||
function _createExtractFolder(dest) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (!dest) {
|
||||
// create a temp dir
|
||||
dest = path.join(tempDirectory, uuidV4());
|
||||
}
|
||||
yield io.mkdirP(dest);
|
||||
return dest;
|
||||
});
|
||||
}
|
||||
function _createToolPath(tool, version, arch) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const folderPath = path.join(cacheRoot, tool, semver.clean(version) || version, arch || '');
|
||||
core.debug(`destination ${folderPath}`);
|
||||
const markerPath = `${folderPath}.complete`;
|
||||
yield io.rmRF(folderPath);
|
||||
yield io.rmRF(markerPath);
|
||||
yield io.mkdirP(folderPath);
|
||||
return folderPath;
|
||||
});
|
||||
}
|
||||
function _completeToolPath(tool, version, arch) {
|
||||
const folderPath = path.join(cacheRoot, tool, semver.clean(version) || version, arch || '');
|
||||
const markerPath = `${folderPath}.complete`;
|
||||
fs.writeFileSync(markerPath, '');
|
||||
core.debug('finished caching tool');
|
||||
}
|
||||
function _isExplicitVersion(versionSpec) {
|
||||
const c = semver.clean(versionSpec) || '';
|
||||
core.debug(`isExplicit: ${c}`);
|
||||
const valid = semver.valid(c) != null;
|
||||
core.debug(`explicit? ${valid}`);
|
||||
return valid;
|
||||
}
|
||||
function _evaluateVersions(versions, versionSpec) {
|
||||
let version = '';
|
||||
core.debug(`evaluating ${versions.length} versions`);
|
||||
versions = versions.sort((a, b) => {
|
||||
if (semver.gt(a, b)) {
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
});
|
||||
for (let i = versions.length - 1; i >= 0; i--) {
|
||||
const potential = versions[i];
|
||||
const satisfied = semver.satisfies(potential, versionSpec);
|
||||
if (satisfied) {
|
||||
version = potential;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (version) {
|
||||
core.debug(`matched: ${version}`);
|
||||
}
|
||||
else {
|
||||
core.debug('match not found');
|
||||
}
|
||||
return version;
|
||||
}
|
||||
//# sourceMappingURL=tool-cache.js.map
|
||||
|
|
|
@ -1,60 +1,60 @@
|
|||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Source,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Target)
|
||||
|
||||
# This script translates the output from 7zdec into UTF8. Node has limited
|
||||
# built-in support for encodings.
|
||||
#
|
||||
# 7zdec uses the system default code page. The system default code page varies
|
||||
# depending on the locale configuration. On an en-US box, the system default code
|
||||
# page is Windows-1252.
|
||||
#
|
||||
# Note, on a typical en-US box, testing with the 'ç' character is a good way to
|
||||
# determine whether data is passed correctly between processes. This is because
|
||||
# the 'ç' character has a different code point across each of the common encodings
|
||||
# on a typical en-US box, i.e.
|
||||
# 1) the default console-output code page (IBM437)
|
||||
# 2) the system default code page (i.e. CP_ACP) (Windows-1252)
|
||||
# 3) UTF8
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
# Redefine the wrapper over STDOUT to use UTF8. Node expects UTF8 by default.
|
||||
$stdout = [System.Console]::OpenStandardOutput()
|
||||
$utf8 = New-Object System.Text.UTF8Encoding($false) # do not emit BOM
|
||||
$writer = New-Object System.IO.StreamWriter($stdout, $utf8)
|
||||
[System.Console]::SetOut($writer)
|
||||
|
||||
# All subsequent output must be written using [System.Console]::WriteLine(). In
|
||||
# PowerShell 4, Write-Host and Out-Default do not consider the updated stream writer.
|
||||
|
||||
Set-Location -LiteralPath $Target
|
||||
|
||||
# Print the ##command.
|
||||
$_7zdec = Join-Path -Path "$PSScriptRoot" -ChildPath "externals/7zdec.exe"
|
||||
[System.Console]::WriteLine("##[command]$_7zdec x `"$Source`"")
|
||||
|
||||
# The $OutputEncoding variable instructs PowerShell how to interpret the output
|
||||
# from the external command.
|
||||
$OutputEncoding = [System.Text.Encoding]::Default
|
||||
|
||||
# Note, the output from 7zdec.exe needs to be iterated over. Otherwise PowerShell.exe
|
||||
# will launch the external command in such a way that it inherits the streams.
|
||||
& $_7zdec x $Source 2>&1 |
|
||||
ForEach-Object {
|
||||
if ($_ -is [System.Management.Automation.ErrorRecord]) {
|
||||
[System.Console]::WriteLine($_.Exception.Message)
|
||||
}
|
||||
else {
|
||||
[System.Console]::WriteLine($_)
|
||||
}
|
||||
}
|
||||
[System.Console]::WriteLine("##[debug]7zdec.exe exit code '$LASTEXITCODE'")
|
||||
[System.Console]::Out.Flush()
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
exit $LASTEXITCODE
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Source,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Target)
|
||||
|
||||
# This script translates the output from 7zdec into UTF8. Node has limited
|
||||
# built-in support for encodings.
|
||||
#
|
||||
# 7zdec uses the system default code page. The system default code page varies
|
||||
# depending on the locale configuration. On an en-US box, the system default code
|
||||
# page is Windows-1252.
|
||||
#
|
||||
# Note, on a typical en-US box, testing with the 'ç' character is a good way to
|
||||
# determine whether data is passed correctly between processes. This is because
|
||||
# the 'ç' character has a different code point across each of the common encodings
|
||||
# on a typical en-US box, i.e.
|
||||
# 1) the default console-output code page (IBM437)
|
||||
# 2) the system default code page (i.e. CP_ACP) (Windows-1252)
|
||||
# 3) UTF8
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
# Redefine the wrapper over STDOUT to use UTF8. Node expects UTF8 by default.
|
||||
$stdout = [System.Console]::OpenStandardOutput()
|
||||
$utf8 = New-Object System.Text.UTF8Encoding($false) # do not emit BOM
|
||||
$writer = New-Object System.IO.StreamWriter($stdout, $utf8)
|
||||
[System.Console]::SetOut($writer)
|
||||
|
||||
# All subsequent output must be written using [System.Console]::WriteLine(). In
|
||||
# PowerShell 4, Write-Host and Out-Default do not consider the updated stream writer.
|
||||
|
||||
Set-Location -LiteralPath $Target
|
||||
|
||||
# Print the ##command.
|
||||
$_7zdec = Join-Path -Path "$PSScriptRoot" -ChildPath "externals/7zdec.exe"
|
||||
[System.Console]::WriteLine("##[command]$_7zdec x `"$Source`"")
|
||||
|
||||
# The $OutputEncoding variable instructs PowerShell how to interpret the output
|
||||
# from the external command.
|
||||
$OutputEncoding = [System.Text.Encoding]::Default
|
||||
|
||||
# Note, the output from 7zdec.exe needs to be iterated over. Otherwise PowerShell.exe
|
||||
# will launch the external command in such a way that it inherits the streams.
|
||||
& $_7zdec x $Source 2>&1 |
|
||||
ForEach-Object {
|
||||
if ($_ -is [System.Management.Automation.ErrorRecord]) {
|
||||
[System.Console]::WriteLine($_.Exception.Message)
|
||||
}
|
||||
else {
|
||||
[System.Console]::WriteLine($_)
|
||||
}
|
||||
}
|
||||
[System.Console]::WriteLine("##[debug]7zdec.exe exit code '$LASTEXITCODE'")
|
||||
[System.Console]::Out.Flush()
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
exit $LASTEXITCODE
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License
|
||||
|
||||
Copyright (c) 2018 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.
|
|
@ -0,0 +1,421 @@
|
|||
# endpoint.js
|
||||
|
||||
> Turns GitHub REST API endpoints into generic request options
|
||||
|
||||
[![@latest](https://img.shields.io/npm/v/@octokit/endpoint.svg)](https://www.npmjs.com/package/@octokit/endpoint)
|
||||
[![Build Status](https://travis-ci.org/octokit/endpoint.js.svg?branch=master)](https://travis-ci.org/octokit/endpoint.js)
|
||||
[![Greenkeeper](https://badges.greenkeeper.io/octokit/endpoint.js.svg)](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)
|
||||
- [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)
|
||||
- [LICENSE](#license)
|
||||
|
||||
<!-- tocstop -->
|
||||
|
||||
## Usage
|
||||
|
||||
<table>
|
||||
<tbody valign=top align=left>
|
||||
<tr><th>
|
||||
Browsers
|
||||
</th><td width=100%>
|
||||
Load <code>@octokit/endpoint</code> directly from <a href="https://cdn.pika.dev">cdn.pika.dev</a>
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import { endpoint } from "https://cdn.pika.dev/@octokit/endpoint";
|
||||
</script>
|
||||
```
|
||||
|
||||
</td></tr>
|
||||
<tr><th>
|
||||
Node
|
||||
</th><td>
|
||||
|
||||
Install with <code>npm install @octokit/endpoint</code>
|
||||
|
||||
```js
|
||||
const { endpoint } = require("@octokit/endpoint");
|
||||
// or: import { endpoint } from "@octokit/endpoint";
|
||||
```
|
||||
|
||||
</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
Example for [List organization repositories](https://developer.github.com/v3/repos/#list-organization-repositories)
|
||||
|
||||
```js
|
||||
const requestOptions = endpoint("GET /orgs/:org/repos", {
|
||||
headers: {
|
||||
authorization: "token 0000000000000000000000000000000000000001"
|
||||
},
|
||||
org: "octokit",
|
||||
type: "private"
|
||||
});
|
||||
```
|
||||
|
||||
The resulting `requestOptions` looks as follows
|
||||
|
||||
```json
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "https://api.github.com/orgs/octokit/repos?type=private",
|
||||
"headers": {
|
||||
"accept": "application/vnd.github.v3+json",
|
||||
"authorization": "token 0000000000000000000000000000000000000001",
|
||||
"user-agent": "octokit/endpoint.js v1.2.3"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can pass `requestOptions` to commen request libraries
|
||||
|
||||
```js
|
||||
const { url, ...options } = requestOptions;
|
||||
// using with fetch (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
|
||||
fetch(url, options);
|
||||
// using with request (https://github.com/request/request)
|
||||
request(requestOptions);
|
||||
// using with got (https://github.com/sindresorhus/got)
|
||||
got[options.method](url, options);
|
||||
// using with axios
|
||||
axios(requestOptions);
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### `endpoint(route, options)` or `endpoint(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>route</code>
|
||||
</th>
|
||||
<td>
|
||||
String
|
||||
</td>
|
||||
<td>
|
||||
If set, it has to be a string consisting of URL and the request method, e.g., <code>GET /orgs/:org</code>. If it’s set to a URL, only the method defaults to <code>GET</code>.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<code>options.method</code>
|
||||
</th>
|
||||
<td>
|
||||
String
|
||||
</td>
|
||||
<td>
|
||||
<strong>Required unless <code>route</code> is set.</strong> Any supported <a href="https://developer.github.com/v3/#http-verbs">http verb</a>. <em>Defaults to <code>GET</code></em>.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<code>options.url</code>
|
||||
</th>
|
||||
<td>
|
||||
String
|
||||
</td>
|
||||
<td>
|
||||
<strong>Required unless <code>route</code> is set.</strong> A path or full URL which may contain <code>:variable</code> or <code>{variable}</code> placeholders,
|
||||
e.g., <code>/orgs/:org/repos</code>. The <code>url</code> is parsed using <a href="https://github.com/bramstein/url-template">url-template</a>.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<code>options.baseUrl</code>
|
||||
</th>
|
||||
<td>
|
||||
String
|
||||
</td>
|
||||
<td>
|
||||
<em>Defaults to <code>https://api.github.com</code></em>.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<code>options.headers</code>
|
||||
</th>
|
||||
<td>
|
||||
Object
|
||||
</td>
|
||||
<td>
|
||||
Custom headers. Passed headers are merged with defaults:<br>
|
||||
<em><code>headers['user-agent']</code> defaults to <code>octokit-endpoint.js/1.2.3</code> (where <code>1.2.3</code> is the released version)</em>.<br>
|
||||
<em><code>headers['accept']</code> defaults to <code>application/vnd.github.v3+json</code></em>.<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<code>options.mediaType.format</code>
|
||||
</th>
|
||||
<td>
|
||||
String
|
||||
</td>
|
||||
<td>
|
||||
Media type param, such as <code>raw</code>, <code>diff</code>, or <code>text+json</code>. See <a href="https://developer.github.com/v3/media/">Media Types</a>. Setting <code>options.mediaType.format</code> will amend the <code>headers.accept</code> value.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<code>options.mediaType.previews</code>
|
||||
</th>
|
||||
<td>
|
||||
Array of Strings
|
||||
</td>
|
||||
<td>
|
||||
Name of previews, such as <code>mercy</code>, <code>symmetra</code>, or <code>scarlet-witch</code>. See <a href="https://developer.github.com/v3/previews/">API Previews</a>. If <code>options.mediaType.previews</code> was set as default, the new previews will be merged into the default ones. Setting <code>options.mediaType.previews</code> will amend the <code>headers.accept</code> value. <code>options.mediaType.previews</code> will be merged with an existing array set using <code>.defaults()</code>.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<code>options.data</code>
|
||||
</th>
|
||||
<td>
|
||||
Any
|
||||
</td>
|
||||
<td>
|
||||
Set request body directly instead of setting it to JSON based on additional parameters. See <a href="#data-parameter">"The <code>data</code> parameter"</a> below.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<code>options.request</code>
|
||||
</th>
|
||||
<td>
|
||||
Object
|
||||
</td>
|
||||
<td>
|
||||
Pass custom meta information for the request. The <code>request</code> object will be returned as is.
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
All other options will be passed depending on the `method` and `url` options.
|
||||
|
||||
1. If the option key has a placeholder in the `url`, it will be used as the replacement. For example, if the passed options are `{url: '/orgs/:org/repos', org: 'foo'}` the returned `options.url` is `https://api.github.com/orgs/foo/repos`.
|
||||
2. If the `method` is `GET` or `HEAD`, the option is passed as a query parameter.
|
||||
3. Otherwise, the parameter is passed in the request body as a JSON key.
|
||||
|
||||
**Result**
|
||||
|
||||
`endpoint()` is a synchronous method and returns an object with the following keys:
|
||||
|
||||
<table>
|
||||
<thead align=left>
|
||||
<tr>
|
||||
<th>
|
||||
key
|
||||
</th>
|
||||
<th>
|
||||
type
|
||||
</th>
|
||||
<th width=100%>
|
||||
description
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody align=left valign=top>
|
||||
<tr>
|
||||
<th><code>method</code></th>
|
||||
<td>String</td>
|
||||
<td>The http method. Always lowercase.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>url</code></th>
|
||||
<td>String</td>
|
||||
<td>The url with placeholders replaced with passed parameters.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>headers</code></th>
|
||||
<td>Object</td>
|
||||
<td>All header names are lowercased.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>body</code></th>
|
||||
<td>Any</td>
|
||||
<td>The request body if one is present. Only for <code>PATCH</code>, <code>POST</code>, <code>PUT</code>, <code>DELETE</code> requests.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>request</code></th>
|
||||
<td>Object</td>
|
||||
<td>Request meta option, it will be returned as it was passed into <code>endpoint()</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### `endpoint.defaults()`
|
||||
|
||||
Override or set default options. Example:
|
||||
|
||||
```js
|
||||
const request = require("request");
|
||||
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`
|
||||
},
|
||||
org: "my-project",
|
||||
per_page: 100
|
||||
});
|
||||
|
||||
request(myEndpoint(`GET /orgs/:org/repos`));
|
||||
```
|
||||
|
||||
You can call `.defaults()` again on the returned method, the defaults will cascade.
|
||||
|
||||
```js
|
||||
const myProjectEndpoint = endpoint.defaults({
|
||||
baseUrl: "https://github-enterprise.acme-inc.com/api/v3",
|
||||
headers: {
|
||||
"user-agent": "myApp/1.2.3"
|
||||
},
|
||||
org: "my-project"
|
||||
});
|
||||
const myProjectEndpointWithAuth = myProjectEndpoint.defaults({
|
||||
headers: {
|
||||
authorization: `token 0000000000000000000000000000000000000001`
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
`myProjectEndpointWithAuth` now defaults the `baseUrl`, `headers['user-agent']`,
|
||||
`org` and `headers['authorization']` on top of `headers['accept']` that is set
|
||||
by the global default.
|
||||
|
||||
### `endpoint.DEFAULTS`
|
||||
|
||||
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"
|
||||
});
|
||||
myEndpoint.DEFAULTS.baseUrl; // https://github-enterprise.acme-inc.com/api/v3
|
||||
```
|
||||
|
||||
### `endpoint.merge(route, options)` or `endpoint.merge(options)`
|
||||
|
||||
Get the defaulted endpoint options, but without parsing them into request options:
|
||||
|
||||
```js
|
||||
const myProjectEndpoint = endpoint.defaults({
|
||||
baseUrl: "https://github-enterprise.acme-inc.com/api/v3",
|
||||
headers: {
|
||||
"user-agent": "myApp/1.2.3"
|
||||
},
|
||||
org: "my-project"
|
||||
});
|
||||
myProjectEndpoint.merge("GET /orgs/:org/repos", {
|
||||
headers: {
|
||||
authorization: `token 0000000000000000000000000000000000000001`
|
||||
},
|
||||
org: "my-secret-project",
|
||||
type: "private"
|
||||
});
|
||||
|
||||
// {
|
||||
// baseUrl: 'https://github-enterprise.acme-inc.com/api/v3',
|
||||
// method: 'GET',
|
||||
// url: '/orgs/:org/repos',
|
||||
// headers: {
|
||||
// accept: 'application/vnd.github.v3+json',
|
||||
// authorization: `token 0000000000000000000000000000000000000001`,
|
||||
// 'user-agent': 'myApp/1.2.3'
|
||||
// },
|
||||
// org: 'my-secret-project',
|
||||
// type: 'private'
|
||||
// }
|
||||
```
|
||||
|
||||
### `endpoint.parse()`
|
||||
|
||||
Stateless method to turn endpoint options into request options. Calling
|
||||
`endpoint(options)` is the same as calling `endpoint.parse(endpoint.merge(options))`.
|
||||
|
||||
## Special cases
|
||||
|
||||
<a name="data-parameter"></a>
|
||||
|
||||
### The `data` parameter – set request body directly
|
||||
|
||||
Some endpoints such as [Render a Markdown document in raw mode](https://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode) don’t have parameters that are sent as request body keys, instead, the request body needs to be set directly. In these cases, set the `data` parameter.
|
||||
|
||||
```js
|
||||
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"
|
||||
}
|
||||
});
|
||||
|
||||
// options is
|
||||
// {
|
||||
// method: 'post',
|
||||
// url: 'https://api.github.com/markdown/raw',
|
||||
// headers: {
|
||||
// accept: 'text/html;charset=utf-8',
|
||||
// 'content-type': 'text/plain',
|
||||
// 'user-agent': userAgent
|
||||
// },
|
||||
// body: 'Hello world github/linguist#1 **cool**, and #1!'
|
||||
// }
|
||||
```
|
||||
|
||||
### Set parameters for both the URL/query and the request body
|
||||
|
||||
There are API endpoints that accept both query parameters as well as a body. In that case, you need to add the query parameters as templates to `options.url`, as defined in the [RFC 6570 URI Template specification](https://tools.ietf.org/html/rfc6570).
|
||||
|
||||
Example
|
||||
|
||||
```js
|
||||
endpoint(
|
||||
"POST https://uploads.github.com/repos/octocat/Hello-World/releases/1/assets{?name,label}",
|
||||
{
|
||||
name: "example.zip",
|
||||
label: "short description",
|
||||
headers: {
|
||||
"content-type": "text/plain",
|
||||
"content-length": 14,
|
||||
authorization: `token 0000000000000000000000000000000000000001`
|
||||
},
|
||||
data: "Hello, world!"
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
## LICENSE
|
||||
|
||||
[MIT](LICENSE)
|
|
@ -0,0 +1,197 @@
|
|||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
||||
|
||||
var deepmerge = _interopDefault(require('deepmerge'));
|
||||
var isPlainObject = _interopDefault(require('is-plain-object'));
|
||||
var urlTemplate = _interopDefault(require('url-template'));
|
||||
var getUserAgent = _interopDefault(require('universal-user-agent'));
|
||||
|
||||
function lowercaseKeys(object) {
|
||||
if (!object) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return Object.keys(object).reduce((newObj, key) => {
|
||||
newObj[key.toLowerCase()] = object[key];
|
||||
return newObj;
|
||||
}, {});
|
||||
}
|
||||
|
||||
function merge(defaults, route, options) {
|
||||
if (typeof route === "string") {
|
||||
let [method, url] = route.split(" ");
|
||||
options = Object.assign(url ? {
|
||||
method,
|
||||
url
|
||||
} : {
|
||||
url: method
|
||||
}, options);
|
||||
} else {
|
||||
options = route || {};
|
||||
} // lowercase header names before merging with defaults to avoid duplicates
|
||||
|
||||
|
||||
options.headers = lowercaseKeys(options.headers);
|
||||
const mergedOptions = deepmerge.all([defaults, options].filter(Boolean), {
|
||||
isMergeableObject: isPlainObject
|
||||
}); // 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)).concat(mergedOptions.mediaType.previews);
|
||||
}
|
||||
|
||||
mergedOptions.mediaType.previews = mergedOptions.mediaType.previews.map(preview => preview.replace(/-preview/, ""));
|
||||
return mergedOptions;
|
||||
}
|
||||
|
||||
function addQueryParameters(url, parameters) {
|
||||
const separator = /\?/.test(url) ? "&" : "?";
|
||||
const names = Object.keys(parameters);
|
||||
|
||||
if (names.length === 0) {
|
||||
return url;
|
||||
}
|
||||
|
||||
return url + separator + names.map(name => {
|
||||
if (name === "q") {
|
||||
return "q=" + parameters.q.split("+").map(encodeURIComponent).join("+");
|
||||
}
|
||||
|
||||
return `${name}=${encodeURIComponent(parameters[name])}`;
|
||||
}).join("&");
|
||||
}
|
||||
|
||||
const urlVariableRegex = /\{[^}]+\}/g;
|
||||
|
||||
function removeNonChars(variableName) {
|
||||
return variableName.replace(/^\W+|\W+$/g, "").split(/,/);
|
||||
}
|
||||
|
||||
function extractUrlVariableNames(url) {
|
||||
const matches = url.match(urlVariableRegex);
|
||||
|
||||
if (!matches) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return matches.map(removeNonChars).reduce((a, b) => a.concat(b), []);
|
||||
}
|
||||
|
||||
function omit(object, keysToOmit) {
|
||||
return Object.keys(object).filter(option => !keysToOmit.includes(option)).reduce((obj, key) => {
|
||||
obj[key] = object[key];
|
||||
return obj;
|
||||
}, {});
|
||||
}
|
||||
|
||||
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 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
|
||||
|
||||
const urlVariableNames = extractUrlVariableNames(url);
|
||||
url = urlTemplate.parse(url).expand(parameters);
|
||||
|
||||
if (!/^http/.test(url)) {
|
||||
url = options.baseUrl + url;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (!isBinaryRequset) {
|
||||
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(",");
|
||||
}
|
||||
|
||||
if (options.mediaType.previews.length) {
|
||||
const previewsFromAcceptHeader = headers.accept.match(/[\w-]+(?=-preview)/g) || [];
|
||||
headers.accept = previewsFromAcceptHeader.concat(options.mediaType.previews).map(preview => {
|
||||
const format = options.mediaType.format ? `.${options.mediaType.format}` : "+json";
|
||||
return `application/vnd.github.${preview}-preview${format}`;
|
||||
}).join(",");
|
||||
}
|
||||
} // for GET/HEAD requests, set URL query parameters from remaining parameters
|
||||
// for PATCH/POST/PUT/DELETE requests, set request body from remaining parameters
|
||||
|
||||
|
||||
if (["GET", "HEAD"].includes(method)) {
|
||||
url = addQueryParameters(url, remainingParameters);
|
||||
} else {
|
||||
if ("data" in remainingParameters) {
|
||||
body = remainingParameters.data;
|
||||
} else {
|
||||
if (Object.keys(remainingParameters).length) {
|
||||
body = remainingParameters;
|
||||
} else {
|
||||
headers["content-length"] = 0;
|
||||
}
|
||||
}
|
||||
} // default content-type for JSON if body is set
|
||||
|
||||
|
||||
if (!headers["content-type"] && typeof body !== "undefined") {
|
||||
headers["content-type"] = "application/json; charset=utf-8";
|
||||
} // GitHub expects 'content-length: 0' header for PUT/PATCH requests without body.
|
||||
// fetch does not allow to set `content-length` header, but we can set body to an empty string
|
||||
|
||||
|
||||
if (["PATCH", "PUT"].includes(method) && typeof body === "undefined") {
|
||||
body = "";
|
||||
} // Only return body/request keys if present
|
||||
|
||||
|
||||
return Object.assign({
|
||||
method,
|
||||
url,
|
||||
headers
|
||||
}, typeof body !== "undefined" ? {
|
||||
body
|
||||
} : null, options.request ? {
|
||||
request: options.request
|
||||
} : null);
|
||||
}
|
||||
|
||||
function endpointWithDefaults(defaults, route, options) {
|
||||
return parse(merge(defaults, route, options));
|
||||
}
|
||||
|
||||
function withDefaults(oldDefaults, newDefaults) {
|
||||
const DEFAULTS = merge(oldDefaults, newDefaults);
|
||||
const endpoint = endpointWithDefaults.bind(null, DEFAULTS);
|
||||
return Object.assign(endpoint, {
|
||||
DEFAULTS,
|
||||
defaults: withDefaults.bind(null, DEFAULTS),
|
||||
merge: merge.bind(null, DEFAULTS),
|
||||
parse
|
||||
});
|
||||
}
|
||||
|
||||
const VERSION = "0.0.0-development";
|
||||
|
||||
const userAgent = `octokit-endpoint.js/${VERSION} ${getUserAgent()}`;
|
||||
const DEFAULTS = {
|
||||
method: "GET",
|
||||
baseUrl: "https://api.github.com",
|
||||
headers: {
|
||||
accept: "application/vnd.github.v3+json",
|
||||
"user-agent": userAgent
|
||||
},
|
||||
mediaType: {
|
||||
format: "",
|
||||
previews: []
|
||||
}
|
||||
};
|
||||
|
||||
const endpoint = withDefaults(null, DEFAULTS);
|
||||
|
||||
exports.endpoint = endpoint;
|
|
@ -0,0 +1,15 @@
|
|||
import getUserAgent from "universal-user-agent";
|
||||
import { VERSION } from "./version";
|
||||
const userAgent = `octokit-endpoint.js/${VERSION} ${getUserAgent()}`;
|
||||
export const DEFAULTS = {
|
||||
method: "GET",
|
||||
baseUrl: "https://api.github.com",
|
||||
headers: {
|
||||
accept: "application/vnd.github.v3+json",
|
||||
"user-agent": userAgent
|
||||
},
|
||||
mediaType: {
|
||||
format: "",
|
||||
previews: []
|
||||
}
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
import { merge } from "./merge";
|
||||
import { parse } from "./parse";
|
||||
export function endpointWithDefaults(defaults, route, options) {
|
||||
return parse(merge(defaults, route, options));
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
import { withDefaults } from "./with-defaults";
|
||||
import { DEFAULTS } from "./defaults";
|
||||
export const endpoint = withDefaults(null, DEFAULTS);
|
|
@ -0,0 +1,25 @@
|
|||
import deepmerge from "deepmerge";
|
||||
import isPlainObject from "is-plain-object";
|
||||
import { lowercaseKeys } from "./util/lowercase-keys";
|
||||
export function merge(defaults, route, options) {
|
||||
if (typeof route === "string") {
|
||||
let [method, url] = route.split(" ");
|
||||
options = Object.assign(url ? { method, url } : { url: method }, options);
|
||||
}
|
||||
else {
|
||||
options = route || {};
|
||||
}
|
||||
// lowercase header names before merging with defaults to avoid duplicates
|
||||
options.headers = lowercaseKeys(options.headers);
|
||||
const mergedOptions = deepmerge.all([defaults, options].filter(Boolean), {
|
||||
isMergeableObject: isPlainObject
|
||||
});
|
||||
// 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))
|
||||
.concat(mergedOptions.mediaType.previews);
|
||||
}
|
||||
mergedOptions.mediaType.previews = mergedOptions.mediaType.previews.map((preview) => preview.replace(/-preview/, ""));
|
||||
return mergedOptions;
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
import urlTemplate from "url-template";
|
||||
import { addQueryParameters } from "./util/add-query-parameters";
|
||||
import { extractUrlVariableNames } from "./util/extract-url-variable-names";
|
||||
import { omit } from "./util/omit";
|
||||
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 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
|
||||
const urlVariableNames = extractUrlVariableNames(url);
|
||||
url = urlTemplate.parse(url).expand(parameters);
|
||||
if (!/^http/.test(url)) {
|
||||
url = options.baseUrl + url;
|
||||
}
|
||||
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);
|
||||
if (!isBinaryRequset) {
|
||||
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(",");
|
||||
}
|
||||
if (options.mediaType.previews.length) {
|
||||
const previewsFromAcceptHeader = headers.accept.match(/[\w-]+(?=-preview)/g) || [];
|
||||
headers.accept = previewsFromAcceptHeader
|
||||
.concat(options.mediaType.previews)
|
||||
.map(preview => {
|
||||
const format = options.mediaType.format
|
||||
? `.${options.mediaType.format}`
|
||||
: "+json";
|
||||
return `application/vnd.github.${preview}-preview${format}`;
|
||||
})
|
||||
.join(",");
|
||||
}
|
||||
}
|
||||
// for GET/HEAD requests, set URL query parameters from remaining parameters
|
||||
// for PATCH/POST/PUT/DELETE requests, set request body from remaining parameters
|
||||
if (["GET", "HEAD"].includes(method)) {
|
||||
url = addQueryParameters(url, remainingParameters);
|
||||
}
|
||||
else {
|
||||
if ("data" in remainingParameters) {
|
||||
body = remainingParameters.data;
|
||||
}
|
||||
else {
|
||||
if (Object.keys(remainingParameters).length) {
|
||||
body = remainingParameters;
|
||||
}
|
||||
else {
|
||||
headers["content-length"] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// default content-type for JSON if body is set
|
||||
if (!headers["content-type"] && typeof body !== "undefined") {
|
||||
headers["content-type"] = "application/json; charset=utf-8";
|
||||
}
|
||||
// GitHub expects 'content-length: 0' header for PUT/PATCH requests without body.
|
||||
// fetch does not allow to set `content-length` header, but we can set body to an empty string
|
||||
if (["PATCH", "PUT"].includes(method) && typeof body === "undefined") {
|
||||
body = "";
|
||||
}
|
||||
// Only return body/request keys if present
|
||||
return Object.assign({ method, url, headers }, typeof body !== "undefined" ? { body } : null, options.request ? { request: options.request } : null);
|
||||
}
|
21
node_modules/@octokit/endpoint/dist-src/util/add-query-parameters.js
generated
vendored
Normal file
21
node_modules/@octokit/endpoint/dist-src/util/add-query-parameters.js
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
export function addQueryParameters(url, parameters) {
|
||||
const separator = /\?/.test(url) ? "&" : "?";
|
||||
const names = Object.keys(parameters);
|
||||
if (names.length === 0) {
|
||||
return url;
|
||||
}
|
||||
return (url +
|
||||
separator +
|
||||
names
|
||||
.map(name => {
|
||||
if (name === "q") {
|
||||
return ("q=" +
|
||||
parameters
|
||||
.q.split("+")
|
||||
.map(encodeURIComponent)
|
||||
.join("+"));
|
||||
}
|
||||
return `${name}=${encodeURIComponent(parameters[name])}`;
|
||||
})
|
||||
.join("&"));
|
||||
}
|
11
node_modules/@octokit/endpoint/dist-src/util/extract-url-variable-names.js
generated
vendored
Normal file
11
node_modules/@octokit/endpoint/dist-src/util/extract-url-variable-names.js
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
const urlVariableRegex = /\{[^}]+\}/g;
|
||||
function removeNonChars(variableName) {
|
||||
return variableName.replace(/^\W+|\W+$/g, "").split(/,/);
|
||||
}
|
||||
export function extractUrlVariableNames(url) {
|
||||
const matches = url.match(urlVariableRegex);
|
||||
if (!matches) {
|
||||
return [];
|
||||
}
|
||||
return matches.map(removeNonChars).reduce((a, b) => a.concat(b), []);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
export function lowercaseKeys(object) {
|
||||
if (!object) {
|
||||
return {};
|
||||
}
|
||||
return Object.keys(object).reduce((newObj, key) => {
|
||||
newObj[key.toLowerCase()] = object[key];
|
||||
return newObj;
|
||||
}, {});
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
export function omit(object, keysToOmit) {
|
||||
return Object.keys(object)
|
||||
.filter(option => !keysToOmit.includes(option))
|
||||
.reduce((obj, key) => {
|
||||
obj[key] = object[key];
|
||||
return obj;
|
||||
}, {});
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export const VERSION = "0.0.0-development";
|
|
@ -0,0 +1,13 @@
|
|||
import { endpointWithDefaults } from "./endpoint-with-defaults";
|
||||
import { merge } from "./merge";
|
||||
import { parse } from "./parse";
|
||||
export function withDefaults(oldDefaults, newDefaults) {
|
||||
const DEFAULTS = merge(oldDefaults, newDefaults);
|
||||
const endpoint = endpointWithDefaults.bind(null, DEFAULTS);
|
||||
return Object.assign(endpoint, {
|
||||
DEFAULTS,
|
||||
defaults: withDefaults.bind(null, DEFAULTS),
|
||||
merge: merge.bind(null, DEFAULTS),
|
||||
parse
|
||||
});
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
import { Defaults } from "./types";
|
||||
export declare const DEFAULTS: Defaults;
|
2
node_modules/@octokit/endpoint/dist-types/endpoint-with-defaults.d.ts
generated
vendored
Normal file
2
node_modules/@octokit/endpoint/dist-types/endpoint-with-defaults.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
import { Defaults, Endpoint, RequestOptions, Route, Parameters } from "./types";
|
||||
export declare function endpointWithDefaults(defaults: Defaults, route: Route | Endpoint, options?: Parameters): RequestOptions;
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
|||
export declare const endpoint: import("./types").endpoint;
|
|
@ -0,0 +1,2 @@
|
|||
import { Defaults, Route, Parameters } from "./types";
|
||||
export declare function merge(defaults: Defaults | null, route?: Route | Parameters, options?: Parameters): Defaults;
|
|
@ -0,0 +1,2 @@
|
|||
import { Defaults, RequestOptions } from "./types";
|
||||
export declare function parse(options: Defaults): RequestOptions;
|
|
@ -0,0 +1,150 @@
|
|||
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;
|
||||
};
|
4
node_modules/@octokit/endpoint/dist-types/util/add-query-parameters.d.ts
generated
vendored
Normal file
4
node_modules/@octokit/endpoint/dist-types/util/add-query-parameters.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
export declare function addQueryParameters(url: string, parameters: {
|
||||
[x: string]: string | undefined;
|
||||
q?: string;
|
||||
}): string;
|
1
node_modules/@octokit/endpoint/dist-types/util/extract-url-variable-names.d.ts
generated
vendored
Normal file
1
node_modules/@octokit/endpoint/dist-types/util/extract-url-variable-names.d.ts
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export declare function extractUrlVariableNames(url: string): string[];
|
|
@ -0,0 +1,3 @@
|
|||
export declare function lowercaseKeys(object?: {
|
||||
[key: string]: any;
|
||||
}): {};
|
|
@ -0,0 +1,5 @@
|
|||
export declare function omit(object: {
|
||||
[key: string]: any;
|
||||
}, keysToOmit: string[]): {
|
||||
[key: string]: any;
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
export declare const VERSION = "0.0.0-development";
|
|
@ -0,0 +1,2 @@
|
|||
import { Defaults, endpoint, Parameters } from "./types";
|
||||
export declare function withDefaults(oldDefaults: Defaults | null, newDefaults: Parameters): endpoint;
|
|
@ -0,0 +1,233 @@
|
|||
import deepmerge from 'deepmerge';
|
||||
import isPlainObject from 'is-plain-object';
|
||||
import urlTemplate from 'url-template';
|
||||
import getUserAgent from 'universal-user-agent';
|
||||
|
||||
function _slicedToArray(arr, i) {
|
||||
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
|
||||
}
|
||||
|
||||
function _arrayWithHoles(arr) {
|
||||
if (Array.isArray(arr)) return arr;
|
||||
}
|
||||
|
||||
function _iterableToArrayLimit(arr, i) {
|
||||
var _arr = [];
|
||||
var _n = true;
|
||||
var _d = false;
|
||||
var _e = undefined;
|
||||
|
||||
try {
|
||||
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
|
||||
_arr.push(_s.value);
|
||||
|
||||
if (i && _arr.length === i) break;
|
||||
}
|
||||
} catch (err) {
|
||||
_d = true;
|
||||
_e = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_n && _i["return"] != null) _i["return"]();
|
||||
} finally {
|
||||
if (_d) throw _e;
|
||||
}
|
||||
}
|
||||
|
||||
return _arr;
|
||||
}
|
||||
|
||||
function _nonIterableRest() {
|
||||
throw new TypeError("Invalid attempt to destructure non-iterable instance");
|
||||
}
|
||||
|
||||
function lowercaseKeys(object) {
|
||||
if (!object) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return Object.keys(object).reduce((newObj, key) => {
|
||||
newObj[key.toLowerCase()] = object[key];
|
||||
return newObj;
|
||||
}, {});
|
||||
}
|
||||
|
||||
function merge(defaults, route, options) {
|
||||
if (typeof route === "string") {
|
||||
let _route$split = route.split(" "),
|
||||
_route$split2 = _slicedToArray(_route$split, 2),
|
||||
method = _route$split2[0],
|
||||
url = _route$split2[1];
|
||||
|
||||
options = Object.assign(url ? {
|
||||
method,
|
||||
url
|
||||
} : {
|
||||
url: method
|
||||
}, options);
|
||||
} else {
|
||||
options = route || {};
|
||||
} // lowercase header names before merging with defaults to avoid duplicates
|
||||
|
||||
|
||||
options.headers = lowercaseKeys(options.headers);
|
||||
const mergedOptions = deepmerge.all([defaults, options].filter(Boolean), {
|
||||
isMergeableObject: isPlainObject
|
||||
}); // 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)).concat(mergedOptions.mediaType.previews);
|
||||
}
|
||||
|
||||
mergedOptions.mediaType.previews = mergedOptions.mediaType.previews.map(preview => preview.replace(/-preview/, ""));
|
||||
return mergedOptions;
|
||||
}
|
||||
|
||||
function addQueryParameters(url, parameters) {
|
||||
const separator = /\?/.test(url) ? "&" : "?";
|
||||
const names = Object.keys(parameters);
|
||||
|
||||
if (names.length === 0) {
|
||||
return url;
|
||||
}
|
||||
|
||||
return url + separator + names.map(name => {
|
||||
if (name === "q") {
|
||||
return "q=" + parameters.q.split("+").map(encodeURIComponent).join("+");
|
||||
}
|
||||
|
||||
return "".concat(name, "=").concat(encodeURIComponent(parameters[name]));
|
||||
}).join("&");
|
||||
}
|
||||
|
||||
const urlVariableRegex = /\{[^}]+\}/g;
|
||||
|
||||
function removeNonChars(variableName) {
|
||||
return variableName.replace(/^\W+|\W+$/g, "").split(/,/);
|
||||
}
|
||||
|
||||
function extractUrlVariableNames(url) {
|
||||
const matches = url.match(urlVariableRegex);
|
||||
|
||||
if (!matches) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return matches.map(removeNonChars).reduce((a, b) => a.concat(b), []);
|
||||
}
|
||||
|
||||
function omit(object, keysToOmit) {
|
||||
return Object.keys(object).filter(option => !keysToOmit.includes(option)).reduce((obj, key) => {
|
||||
obj[key] = object[key];
|
||||
return obj;
|
||||
}, {});
|
||||
}
|
||||
|
||||
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 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
|
||||
|
||||
const urlVariableNames = extractUrlVariableNames(url);
|
||||
url = urlTemplate.parse(url).expand(parameters);
|
||||
|
||||
if (!/^http/.test(url)) {
|
||||
url = options.baseUrl + url;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (!isBinaryRequset) {
|
||||
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.".concat(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 => {
|
||||
const format = options.mediaType.format ? ".".concat(options.mediaType.format) : "+json";
|
||||
return "application/vnd.github.".concat(preview, "-preview").concat(format);
|
||||
}).join(",");
|
||||
}
|
||||
} // for GET/HEAD requests, set URL query parameters from remaining parameters
|
||||
// for PATCH/POST/PUT/DELETE requests, set request body from remaining parameters
|
||||
|
||||
|
||||
if (["GET", "HEAD"].includes(method)) {
|
||||
url = addQueryParameters(url, remainingParameters);
|
||||
} else {
|
||||
if ("data" in remainingParameters) {
|
||||
body = remainingParameters.data;
|
||||
} else {
|
||||
if (Object.keys(remainingParameters).length) {
|
||||
body = remainingParameters;
|
||||
} else {
|
||||
headers["content-length"] = 0;
|
||||
}
|
||||
}
|
||||
} // default content-type for JSON if body is set
|
||||
|
||||
|
||||
if (!headers["content-type"] && typeof body !== "undefined") {
|
||||
headers["content-type"] = "application/json; charset=utf-8";
|
||||
} // GitHub expects 'content-length: 0' header for PUT/PATCH requests without body.
|
||||
// fetch does not allow to set `content-length` header, but we can set body to an empty string
|
||||
|
||||
|
||||
if (["PATCH", "PUT"].includes(method) && typeof body === "undefined") {
|
||||
body = "";
|
||||
} // Only return body/request keys if present
|
||||
|
||||
|
||||
return Object.assign({
|
||||
method,
|
||||
url,
|
||||
headers
|
||||
}, typeof body !== "undefined" ? {
|
||||
body
|
||||
} : null, options.request ? {
|
||||
request: options.request
|
||||
} : null);
|
||||
}
|
||||
|
||||
function endpointWithDefaults(defaults, route, options) {
|
||||
return parse(merge(defaults, route, options));
|
||||
}
|
||||
|
||||
function withDefaults(oldDefaults, newDefaults) {
|
||||
const DEFAULTS = merge(oldDefaults, newDefaults);
|
||||
const endpoint = endpointWithDefaults.bind(null, DEFAULTS);
|
||||
return Object.assign(endpoint, {
|
||||
DEFAULTS,
|
||||
defaults: withDefaults.bind(null, DEFAULTS),
|
||||
merge: merge.bind(null, DEFAULTS),
|
||||
parse
|
||||
});
|
||||
}
|
||||
|
||||
const VERSION = "0.0.0-development";
|
||||
|
||||
const userAgent = "octokit-endpoint.js/".concat(VERSION, " ").concat(getUserAgent());
|
||||
const DEFAULTS = {
|
||||
method: "GET",
|
||||
baseUrl: "https://api.github.com",
|
||||
headers: {
|
||||
accept: "application/vnd.github.v3+json",
|
||||
"user-agent": userAgent
|
||||
},
|
||||
mediaType: {
|
||||
format: "",
|
||||
previews: []
|
||||
}
|
||||
};
|
||||
|
||||
const endpoint = withDefaults(null, DEFAULTS);
|
||||
|
||||
export { endpoint };
|
21
node_modules/@octokit/endpoint/node_modules/is-plain-object/LICENSE
generated
vendored
Normal file
21
node_modules/@octokit/endpoint/node_modules/is-plain-object/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2017, Jon Schlinkert.
|
||||
|
||||
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.
|
119
node_modules/@octokit/endpoint/node_modules/is-plain-object/README.md
generated
vendored
Normal file
119
node_modules/@octokit/endpoint/node_modules/is-plain-object/README.md
generated
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
# is-plain-object [![NPM version](https://img.shields.io/npm/v/is-plain-object.svg?style=flat)](https://www.npmjs.com/package/is-plain-object) [![NPM monthly downloads](https://img.shields.io/npm/dm/is-plain-object.svg?style=flat)](https://npmjs.org/package/is-plain-object) [![NPM total downloads](https://img.shields.io/npm/dt/is-plain-object.svg?style=flat)](https://npmjs.org/package/is-plain-object) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/is-plain-object.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/is-plain-object)
|
||||
|
||||
> Returns true if an object was created by the `Object` constructor.
|
||||
|
||||
Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/):
|
||||
|
||||
```sh
|
||||
$ npm install --save is-plain-object
|
||||
```
|
||||
|
||||
Use [isobject](https://github.com/jonschlinkert/isobject) if you only want to check if the value is an object and not an array or null.
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
import isPlainObject from 'is-plain-object';
|
||||
```
|
||||
|
||||
**true** when created by the `Object` constructor.
|
||||
|
||||
```js
|
||||
isPlainObject(Object.create({}));
|
||||
//=> true
|
||||
isPlainObject(Object.create(Object.prototype));
|
||||
//=> true
|
||||
isPlainObject({foo: 'bar'});
|
||||
//=> true
|
||||
isPlainObject({});
|
||||
//=> true
|
||||
```
|
||||
|
||||
**false** when not created by the `Object` constructor.
|
||||
|
||||
```js
|
||||
isPlainObject(1);
|
||||
//=> false
|
||||
isPlainObject(['foo', 'bar']);
|
||||
//=> false
|
||||
isPlainObject([]);
|
||||
//=> false
|
||||
isPlainObject(new Foo);
|
||||
//=> false
|
||||
isPlainObject(null);
|
||||
//=> false
|
||||
isPlainObject(Object.create(null));
|
||||
//=> false
|
||||
```
|
||||
|
||||
## About
|
||||
|
||||
<details>
|
||||
<summary><strong>Contributing</strong></summary>
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Running Tests</strong></summary>
|
||||
|
||||
Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
|
||||
|
||||
```sh
|
||||
$ npm install && npm test
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Building docs</strong></summary>
|
||||
|
||||
_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
|
||||
|
||||
To generate the readme, run the following command:
|
||||
|
||||
```sh
|
||||
$ npm install -g verbose/verb#dev verb-generate-readme && verb
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Related projects
|
||||
|
||||
You might also be interested in these projects:
|
||||
|
||||
* [is-number](https://www.npmjs.com/package/is-number): Returns true if a number or string value is a finite number. Useful for regex… [more](https://github.com/jonschlinkert/is-number) | [homepage](https://github.com/jonschlinkert/is-number "Returns true if a number or string value is a finite number. Useful for regex matches, parsing, user input, etc.")
|
||||
* [isobject](https://www.npmjs.com/package/isobject): Returns true if the value is an object and not an array or null. | [homepage](https://github.com/jonschlinkert/isobject "Returns true if the value is an object and not an array or null.")
|
||||
* [kind-of](https://www.npmjs.com/package/kind-of): Get the native type of a value. | [homepage](https://github.com/jonschlinkert/kind-of "Get the native type of a value.")
|
||||
|
||||
### Contributors
|
||||
|
||||
| **Commits** | **Contributor** |
|
||||
| --- | --- |
|
||||
| 19 | [jonschlinkert](https://github.com/jonschlinkert) |
|
||||
| 6 | [TrySound](https://github.com/TrySound) |
|
||||
| 6 | [stevenvachon](https://github.com/stevenvachon) |
|
||||
| 3 | [onokumus](https://github.com/onokumus) |
|
||||
| 1 | [wtgtybhertgeghgtwtg](https://github.com/wtgtybhertgeghgtwtg) |
|
||||
|
||||
### Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
* [GitHub Profile](https://github.com/jonschlinkert)
|
||||
* [Twitter Profile](https://twitter.com/jonschlinkert)
|
||||
* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert)
|
||||
|
||||
### License
|
||||
|
||||
Copyright © 2019, [Jon Schlinkert](https://github.com/jonschlinkert).
|
||||
Released under the [MIT License](LICENSE).
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on April 28, 2019._
|
48
node_modules/@octokit/endpoint/node_modules/is-plain-object/index.cjs.js
generated
vendored
Normal file
48
node_modules/@octokit/endpoint/node_modules/is-plain-object/index.cjs.js
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
'use strict';
|
||||
|
||||
/*!
|
||||
* isobject <https://github.com/jonschlinkert/isobject>
|
||||
*
|
||||
* Copyright (c) 2014-2017, Jon Schlinkert.
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
function isObject(val) {
|
||||
return val != null && typeof val === 'object' && Array.isArray(val) === false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* is-plain-object <https://github.com/jonschlinkert/is-plain-object>
|
||||
*
|
||||
* Copyright (c) 2014-2017, Jon Schlinkert.
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
function isObjectObject(o) {
|
||||
return isObject(o) === true
|
||||
&& Object.prototype.toString.call(o) === '[object Object]';
|
||||
}
|
||||
|
||||
function isPlainObject(o) {
|
||||
var ctor,prot;
|
||||
|
||||
if (isObjectObject(o) === false) return false;
|
||||
|
||||
// If has modified constructor
|
||||
ctor = o.constructor;
|
||||
if (typeof ctor !== 'function') return false;
|
||||
|
||||
// If has modified prototype
|
||||
prot = ctor.prototype;
|
||||
if (isObjectObject(prot) === false) return false;
|
||||
|
||||
// If constructor does not have an Object-specific method
|
||||
if (prot.hasOwnProperty('isPrototypeOf') === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Most likely a plain Object
|
||||
return true;
|
||||
}
|
||||
|
||||
module.exports = isPlainObject;
|
3
node_modules/@octokit/endpoint/node_modules/is-plain-object/index.d.ts
generated
vendored
Normal file
3
node_modules/@octokit/endpoint/node_modules/is-plain-object/index.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
declare function isPlainObject(o: any): boolean;
|
||||
|
||||
export default isPlainObject;
|
35
node_modules/@octokit/endpoint/node_modules/is-plain-object/index.js
generated
vendored
Normal file
35
node_modules/@octokit/endpoint/node_modules/is-plain-object/index.js
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*!
|
||||
* is-plain-object <https://github.com/jonschlinkert/is-plain-object>
|
||||
*
|
||||
* Copyright (c) 2014-2017, Jon Schlinkert.
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
import isObject from 'isobject';
|
||||
|
||||
function isObjectObject(o) {
|
||||
return isObject(o) === true
|
||||
&& Object.prototype.toString.call(o) === '[object Object]';
|
||||
}
|
||||
|
||||
export default function isPlainObject(o) {
|
||||
var ctor,prot;
|
||||
|
||||
if (isObjectObject(o) === false) return false;
|
||||
|
||||
// If has modified constructor
|
||||
ctor = o.constructor;
|
||||
if (typeof ctor !== 'function') return false;
|
||||
|
||||
// If has modified prototype
|
||||
prot = ctor.prototype;
|
||||
if (isObjectObject(prot) === false) return false;
|
||||
|
||||
// If constructor does not have an Object-specific method
|
||||
if (prot.hasOwnProperty('isPrototypeOf') === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Most likely a plain Object
|
||||
return true;
|
||||
};
|
124
node_modules/@octokit/endpoint/node_modules/is-plain-object/package.json
generated
vendored
Normal file
124
node_modules/@octokit/endpoint/node_modules/is-plain-object/package.json
generated
vendored
Normal file
|
@ -0,0 +1,124 @@
|
|||
{
|
||||
"_from": "is-plain-object@^3.0.0",
|
||||
"_id": "is-plain-object@3.0.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==",
|
||||
"_location": "/@octokit/endpoint/is-plain-object",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "is-plain-object@^3.0.0",
|
||||
"name": "is-plain-object",
|
||||
"escapedName": "is-plain-object",
|
||||
"rawSpec": "^3.0.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^3.0.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/@octokit/endpoint"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz",
|
||||
"_shasum": "47bfc5da1b5d50d64110806c199359482e75a928",
|
||||
"_spec": "is-plain-object@^3.0.0",
|
||||
"_where": "C:\\Users\\Administrator\\Documents\\setup-node\\node_modules\\@octokit\\endpoint",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/is-plain-object/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "http://twitter.com/jonschlinkert"
|
||||
},
|
||||
{
|
||||
"name": "Osman Nuri Okumuş",
|
||||
"url": "http://onokumus.com"
|
||||
},
|
||||
{
|
||||
"name": "Steven Vachon",
|
||||
"url": "https://svachon.com"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/wtgtybhertgeghgtwtg"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"isobject": "^4.0.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Returns true if an object was created by the `Object` constructor.",
|
||||
"devDependencies": {
|
||||
"chai": "^4.2.0",
|
||||
"esm": "^3.2.22",
|
||||
"gulp-format-md": "^1.0.0",
|
||||
"mocha": "^6.1.4",
|
||||
"mocha-headless-chrome": "^2.0.2",
|
||||
"rollup": "^1.10.1",
|
||||
"rollup-plugin-node-resolve": "^4.2.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js",
|
||||
"index.cjs.js"
|
||||
],
|
||||
"homepage": "https://github.com/jonschlinkert/is-plain-object",
|
||||
"keywords": [
|
||||
"check",
|
||||
"is",
|
||||
"is-object",
|
||||
"isobject",
|
||||
"javascript",
|
||||
"kind",
|
||||
"kind-of",
|
||||
"object",
|
||||
"plain",
|
||||
"type",
|
||||
"typeof",
|
||||
"value"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.cjs.js",
|
||||
"module": "index.js",
|
||||
"name": "is-plain-object",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jonschlinkert/is-plain-object.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rollup -c",
|
||||
"prepare": "rollup -c",
|
||||
"test": "npm run test_node && npm run build && npm run test_browser",
|
||||
"test_browser": "mocha-headless-chrome --args=disable-web-security -f test/browser.html",
|
||||
"test_node": "mocha -r esm"
|
||||
},
|
||||
"types": "index.d.ts",
|
||||
"verb": {
|
||||
"toc": false,
|
||||
"layout": "default",
|
||||
"tasks": [
|
||||
"readme"
|
||||
],
|
||||
"plugins": [
|
||||
"gulp-format-md"
|
||||
],
|
||||
"related": {
|
||||
"list": [
|
||||
"is-number",
|
||||
"isobject",
|
||||
"kind-of"
|
||||
]
|
||||
},
|
||||
"lint": {
|
||||
"reflinks": true
|
||||
}
|
||||
},
|
||||
"version": "3.0.0"
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2017, Jon Schlinkert.
|
||||
|
||||
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.
|
|
@ -0,0 +1,127 @@
|
|||
# isobject [![NPM version](https://img.shields.io/npm/v/isobject.svg?style=flat)](https://www.npmjs.com/package/isobject) [![NPM monthly downloads](https://img.shields.io/npm/dm/isobject.svg?style=flat)](https://npmjs.org/package/isobject) [![NPM total downloads](https://img.shields.io/npm/dt/isobject.svg?style=flat)](https://npmjs.org/package/isobject) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/isobject.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/isobject)
|
||||
|
||||
> Returns true if the value is an object and not an array or null.
|
||||
|
||||
Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/):
|
||||
|
||||
```sh
|
||||
$ npm install --save isobject
|
||||
```
|
||||
|
||||
Use [is-plain-object](https://github.com/jonschlinkert/is-plain-object) if you want only objects that are created by the `Object` constructor.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/):
|
||||
|
||||
```sh
|
||||
$ npm install isobject
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
import isObject from 'isobject';
|
||||
```
|
||||
|
||||
**True**
|
||||
|
||||
All of the following return `true`:
|
||||
|
||||
```js
|
||||
isObject({});
|
||||
isObject(Object.create({}));
|
||||
isObject(Object.create(Object.prototype));
|
||||
isObject(Object.create(null));
|
||||
isObject({});
|
||||
isObject(new Foo);
|
||||
isObject(/foo/);
|
||||
```
|
||||
|
||||
**False**
|
||||
|
||||
All of the following return `false`:
|
||||
|
||||
```js
|
||||
isObject();
|
||||
isObject(function () {});
|
||||
isObject(1);
|
||||
isObject([]);
|
||||
isObject(undefined);
|
||||
isObject(null);
|
||||
```
|
||||
|
||||
## About
|
||||
|
||||
<details>
|
||||
<summary><strong>Contributing</strong></summary>
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Running Tests</strong></summary>
|
||||
|
||||
Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
|
||||
|
||||
```sh
|
||||
$ npm install && npm test
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Building docs</strong></summary>
|
||||
|
||||
_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
|
||||
|
||||
To generate the readme, run the following command:
|
||||
|
||||
```sh
|
||||
$ npm install -g verbose/verb#dev verb-generate-readme && verb
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Related projects
|
||||
|
||||
You might also be interested in these projects:
|
||||
|
||||
* [extend-shallow](https://www.npmjs.com/package/extend-shallow): Extend an object with the properties of additional objects. node.js/javascript util. | [homepage](https://github.com/jonschlinkert/extend-shallow "Extend an object with the properties of additional objects. node.js/javascript util.")
|
||||
* [is-plain-object](https://www.npmjs.com/package/is-plain-object): Returns true if an object was created by the `Object` constructor. | [homepage](https://github.com/jonschlinkert/is-plain-object "Returns true if an object was created by the `Object` constructor.")
|
||||
* [kind-of](https://www.npmjs.com/package/kind-of): Get the native type of a value. | [homepage](https://github.com/jonschlinkert/kind-of "Get the native type of a value.")
|
||||
* [merge-deep](https://www.npmjs.com/package/merge-deep): Recursively merge values in a javascript object. | [homepage](https://github.com/jonschlinkert/merge-deep "Recursively merge values in a javascript object.")
|
||||
|
||||
### Contributors
|
||||
|
||||
| **Commits** | **Contributor** |
|
||||
| --- | --- |
|
||||
| 30 | [jonschlinkert](https://github.com/jonschlinkert) |
|
||||
| 8 | [doowb](https://github.com/doowb) |
|
||||
| 7 | [TrySound](https://github.com/TrySound) |
|
||||
| 3 | [onokumus](https://github.com/onokumus) |
|
||||
| 1 | [LeSuisse](https://github.com/LeSuisse) |
|
||||
| 1 | [tmcw](https://github.com/tmcw) |
|
||||
| 1 | [ZhouHansen](https://github.com/ZhouHansen) |
|
||||
|
||||
### Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
* [GitHub Profile](https://github.com/jonschlinkert)
|
||||
* [Twitter Profile](https://twitter.com/jonschlinkert)
|
||||
* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert)
|
||||
|
||||
### License
|
||||
|
||||
Copyright © 2019, [Jon Schlinkert](https://github.com/jonschlinkert).
|
||||
Released under the [MIT License](LICENSE).
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on April 28, 2019._
|
|
@ -0,0 +1,14 @@
|
|||
'use strict';
|
||||
|
||||
/*!
|
||||
* isobject <https://github.com/jonschlinkert/isobject>
|
||||
*
|
||||
* Copyright (c) 2014-2017, Jon Schlinkert.
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
function isObject(val) {
|
||||
return val != null && typeof val === 'object' && Array.isArray(val) === false;
|
||||
}
|
||||
|
||||
module.exports = isObject;
|
|
@ -0,0 +1,3 @@
|
|||
declare function isObject(val: any): boolean;
|
||||
|
||||
export default isObject;
|
|
@ -0,0 +1,10 @@
|
|||
/*!
|
||||
* isobject <https://github.com/jonschlinkert/isobject>
|
||||
*
|
||||
* Copyright (c) 2014-2017, Jon Schlinkert.
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
export default function isObject(val) {
|
||||
return val != null && typeof val === 'object' && Array.isArray(val) === false;
|
||||
};
|
125
node_modules/@octokit/endpoint/node_modules/isobject/package.json
generated
vendored
Normal file
125
node_modules/@octokit/endpoint/node_modules/isobject/package.json
generated
vendored
Normal file
|
@ -0,0 +1,125 @@
|
|||
{
|
||||
"_from": "isobject@^4.0.0",
|
||||
"_id": "isobject@4.0.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==",
|
||||
"_location": "/@octokit/endpoint/isobject",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "isobject@^4.0.0",
|
||||
"name": "isobject",
|
||||
"escapedName": "isobject",
|
||||
"rawSpec": "^4.0.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^4.0.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/@octokit/endpoint/is-plain-object"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz",
|
||||
"_shasum": "3f1c9155e73b192022a80819bacd0343711697b0",
|
||||
"_spec": "isobject@^4.0.0",
|
||||
"_where": "C:\\Users\\Administrator\\Documents\\setup-node\\node_modules\\@octokit\\endpoint\\node_modules\\is-plain-object",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/isobject/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"contributors": [
|
||||
{
|
||||
"url": "https://github.com/LeSuisse"
|
||||
},
|
||||
{
|
||||
"name": "Brian Woodward",
|
||||
"url": "https://twitter.com/doowb"
|
||||
},
|
||||
{
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "http://twitter.com/jonschlinkert"
|
||||
},
|
||||
{
|
||||
"name": "Magnús Dæhlen",
|
||||
"url": "https://github.com/magnudae"
|
||||
},
|
||||
{
|
||||
"name": "Tom MacWright",
|
||||
"url": "https://macwright.org"
|
||||
}
|
||||
],
|
||||
"dependencies": {},
|
||||
"deprecated": false,
|
||||
"description": "Returns true if the value is an object and not an array or null.",
|
||||
"devDependencies": {
|
||||
"esm": "^3.2.22",
|
||||
"gulp-format-md": "^0.1.9",
|
||||
"mocha": "^2.4.5",
|
||||
"rollup": "^1.10.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.cjs.js",
|
||||
"index.js"
|
||||
],
|
||||
"homepage": "https://github.com/jonschlinkert/isobject",
|
||||
"keywords": [
|
||||
"check",
|
||||
"is",
|
||||
"is-object",
|
||||
"isobject",
|
||||
"kind",
|
||||
"kind-of",
|
||||
"kindof",
|
||||
"native",
|
||||
"object",
|
||||
"type",
|
||||
"typeof",
|
||||
"value"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.cjs.js",
|
||||
"module": "index.js",
|
||||
"name": "isobject",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jonschlinkert/isobject.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rollup -i index.js -o index.cjs.js -f cjs",
|
||||
"prepublish": "npm run build",
|
||||
"test": "mocha -r esm"
|
||||
},
|
||||
"types": "index.d.ts",
|
||||
"verb": {
|
||||
"related": {
|
||||
"list": [
|
||||
"extend-shallow",
|
||||
"is-plain-object",
|
||||
"kind-of",
|
||||
"merge-deep"
|
||||
]
|
||||
},
|
||||
"toc": false,
|
||||
"layout": "default",
|
||||
"tasks": [
|
||||
"readme"
|
||||
],
|
||||
"plugins": [
|
||||
"gulp-format-md"
|
||||
],
|
||||
"lint": {
|
||||
"reflinks": true
|
||||
},
|
||||
"reflinks": [
|
||||
"verb"
|
||||
]
|
||||
},
|
||||
"version": "4.0.0"
|
||||
}
|
35
node_modules/@octokit/endpoint/node_modules/universal-user-agent/.travis.yml
generated
vendored
Normal file
35
node_modules/@octokit/endpoint/node_modules/universal-user-agent/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
language: node_js
|
||||
cache: npm
|
||||
|
||||
# Trigger a push build on master and greenkeeper branches + PRs build on every branches
|
||||
# Avoid double build on PRs (See https://github.com/travis-ci/travis-ci/issues/1147)
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /^greenkeeper.*$/
|
||||
|
||||
stages:
|
||||
- test
|
||||
- name: release
|
||||
if: branch = master AND type IN (push)
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: test
|
||||
node_js: 12
|
||||
script: npm run test
|
||||
- node_js: 8
|
||||
script: npm run test
|
||||
- node_js: 10
|
||||
env: Node 10 & coverage upload
|
||||
script:
|
||||
- npm run test
|
||||
- npm run coverage:upload
|
||||
- node_js: lts/*
|
||||
env: browser tests
|
||||
script: npm run test:browser
|
||||
|
||||
- stage: release
|
||||
node_js: lts/*
|
||||
env: semantic-release
|
||||
script: npm run semantic-release
|
7
node_modules/@octokit/endpoint/node_modules/universal-user-agent/LICENSE.md
generated
vendored
Normal file
7
node_modules/@octokit/endpoint/node_modules/universal-user-agent/LICENSE.md
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
# [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
node_modules/@octokit/endpoint/node_modules/universal-user-agent/README.md
generated
vendored
Normal file
25
node_modules/@octokit/endpoint/node_modules/universal-user-agent/README.md
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
# universal-user-agent
|
||||
|
||||
> Get a user agent string in both browser and node
|
||||
|
||||
[![@latest](https://img.shields.io/npm/v/universal-user-agent.svg)](https://www.npmjs.com/package/universal-user-agent)
|
||||
[![Build Status](https://travis-ci.com/gr2m/universal-user-agent.svg?branch=master)](https://travis-ci.com/gr2m/universal-user-agent)
|
||||
[![Coverage Status](https://coveralls.io/repos/github/gr2m/universal-user-agent/badge.svg)](https://coveralls.io/github/gr2m/universal-user-agent)
|
||||
[![Greenkeeper](https://badges.greenkeeper.io/gr2m/universal-user-agent.svg)](https://greenkeeper.io/)
|
||||
|
||||
```js
|
||||
const getUserAgent = require('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)
|
6
node_modules/@octokit/endpoint/node_modules/universal-user-agent/browser.js
generated
vendored
Normal file
6
node_modules/@octokit/endpoint/node_modules/universal-user-agent/browser.js
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
module.exports = getUserAgentBrowser
|
||||
|
||||
function getUserAgentBrowser () {
|
||||
/* global navigator */
|
||||
return navigator.userAgent
|
||||
}
|
4
node_modules/@octokit/endpoint/node_modules/universal-user-agent/cypress.json
generated
vendored
Normal file
4
node_modules/@octokit/endpoint/node_modules/universal-user-agent/cypress.json
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"integrationFolder": "test",
|
||||
"video": false
|
||||
}
|
1
node_modules/@octokit/endpoint/node_modules/universal-user-agent/index.d.ts
generated
vendored
Normal file
1
node_modules/@octokit/endpoint/node_modules/universal-user-agent/index.d.ts
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export default function getUserAgentNode(): string;
|
15
node_modules/@octokit/endpoint/node_modules/universal-user-agent/index.js
generated
vendored
Normal file
15
node_modules/@octokit/endpoint/node_modules/universal-user-agent/index.js
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
module.exports = getUserAgentNode
|
||||
|
||||
const osName = require('os-name')
|
||||
|
||||
function getUserAgentNode () {
|
||||
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
|
||||
}
|
||||
}
|
82
node_modules/@octokit/endpoint/node_modules/universal-user-agent/package.json
generated
vendored
Normal file
82
node_modules/@octokit/endpoint/node_modules/universal-user-agent/package.json
generated
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
{
|
||||
"_from": "universal-user-agent@^3.0.0",
|
||||
"_id": "universal-user-agent@3.0.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-T3siHThqoj5X0benA5H0qcDnrKGXzU8TKoX15x/tQHw1hQBvIEBHjxQ2klizYsqBOO/Q+WuxoQUihadeeqDnoA==",
|
||||
"_location": "/@octokit/endpoint/universal-user-agent",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "universal-user-agent@^3.0.0",
|
||||
"name": "universal-user-agent",
|
||||
"escapedName": "universal-user-agent",
|
||||
"rawSpec": "^3.0.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^3.0.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/@octokit/endpoint"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-3.0.0.tgz",
|
||||
"_shasum": "4cc88d68097bffd7ac42e3b7c903e7481424b4b9",
|
||||
"_spec": "universal-user-agent@^3.0.0",
|
||||
"_where": "C:\\Users\\Administrator\\Documents\\setup-node\\node_modules\\@octokit\\endpoint",
|
||||
"author": {
|
||||
"name": "Gregor Martynus",
|
||||
"url": "https://github.com/gr2m"
|
||||
},
|
||||
"browser": "browser.js",
|
||||
"bugs": {
|
||||
"url": "https://github.com/gr2m/universal-user-agent/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"os-name": "^3.0.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Get a user agent string in both browser and node",
|
||||
"devDependencies": {
|
||||
"chai": "^4.1.2",
|
||||
"coveralls": "^3.0.2",
|
||||
"cypress": "^3.1.0",
|
||||
"mocha": "^6.0.0",
|
||||
"nyc": "^14.0.0",
|
||||
"proxyquire": "^2.1.0",
|
||||
"semantic-release": "^15.9.15",
|
||||
"sinon": "^7.2.4",
|
||||
"sinon-chai": "^3.2.0",
|
||||
"standard": "^13.0.1",
|
||||
"test": "^0.6.0",
|
||||
"travis-deploy-once": "^5.0.7"
|
||||
},
|
||||
"homepage": "https://github.com/gr2m/universal-user-agent#readme",
|
||||
"keywords": [],
|
||||
"license": "ISC",
|
||||
"main": "index.js",
|
||||
"name": "universal-user-agent",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/gr2m/universal-user-agent.git"
|
||||
},
|
||||
"scripts": {
|
||||
"coverage": "nyc report --reporter=html && open coverage/index.html",
|
||||
"coverage:upload": "nyc report --reporter=text-lcov | coveralls",
|
||||
"pretest": "standard",
|
||||
"semantic-release": "semantic-release",
|
||||
"test": "nyc mocha \"test/*-test.js\"",
|
||||
"test:browser": "cypress run --browser chrome",
|
||||
"travis-deploy-once": "travis-deploy-once"
|
||||
},
|
||||
"standard": {
|
||||
"globals": [
|
||||
"describe",
|
||||
"it",
|
||||
"beforeEach",
|
||||
"afterEach",
|
||||
"expect"
|
||||
]
|
||||
},
|
||||
"types": "index.d.ts",
|
||||
"version": "3.0.0"
|
||||
}
|
57
node_modules/@octokit/endpoint/node_modules/universal-user-agent/test/smoke-test.js
generated
vendored
Normal file
57
node_modules/@octokit/endpoint/node_modules/universal-user-agent/test/smoke-test.js
generated
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
// make tests run in both Node & Express
|
||||
if (!global.cy) {
|
||||
const chai = require('chai')
|
||||
const sinon = require('sinon')
|
||||
const sinonChai = require('sinon-chai')
|
||||
chai.use(sinonChai)
|
||||
global.expect = chai.expect
|
||||
|
||||
let sandbox
|
||||
beforeEach(() => {
|
||||
sandbox = sinon.createSandbox()
|
||||
global.cy = {
|
||||
stub: function () {
|
||||
return sandbox.stub.apply(sandbox, arguments)
|
||||
},
|
||||
log () {
|
||||
console.log.apply(console, arguments)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
sandbox.restore()
|
||||
})
|
||||
}
|
||||
|
||||
const getUserAgent = require('..')
|
||||
|
||||
describe('smoke', () => {
|
||||
it('works', () => {
|
||||
expect(getUserAgent()).to.be.a('string')
|
||||
expect(getUserAgent().length).to.be.above(10)
|
||||
})
|
||||
|
||||
if (!process.browser) { // test on node only
|
||||
const proxyquire = require('proxyquire').noCallThru()
|
||||
it('works around wmic error on Windows (#5)', () => {
|
||||
const getUserAgent = proxyquire('..', {
|
||||
'os-name': () => {
|
||||
throw new Error('Command failed: wmic os get Caption')
|
||||
}
|
||||
})
|
||||
|
||||
expect(getUserAgent()).to.equal('Windows <version undetectable>')
|
||||
})
|
||||
|
||||
it('does not swallow unexpected errors', () => {
|
||||
const getUserAgent = proxyquire('..', {
|
||||
'os-name': () => {
|
||||
throw new Error('oops')
|
||||
}
|
||||
})
|
||||
|
||||
expect(getUserAgent).to.throw('oops')
|
||||
})
|
||||
}
|
||||
})
|
|
@ -0,0 +1,88 @@
|
|||
{
|
||||
"_from": "@octokit/endpoint@^5.1.0",
|
||||
"_id": "@octokit/endpoint@5.3.2",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-gRjteEM9I6f4D8vtwU2iGUTn9RX/AJ0SVXiqBUEuYEWVGGAVjSXdT0oNmghH5lvQNWs8mwt6ZaultuG6yXivNw==",
|
||||
"_location": "/@octokit/endpoint",
|
||||
"_phantomChildren": {
|
||||
"os-name": "3.1.0"
|
||||
},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "@octokit/endpoint@^5.1.0",
|
||||
"name": "@octokit/endpoint",
|
||||
"escapedName": "@octokit%2fendpoint",
|
||||
"scope": "@octokit",
|
||||
"rawSpec": "^5.1.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^5.1.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/@octokit/request"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-5.3.2.tgz",
|
||||
"_shasum": "2deda2d869cac9ba7f370287d55667be2a808d4b",
|
||||
"_spec": "@octokit/endpoint@^5.1.0",
|
||||
"_where": "C:\\Users\\Administrator\\Documents\\setup-node\\node_modules\\@octokit\\request",
|
||||
"bugs": {
|
||||
"url": "https://github.com/octokit/endpoint.js/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"deepmerge": "4.0.0",
|
||||
"is-plain-object": "^3.0.0",
|
||||
"universal-user-agent": "^3.0.0",
|
||||
"url-template": "^2.0.8"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Turns REST API endpoints into generic request options",
|
||||
"devDependencies": {
|
||||
"@octokit/routes": "20.9.2",
|
||||
"@pika/pack": "^0.4.0",
|
||||
"@pika/plugin-build-node": "^0.4.0",
|
||||
"@pika/plugin-build-web": "^0.4.0",
|
||||
"@pika/plugin-ts-standard-pkg": "^0.4.0",
|
||||
"@types/jest": "^24.0.11",
|
||||
"@types/url-template": "^2.0.28",
|
||||
"glob": "^7.1.3",
|
||||
"handlebars": "^4.1.2",
|
||||
"jest": "^24.7.1",
|
||||
"lodash.set": "^4.3.2",
|
||||
"nyc": "^14.0.0",
|
||||
"pascal-case": "^2.0.1",
|
||||
"prettier": "1.18.2",
|
||||
"semantic-release": "^15.13.8",
|
||||
"semantic-release-plugin-update-version-in-files": "^1.0.0",
|
||||
"string-to-jsdoc-comment": "^1.0.0",
|
||||
"ts-jest": "^24.0.2",
|
||||
"typescript": "^3.4.5"
|
||||
},
|
||||
"files": [
|
||||
"dist-*/",
|
||||
"bin/"
|
||||
],
|
||||
"homepage": "https://github.com/octokit/endpoint.js#readme",
|
||||
"keywords": [
|
||||
"octokit",
|
||||
"github",
|
||||
"api",
|
||||
"rest"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "dist-node/index.js",
|
||||
"module": "dist-web/index.js",
|
||||
"name": "@octokit/endpoint",
|
||||
"pika": true,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/octokit/endpoint.js.git"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"source": "dist-src/index.js",
|
||||
"types": "dist-types/index.d.ts",
|
||||
"version": "5.3.2"
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License
|
||||
|
||||
Copyright (c) 2018 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.
|
|
@ -0,0 +1,292 @@
|
|||
# graphql.js
|
||||
|
||||
> GitHub GraphQL API client for browsers and Node
|
||||
|
||||
[![@latest](https://img.shields.io/npm/v/@octokit/graphql.svg)](https://www.npmjs.com/package/@octokit/graphql)
|
||||
[![Build Status](https://travis-ci.com/octokit/graphql.js.svg?branch=master)](https://travis-ci.com/octokit/graphql.js)
|
||||
[![Coverage Status](https://coveralls.io/repos/github/octokit/graphql.js/badge.svg)](https://coveralls.io/github/octokit/graphql.js)
|
||||
[![Greenkeeper](https://badges.greenkeeper.io/octokit/graphql.js.svg)](https://greenkeeper.io/)
|
||||
|
||||
<!-- toc -->
|
||||
|
||||
- [Usage](#usage)
|
||||
- [Errors](#errors)
|
||||
- [Writing tests](#writing-tests)
|
||||
- [License](#license)
|
||||
|
||||
<!-- tocstop -->
|
||||
|
||||
## Usage
|
||||
|
||||
Send a simple query
|
||||
|
||||
```js
|
||||
const graphql = require('@octokit/graphql')
|
||||
const { repository } = await graphql(`{
|
||||
repository(owner:"octokit", name:"graphql.js") {
|
||||
issues(last:3) {
|
||||
edges {
|
||||
node {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`, {
|
||||
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:
|
||||
|
||||
```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`
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Create two new clients and set separate default configs for them.
|
||||
|
||||
```js
|
||||
const graphql1 = require('@octokit/graphql').defaults({
|
||||
headers: {
|
||||
authorization: `token secret123`
|
||||
}
|
||||
})
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`)
|
||||
```
|
||||
|
||||
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) {
|
||||
issues(last:$num) {
|
||||
edges {
|
||||
node {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
owner: 'octokit',
|
||||
repo: 'graphql.js'
|
||||
headers: {
|
||||
authorization: `token secret123`
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Use with GitHub Enterprise
|
||||
|
||||
```js
|
||||
const graphql = require('@octokit/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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`)
|
||||
```
|
||||
|
||||
## Errors
|
||||
|
||||
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({
|
||||
headers: {
|
||||
authorization: `token secret123`
|
||||
}
|
||||
})
|
||||
const query = `{
|
||||
viewer {
|
||||
bioHtml
|
||||
}
|
||||
}`
|
||||
|
||||
try {
|
||||
const result = await graphql(query)
|
||||
} catch (error) {
|
||||
// server responds with
|
||||
// {
|
||||
// "data": null,
|
||||
// "errors": [{
|
||||
// "message": "Field 'bioHtml' doesn't exist on type 'User'",
|
||||
// "locations": [{
|
||||
// "line": 3,
|
||||
// "column": 5
|
||||
// }]
|
||||
// }]
|
||||
// }
|
||||
|
||||
console.log('Request failed:', error.request) // { query, variables: {}, headers: { authorization: 'token secret123' } }
|
||||
console.log(error.message) // Field 'bioHtml' doesn't exist on type 'User'
|
||||
}
|
||||
```
|
||||
|
||||
## Partial responses
|
||||
|
||||
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({
|
||||
headers: {
|
||||
authorization: `token secret123`
|
||||
}
|
||||
})
|
||||
const query = `{
|
||||
repository(name: "probot", owner: "probot") {
|
||||
name
|
||||
ref(qualifiedName: "master") {
|
||||
target {
|
||||
... on Commit {
|
||||
history(first: 25, after: "invalid cursor") {
|
||||
nodes {
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
try {
|
||||
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."
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
|
||||
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 } }
|
||||
}
|
||||
```
|
||||
|
||||
## Writing tests
|
||||
|
||||
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 graphql = require('@octokit/graphql')
|
||||
|
||||
graphql('{ viewer { login } }', {
|
||||
headers: {
|
||||
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: {} }
|
||||
})
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
|
@ -0,0 +1,15 @@
|
|||
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
|
||||
}
|
||||
})
|
|
@ -0,0 +1,16 @@
|
|||
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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
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
|
||||
})
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
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
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
{
|
||||
"_from": "@octokit/graphql@^2.0.1",
|
||||
"_id": "@octokit/graphql@2.1.3",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-XoXJqL2ondwdnMIW3wtqJWEwcBfKk37jO/rYkoxNPEVeLBDGsGO1TCWggrAlq3keGt/O+C/7VepXnukUxwt5vA==",
|
||||
"_location": "/@octokit/graphql",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "@octokit/graphql@^2.0.1",
|
||||
"name": "@octokit/graphql",
|
||||
"escapedName": "@octokit%2fgraphql",
|
||||
"scope": "@octokit",
|
||||
"rawSpec": "^2.0.1",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^2.0.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/@actions/github"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-2.1.3.tgz",
|
||||
"_shasum": "60c058a0ed5fa242eca6f938908d95fd1a2f4b92",
|
||||
"_spec": "@octokit/graphql@^2.0.1",
|
||||
"_where": "C:\\Users\\Administrator\\Documents\\setup-node\\toolkit\\actions-github-0.0.0.tgz",
|
||||
"author": {
|
||||
"name": "Gregor Martynus",
|
||||
"url": "https://github.com/gr2m"
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"homepage": "https://github.com/octokit/graphql.js#readme",
|
||||
"keywords": [
|
||||
"octokit",
|
||||
"github",
|
||||
"api",
|
||||
"graphql"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"name": "@octokit/graphql",
|
||||
"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"
|
||||
}
|
|
@ -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.
|
|
@ -0,0 +1,68 @@
|
|||
# http-error.js
|
||||
|
||||
> Error class for Octokit request errors
|
||||
|
||||
[![@latest](https://img.shields.io/npm/v/@octokit/request-error.svg)](https://www.npmjs.com/package/@octokit/request-error)
|
||||
[![Build Status](https://travis-ci.com/octokit/request-error.js.svg?branch=master)](https://travis-ci.com/octokit/request-error.js)
|
||||
[![Greenkeeper](https://badges.greenkeeper.io/octokit/request-error.js.svg)](https://greenkeeper.io/)
|
||||
|
||||
## Usage
|
||||
|
||||
<table>
|
||||
<tbody valign=top align=left>
|
||||
<tr><th>
|
||||
Browsers
|
||||
</th><td width=100%>
|
||||
Load <code>@octokit/request-error</code> directly from <a href="https://cdn.pika.dev">cdn.pika.dev</a>
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import { RequestError } from "https://cdn.pika.dev/@octokit/request-error";
|
||||
</script>
|
||||
```
|
||||
|
||||
</td></tr>
|
||||
<tr><th>
|
||||
Node
|
||||
</th><td>
|
||||
|
||||
Install with <code>npm install @octokit/request-error</code>
|
||||
|
||||
```js
|
||||
const { RequestError } = require("@octokit/request-error");
|
||||
// or: import { RequestError } from "@octokit/request-error";
|
||||
```
|
||||
|
||||
</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
```js
|
||||
const error = new RequestError("Oops", 500, {
|
||||
headers: {
|
||||
"x-github-request-id": "1:2:3:4"
|
||||
}, // response headers
|
||||
request: {
|
||||
method: "POST",
|
||||
url: "https://api.github.com/foo",
|
||||
body: {
|
||||
bar: "baz"
|
||||
},
|
||||
headers: {
|
||||
authorization: "token secret123"
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
error.message; // Oops
|
||||
error.status; // 500
|
||||
error.headers; // { 'x-github-request-id': '1:2:3:4' }
|
||||
error.request.method; // POST
|
||||
error.request.url; // https://api.github.com/foo
|
||||
error.request.body; // { bar: 'baz' }
|
||||
error.request.headers; // { authorization: 'token [REDACTED]' }
|
||||
```
|
||||
|
||||
## LICENSE
|
||||
|
||||
[MIT](LICENSE)
|
|
@ -0,0 +1,54 @@
|
|||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
||||
|
||||
var deprecation = require('deprecation');
|
||||
var once = _interopDefault(require('once'));
|
||||
|
||||
const logOnce = once(deprecation => console.warn(deprecation));
|
||||
/**
|
||||
* Error with extra properties to help with debugging
|
||||
*/
|
||||
|
||||
class RequestError extends Error {
|
||||
constructor(message, statusCode, options) {
|
||||
super(message); // Maintains proper stack trace (only available on V8)
|
||||
|
||||
/* istanbul ignore next */
|
||||
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, this.constructor);
|
||||
}
|
||||
|
||||
this.name = "HttpError";
|
||||
this.status = statusCode;
|
||||
Object.defineProperty(this, "code", {
|
||||
get() {
|
||||
logOnce(new deprecation.Deprecation("[@octokit/request-error] `error.code` is deprecated, use `error.status`."));
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
});
|
||||
this.headers = options.headers; // redact request credentials without mutating original request options
|
||||
|
||||
const requestCopy = Object.assign({}, options.request);
|
||||
|
||||
if (options.request.headers.authorization) {
|
||||
requestCopy.headers = Object.assign({}, options.request.headers, {
|
||||
authorization: options.request.headers.authorization.replace(/ .*$/, " [REDACTED]")
|
||||
});
|
||||
}
|
||||
|
||||
requestCopy.url = requestCopy.url // client_id & client_secret can be passed as URL query parameters to increase rate limit
|
||||
// see https://developer.github.com/v3/#increasing-the-unauthenticated-rate-limit-for-oauth-applications
|
||||
.replace(/\bclient_secret=\w+/g, "client_secret=[REDACTED]") // OAuth tokens can be passed as URL query parameters, although it is not recommended
|
||||
// see https://developer.github.com/v3/#oauth2-token-sent-in-a-header
|
||||
.replace(/\baccess_token=\w+/g, "access_token=[REDACTED]");
|
||||
this.request = requestCopy;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.RequestError = RequestError;
|
|
@ -0,0 +1,40 @@
|
|||
import { Deprecation } from "deprecation";
|
||||
import once from "once";
|
||||
const logOnce = once((deprecation) => console.warn(deprecation));
|
||||
/**
|
||||
* Error with extra properties to help with debugging
|
||||
*/
|
||||
export class RequestError extends Error {
|
||||
constructor(message, statusCode, options) {
|
||||
super(message);
|
||||
// Maintains proper stack trace (only available on V8)
|
||||
/* istanbul ignore next */
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, this.constructor);
|
||||
}
|
||||
this.name = "HttpError";
|
||||
this.status = statusCode;
|
||||
Object.defineProperty(this, "code", {
|
||||
get() {
|
||||
logOnce(new Deprecation("[@octokit/request-error] `error.code` is deprecated, use `error.status`."));
|
||||
return statusCode;
|
||||
}
|
||||
});
|
||||
this.headers = options.headers;
|
||||
// redact request credentials without mutating original request options
|
||||
const requestCopy = Object.assign({}, options.request);
|
||||
if (options.request.headers.authorization) {
|
||||
requestCopy.headers = Object.assign({}, options.request.headers, {
|
||||
authorization: options.request.headers.authorization.replace(/ .*$/, " [REDACTED]")
|
||||
});
|
||||
}
|
||||
requestCopy.url = requestCopy.url
|
||||
// client_id & client_secret can be passed as URL query parameters to increase rate limit
|
||||
// see https://developer.github.com/v3/#increasing-the-unauthenticated-rate-limit-for-oauth-applications
|
||||
.replace(/\bclient_secret=\w+/g, "client_secret=[REDACTED]")
|
||||
// OAuth tokens can be passed as URL query parameters, although it is not recommended
|
||||
// see https://developer.github.com/v3/#oauth2-token-sent-in-a-header
|
||||
.replace(/\baccess_token=\w+/g, "access_token=[REDACTED]");
|
||||
this.request = requestCopy;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import { RequestOptions, ResponseHeaders, RequestErrorOptions } from "./types";
|
||||
/**
|
||||
* Error with extra properties to help with debugging
|
||||
*/
|
||||
export declare class RequestError extends Error {
|
||||
name: "HttpError";
|
||||
/**
|
||||
* http status code
|
||||
*/
|
||||
status: number;
|
||||
/**
|
||||
* http status code
|
||||
*
|
||||
* @deprecated `error.code` is deprecated in favor of `error.status`
|
||||
*/
|
||||
code: number;
|
||||
/**
|
||||
* error response headers
|
||||
*/
|
||||
headers: ResponseHeaders;
|
||||
/**
|
||||
* Request options that lead to the error.
|
||||
*/
|
||||
request: RequestOptions;
|
||||
constructor(message: string, statusCode: number, options: RequestErrorOptions);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue