Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for custom HTTP(S) agents #107

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Type definitions for wait-on 5.3
// Project: https://github.com/jeffbski/wait-on#readme
// Definitions by: Ifiok Jr. <https://github.com/ifiokjr>
// Andrew Leedham <https://github.com/AndrewLeedham>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped

/// <reference types="node" />

import { Agent } from "http";
import { SecureContextOptions } from "tls";
export = waitOn;

declare function waitOn(options: waitOn.WaitOnOptions): Promise<void>;
declare function waitOn(options: waitOn.WaitOnOptions, cb: (err: any) => void): void;

declare namespace waitOn {
interface WaitOnOptions extends SecureContextOptions {
/**
* Array of string resources to wait for. prefix determines the type of resource with the default type of file:
*/
resources: string[];
/**
* Initial delay in ms.
* @default 0
*/
delay?: number | undefined;
/**
* Poll resource interval in ms,
* @default 250ms
*/
interval?: number | undefined;
/**
* Flag which outputs to stdout, remaining resources waited on and when complete or any error occurs.
*/
log?: boolean | undefined;
/**
* Flag to reverse operation so checks are for resources being NOT available.
* @default false
*/
reverse?: boolean | undefined;
/**
* Timeout in ms until it aborts with error.
* @default Infinity
*/
timeout?: number | undefined;
/**
* http HEAD/GET timeout to wait for request
* @default 0
*/
httpTimeout?: number | undefined;
/**
* Tcp timeout in ms.
* @default 300
*/
tcpTimeout?: number | undefined;
/**
* Flag which outputs debug output.
* @default false
*/
verbose?: boolean | undefined;
/**
* Stabilization time in ms
* Waits this amount of time for file sizes to stabilize or other resource availability to remain unchanged.
* @default 750ms.
*/
window?: number | undefined;
/**
* Limit of concurrent connections to a resource
* @default Infinity
*/
simultaneous?: number | undefined;
/**
* Https specific option.
* see https://github.com/request/request#readme for specific details
*/
auth?: WaitOnAuth | undefined;
/**
* Validates whether a status is valid.
*/
validateStatus?: ValidateStatus | undefined;
/**
* Proxy options.
* see https://github.com/axios/axios#config-defaults
*/
proxy?: AxiosProxyConfig | undefined;
strictSSL?: boolean | undefined;
followRedirect?: boolean | undefined;
headers?: Record<string, any> | undefined;
httpAgent?: Agent;
httpsAgent?: Agent;
}

interface HttpSignature {
keyId: string;
key: string;
}

interface WaitOnAuth {
username: string;
password: string;
}

type ValidateStatus = (status: number) => boolean;

interface AxiosProxyConfig {
host: string;
port: number;
auth?:
| {
username: string;
password: string;
}
| undefined;
protocol?: string | undefined;
}
}
20 changes: 14 additions & 6 deletions lib/wait-on.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ const WAIT_ON_SCHEMA = Joi.object({
}),
strictSSL: Joi.boolean().default(false),
followRedirect: Joi.boolean().default(true), // HTTP 3XX responses
headers: Joi.object()
headers: Joi.object(),
httpAgent: Joi.object(),
httpsAgent: Joi.object(),
});

/**
Expand Down Expand Up @@ -274,7 +276,9 @@ function createHTTP$({ validatedOpts, output }, resource) {
proxy,
reverse,
simultaneous,
strictSSL: rejectUnauthorized
strictSSL: rejectUnauthorized,
httpAgent,
httpsAgent
} = validatedOpts;
const method = HTTP_GET_RE.test(resource) ? 'get' : 'head';
const url = resource.replace('-get:', ':');
Expand All @@ -283,12 +287,16 @@ function createHTTP$({ validatedOpts, output }, resource) {
? { socketPath: matchHttpUnixSocket[1], url: matchHttpUnixSocket[2] }
: { url };
const socketPathDesc = urlSocketOptions.socketPath ? `socketPath:${urlSocketOptions.socketPath}` : '';
const httpOptions = {
...pick(['auth', 'headers', 'validateStatus'], validatedOpts),
httpsAgent: new https.Agent({
if (!httpsAgent) {
httpsAgent = new https.Agent({
rejectUnauthorized,
...pick(['ca', 'cert', 'key', 'passphrase'], validatedOpts)
}),
});
};
const httpOptions = {
...pick(['auth', 'headers', 'validateStatus'], validatedOpts),
httpAgent: httpAgent,
httpsAgent: httpsAgent,
...(followRedirect ? {} : { maxRedirects: 0 }), // defaults to 5 (enabled)
proxy, // can be undefined, false, or object
...(timeout && { timeout }),
Expand Down
16 changes: 16 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": ["es6"],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": ["../"],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
},
"files": ["index.d.ts", "wait-on-tests.ts"]
}
1 change: 1 addition & 0 deletions tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "extends": "@definitelytyped/dtslint/dt.json" }
84 changes: 84 additions & 0 deletions wait-on-tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import waitOn = require('wait-on');
import { WaitOnOptions } from 'wait-on';

const opts: WaitOnOptions = {
resources: [
'file1',
'http://foo.com:8000/bar',
'https://my.com/cat',
'http-get://foo.com:8000/bar',
'https-get://my.com/cat',
'tcp:foo.com:8000',
'socket:/my/sock',
'http://unix:/my/sock:/my/url',
'http-get://unix:/my/sock:/my/url',
],
delay: 1000, // initial delay in ms, default 0
interval: 100, // poll interval in ms, default 250ms
timeout: 30000, // timeout in ms, default Infinity
tcpTimeout: 1000, // tcp timeout in ms, default 300ms
httpTimeout: 1000,
window: 1000, // stabilization time in ms, default 750ms

// http options
ca: [
/* strings or binaries */
],
cert: [
/* strings or binaries */
],
key: [
/* strings or binaries */
],
passphrase: 'yourpassphrase',
auth: {
username: 'theuser',
password: 'thepassword',
},
validateStatus: (status: number) => {
return status === 401 || (status >= 200 && status < 300);
},
proxy: {
host: '127.0.0.1',
port: 9000,
auth: {
username: 'mikeymike',
password: 'rapunz3l',
},
},
strictSSL: false,
followRedirect: true,
headers: {
'x-custom': 'headers',
},
simultaneous: 2,
};

const handleError = (err: any) => undefined;

// Usage with callback function
waitOn(opts, err => {
if (err) {
return handleError(err);
}
// once here, all resources are available
});

// Usage with promises
waitOn(opts)
.then(() => {
// once here, all resources are available
})
.catch(err => {
handleError(err);
});

// Usage with async await
(async () => {
try {
await waitOn(opts);
// once here, all resources are available
} catch (err) {
handleError(err);
}
})();