Skip to content

Commit a33feb2

Browse files
committed
feat(proxy): add proxy config setting
1 parent 7a56169 commit a33feb2

8 files changed

Lines changed: 37 additions & 104 deletions

File tree

packages/@ionic/cli-utils/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
"split2": "^2.2.0",
5454
"ssh-config": "^1.1.1",
5555
"superagent": "^3.8.2",
56+
"superagent-proxy": "^1.0.3",
5657
"tar": "^4.3.0",
5758
"through2": "^2.0.3",
5859
"tslib": "^1.9.0",
@@ -78,7 +79,6 @@
7879
"jest-cli": "^22.4.2",
7980
"rimraf": "^2.6.2",
8081
"source-map": "^0.7.0",
81-
"superagent-proxy": "^1.0.3",
8282
"ts-jest": "^22.4.1",
8383
"tslint": "^5.9.1",
8484
"typescript": "~2.8.1"

packages/@ionic/cli-utils/src/definitions.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ export interface ConfigFile {
401401
gitPort?: number;
402402
};
403403
ssl?: SSLConfig;
404+
proxy?: string;
404405
git: {
405406
setup?: boolean;
406407
};
@@ -426,6 +427,7 @@ export interface SSLConfig {
426427

427428
export interface CreateRequestOptions {
428429
ssl?: SSLConfig;
430+
proxy?: string;
429431
}
430432

431433
export interface IBaseConfig<T extends { [key: string]: any }> {

packages/@ionic/cli-utils/src/index.ts

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -162,24 +162,5 @@ export async function generateIonicEnvironment(ctx: IonicContext, pargv: string[
162162
log.warn(`${chalk.green('--yarn')} / ${chalk.green('--no-yarn')} was removed in CLI 4.0. Use ${chalk.green(`ionic config set -g npmClient ${argv['yarn'] ? 'yarn' : 'npm'}`)}.`);
163163
}
164164

165-
if (proxyVars.length > 0) {
166-
const [ , proxyVar ] = proxyVars[0];
167-
168-
try {
169-
require.resolve('superagent-proxy');
170-
} catch (e) {
171-
if (e.code !== 'MODULE_NOT_FOUND') {
172-
throw e;
173-
}
174-
175-
log.warn(
176-
`Missing ${chalk.bold('superagent-proxy')} package.\n` +
177-
`Detected ${chalk.green(proxyVar)} in environment, but missing proxy package: ${chalk.bold('superagent-proxy')}. Please install it to proxy CLI requests.\n\n` +
178-
`See the CLI documentation on proxies: ${chalk.bold('https://ionicframework.com/docs/cli/configuring.html#using-a-proxy')}`
179-
);
180-
}
181-
}
182-
}
183-
184165
return ienv;
185166
}

packages/@ionic/cli-utils/src/lib/integrations/index.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ export abstract class BaseIntegration implements IIntegration {
107107
const onFileCreate = opts && opts.onFileCreate ? opts.onFileCreate : lodash.noop;
108108
const conflictHandler = opts && opts.conflictHandler ? opts.conflictHandler : async () => false;
109109

110-
const { download } = await import('../utils/http');
110+
const { createRequest, download } = await import('../utils/http');
111111
const { createTarExtraction } = await import('../utils/archive');
112112

113113
const task = this.tasks.next(`Downloading integration ${chalk.green(this.name)}`);
@@ -123,10 +123,8 @@ export abstract class BaseIntegration implements IIntegration {
123123

124124
const ws = await createTarExtraction({ cwd: tmpdir });
125125
const c = await this.config.load();
126-
await download(this.archiveUrl, ws, {
127-
progress: (loaded, total) => task.progress(loaded, total),
128-
ssl: c.ssl,
129-
});
126+
const { req } = await createRequest('GET', this.archiveUrl, c);
127+
await download(req, ws, { progress: (loaded, total) => task.progress(loaded, total) });
130128
this.tasks.end();
131129

132130
const contents = await readDir(tmpdir);

packages/@ionic/cli-utils/src/lib/utils/http.ts

Lines changed: 25 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import chalk from 'chalk';
21
import * as Debug from 'debug';
32

43
import * as superagentType from 'superagent';
@@ -10,121 +9,76 @@ import { CreateRequestOptions, HttpMethod } from '../../definitions';
109

1110
const debug = Debug('ionic:cli-utils:lib:utils:http');
1211

13-
let _proxyInstalled = false;
14-
15-
let CAS: string[] | undefined;
16-
let CERTS: string[] | undefined;
17-
let KEYS: string[] | undefined;
18-
1912
export const PROXY_ENVIRONMENT_VARIABLES: ReadonlyArray<string> = ['IONIC_HTTP_PROXY', 'HTTPS_PROXY', 'HTTP_PROXY', 'PROXY', 'https_proxy', 'http_proxy', 'proxy'];
2013

21-
function getGlobalProxy(): [string, string] | [undefined, undefined] {
14+
function getGlobalProxy(): { envvar: string; envval: string; } | undefined {
2215
for (const envvar of PROXY_ENVIRONMENT_VARIABLES) {
23-
if (process.env[envvar]) {
24-
return [process.env[envvar], envvar];
16+
const envval = process.env[envvar];
17+
18+
if (envval) {
19+
return { envval, envvar };
2520
}
2621
}
27-
28-
return [undefined, undefined];
2922
}
3023

31-
export async function installProxy(superagent: superagentType.SuperAgentStatic, proxy: string, proxyVar: string): Promise<boolean> {
32-
if (_proxyInstalled) {
33-
return true;
34-
}
24+
export async function createRequest(method: HttpMethod, url: string, { proxy, ssl }: CreateRequestOptions): Promise<{ req: superagentType.SuperAgentRequest; }> {
25+
const superagent = await import('superagent');
3526

36-
debug(`Detected ${chalk.green(proxyVar)} in environment`);
27+
if (!proxy) {
28+
const gproxy = getGlobalProxy();
3729

38-
try {
39-
const superagentProxy = await import('superagent-proxy');
40-
superagentProxy(superagent);
41-
_proxyInstalled = true;
42-
debug(`Proxy installed to ${chalk.green(proxy)}`);
43-
} catch (e) {
44-
if (e.code !== 'MODULE_NOT_FOUND') {
45-
throw e;
30+
if (gproxy) {
31+
proxy = gproxy.envval;
4632
}
47-
48-
debug(`Missing proxy package: ${chalk.bold('superagent-proxy')}`);
49-
50-
return false;
5133
}
5234

53-
return true;
54-
}
55-
56-
export async function createRequest(method: HttpMethod, url: string, opts?: CreateRequestOptions): Promise<{ req: superagentType.SuperAgentRequest; }> {
57-
const superagent = await import('superagent');
58-
const [ proxy, proxyVar ] = getGlobalProxy();
59-
6035
const req = superagent(method, url);
6136

6237
req.redirects(25);
6338

64-
if (proxy && proxyVar) {
65-
await installProxy(superagent, proxy, proxyVar);
39+
if (proxy) {
40+
const superagentProxy = await import('superagent-proxy');
41+
superagentProxy(superagent);
6642

6743
if (req.proxy) {
6844
req.proxy(proxy);
45+
} else {
46+
debug(`Cannot install proxy--req.proxy not defined`);
6947
}
7048
}
7149

72-
if (opts && opts.ssl) {
73-
if (!CAS) {
74-
CAS = await Promise.all(conform(opts.ssl.cafile).map(p => fsReadFile(p, { encoding: 'utf8' })));
75-
}
76-
77-
if (!CERTS) {
78-
CERTS = await Promise.all(conform(opts.ssl.certfile).map(p => fsReadFile(p, { encoding: 'utf8' })));
79-
}
80-
81-
if (!KEYS) {
82-
KEYS = await Promise.all(conform(opts.ssl.keyfile).map(p => fsReadFile(p, { encoding: 'utf8' })));
83-
}
84-
85-
if (CAS.length > 0) {
86-
req.ca(CAS);
87-
}
88-
89-
if (CERTS.length > 0) {
90-
req.cert(CERTS);
91-
}
92-
93-
if (KEYS.length > 0) {
94-
req.key(KEYS);
95-
}
50+
if (ssl) {
51+
req.ca(await Promise.all(conform(ssl.cafile).map(p => fsReadFile(p, { encoding: 'utf8' }))));
52+
req.cert(await Promise.all(conform(ssl.certfile).map(p => fsReadFile(p, { encoding: 'utf8' }))));
53+
req.key(await Promise.all(conform(ssl.keyfile).map(p => fsReadFile(p, { encoding: 'utf8' }))));
9654
}
9755

9856
return { req };
9957
}
10058

101-
export async function download(url: string, ws: NodeJS.WritableStream, opts?: { progress?: (loaded: number, total: number) => void; } & CreateRequestOptions) {
102-
const { req } = await createRequest('GET', url, opts);
103-
104-
const progressFn = opts ? opts.progress : undefined;
105-
59+
export async function download(req: superagentType.SuperAgentRequest, ws: NodeJS.WritableStream, { progress }: { progress?: (loaded: number, total: number) => void; }): Promise<void> {
10660
return new Promise<void>((resolve, reject) => {
10761
req
10862
.on('response', res => {
10963
if (res.statusCode !== 200) {
11064
reject(new Error(
111-
`Encountered bad status code (${res.statusCode}) for ${url}\n` +
65+
`Encountered bad status code (${res.statusCode}) for ${req.url}\n` +
11266
`This could mean the server is experiencing difficulties right now--please try again later.`
11367
));
11468
}
11569

116-
if (progressFn) {
70+
if (progress) {
11771
let loaded = 0;
11872
const total = Number(res.headers['content-length']);
11973
res.on('data', chunk => {
12074
loaded += chunk.length;
121-
progressFn(loaded, total);
75+
progress(loaded, total);
12276
});
12377
}
12478
})
12579
.on('error', err => {
12680
if (err.code === 'ECONNABORTED') {
127-
reject(new Error(`Timeout of ${err.timeout}ms reached for ${url}`));
81+
reject(new Error(`Timeout of ${err.timeout}ms reached for ${req.url}`));
12882
} else {
12983
reject(err);
13084
}

packages/ionic/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ down the main CLI package. All functionality is still supported, but the
8787
[#2919](https://github.com/ionic-team/ionic-cli/issues/2919)
8888
* Better monorepo support. See the discussion in
8989
[#2232](https://github.com/ionic-team/ionic-cli/issues/2232).
90+
* No need for `@ionic/cli-plugin-proxy`. Proxy support is now built-in. Use
91+
existing environment variables or use `ionic config set -g proxy <url>`.
9092

9193
#### :bug: Bug Fixes
9294

packages/ionic/src/commands/start.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -560,17 +560,15 @@ ${chalk.cyan('[1]')}: ${chalk.bold('https://ionicframework.com/docs/cli/starters
560560
}
561561

562562
async downloadStarterTemplate(projectDir: string, starterTemplate: ResolvedStarterTemplate) {
563-
const { download } = await import('@ionic/cli-utils/lib/utils/http');
563+
const { createRequest, download } = await import('@ionic/cli-utils/lib/utils/http');
564564
const { createTarExtraction } = await import('@ionic/cli-utils/lib/utils/archive');
565565

566566
const task = this.env.tasks.next(`Downloading and extracting ${chalk.green(starterTemplate.name.toString())} starter`);
567567
const config = await this.env.config.load();
568568
const ws = await createTarExtraction({ cwd: projectDir, strip: starterTemplate.strip ? 1 : 0 });
569569

570-
await download(starterTemplate.archive, ws, {
571-
progress: (loaded, total) => task.progress(loaded, total),
572-
ssl: config.ssl,
573-
});
570+
const { req } = await createRequest('GET', starterTemplate.archive, config);
571+
await download(req, ws, { progress: (loaded, total) => task.progress(loaded, total) });
574572

575573
this.env.tasks.end();
576574
}

types/superagent-proxy.d.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
declare module "superagent-proxy" {
2-
import superagent = require('superagent');
3-
4-
namespace superagentProxy {}
2+
import * as superagent from 'superagent';
53

64
function superagentProxy(s: typeof superagent): void;
75

0 commit comments

Comments
 (0)