@teamkeel/testing-runtime 0.393.3 → 0.394.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/package.json +2 -1
- package/src/Executor.mjs +104 -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",
|
|
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": "0.394.0-prerelease",
|
|
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,115 @@ 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
|
+
if (inputs != null && typeof inputs === "object") {
|
|
119
|
+
for (const keys of Object.keys(inputs)) {
|
|
120
|
+
if (inputs[keys] !== null && typeof inputs[keys] === "object") {
|
|
121
|
+
if (isInlineFileOrFile(inputs[keys])) {
|
|
122
|
+
const contents = await inputs[keys].read();
|
|
123
|
+
inputs[keys] = `data:${inputs[keys].contentType};name=${
|
|
124
|
+
inputs[keys].filename
|
|
125
|
+
};base64,${contents.toString("base64")}`;
|
|
126
|
+
} else {
|
|
127
|
+
inputs[keys] = await parseInputs(inputs[keys]);
|
|
128
|
+
}
|
|
102
129
|
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return inputs;
|
|
133
|
+
}
|
|
103
134
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
135
|
+
function isInlineFileOrFile(obj) {
|
|
136
|
+
return (
|
|
137
|
+
obj &&
|
|
138
|
+
typeof obj === "object" &&
|
|
139
|
+
(obj.constructor.name === "InlineFile" || obj.constructor.name === "File")
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function parseOutputs(data) {
|
|
144
|
+
if (!data) {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (!isPlainObject(data)) {
|
|
149
|
+
return data;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const keys = data ? Object.keys(data) : [];
|
|
153
|
+
const row = {};
|
|
154
|
+
|
|
155
|
+
for (const key of keys) {
|
|
156
|
+
const value = data[key];
|
|
157
|
+
|
|
158
|
+
if (isPlainObject(value)) {
|
|
159
|
+
if (value.key && value.size && value.filename && value.contentType) {
|
|
160
|
+
row[key] = File.fromDbRecord(value);
|
|
161
|
+
} else {
|
|
162
|
+
row[key] = parseOutputs(value);
|
|
108
163
|
}
|
|
109
|
-
}
|
|
164
|
+
} else if (
|
|
165
|
+
Array.isArray(value) &&
|
|
166
|
+
value.every((item) => typeof item === "object" && item !== null)
|
|
167
|
+
) {
|
|
168
|
+
const arr = [];
|
|
169
|
+
for (let item of value) {
|
|
170
|
+
arr.push(parseOutputs(item));
|
|
171
|
+
}
|
|
172
|
+
row[key] = arr;
|
|
173
|
+
} else {
|
|
174
|
+
row[key] = value;
|
|
175
|
+
}
|
|
110
176
|
}
|
|
177
|
+
return row;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function isPlainObject(obj) {
|
|
181
|
+
return Object.prototype.toString.call(obj) === "[object Object]";
|
|
111
182
|
}
|
|
112
183
|
|
|
113
184
|
const dateFormat = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:(\d{2}(?:\.\d*)?)Z$/;
|