@teamkeel/testing-runtime 0.393.2 → 0.394.0-prerelease
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/package.json +2 -1
- package/src/Executor.mjs +97 -33
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teamkeel/testing-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.394.0-prerelease",
|
|
4
4
|
"description": "Internal package used by the generated @teamkeel/testing package",
|
|
5
5
|
"exports": "./src/index.mjs",
|
|
6
6
|
"typings": "src/index.d.ts",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"prettier": "3.1.1"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
+
"@teamkeel/functions-runtime": "link:../functions-runtime",
|
|
21
22
|
"jsonwebtoken": "^9.0.2",
|
|
22
23
|
"kysely": "^0.26.3",
|
|
23
24
|
"lodash.ismatch": "^4.4.0",
|
package/src/Executor.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import jwt from "jsonwebtoken";
|
|
2
|
+
import { InlineFile, File } from "@teamkeel/functions-runtime";
|
|
2
3
|
|
|
3
4
|
export class Executor {
|
|
4
5
|
constructor(props) {
|
|
@@ -69,45 +70,108 @@ export class Executor {
|
|
|
69
70
|
headers["X-Trigger-Type"] = "manual";
|
|
70
71
|
}
|
|
71
72
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
73
|
+
return parseInputs(params).then((inputs) => {
|
|
74
|
+
// Use the HTTP JSON API as that returns more friendly errors than
|
|
75
|
+
// the JSON-RPC API.
|
|
76
|
+
return fetch(this._apiBaseUrl + "/" + method, {
|
|
77
|
+
method: "POST",
|
|
78
|
+
body: JSON.stringify(inputs),
|
|
79
|
+
headers,
|
|
80
|
+
}).then((r) => {
|
|
81
|
+
if (r.status !== 200) {
|
|
82
|
+
// For non-200 first read the response as text
|
|
83
|
+
return r.text().then((t) => {
|
|
84
|
+
let d;
|
|
85
|
+
try {
|
|
86
|
+
d = JSON.parse(t);
|
|
87
|
+
} catch (e) {
|
|
88
|
+
if ("DEBUG" in process.env) {
|
|
89
|
+
console.log(e);
|
|
90
|
+
}
|
|
91
|
+
// If JSON parsing fails then throw an error with the
|
|
92
|
+
// response text as the message
|
|
93
|
+
throw new Error(t);
|
|
88
94
|
}
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
value: () => t,
|
|
98
|
-
enumerable: false,
|
|
95
|
+
// Otherwise throw the parsed JSON error response
|
|
96
|
+
// We override toString as otherwise you get expect errors like:
|
|
97
|
+
// `expected to resolve but rejected with "[object Object]"`
|
|
98
|
+
Object.defineProperty(d, "toString", {
|
|
99
|
+
value: () => t,
|
|
100
|
+
enumerable: false,
|
|
101
|
+
});
|
|
102
|
+
throw d;
|
|
99
103
|
});
|
|
100
|
-
|
|
101
|
-
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (this._parseJsonResult) {
|
|
107
|
+
return r.text().then((t) => {
|
|
108
|
+
const response = JSON.parse(t, reviver);
|
|
109
|
+
return parseOutputs(response);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async function parseInputs(inputs) {
|
|
118
|
+
// console.log(inputs)
|
|
119
|
+
if (inputs != null && typeof inputs === "object") {
|
|
120
|
+
for (const i of Object.keys(inputs)) {
|
|
121
|
+
if (inputs[i] !== null && typeof inputs[i] === "object") {
|
|
122
|
+
if (inputs[i] instanceof InlineFile || inputs[i] instanceof File) {
|
|
123
|
+
const contents = await inputs[i].read();
|
|
124
|
+
inputs[i] = `data:${inputs[i].contentType};name=${
|
|
125
|
+
inputs[i].filename
|
|
126
|
+
};base64,${contents.toString("base64")}`;
|
|
127
|
+
} else {
|
|
128
|
+
inputs[i] = await parseInputs(inputs[i]);
|
|
129
|
+
}
|
|
102
130
|
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return inputs;
|
|
134
|
+
}
|
|
103
135
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
136
|
+
function parseOutputs(data) {
|
|
137
|
+
if (!data) {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (!isPlainObject(data)) {
|
|
142
|
+
return data;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const keys = data ? Object.keys(data) : [];
|
|
146
|
+
const row = {};
|
|
147
|
+
|
|
148
|
+
for (const key of keys) {
|
|
149
|
+
const value = data[key];
|
|
150
|
+
|
|
151
|
+
if (isPlainObject(value)) {
|
|
152
|
+
if (value.key && value.size && value.filename && value.contentType) {
|
|
153
|
+
row[key] = File.fromDbRecord(value);
|
|
154
|
+
} else {
|
|
155
|
+
row[key] = parseOutputs(value);
|
|
108
156
|
}
|
|
109
|
-
}
|
|
157
|
+
} else if (
|
|
158
|
+
Array.isArray(value) &&
|
|
159
|
+
value.every((item) => typeof item === "object" && item !== null)
|
|
160
|
+
) {
|
|
161
|
+
const arr = [];
|
|
162
|
+
for (let item of value) {
|
|
163
|
+
arr.push(parseOutputs(item));
|
|
164
|
+
}
|
|
165
|
+
row[key] = arr;
|
|
166
|
+
} else {
|
|
167
|
+
row[key] = value;
|
|
168
|
+
}
|
|
110
169
|
}
|
|
170
|
+
return row;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function isPlainObject(obj) {
|
|
174
|
+
return Object.prototype.toString.call(obj) === "[object Object]";
|
|
111
175
|
}
|
|
112
176
|
|
|
113
177
|
const dateFormat = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:(\d{2}(?:\.\d*)?)Z$/;
|