@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.
Files changed (76) hide show
  1. package/build/browser.d.ts +5 -1
  2. package/build/browser.js.map +1 -1
  3. package/build/index.d.ts +6 -1
  4. package/build/index.js +8 -0
  5. package/build/index.js.map +1 -1
  6. package/build/src/cookies/CookieParser.d.ts +11 -0
  7. package/build/src/cookies/CookieParser.js +39 -26
  8. package/build/src/cookies/CookieParser.js.map +1 -1
  9. package/build/src/events/EventTypes.d.ts +3 -4
  10. package/build/src/events/Events.d.ts +3 -4
  11. package/build/src/events/transport/TransportEventTypes.d.ts +3 -4
  12. package/build/src/events/transport/TransportEventTypes.js +3 -7
  13. package/build/src/events/transport/TransportEventTypes.js.map +1 -1
  14. package/build/src/events/transport/TransportEvents.d.ts +21 -29
  15. package/build/src/events/transport/TransportEvents.js +26 -29
  16. package/build/src/events/transport/TransportEvents.js.map +1 -1
  17. package/build/src/lib/transformers/PayloadSerializer.js +1 -0
  18. package/build/src/lib/transformers/PayloadSerializer.js.map +1 -1
  19. package/build/src/models/AppProject.d.ts +10 -0
  20. package/build/src/models/AppProject.js +14 -0
  21. package/build/src/models/AppProject.js.map +1 -1
  22. package/build/src/models/HttpResponse.js.map +1 -1
  23. package/build/src/models/ProjectRequest.js.map +1 -1
  24. package/build/src/models/Request.js.map +1 -1
  25. package/build/src/models/legacy/Normalizer.d.ts +1 -1
  26. package/build/src/models/legacy/Normalizer.js +1 -1
  27. package/build/src/proxy/AppProjectProxy.d.ts +27 -0
  28. package/build/src/proxy/AppProjectProxy.js +107 -0
  29. package/build/src/proxy/AppProjectProxy.js.map +1 -0
  30. package/build/src/proxy/HttpProjectProxy.d.ts +23 -0
  31. package/build/src/proxy/HttpProjectProxy.js +99 -0
  32. package/build/src/proxy/HttpProjectProxy.js.map +1 -0
  33. package/build/src/proxy/Proxy.d.ts +27 -0
  34. package/build/src/proxy/Proxy.js +7 -0
  35. package/build/src/proxy/Proxy.js.map +1 -0
  36. package/build/src/proxy/ProxyService.d.ts +42 -0
  37. package/build/src/proxy/ProxyService.js +66 -0
  38. package/build/src/proxy/ProxyService.js.map +1 -0
  39. package/build/src/proxy/RequestProxy.d.ts +42 -0
  40. package/build/src/proxy/RequestProxy.js +59 -0
  41. package/build/src/proxy/RequestProxy.js.map +1 -0
  42. package/build/src/runtime/http-runner/HttpRequestRunner.d.ts +5 -0
  43. package/build/src/runtime/http-runner/HttpRequestRunner.js +18 -0
  44. package/build/src/runtime/http-runner/HttpRequestRunner.js.map +1 -1
  45. package/build/src/runtime/node/InteropInterfaces.d.ts +2 -1
  46. package/build/src/runtime/node/ProjectParallelRunner.d.ts +3 -2
  47. package/build/src/runtime/node/ProjectParallelRunner.js.map +1 -1
  48. package/build/src/runtime/node/ProjectRequestRunner.d.ts +0 -5
  49. package/build/src/runtime/node/ProjectRequestRunner.js +1 -18
  50. package/build/src/runtime/node/ProjectRequestRunner.js.map +1 -1
  51. package/build/src/runtime/node/ProjectRunner.d.ts +3 -3
  52. package/build/src/runtime/node/ProjectRunner.js.map +1 -1
  53. package/build/src/runtime/node/ProjectRunnerWorker.js +23 -5
  54. package/build/src/runtime/node/ProjectRunnerWorker.js.map +1 -1
  55. package/package.json +4 -1
  56. package/src/cookies/CookieParser.ts +40 -26
  57. package/src/events/transport/TransportEventTypes.ts +4 -8
  58. package/src/events/transport/TransportEvents.ts +32 -45
  59. package/src/lib/transformers/PayloadSerializer.ts +1 -0
  60. package/src/models/AppProject.ts +16 -0
  61. package/src/models/HttpResponse.ts +2 -2
  62. package/src/models/ProjectRequest.ts +8 -8
  63. package/src/models/Request.ts +7 -7
  64. package/src/models/legacy/Normalizer.ts +1 -1
  65. package/src/proxy/AppProjectProxy.ts +125 -0
  66. package/src/proxy/HttpProjectProxy.ts +113 -0
  67. package/src/proxy/Proxy.ts +30 -0
  68. package/src/proxy/ProxyService.ts +73 -0
  69. package/src/proxy/RequestProxy.ts +94 -0
  70. package/src/proxy/readme.md +14 -0
  71. package/src/runtime/http-runner/HttpRequestRunner.ts +19 -0
  72. package/src/runtime/node/InteropInterfaces.ts +2 -1
  73. package/src/runtime/node/ProjectParallelRunner.ts +3 -2
  74. package/src/runtime/node/ProjectRequestRunner.ts +2 -20
  75. package/src/runtime/node/ProjectRunner.ts +3 -3
  76. 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.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
- * When `host` or `path` part is missing from the cookie, the URL values are used.
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 parse(requestUrl: string, setCookie?: string): HttpCookie[] {
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
- // At this point we have all cookies set by the server. Now we need to filter out cookies
157
- // set for a different domains.
158
-
159
- // first lets set cookie domain and path.
160
- const url = new URL(requestUrl);
161
- const domain = this.canonicalDomain(url.host);
162
- const path = this.getPath(url);
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
- result.forEach((cookie) => {
165
- if (!cookie.path) {
166
- cookie.path = path;
167
- }
168
- if (!cookie.domain) {
169
- // point 6. of https://tools.ietf.org/html/rfc6265#section-5.3
170
- cookie.domain = domain;
171
- cookie.hostOnly = true;
172
- } else if (cookie.domain[0] !== '.') {
173
- // https://stackoverflow.com/a/1063760/1127848
174
- cookie.domain = `.${cookie.domain}`;
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
- // sends a request
7
- send: 'coretransportsend',
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
- export interface ICoreRequestDetail {
14
- request: IHttpRequest;
15
- authorization?: IRequestAuthorization[];
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 request The request definition
40
- * @param authorization When known, a list of authorization configuration to apply to the request.
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
- send: async (request: IHttpRequest, authorization?: IRequestAuthorization[], config?: IRequestBaseConfig, target: EventTarget = window): Promise<IRequestLog | undefined> => {
45
- const e = new ContextEvent<ICoreRequestDetail, IRequestLog>(TransportEventTypes.Core.send, {
46
- request,
47
- authorization,
48
- config
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
  }
@@ -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
  }
@@ -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
+ }