@api-client/core 0.7.7 → 0.7.10
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/build/browser.d.ts +5 -1
- package/build/browser.js.map +1 -1
- package/build/index.d.ts +6 -1
- package/build/index.js +8 -0
- package/build/index.js.map +1 -1
- package/build/src/cookies/CookieParser.d.ts +11 -0
- package/build/src/cookies/CookieParser.js +39 -26
- package/build/src/cookies/CookieParser.js.map +1 -1
- package/build/src/events/EventTypes.d.ts +3 -4
- package/build/src/events/Events.d.ts +3 -4
- package/build/src/events/transport/TransportEventTypes.d.ts +3 -4
- package/build/src/events/transport/TransportEventTypes.js +3 -7
- package/build/src/events/transport/TransportEventTypes.js.map +1 -1
- package/build/src/events/transport/TransportEvents.d.ts +21 -29
- package/build/src/events/transport/TransportEvents.js +26 -29
- package/build/src/events/transport/TransportEvents.js.map +1 -1
- package/build/src/lib/transformers/PayloadSerializer.js +1 -0
- package/build/src/lib/transformers/PayloadSerializer.js.map +1 -1
- package/build/src/models/AppProject.d.ts +10 -0
- package/build/src/models/AppProject.js +14 -0
- package/build/src/models/AppProject.js.map +1 -1
- package/build/src/models/HttpResponse.js.map +1 -1
- package/build/src/models/ProjectRequest.js.map +1 -1
- package/build/src/models/Request.js.map +1 -1
- package/build/src/models/legacy/Normalizer.d.ts +1 -1
- package/build/src/models/legacy/Normalizer.js +1 -1
- package/build/src/proxy/AppProjectProxy.d.ts +27 -0
- package/build/src/proxy/AppProjectProxy.js +107 -0
- package/build/src/proxy/AppProjectProxy.js.map +1 -0
- package/build/src/proxy/HttpProjectProxy.d.ts +23 -0
- package/build/src/proxy/HttpProjectProxy.js +99 -0
- package/build/src/proxy/HttpProjectProxy.js.map +1 -0
- package/build/src/proxy/Proxy.d.ts +27 -0
- package/build/src/proxy/Proxy.js +7 -0
- package/build/src/proxy/Proxy.js.map +1 -0
- package/build/src/proxy/ProxyService.d.ts +42 -0
- package/build/src/proxy/ProxyService.js +66 -0
- package/build/src/proxy/ProxyService.js.map +1 -0
- package/build/src/proxy/RequestProxy.d.ts +42 -0
- package/build/src/proxy/RequestProxy.js +59 -0
- package/build/src/proxy/RequestProxy.js.map +1 -0
- package/build/src/runtime/http-runner/HttpRequestRunner.d.ts +5 -0
- package/build/src/runtime/http-runner/HttpRequestRunner.js +18 -0
- package/build/src/runtime/http-runner/HttpRequestRunner.js.map +1 -1
- package/build/src/runtime/node/InteropInterfaces.d.ts +2 -1
- package/build/src/runtime/node/ProjectParallelRunner.d.ts +3 -2
- package/build/src/runtime/node/ProjectParallelRunner.js.map +1 -1
- package/build/src/runtime/node/ProjectRequestRunner.d.ts +0 -5
- package/build/src/runtime/node/ProjectRequestRunner.js +1 -18
- package/build/src/runtime/node/ProjectRequestRunner.js.map +1 -1
- package/build/src/runtime/node/ProjectRunner.d.ts +3 -3
- package/build/src/runtime/node/ProjectRunner.js.map +1 -1
- package/build/src/runtime/node/ProjectRunnerWorker.js +23 -5
- package/build/src/runtime/node/ProjectRunnerWorker.js.map +1 -1
- package/package.json +4 -1
- package/src/cookies/CookieParser.ts +40 -26
- package/src/events/transport/TransportEventTypes.ts +4 -8
- package/src/events/transport/TransportEvents.ts +32 -45
- package/src/lib/transformers/PayloadSerializer.ts +1 -0
- package/src/models/AppProject.ts +16 -0
- package/src/models/HttpResponse.ts +2 -2
- package/src/models/ProjectRequest.ts +8 -8
- package/src/models/Request.ts +7 -7
- package/src/models/legacy/Normalizer.ts +1 -1
- package/src/proxy/AppProjectProxy.ts +125 -0
- package/src/proxy/HttpProjectProxy.ts +113 -0
- package/src/proxy/Proxy.ts +30 -0
- package/src/proxy/ProxyService.ts +73 -0
- package/src/proxy/RequestProxy.ts +94 -0
- package/src/proxy/readme.md +14 -0
- package/src/runtime/http-runner/HttpRequestRunner.ts +19 -0
- package/src/runtime/node/InteropInterfaces.ts +2 -1
- package/src/runtime/node/ProjectParallelRunner.ts +3 -2
- package/src/runtime/node/ProjectRequestRunner.ts +2 -20
- package/src/runtime/node/ProjectRunner.ts +3 -3
- package/src/runtime/node/ProjectRunnerWorker.ts +21 -5
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@api-client/core",
|
|
3
3
|
"description": "The API Client's core client library. Works in NodeJS and in a ES enabled browser.",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.10",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "build/index.js",
|
|
7
7
|
"module": "build/index.js",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"@esm-bundle/chai": "^4.3.4-fix.0",
|
|
29
29
|
"@types/chai": "^4.2.22",
|
|
30
30
|
"@types/chai-as-promised": "^7.1.5",
|
|
31
|
+
"@types/chai-uuid": "^1.0.2",
|
|
31
32
|
"@types/cors": "^2.8.12",
|
|
32
33
|
"@types/express-ntlm": "^2.3.3",
|
|
33
34
|
"@types/fs-extra": "^9.0.13",
|
|
@@ -42,6 +43,7 @@
|
|
|
42
43
|
"amf-client-js": "^5.0.8-0",
|
|
43
44
|
"chai": "^4.3.4",
|
|
44
45
|
"chai-as-promised": "^7.1.1",
|
|
46
|
+
"chai-uuid": "^1.0.6",
|
|
45
47
|
"cors": "^2.8.5",
|
|
46
48
|
"eslint": "^8.9.0",
|
|
47
49
|
"eslint-config-prettier": "^8.3.0",
|
|
@@ -55,6 +57,7 @@
|
|
|
55
57
|
"husky": "^8.0.1",
|
|
56
58
|
"lint-staged": "^13.0.1",
|
|
57
59
|
"mocha": "^10.0.0",
|
|
60
|
+
"nock": "^13.2.7",
|
|
58
61
|
"oauth2-mock-server": "^4.3.1",
|
|
59
62
|
"sinon": "^14.0.0",
|
|
60
63
|
"source-map-support": "^0.5.21",
|
|
@@ -71,19 +71,20 @@ export class CookieParser {
|
|
|
71
71
|
|
|
72
72
|
/**
|
|
73
73
|
* Parses the `set-cookie` header value and creates a list of cookies.
|
|
74
|
-
* The cookie configuration must match the `url`. This means that if the cookie has a `host` property
|
|
75
|
-
* this must match the request URL (browsers do not allow setting cookies from one domain for another).
|
|
76
74
|
*
|
|
77
|
-
*
|
|
75
|
+
* Notes:
|
|
76
|
+
* - This does not check whether the cookie should be stored in the Cookie Jar based on the request URL, use `parse()` instead
|
|
77
|
+
* - This will fill up cookies' `domain` and `path` when `requestUrl` is provided. Otherwise it will leave these fields empty which makes the cookie invalid. Use `parse()` instead
|
|
78
78
|
*
|
|
79
|
-
* @param requestUrl The HTTP request URL. Cookies must match this URL or will be ignored.
|
|
80
79
|
* @param setCookie The value of the `set-cookie` string.
|
|
80
|
+
* @param requestUrl The HTTP request URL.
|
|
81
81
|
*/
|
|
82
|
-
static
|
|
82
|
+
static parseRelaxed(setCookie?: string, requestUrl?: string): HttpCookie[] {
|
|
83
83
|
const result: HttpCookie[] = [];
|
|
84
84
|
if (!setCookie || typeof setCookie !== 'string') {
|
|
85
85
|
return result;
|
|
86
86
|
}
|
|
87
|
+
|
|
87
88
|
const blocks = setCookie.split(';').map(i => i.trim());
|
|
88
89
|
blocks.forEach((part, index) => {
|
|
89
90
|
// Consider the following set-cookie string:
|
|
@@ -153,28 +154,41 @@ export class CookieParser {
|
|
|
153
154
|
}
|
|
154
155
|
});
|
|
155
156
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
157
|
+
if (requestUrl) {
|
|
158
|
+
const url = new URL(requestUrl);
|
|
159
|
+
const domain = this.canonicalDomain(url.host);
|
|
160
|
+
const path = this.getPath(url);
|
|
161
|
+
|
|
162
|
+
result.forEach((cookie) => {
|
|
163
|
+
if (!cookie.path) {
|
|
164
|
+
cookie.path = path;
|
|
165
|
+
}
|
|
166
|
+
if (!cookie.domain) {
|
|
167
|
+
// point 6. of https://tools.ietf.org/html/rfc6265#section-5.3
|
|
168
|
+
cookie.domain = domain;
|
|
169
|
+
cookie.hostOnly = true;
|
|
170
|
+
} else if (cookie.domain[0] !== '.') {
|
|
171
|
+
// https://stackoverflow.com/a/1063760/1127848
|
|
172
|
+
cookie.domain = `.${cookie.domain}`;
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
163
178
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
return this.filterCookies(result, requestUrl);
|
|
179
|
+
/**
|
|
180
|
+
* Parses the `set-cookie` header value and creates a list of cookies.
|
|
181
|
+
* The cookie configuration must match the `url`. This means that if the cookie has a `host` property
|
|
182
|
+
* this must match the request URL (browsers do not allow setting cookies from one domain for another).
|
|
183
|
+
*
|
|
184
|
+
* When `host` or `path` part is missing from the cookie, the URL values are used.
|
|
185
|
+
*
|
|
186
|
+
* @param requestUrl The HTTP request URL. Cookies must match this URL or will be ignored.
|
|
187
|
+
* @param setCookie The value of the `set-cookie` string.
|
|
188
|
+
*/
|
|
189
|
+
static parse(requestUrl: string, setCookie?: string): HttpCookie[] {
|
|
190
|
+
const cookies = this.parseRelaxed(setCookie, requestUrl);
|
|
191
|
+
return this.filterCookies(cookies, requestUrl);
|
|
178
192
|
}
|
|
179
193
|
|
|
180
194
|
/**
|
|
@@ -3,9 +3,11 @@ export const TransportEventTypes = Object.freeze({
|
|
|
3
3
|
* Transport via the CoreEngine.
|
|
4
4
|
*/
|
|
5
5
|
Core: Object.freeze({
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
request: 'transportcorerequest',
|
|
7
|
+
httpProject: 'transportcorehttpproject',
|
|
8
|
+
appProject: 'transportcoreappproject',
|
|
8
9
|
}),
|
|
10
|
+
|
|
9
11
|
/**
|
|
10
12
|
* Transport via the native platform's bindings.
|
|
11
13
|
*/
|
|
@@ -13,12 +15,6 @@ export const TransportEventTypes = Object.freeze({
|
|
|
13
15
|
send: 'httptransportsend',
|
|
14
16
|
}),
|
|
15
17
|
|
|
16
|
-
// project runner
|
|
17
|
-
Project: Object.freeze({
|
|
18
|
-
// for both a request or a folder (since it's all single configuration.)
|
|
19
|
-
send: 'transportprojectsend',
|
|
20
|
-
}),
|
|
21
|
-
|
|
22
18
|
// web sockets.
|
|
23
19
|
Ws: Object.freeze({
|
|
24
20
|
/**
|
|
@@ -1,31 +1,20 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
3
|
-
import { IRequestAuthorization } from "../../models/RequestAuthorization.js";
|
|
4
3
|
import { IHttpRequest } from "../../models/HttpRequest.js";
|
|
5
|
-
import { IRequestBaseConfig } from "../../models/RequestConfig.js";
|
|
6
4
|
import { IRequestLog } from '../../models/RequestLog.js';
|
|
7
|
-
import { HttpProject } from "../../models/HttpProject.js";
|
|
8
5
|
import { ContextEvent } from "../BaseEvents.js";
|
|
9
6
|
import { TransportEventTypes } from "./TransportEventTypes.js";
|
|
10
|
-
import { IProjectRunnerOptions } from "../../runtime/node/InteropInterfaces.js";
|
|
11
7
|
import { IProjectExecutionLog } from "../../runtime/reporters/Reporter.js";
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
config?: IRequestBaseConfig;
|
|
17
|
-
}
|
|
8
|
+
import { IRequestProxyInit } from "../../proxy/RequestProxy.js";
|
|
9
|
+
import { IHttpProjectProxyInit } from "../../proxy/HttpProjectProxy.js";
|
|
10
|
+
import { IAppProjectProxyInit } from "../../proxy/AppProjectProxy.js";
|
|
11
|
+
import { IProxyResult } from "../../proxy/Proxy.js";
|
|
18
12
|
|
|
19
13
|
export interface IHttpRequestDetail {
|
|
20
14
|
request: IHttpRequest;
|
|
21
15
|
init?: RequestInit;
|
|
22
16
|
}
|
|
23
17
|
|
|
24
|
-
export interface IProjectRequestDetail {
|
|
25
|
-
project: HttpProject | string;
|
|
26
|
-
opts: IProjectRunnerOptions;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
18
|
/* eslint-disable no-unused-vars */
|
|
30
19
|
export const TransportEvent = Object.freeze({
|
|
31
20
|
/**
|
|
@@ -36,17 +25,35 @@ export const TransportEvent = Object.freeze({
|
|
|
36
25
|
* Sends a single request without a context of a project.
|
|
37
26
|
*
|
|
38
27
|
* @param target The events target.
|
|
39
|
-
* @param
|
|
40
|
-
* @
|
|
41
|
-
* @param config Optional request configuration.
|
|
42
|
-
* @returns The execution log or `undefined` when the event was not handled.
|
|
28
|
+
* @param init The request execution configuration
|
|
29
|
+
* @returns The execution log with the variables evaluated during the run or `undefined` when the event was not handled.
|
|
43
30
|
*/
|
|
44
|
-
|
|
45
|
-
const e = new ContextEvent<
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
31
|
+
request: async (init: IRequestProxyInit, target: EventTarget = window): Promise<IProxyResult<IRequestLog> | undefined> => {
|
|
32
|
+
const e = new ContextEvent<IRequestProxyInit, IProxyResult<IRequestLog>>(TransportEventTypes.Core.request, init);
|
|
33
|
+
target.dispatchEvent(e);
|
|
34
|
+
return e.detail.result;
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* For both the project or a folder (since it's all single configuration.)
|
|
39
|
+
*
|
|
40
|
+
* @param target The events target
|
|
41
|
+
* @param init The project execution configuration
|
|
42
|
+
*/
|
|
43
|
+
httpProject: async (init: IHttpProjectProxyInit, target: EventTarget = window): Promise<IProxyResult<IProjectExecutionLog> | undefined> => {
|
|
44
|
+
const e = new ContextEvent<IHttpProjectProxyInit, IProxyResult<IProjectExecutionLog>>(TransportEventTypes.Core.httpProject, init);
|
|
45
|
+
target.dispatchEvent(e);
|
|
46
|
+
return e.detail.result;
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* For both the project or a folder (since it's all single configuration.)
|
|
51
|
+
*
|
|
52
|
+
* @param target The events target
|
|
53
|
+
* @param init The project execution configuration
|
|
54
|
+
*/
|
|
55
|
+
appProject: async (init: IAppProjectProxyInit, target: EventTarget = window): Promise<IProxyResult<IProjectExecutionLog> | undefined> => {
|
|
56
|
+
const e = new ContextEvent<IAppProjectProxyInit, IProxyResult<IProjectExecutionLog>>(TransportEventTypes.Core.appProject, init);
|
|
50
57
|
target.dispatchEvent(e);
|
|
51
58
|
return e.detail.result;
|
|
52
59
|
},
|
|
@@ -74,26 +81,6 @@ export const TransportEvent = Object.freeze({
|
|
|
74
81
|
},
|
|
75
82
|
}),
|
|
76
83
|
|
|
77
|
-
// project runner
|
|
78
|
-
Project: Object.freeze({
|
|
79
|
-
/**
|
|
80
|
-
* For both a request or a folder (since it's all single configuration.)
|
|
81
|
-
*
|
|
82
|
-
* @param target The events target
|
|
83
|
-
* @param project The instance of a project or an id of the project to execute. The current user has to be already authenticated.
|
|
84
|
-
* @param opts The project execution options.
|
|
85
|
-
* @returns
|
|
86
|
-
*/
|
|
87
|
-
send: async (project: HttpProject | string, opts: IProjectRunnerOptions, target: EventTarget = window): Promise<IProjectExecutionLog | undefined> => {
|
|
88
|
-
const e = new ContextEvent<IProjectRequestDetail, IProjectExecutionLog>(TransportEventTypes.Project.send, {
|
|
89
|
-
project,
|
|
90
|
-
opts,
|
|
91
|
-
});
|
|
92
|
-
target.dispatchEvent(e);
|
|
93
|
-
return e.detail.result;
|
|
94
|
-
},
|
|
95
|
-
}),
|
|
96
|
-
|
|
97
84
|
// web sockets.
|
|
98
85
|
Ws: Object.freeze({
|
|
99
86
|
/**
|
|
@@ -154,6 +154,7 @@ export class PayloadSerializer {
|
|
|
154
154
|
const result = await PayloadSerializer.stringifyFormData(payload);
|
|
155
155
|
return result;
|
|
156
156
|
} catch (e: unknown) {
|
|
157
|
+
// eslint-disable-next-line no-console
|
|
157
158
|
console.warn(`Unable to transform FormData: ${(e as Error).message}`);
|
|
158
159
|
}
|
|
159
160
|
}
|
package/src/models/AppProject.ts
CHANGED
|
@@ -983,6 +983,13 @@ export class AppProjectFolder extends AppProjectParent {
|
|
|
983
983
|
listEnvironments(): Environment[] {
|
|
984
984
|
return this.project.listEnvironments({ parent: this.key });
|
|
985
985
|
}
|
|
986
|
+
|
|
987
|
+
/**
|
|
988
|
+
* @returns The list of environments defined in this folder
|
|
989
|
+
*/
|
|
990
|
+
getEnvironments(): Environment[] {
|
|
991
|
+
return this.project.getEnvironments({ parent: this.key });
|
|
992
|
+
}
|
|
986
993
|
}
|
|
987
994
|
|
|
988
995
|
/**
|
|
@@ -1879,6 +1886,15 @@ export class AppProject extends AppProjectParent {
|
|
|
1879
1886
|
return env;
|
|
1880
1887
|
}
|
|
1881
1888
|
|
|
1889
|
+
/**
|
|
1890
|
+
* This method is a link to `listEnvironments()` to be compatible with the HttpProject.
|
|
1891
|
+
*
|
|
1892
|
+
* @returns The list of environments defined in this folder
|
|
1893
|
+
*/
|
|
1894
|
+
getEnvironments(opts?: IAppProjectItemOptions): Environment[] {
|
|
1895
|
+
return this.listEnvironments(opts);
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1882
1898
|
/**
|
|
1883
1899
|
* This is a link to the `getEnvironments()`. The difference is that on the
|
|
1884
1900
|
* project level it won't return environments defined with the class initialization.
|
|
@@ -72,7 +72,7 @@ export class HttpResponse extends SerializablePayload {
|
|
|
72
72
|
/**
|
|
73
73
|
* @param input The response definition used to restore the state.
|
|
74
74
|
*/
|
|
75
|
-
constructor(input?: string|IHttpResponse) {
|
|
75
|
+
constructor(input?: string | IHttpResponse) {
|
|
76
76
|
super();
|
|
77
77
|
let init: IHttpResponse;
|
|
78
78
|
if (typeof input === 'string') {
|
|
@@ -97,7 +97,7 @@ export class HttpResponse extends SerializablePayload {
|
|
|
97
97
|
if (!HttpResponse.isHttpResponse(init)) {
|
|
98
98
|
throw new Error(`Not a response.`);
|
|
99
99
|
}
|
|
100
|
-
const { status, statusText, headers, payload, kind=Kind } = init;
|
|
100
|
+
const { status, statusText, headers, payload, kind = Kind } = init;
|
|
101
101
|
this.kind = kind;
|
|
102
102
|
this.status = status;
|
|
103
103
|
this.statusText = statusText;
|
|
@@ -70,7 +70,7 @@ export class ProjectRequest extends Request implements ProjectDefinitionProperty
|
|
|
70
70
|
if (!project) {
|
|
71
71
|
throw new Error(`The project is required.`);
|
|
72
72
|
}
|
|
73
|
-
const now:number = Date.now();
|
|
73
|
+
const now: number = Date.now();
|
|
74
74
|
const request = new ProjectRequest(project, {
|
|
75
75
|
key: v4(),
|
|
76
76
|
kind: Kind,
|
|
@@ -100,7 +100,7 @@ export class ProjectRequest extends Request implements ProjectDefinitionProperty
|
|
|
100
100
|
if (!project) {
|
|
101
101
|
throw new Error(`The project is required.`);
|
|
102
102
|
}
|
|
103
|
-
const now:number = Date.now();
|
|
103
|
+
const now: number = Date.now();
|
|
104
104
|
const request = new ProjectRequest(project, {
|
|
105
105
|
key: v4(),
|
|
106
106
|
kind: Kind,
|
|
@@ -130,7 +130,7 @@ export class ProjectRequest extends Request implements ProjectDefinitionProperty
|
|
|
130
130
|
if (!project) {
|
|
131
131
|
throw new Error(`The project is required.`);
|
|
132
132
|
}
|
|
133
|
-
const now:number = Date.now();
|
|
133
|
+
const now: number = Date.now();
|
|
134
134
|
const request = new ProjectRequest(project, {
|
|
135
135
|
key: v4(),
|
|
136
136
|
kind: Kind,
|
|
@@ -160,8 +160,8 @@ export class ProjectRequest extends Request implements ProjectDefinitionProperty
|
|
|
160
160
|
const result = new ProjectRequest(project, init);
|
|
161
161
|
return result;
|
|
162
162
|
}
|
|
163
|
-
|
|
164
|
-
constructor(project: HttpProject, input?: string|IProjectRequest | IAppProjectRequest) {
|
|
163
|
+
|
|
164
|
+
constructor(project: HttpProject, input?: string | IProjectRequest | IAppProjectRequest) {
|
|
165
165
|
super(input);
|
|
166
166
|
this.project = project;
|
|
167
167
|
let init: IProjectRequest | IAppProjectRequest;
|
|
@@ -170,7 +170,7 @@ export class ProjectRequest extends Request implements ProjectDefinitionProperty
|
|
|
170
170
|
} else if (typeof input === 'object') {
|
|
171
171
|
init = input;
|
|
172
172
|
} else {
|
|
173
|
-
const now:number = Date.now();
|
|
173
|
+
const now: number = Date.now();
|
|
174
174
|
init = {
|
|
175
175
|
key: v4(),
|
|
176
176
|
kind: Kind,
|
|
@@ -192,7 +192,7 @@ export class ProjectRequest extends Request implements ProjectDefinitionProperty
|
|
|
192
192
|
|
|
193
193
|
new(init: IProjectRequest | IAppProjectRequest): void {
|
|
194
194
|
super.new(init);
|
|
195
|
-
|
|
195
|
+
|
|
196
196
|
const { key } = init;
|
|
197
197
|
this.key = key || v4();
|
|
198
198
|
}
|
|
@@ -224,7 +224,7 @@ export class ProjectRequest extends Request implements ProjectDefinitionProperty
|
|
|
224
224
|
/**
|
|
225
225
|
* @returns The instance of the HttpProject or a ProjectFolder that is a closes parent of this instance.
|
|
226
226
|
*/
|
|
227
|
-
getParent(): ProjectFolder|HttpProject|undefined {
|
|
227
|
+
getParent(): ProjectFolder | HttpProject | undefined {
|
|
228
228
|
const { project, key } = this;
|
|
229
229
|
return project.findParent(key);
|
|
230
230
|
}
|
package/src/models/Request.ts
CHANGED
|
@@ -117,7 +117,7 @@ export class Request {
|
|
|
117
117
|
* @param url The Request URL.
|
|
118
118
|
*/
|
|
119
119
|
static fromUrl(url: string): Request {
|
|
120
|
-
const now:number = Date.now();
|
|
120
|
+
const now: number = Date.now();
|
|
121
121
|
const request = new Request({
|
|
122
122
|
kind: Kind,
|
|
123
123
|
created: now,
|
|
@@ -141,7 +141,7 @@ export class Request {
|
|
|
141
141
|
* @param name The Request name.
|
|
142
142
|
*/
|
|
143
143
|
static fromName(name: string): Request {
|
|
144
|
-
const now:number = Date.now();
|
|
144
|
+
const now: number = Date.now();
|
|
145
145
|
const request = new Request({
|
|
146
146
|
kind: Kind,
|
|
147
147
|
created: now,
|
|
@@ -165,7 +165,7 @@ export class Request {
|
|
|
165
165
|
* @param info The request data.
|
|
166
166
|
*/
|
|
167
167
|
static fromHttpRequest(info: IHttpRequest): Request {
|
|
168
|
-
const now:number = Date.now();
|
|
168
|
+
const now: number = Date.now();
|
|
169
169
|
const request = new Request({
|
|
170
170
|
kind: Kind,
|
|
171
171
|
created: now,
|
|
@@ -185,12 +185,12 @@ export class Request {
|
|
|
185
185
|
return request;
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
static async fromLegacy(request: ARCSavedRequest|ARCHistoryRequest): Promise<Request> {
|
|
188
|
+
static async fromLegacy(request: ARCSavedRequest | ARCHistoryRequest): Promise<Request> {
|
|
189
189
|
const normalized = Normalizer.normalizeRequest(request) as ARCSavedRequest;
|
|
190
190
|
if (!normalized) {
|
|
191
191
|
throw new Error(`Unknown object.`);
|
|
192
192
|
}
|
|
193
|
-
const init:IRequest = {
|
|
193
|
+
const init: IRequest = {
|
|
194
194
|
kind: Kind,
|
|
195
195
|
expects: {
|
|
196
196
|
kind: HttpRequestKind,
|
|
@@ -312,14 +312,14 @@ export class Request {
|
|
|
312
312
|
return this.defaultMidnight();
|
|
313
313
|
}
|
|
314
314
|
|
|
315
|
-
constructor(input?: string|IRequest) {
|
|
315
|
+
constructor(input?: string | IRequest) {
|
|
316
316
|
let init: IRequest;
|
|
317
317
|
if (typeof input === 'string') {
|
|
318
318
|
init = JSON.parse(input);
|
|
319
319
|
} else if (typeof input === 'object') {
|
|
320
320
|
init = input;
|
|
321
321
|
} else {
|
|
322
|
-
const now:number = Date.now();
|
|
322
|
+
const now: number = Date.now();
|
|
323
323
|
init = {
|
|
324
324
|
kind: Kind,
|
|
325
325
|
created: now,
|
|
@@ -82,7 +82,7 @@ export class Normalizer {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
/**
|
|
85
|
-
* Transforms the `TransformedPayload` object to its original data type.
|
|
85
|
+
* Transforms the legacy `TransformedPayload` object to its original data type.
|
|
86
86
|
*/
|
|
87
87
|
static restoreTransformedPayload(body: string | ArrayBuffer | Buffer | LegacyTransformedPayload): string | Buffer | ArrayBuffer | undefined {
|
|
88
88
|
if (!body) {
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { IProjectRunnerOptions } from "../runtime/node/InteropInterfaces.js";
|
|
2
|
+
import { AppProject, AppProjectKind, IAppProject } from "../models/AppProject.js";
|
|
3
|
+
import { ApiError } from "../runtime/store/Errors.js";
|
|
4
|
+
import { StoreSdk } from "../runtime/store/StoreSdkNode.js";
|
|
5
|
+
import { ProjectSerialRunner } from "../runtime/node/ProjectSerialRunner.js";
|
|
6
|
+
import { ProjectParallelRunner } from "../runtime/node/ProjectParallelRunner.js";
|
|
7
|
+
import Proxy, { IProxyResult } from "./Proxy.js";
|
|
8
|
+
|
|
9
|
+
export interface IAppProjectProxyInit {
|
|
10
|
+
kind: typeof AppProjectKind;
|
|
11
|
+
/**
|
|
12
|
+
* Project key
|
|
13
|
+
*/
|
|
14
|
+
pid: string;
|
|
15
|
+
/**
|
|
16
|
+
* Application that created the project id.
|
|
17
|
+
*/
|
|
18
|
+
appId: string;
|
|
19
|
+
/**
|
|
20
|
+
* Runner options.
|
|
21
|
+
*/
|
|
22
|
+
options: IProjectRunnerOptions;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Runs requests from an AppProject read from the store.
|
|
27
|
+
*/
|
|
28
|
+
export default class AppProjectProxy extends Proxy {
|
|
29
|
+
project?: AppProject;
|
|
30
|
+
options?: IProjectRunnerOptions;
|
|
31
|
+
|
|
32
|
+
async configure(init: IAppProjectProxyInit, token: string, baseUri: string): Promise<void> {
|
|
33
|
+
const { pid, appId, options } = init;
|
|
34
|
+
if (!pid) {
|
|
35
|
+
throw new ApiError({
|
|
36
|
+
error: true,
|
|
37
|
+
message: 'Invalid request',
|
|
38
|
+
detail: 'The "pid" parameter is required.',
|
|
39
|
+
code: 400,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
if (!appId) {
|
|
43
|
+
throw new ApiError({
|
|
44
|
+
error: true,
|
|
45
|
+
message: 'Invalid request',
|
|
46
|
+
detail: 'The "appId" parameter is required.',
|
|
47
|
+
code: 400,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (!options) {
|
|
51
|
+
throw new ApiError({
|
|
52
|
+
error: true,
|
|
53
|
+
message: 'Invalid request',
|
|
54
|
+
detail: 'The "options" parameter is required.',
|
|
55
|
+
code: 400,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
if (!token) {
|
|
59
|
+
throw new ApiError({
|
|
60
|
+
error: true,
|
|
61
|
+
message: 'Invalid request',
|
|
62
|
+
detail: 'Set the authentication credentials.',
|
|
63
|
+
code: 400,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
if (!baseUri) {
|
|
67
|
+
throw new ApiError({
|
|
68
|
+
error: true,
|
|
69
|
+
message: 'Invalid request',
|
|
70
|
+
detail: 'The store uri is missing.',
|
|
71
|
+
code: 400,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
if (!baseUri.startsWith('http')) {
|
|
75
|
+
throw new ApiError({
|
|
76
|
+
error: true,
|
|
77
|
+
message: 'Invalid request',
|
|
78
|
+
detail: 'The store uri is invalid.',
|
|
79
|
+
code: 400,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
const sdk = new StoreSdk(baseUri);
|
|
83
|
+
sdk.token = token;
|
|
84
|
+
let project: IAppProject;
|
|
85
|
+
try {
|
|
86
|
+
project = await sdk.app.projects.read(pid, appId);
|
|
87
|
+
} catch (cause) {
|
|
88
|
+
const e = cause as Error;
|
|
89
|
+
throw new ApiError(e.message, 400);
|
|
90
|
+
}
|
|
91
|
+
if (project.key !== pid) {
|
|
92
|
+
throw new ApiError(`Unable to read the project.`, 500);
|
|
93
|
+
}
|
|
94
|
+
this.options = options;
|
|
95
|
+
this.project = new AppProject(project);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async execute(): Promise<IProxyResult> {
|
|
99
|
+
const project = this.project as AppProject;
|
|
100
|
+
const opts = this.options as IProjectRunnerOptions;
|
|
101
|
+
let factory: ProjectParallelRunner | ProjectSerialRunner;
|
|
102
|
+
if (opts.parallel) {
|
|
103
|
+
factory = new ProjectParallelRunner(project, opts);
|
|
104
|
+
} else {
|
|
105
|
+
factory = new ProjectSerialRunner();
|
|
106
|
+
factory.configure(project, opts);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// eslint-disable-next-line no-inner-declarations
|
|
110
|
+
function unhandledRejection(): void {
|
|
111
|
+
//
|
|
112
|
+
}
|
|
113
|
+
// the executing library handles all related errors it need.
|
|
114
|
+
// However, when executing a request to an unknown host Node process may
|
|
115
|
+
// throw unhandled error event when the error is properly reported by the
|
|
116
|
+
// application. This suppresses these errors.
|
|
117
|
+
// Note, uncomment this line for debug.
|
|
118
|
+
process.on('unhandledRejection', unhandledRejection);
|
|
119
|
+
const report = await factory.execute();
|
|
120
|
+
process.off('unhandledRejection', unhandledRejection);
|
|
121
|
+
return {
|
|
122
|
+
result: report,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|