pro-xy-ui 0.5.8 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.esformatter +28 -28
- package/.eslintrc +15 -15
- package/bin/pro-xy-ui +25 -27
- package/index.html +38 -38
- package/lib/app/_common/app-menu.js +42 -42
- package/lib/app/_common/app-menu.ts +41 -41
- package/lib/app/_common/patchResize.js +33 -33
- package/lib/app/_common/patchResize.ts +32 -32
- package/lib/app/_common/pipes.js +33 -33
- package/lib/app/_common/pipes.ts +21 -21
- package/lib/app/_common/rxjs-extensions.js +20 -20
- package/lib/app/_common/rxjs-extensions.ts +21 -21
- package/lib/app/app.component.css +39 -39
- package/lib/app/app.component.html +35 -35
- package/lib/app/app.module.js +92 -92
- package/lib/app/app.module.ts +89 -89
- package/lib/app/main.js +11 -11
- package/lib/app/main.ts +11 -11
- package/lib/app/model/config.js +69 -69
- package/lib/app/model/config.ts +79 -79
- package/lib/app/model/http.js +116 -116
- package/lib/app/service/config.defaultConfig.js +74 -74
- package/lib/app/service/config.defaultConfig.ts +72 -72
- package/lib/app/service/config.service.js +44 -44
- package/lib/app/service/config.service.ts +39 -39
- package/lib/app/service/socket.service.js +109 -109
- package/lib/app/service/socket.service.ts +131 -131
- package/lib/app/service/traffic.service.js +98 -98
- package/lib/app/views/auto-responder/auto-responder.component.css +37 -37
- package/lib/app/views/auto-responder/auto-responder.component.html +41 -41
- package/lib/app/views/auto-responder/auto-responder.component.js +102 -102
- package/lib/app/views/auto-responder/auto-responder.component.ts +110 -110
- package/lib/app/views/composer/composer.component.css +7 -7
- package/lib/app/views/composer/composer.component.html +9 -9
- package/lib/app/views/composer/composer.component.js +147 -147
- package/lib/app/views/composer/composer.component.ts +148 -148
- package/lib/app/views/config/config.component.css +13 -13
- package/lib/app/views/config/config.component.html +14 -14
- package/lib/app/views/config/config.component.js +163 -163
- package/lib/app/views/config/diff.dialog.html +3 -3
- package/lib/app/views/config/diff.dialog.js +29 -29
- package/lib/app/views/config/diff.dialog.ts +17 -17
- package/lib/app/views/config/plugins.dialog.html +17 -17
- package/lib/app/views/config/plugins.dialog.js +29 -29
- package/lib/app/views/config/plugins.dialog.ts +17 -17
- package/lib/app/views/config-list-base.js +44 -44
- package/lib/app/views/config-list-base.ts +66 -66
- package/lib/app/views/connection/connection.component.html +9 -9
- package/lib/app/views/connection/connection.component.js +87 -89
- package/lib/app/views/connection/connection.component.ts +83 -85
- package/lib/app/views/delay/delay.component.css +23 -23
- package/lib/app/views/delay/delay.component.html +35 -35
- package/lib/app/views/delay/delay.component.js +34 -34
- package/lib/app/views/find/find.component.css +30 -30
- package/lib/app/views/find/find.component.html +10 -10
- package/lib/app/views/find/find.component.js +113 -113
- package/lib/app/views/find/find.component.ts +111 -111
- package/lib/app/views/inspector/inspector.component.css +14 -14
- package/lib/app/views/inspector/inspector.component.html +17 -17
- package/lib/app/views/inspector/inspector.component.js +64 -64
- package/lib/app/views/inspector/inspector.component.ts +54 -54
- package/lib/app/views/logs/logs.component.css +7 -7
- package/lib/app/views/logs/logs.component.html +13 -13
- package/lib/app/views/logs/logs.component.js +56 -56
- package/lib/app/views/logs/logs.component.ts +46 -46
- package/lib/app/views/requests/request-row.component.css +15 -15
- package/lib/app/views/requests/request-row.component.html +7 -7
- package/lib/app/views/requests/request-row.component.js +68 -68
- package/lib/app/views/requests/request.bodyMenu.js +41 -41
- package/lib/app/views/requests/request.bodyMenu.ts +61 -61
- package/lib/app/views/requests/request.headMenu.js +25 -25
- package/lib/app/views/requests/requests.component.css +49 -49
- package/lib/app/views/requests/requests.component.html +33 -33
- package/lib/app/views/requests/requests.component.js +127 -127
- package/lib/app/views/status/status.component.css +18 -18
- package/lib/app/views/status/status.component.html +8 -8
- package/lib/app/views/status/status.component.js +49 -49
- package/lib/app/views/status/status.component.ts +45 -45
- package/lib/app/views/url-replace/url-replace.component.css +32 -32
- package/lib/app/views/url-replace/url-replace.component.html +36 -36
- package/lib/app/views/url-replace/url-replace.component.js +34 -34
- package/lib/index.js +23 -23
- package/lib/lib.d.ts +2 -2
- package/lib/style.css +100 -100
- package/lib/systemjs.config.js +75 -75
- package/package.json +64 -64
- package/readme.md +5 -5
- package/tsconfig.json +23 -23
- package/typings.json +11 -11
- package/npm-shrinkwrap.json +0 -2568
|
@@ -1,110 +1,110 @@
|
|
|
1
|
-
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
|
2
|
-
import { SocketService } from '../../service/socket.service';
|
|
3
|
-
import { ConfigListBase } from '../config-list-base';
|
|
4
|
-
import { ReqRes } from '../../model/http';
|
|
5
|
-
|
|
6
|
-
var path = nw.require("path");
|
|
7
|
-
var url = nw.require("url");
|
|
8
|
-
var fs = nw.require("fs");
|
|
9
|
-
var format = nw.require('date-format');
|
|
10
|
-
var escapeStringRegexp = nw.require('escape-string-regexp');
|
|
11
|
-
|
|
12
|
-
@Component({
|
|
13
|
-
moduleId: module.id,
|
|
14
|
-
templateUrl: 'auto-responder.component.html',
|
|
15
|
-
styleUrls: [
|
|
16
|
-
'auto-responder.component.css'
|
|
17
|
-
],
|
|
18
|
-
selector: 'auto-responder',
|
|
19
|
-
host: { class: 'flex-grow' },
|
|
20
|
-
changeDetection: ChangeDetectionStrategy.OnPush
|
|
21
|
-
})
|
|
22
|
-
export class AutoResponder extends ConfigListBase {
|
|
23
|
-
|
|
24
|
-
configProperty = "autoResponder"
|
|
25
|
-
itemsProperty = "responses"
|
|
26
|
-
|
|
27
|
-
//TODO: how can we move this to parent?
|
|
28
|
-
constructor(socketService: SocketService) {
|
|
29
|
-
super();
|
|
30
|
-
this.socketService = socketService;
|
|
31
|
-
|
|
32
|
-
this.menuItems.splice(1, 0, new nw.MenuItem({ label: "Delete with target", click: () => this.deleteItem(this._lastCtxItem, true) }));
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
openFile(event, item) {
|
|
36
|
-
event.preventDefault();
|
|
37
|
-
|
|
38
|
-
var path = this.getFileLocation(item.target)
|
|
39
|
-
|
|
40
|
-
if (!fs.existsSync(path)) {
|
|
41
|
-
fs.writeFileSync(path, "");
|
|
42
|
-
}
|
|
43
|
-
nw.Shell.openItem(path);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
getFileLocation(target) {
|
|
47
|
-
if (path.isAbsolute(target)) {
|
|
48
|
-
return target;
|
|
49
|
-
}
|
|
50
|
-
return path.join(process.env.HOME, ".auto-respond", target);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
add(reqRes: ReqRes) {
|
|
54
|
-
if (!this.config) {
|
|
55
|
-
alert("Config not availible");
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
var headers = reqRes.resHeaders;
|
|
60
|
-
if (reqRes.isGzip) {
|
|
61
|
-
//we have unzipped the response
|
|
62
|
-
delete headers["content-encoding"];
|
|
63
|
-
}
|
|
64
|
-
delete headers["content-length"]; //node will count it automatically
|
|
65
|
-
|
|
66
|
-
var fileName = makeName(reqRes.url);
|
|
67
|
-
var filePath = this.getFileLocation(fileName);
|
|
68
|
-
|
|
69
|
-
var autoRespFolder = path.join(process.env.HOME, ".auto-respond");
|
|
70
|
-
if (!fs.existsSync(autoRespFolder)) {
|
|
71
|
-
fs.mkdirSync(autoRespFolder);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
fs.writeFileSync(filePath, reqRes.resBody);
|
|
75
|
-
|
|
76
|
-
this.config.addAutoResponse({
|
|
77
|
-
urlPattern: "^" + escapeStringRegexp(reqRes.url) + "$",
|
|
78
|
-
status: reqRes.statusCode,
|
|
79
|
-
headers: headers,
|
|
80
|
-
method: reqRes.method,
|
|
81
|
-
target: fileName,
|
|
82
|
-
disabled: false
|
|
83
|
-
});
|
|
84
|
-
this.socketService.replaceConfig(this.config);
|
|
85
|
-
|
|
86
|
-
function makeName(_url) {
|
|
87
|
-
var path = url.parse(_url).pathname.replace(/\/$/, "");
|
|
88
|
-
return `${path.split("/").slice(-2).join("_")}_${format('yyyyMMdd_hhmmss', new Date())}.txt`;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
checkDropAllow(reqRes: ReqRes) {
|
|
93
|
-
return reqRes.isFinished;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
deleteItem(item, deleteTarget?: boolean) {
|
|
97
|
-
super.deleteItem(item);
|
|
98
|
-
if (deleteTarget) {
|
|
99
|
-
|
|
100
|
-
var path = this.getFileLocation(item.target)
|
|
101
|
-
|
|
102
|
-
if (!fs.existsSync(path)) {
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
fs.unlinkSync(path);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
}
|
|
1
|
+
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
|
2
|
+
import { SocketService } from '../../service/socket.service';
|
|
3
|
+
import { ConfigListBase } from '../config-list-base';
|
|
4
|
+
import { ReqRes } from '../../model/http';
|
|
5
|
+
|
|
6
|
+
var path = nw.require("path");
|
|
7
|
+
var url = nw.require("url");
|
|
8
|
+
var fs = nw.require("fs");
|
|
9
|
+
var format = nw.require('date-format');
|
|
10
|
+
var escapeStringRegexp = nw.require('escape-string-regexp');
|
|
11
|
+
|
|
12
|
+
@Component({
|
|
13
|
+
moduleId: module.id,
|
|
14
|
+
templateUrl: 'auto-responder.component.html',
|
|
15
|
+
styleUrls: [
|
|
16
|
+
'auto-responder.component.css'
|
|
17
|
+
],
|
|
18
|
+
selector: 'auto-responder',
|
|
19
|
+
host: { class: 'flex-grow' },
|
|
20
|
+
changeDetection: ChangeDetectionStrategy.OnPush
|
|
21
|
+
})
|
|
22
|
+
export class AutoResponder extends ConfigListBase {
|
|
23
|
+
|
|
24
|
+
configProperty = "autoResponder"
|
|
25
|
+
itemsProperty = "responses"
|
|
26
|
+
|
|
27
|
+
//TODO: how can we move this to parent?
|
|
28
|
+
constructor(socketService: SocketService) {
|
|
29
|
+
super();
|
|
30
|
+
this.socketService = socketService;
|
|
31
|
+
|
|
32
|
+
this.menuItems.splice(1, 0, new nw.MenuItem({ label: "Delete with target", click: () => this.deleteItem(this._lastCtxItem, true) }));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
openFile(event, item) {
|
|
36
|
+
event.preventDefault();
|
|
37
|
+
|
|
38
|
+
var path = this.getFileLocation(item.target)
|
|
39
|
+
|
|
40
|
+
if (!fs.existsSync(path)) {
|
|
41
|
+
fs.writeFileSync(path, "");
|
|
42
|
+
}
|
|
43
|
+
nw.Shell.openItem(path);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
getFileLocation(target) {
|
|
47
|
+
if (path.isAbsolute(target)) {
|
|
48
|
+
return target;
|
|
49
|
+
}
|
|
50
|
+
return path.join(process.env.HOME, ".auto-respond", target);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
add(reqRes: ReqRes) {
|
|
54
|
+
if (!this.config) {
|
|
55
|
+
alert("Config not availible");
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
var headers = reqRes.resHeaders;
|
|
60
|
+
if (reqRes.isGzip) {
|
|
61
|
+
//we have unzipped the response
|
|
62
|
+
delete headers["content-encoding"];
|
|
63
|
+
}
|
|
64
|
+
delete headers["content-length"]; //node will count it automatically
|
|
65
|
+
|
|
66
|
+
var fileName = makeName(reqRes.url);
|
|
67
|
+
var filePath = this.getFileLocation(fileName);
|
|
68
|
+
|
|
69
|
+
var autoRespFolder = path.join(process.env.HOME, ".auto-respond");
|
|
70
|
+
if (!fs.existsSync(autoRespFolder)) {
|
|
71
|
+
fs.mkdirSync(autoRespFolder);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
fs.writeFileSync(filePath, reqRes.resBody);
|
|
75
|
+
|
|
76
|
+
this.config.addAutoResponse({
|
|
77
|
+
urlPattern: "^" + escapeStringRegexp(reqRes.url) + "$",
|
|
78
|
+
status: reqRes.statusCode,
|
|
79
|
+
headers: headers,
|
|
80
|
+
method: reqRes.method,
|
|
81
|
+
target: fileName,
|
|
82
|
+
disabled: false
|
|
83
|
+
});
|
|
84
|
+
this.socketService.replaceConfig(this.config);
|
|
85
|
+
|
|
86
|
+
function makeName(_url) {
|
|
87
|
+
var path = url.parse(_url).pathname.replace(/\/$/, "");
|
|
88
|
+
return `${path.split("/").slice(-2).join("_")}_${format('yyyyMMdd_hhmmss', new Date())}.txt`;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
checkDropAllow(reqRes: ReqRes) {
|
|
93
|
+
return reqRes.isFinished;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
deleteItem(item, deleteTarget?: boolean) {
|
|
97
|
+
super.deleteItem(item);
|
|
98
|
+
if (deleteTarget) {
|
|
99
|
+
|
|
100
|
+
var path = this.getFileLocation(item.target)
|
|
101
|
+
|
|
102
|
+
if (!fs.existsSync(path)) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
fs.unlinkSync(path);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
textarea {
|
|
2
|
-
resize: none;
|
|
3
|
-
height: 100%;
|
|
4
|
-
font-size: 12px;
|
|
5
|
-
line-height: 12px;
|
|
6
|
-
font-family:Menlo,Monaco,Consolas,"Courier New",monospace
|
|
7
|
-
}
|
|
1
|
+
textarea {
|
|
2
|
+
resize: none;
|
|
3
|
+
height: 100%;
|
|
4
|
+
font-size: 12px;
|
|
5
|
+
line-height: 12px;
|
|
6
|
+
font-family:Menlo,Monaco,Consolas,"Courier New",monospace
|
|
7
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
<div class="mb-2 flex-grow">
|
|
2
|
-
<textarea class="form-control" [value]="model" (keyup)="model=$event.target.value" dnd-droppable (onDropSuccess)="reqRes=$event.dragData"></textarea>
|
|
3
|
-
</div>
|
|
4
|
-
<div>
|
|
5
|
-
<button class="btn btn-sm btn-primary" (click)="send()" [disabled]="invalid">Send</button>
|
|
6
|
-
<button class="btn btn-sm btn-secondary" (click)="loadSample()">Load sample</button>
|
|
7
|
-
|
|
8
|
-
<em style="color:red">{{message}}</em>
|
|
9
|
-
</div>
|
|
1
|
+
<div class="mb-2 flex-grow">
|
|
2
|
+
<textarea class="form-control" [value]="model" (keyup)="model=$event.target.value" dnd-droppable (onDropSuccess)="reqRes=$event.dragData"></textarea>
|
|
3
|
+
</div>
|
|
4
|
+
<div>
|
|
5
|
+
<button class="btn btn-sm btn-primary" (click)="send()" [disabled]="invalid">Send</button>
|
|
6
|
+
<button class="btn btn-sm btn-secondary" (click)="loadSample()">Load sample</button>
|
|
7
|
+
|
|
8
|
+
<em style="color:red">{{message}}</em>
|
|
9
|
+
</div>
|
|
@@ -1,147 +1,147 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
const core_1 = require("@angular/core");
|
|
13
|
-
const http_1 = require("@angular/http");
|
|
14
|
-
const socket_service_1 = require("../../service/socket.service");
|
|
15
|
-
const http_2 = require("../../model/http");
|
|
16
|
-
var app = nw.require('nw.gui').App;
|
|
17
|
-
var validUrl = nw.require('valid-url');
|
|
18
|
-
var url = nw.require('url');
|
|
19
|
-
var SAMPLE_REQUEST = 'POST http://jsonplaceholder.typicode.com/posts\ncontent-type: application/json\naccept: */*\n\n{"sample":1}';
|
|
20
|
-
let ComposerComponent = class ComposerComponent {
|
|
21
|
-
constructor(http, socketService) {
|
|
22
|
-
this.http = http;
|
|
23
|
-
this.socketService = socketService;
|
|
24
|
-
this.invalid = false;
|
|
25
|
-
this._message = "";
|
|
26
|
-
}
|
|
27
|
-
ngOnInit() {
|
|
28
|
-
this.loadSample();
|
|
29
|
-
this.socketService.configObservable.subscribe(config => { this.config = config; });
|
|
30
|
-
}
|
|
31
|
-
set reqRes(reqRes) {
|
|
32
|
-
if (!reqRes) {
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
this.model = `${reqRes.method} ${reqRes.url}\n${reqRes.reqHeadersStr}\n\n${reqRes.reqBody}`;
|
|
36
|
-
}
|
|
37
|
-
get message() { return this._message; }
|
|
38
|
-
set message(message) {
|
|
39
|
-
this._message = message;
|
|
40
|
-
this.invalid = !!message;
|
|
41
|
-
}
|
|
42
|
-
get model() { return this._model; }
|
|
43
|
-
set model(model) {
|
|
44
|
-
this._model = model;
|
|
45
|
-
try {
|
|
46
|
-
this.parsedModel = this.parse(this.model);
|
|
47
|
-
this.message = null;
|
|
48
|
-
}
|
|
49
|
-
catch (e) {
|
|
50
|
-
this.message = e.message;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
parse(value) {
|
|
54
|
-
if (!value) {
|
|
55
|
-
throw new Error("Method and URL are required");
|
|
56
|
-
}
|
|
57
|
-
var lines = value.split(/\r\n?|\n/);
|
|
58
|
-
var parts = lines.shift().split(" ");
|
|
59
|
-
var method = parts[0].trim();
|
|
60
|
-
if (!/^(get|post|put|delete|options|head)$/i.test(method)) {
|
|
61
|
-
throw new Error(`Unknown method: ${method}`);
|
|
62
|
-
}
|
|
63
|
-
;
|
|
64
|
-
var uri = parts.slice(1).join(" ").trim();
|
|
65
|
-
//if (!validUrl.isUri(url)) { //this is now working for some urls, eg: http://toplist.cz/count.asp?id=1128198&logo=mc&http&t=ForcaBarca.sk%2C%20informa%u010Dn%FD%20servis%20FC%20Barcelona&wi=1920&he=1080&cd=24
|
|
66
|
-
//http://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url
|
|
67
|
-
//if (!/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$/.test(url)) {
|
|
68
|
-
validateUrl(uri);
|
|
69
|
-
var bodySepIdx = lines.indexOf("");
|
|
70
|
-
var headerLines = ~bodySepIdx ? lines.slice(0, bodySepIdx) : lines;
|
|
71
|
-
var headers = headerLines.reduce((obj, line) => {
|
|
72
|
-
var parts = line.split(":");
|
|
73
|
-
var name = parts.shift().trim();
|
|
74
|
-
var value = parts.join(":").trim();
|
|
75
|
-
if (!isValidHeaderName(name)) {
|
|
76
|
-
throw new Error(`Invalid header name '${name}'`);
|
|
77
|
-
}
|
|
78
|
-
if (!value) {
|
|
79
|
-
throw new Error(`Invalid header line '${line}'`);
|
|
80
|
-
}
|
|
81
|
-
obj[name] = value;
|
|
82
|
-
return obj;
|
|
83
|
-
}, {});
|
|
84
|
-
var body = "";
|
|
85
|
-
if (~bodySepIdx) {
|
|
86
|
-
body = lines.slice(bodySepIdx + 1).join("\n");
|
|
87
|
-
}
|
|
88
|
-
return { method, url: uri, headers, body };
|
|
89
|
-
function isValidHeaderName(val) {
|
|
90
|
-
//https://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
|
|
91
|
-
return /^[ -~]+$/.test(val) && !/[\(\)<>@,;:\\<>\/\[\]\?={} \t"]/.test(val);
|
|
92
|
-
}
|
|
93
|
-
function validateUrl(val) {
|
|
94
|
-
var parsed = url.parse(val);
|
|
95
|
-
if (!parsed.protocol || !parsed.host) {
|
|
96
|
-
throw new Error("Only absolute URLs are allowed");
|
|
97
|
-
}
|
|
98
|
-
if (!/^http:$/i.test(parsed.protocol)) {
|
|
99
|
-
throw new Error("Only HTTP protocol is allowed");
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
send(reqRes) {
|
|
104
|
-
var req = this.parsedModel;
|
|
105
|
-
if (reqRes) {
|
|
106
|
-
req = {
|
|
107
|
-
url: reqRes.url,
|
|
108
|
-
method: reqRes.method,
|
|
109
|
-
headers: reqRes.reqHeaders,
|
|
110
|
-
body: reqRes.reqBody
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
let options = new http_1.RequestOptions({
|
|
114
|
-
//AR:do not add no-cache, we do not want to spoil headers, we will clear the cache (disabling cache in nw.js seems to be buggy, see issues)
|
|
115
|
-
//headers: new Headers(Object.assign({ pragma: "no-cache" }, req.headers)),
|
|
116
|
-
headers: new http_1.Headers(req.headers),
|
|
117
|
-
method: req.method,
|
|
118
|
-
body: req.body
|
|
119
|
-
});
|
|
120
|
-
app.clearCache();
|
|
121
|
-
app.setProxyConfig(`http=localhost:${this.config.port},direct://;direct://`);
|
|
122
|
-
this.http.request(req.url, options)
|
|
123
|
-
.toPromise()
|
|
124
|
-
.catch(() => null) // no op
|
|
125
|
-
.then(() => app.setProxyConfig(""));
|
|
126
|
-
}
|
|
127
|
-
loadSample() {
|
|
128
|
-
this.model = SAMPLE_REQUEST;
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
__decorate([
|
|
132
|
-
core_1.Input(),
|
|
133
|
-
__metadata("design:type", http_2.ReqRes),
|
|
134
|
-
__metadata("design:paramtypes", [http_2.ReqRes])
|
|
135
|
-
], ComposerComponent.prototype, "reqRes", null);
|
|
136
|
-
ComposerComponent = __decorate([
|
|
137
|
-
core_1.Component({
|
|
138
|
-
moduleId: module.id,
|
|
139
|
-
templateUrl: 'composer.component.html',
|
|
140
|
-
styleUrls: ['composer.component.css'],
|
|
141
|
-
selector: 'composer',
|
|
142
|
-
host: { class: 'flex-grow' },
|
|
143
|
-
changeDetection: core_1.ChangeDetectionStrategy.OnPush
|
|
144
|
-
}),
|
|
145
|
-
__metadata("design:paramtypes", [http_1.Http, socket_service_1.SocketService])
|
|
146
|
-
], ComposerComponent);
|
|
147
|
-
exports.ComposerComponent = ComposerComponent;
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const core_1 = require("@angular/core");
|
|
13
|
+
const http_1 = require("@angular/http");
|
|
14
|
+
const socket_service_1 = require("../../service/socket.service");
|
|
15
|
+
const http_2 = require("../../model/http");
|
|
16
|
+
var app = nw.require('nw.gui').App;
|
|
17
|
+
var validUrl = nw.require('valid-url');
|
|
18
|
+
var url = nw.require('url');
|
|
19
|
+
var SAMPLE_REQUEST = 'POST http://jsonplaceholder.typicode.com/posts\ncontent-type: application/json\naccept: */*\n\n{"sample":1}';
|
|
20
|
+
let ComposerComponent = class ComposerComponent {
|
|
21
|
+
constructor(http, socketService) {
|
|
22
|
+
this.http = http;
|
|
23
|
+
this.socketService = socketService;
|
|
24
|
+
this.invalid = false;
|
|
25
|
+
this._message = "";
|
|
26
|
+
}
|
|
27
|
+
ngOnInit() {
|
|
28
|
+
this.loadSample();
|
|
29
|
+
this.socketService.configObservable.subscribe(config => { this.config = config; });
|
|
30
|
+
}
|
|
31
|
+
set reqRes(reqRes) {
|
|
32
|
+
if (!reqRes) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
this.model = `${reqRes.method} ${reqRes.url}\n${reqRes.reqHeadersStr}\n\n${reqRes.reqBody}`;
|
|
36
|
+
}
|
|
37
|
+
get message() { return this._message; }
|
|
38
|
+
set message(message) {
|
|
39
|
+
this._message = message;
|
|
40
|
+
this.invalid = !!message;
|
|
41
|
+
}
|
|
42
|
+
get model() { return this._model; }
|
|
43
|
+
set model(model) {
|
|
44
|
+
this._model = model;
|
|
45
|
+
try {
|
|
46
|
+
this.parsedModel = this.parse(this.model);
|
|
47
|
+
this.message = null;
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
this.message = e.message;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
parse(value) {
|
|
54
|
+
if (!value) {
|
|
55
|
+
throw new Error("Method and URL are required");
|
|
56
|
+
}
|
|
57
|
+
var lines = value.split(/\r\n?|\n/);
|
|
58
|
+
var parts = lines.shift().split(" ");
|
|
59
|
+
var method = parts[0].trim();
|
|
60
|
+
if (!/^(get|post|put|delete|options|head)$/i.test(method)) {
|
|
61
|
+
throw new Error(`Unknown method: ${method}`);
|
|
62
|
+
}
|
|
63
|
+
;
|
|
64
|
+
var uri = parts.slice(1).join(" ").trim();
|
|
65
|
+
//if (!validUrl.isUri(url)) { //this is now working for some urls, eg: http://toplist.cz/count.asp?id=1128198&logo=mc&http&t=ForcaBarca.sk%2C%20informa%u010Dn%FD%20servis%20FC%20Barcelona&wi=1920&he=1080&cd=24
|
|
66
|
+
//http://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url
|
|
67
|
+
//if (!/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$/.test(url)) {
|
|
68
|
+
validateUrl(uri);
|
|
69
|
+
var bodySepIdx = lines.indexOf("");
|
|
70
|
+
var headerLines = ~bodySepIdx ? lines.slice(0, bodySepIdx) : lines;
|
|
71
|
+
var headers = headerLines.reduce((obj, line) => {
|
|
72
|
+
var parts = line.split(":");
|
|
73
|
+
var name = parts.shift().trim();
|
|
74
|
+
var value = parts.join(":").trim();
|
|
75
|
+
if (!isValidHeaderName(name)) {
|
|
76
|
+
throw new Error(`Invalid header name '${name}'`);
|
|
77
|
+
}
|
|
78
|
+
if (!value) {
|
|
79
|
+
throw new Error(`Invalid header line '${line}'`);
|
|
80
|
+
}
|
|
81
|
+
obj[name] = value;
|
|
82
|
+
return obj;
|
|
83
|
+
}, {});
|
|
84
|
+
var body = "";
|
|
85
|
+
if (~bodySepIdx) {
|
|
86
|
+
body = lines.slice(bodySepIdx + 1).join("\n");
|
|
87
|
+
}
|
|
88
|
+
return { method, url: uri, headers, body };
|
|
89
|
+
function isValidHeaderName(val) {
|
|
90
|
+
//https://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
|
|
91
|
+
return /^[ -~]+$/.test(val) && !/[\(\)<>@,;:\\<>\/\[\]\?={} \t"]/.test(val);
|
|
92
|
+
}
|
|
93
|
+
function validateUrl(val) {
|
|
94
|
+
var parsed = url.parse(val);
|
|
95
|
+
if (!parsed.protocol || !parsed.host) {
|
|
96
|
+
throw new Error("Only absolute URLs are allowed");
|
|
97
|
+
}
|
|
98
|
+
if (!/^http:$/i.test(parsed.protocol)) {
|
|
99
|
+
throw new Error("Only HTTP protocol is allowed");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
send(reqRes) {
|
|
104
|
+
var req = this.parsedModel;
|
|
105
|
+
if (reqRes) {
|
|
106
|
+
req = {
|
|
107
|
+
url: reqRes.url,
|
|
108
|
+
method: reqRes.method,
|
|
109
|
+
headers: reqRes.reqHeaders,
|
|
110
|
+
body: reqRes.reqBody
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
let options = new http_1.RequestOptions({
|
|
114
|
+
//AR:do not add no-cache, we do not want to spoil headers, we will clear the cache (disabling cache in nw.js seems to be buggy, see issues)
|
|
115
|
+
//headers: new Headers(Object.assign({ pragma: "no-cache" }, req.headers)),
|
|
116
|
+
headers: new http_1.Headers(req.headers),
|
|
117
|
+
method: req.method,
|
|
118
|
+
body: req.body
|
|
119
|
+
});
|
|
120
|
+
app.clearCache();
|
|
121
|
+
app.setProxyConfig(`http=localhost:${this.config.port},direct://;direct://`);
|
|
122
|
+
this.http.request(req.url, options)
|
|
123
|
+
.toPromise()
|
|
124
|
+
.catch(() => null) // no op
|
|
125
|
+
.then(() => app.setProxyConfig(""));
|
|
126
|
+
}
|
|
127
|
+
loadSample() {
|
|
128
|
+
this.model = SAMPLE_REQUEST;
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
__decorate([
|
|
132
|
+
core_1.Input(),
|
|
133
|
+
__metadata("design:type", http_2.ReqRes),
|
|
134
|
+
__metadata("design:paramtypes", [http_2.ReqRes])
|
|
135
|
+
], ComposerComponent.prototype, "reqRes", null);
|
|
136
|
+
ComposerComponent = __decorate([
|
|
137
|
+
core_1.Component({
|
|
138
|
+
moduleId: module.id,
|
|
139
|
+
templateUrl: 'composer.component.html',
|
|
140
|
+
styleUrls: ['composer.component.css'],
|
|
141
|
+
selector: 'composer',
|
|
142
|
+
host: { class: 'flex-grow' },
|
|
143
|
+
changeDetection: core_1.ChangeDetectionStrategy.OnPush
|
|
144
|
+
}),
|
|
145
|
+
__metadata("design:paramtypes", [http_1.Http, socket_service_1.SocketService])
|
|
146
|
+
], ComposerComponent);
|
|
147
|
+
exports.ComposerComponent = ComposerComponent;
|