@powerhousedao/pieces-framework 6.2.3-dev.11
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/LICENSE +59 -0
- package/README.md +202 -0
- package/UPSTREAM.md +172 -0
- package/dist/action--RmO83_Y.d.ts +12766 -0
- package/dist/action--RmO83_Y.d.ts.map +1 -0
- package/dist/authentication-B7brX_It.js +242 -0
- package/dist/authentication-B7brX_It.js.map +1 -0
- package/dist/common.d.ts +324 -0
- package/dist/common.d.ts.map +1 -0
- package/dist/common.js +828 -0
- package/dist/common.js.map +1 -0
- package/dist/host.d.ts +95 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +723 -0
- package/dist/host.js.map +1 -0
- package/dist/index-BW6GxXEN.d.ts +5544 -0
- package/dist/index-BW6GxXEN.d.ts.map +1 -0
- package/dist/index.d.ts +1156 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1569 -0
- package/dist/index.js.map +1 -0
- package/dist/input-COuhC1I-.js +308 -0
- package/dist/input-COuhC1I-.js.map +1 -0
- package/dist/markdown-property-Df2l6_y_.js +285 -0
- package/dist/markdown-property-Df2l6_y_.js.map +1 -0
- package/package.json +73 -0
package/dist/common.js
ADDED
|
@@ -0,0 +1,828 @@
|
|
|
1
|
+
import { n as Property, o as assertNotNullOrUndefined, y as createAction } from "./input-COuhC1I-.js";
|
|
2
|
+
import { c as isNil$1, r as tryCatchSync, s as isEmpty } from "./markdown-property-Df2l6_y_.js";
|
|
3
|
+
import * as z from "zod/mini";
|
|
4
|
+
import { PassThrough, Readable } from "node:stream";
|
|
5
|
+
import fs from "node:fs";
|
|
6
|
+
import FormData$1 from "form-data";
|
|
7
|
+
|
|
8
|
+
//#region upstream/common/lib/authentication/index.ts
|
|
9
|
+
let AuthenticationType = /* @__PURE__ */ function(AuthenticationType) {
|
|
10
|
+
AuthenticationType["BEARER_TOKEN"] = "BEARER_TOKEN";
|
|
11
|
+
AuthenticationType["BASIC"] = "BASIC";
|
|
12
|
+
return AuthenticationType;
|
|
13
|
+
}({});
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region upstream/common/lib/http/core/http-header.ts
|
|
17
|
+
let HttpHeader = /* @__PURE__ */ function(HttpHeader) {
|
|
18
|
+
HttpHeader["AUTHORIZATION"] = "Authorization";
|
|
19
|
+
HttpHeader["ACCEPT"] = "Accept";
|
|
20
|
+
HttpHeader["API_KEY"] = "x-api-key";
|
|
21
|
+
HttpHeader["CONTENT_TYPE"] = "Content-Type";
|
|
22
|
+
return HttpHeader;
|
|
23
|
+
}({});
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region upstream/common/lib/http/core/media-type.ts
|
|
27
|
+
let MediaType = /* @__PURE__ */ function(MediaType) {
|
|
28
|
+
MediaType["APPLICATION_JSON"] = "application/json";
|
|
29
|
+
MediaType["TEXT_CSV"] = "text/csv";
|
|
30
|
+
return MediaType;
|
|
31
|
+
}({});
|
|
32
|
+
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region upstream/common/lib/http/core/base-http-client.ts
|
|
35
|
+
var BaseHttpClient = class {
|
|
36
|
+
constructor(baseUrl, authenticationConverter) {
|
|
37
|
+
this.baseUrl = baseUrl;
|
|
38
|
+
this.authenticationConverter = authenticationConverter;
|
|
39
|
+
}
|
|
40
|
+
getUrl(request) {
|
|
41
|
+
const url = new URL(`${this.baseUrl}${request.url}`);
|
|
42
|
+
const urlWithoutQueryParams = `${url.origin}${url.pathname}`;
|
|
43
|
+
const queryParams = new URLSearchParams();
|
|
44
|
+
url.searchParams.forEach((value, key) => {
|
|
45
|
+
queryParams.append(key, value);
|
|
46
|
+
});
|
|
47
|
+
return {
|
|
48
|
+
urlWithoutQueryParams,
|
|
49
|
+
queryParams
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
getHeaders(request) {
|
|
53
|
+
let requestHeaders = { [HttpHeader.ACCEPT]: MediaType.APPLICATION_JSON };
|
|
54
|
+
if (request.authentication) this.populateAuthentication(request.authentication, requestHeaders);
|
|
55
|
+
if (request.body) switch (request.headers?.["Content-Type"]) {
|
|
56
|
+
case "text/csv":
|
|
57
|
+
requestHeaders[HttpHeader.CONTENT_TYPE] = MediaType.TEXT_CSV;
|
|
58
|
+
break;
|
|
59
|
+
default:
|
|
60
|
+
requestHeaders[HttpHeader.CONTENT_TYPE] = MediaType.APPLICATION_JSON;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
if (request.headers) requestHeaders = {
|
|
64
|
+
...requestHeaders,
|
|
65
|
+
...request.headers
|
|
66
|
+
};
|
|
67
|
+
return requestHeaders;
|
|
68
|
+
}
|
|
69
|
+
populateAuthentication(authentication, headers) {
|
|
70
|
+
this.authenticationConverter.convert(authentication, headers);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
//#endregion
|
|
75
|
+
//#region upstream/common/lib/http/core/delegating-authentication-converter.ts
|
|
76
|
+
var DelegatingAuthenticationConverter = class {
|
|
77
|
+
converters;
|
|
78
|
+
constructor(bearerTokenConverter = new BearerTokenAuthenticationConverter(), basicTokenConverter = new BasicTokenAuthenticationConverter()) {
|
|
79
|
+
this.converters = {
|
|
80
|
+
[AuthenticationType.BEARER_TOKEN]: bearerTokenConverter,
|
|
81
|
+
[AuthenticationType.BASIC]: basicTokenConverter
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
convert(authentication, headers) {
|
|
85
|
+
return this.converters[authentication.type].convert(authentication, headers);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
var BearerTokenAuthenticationConverter = class {
|
|
89
|
+
convert(authentication, headers) {
|
|
90
|
+
headers[HttpHeader.AUTHORIZATION] = `Bearer ${authentication.token}`;
|
|
91
|
+
return headers;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
var BasicTokenAuthenticationConverter = class {
|
|
95
|
+
convert(authentication, headers) {
|
|
96
|
+
const credentials = `${authentication.username}:${authentication.password}`;
|
|
97
|
+
const encoded = Buffer.from(credentials).toString("base64");
|
|
98
|
+
headers[HttpHeader.AUTHORIZATION] = `Basic ${encoded}`;
|
|
99
|
+
return headers;
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region upstream/common/lib/http/core/http-error.ts
|
|
105
|
+
var HttpError = class extends Error {
|
|
106
|
+
status;
|
|
107
|
+
responseBody;
|
|
108
|
+
constructor(requestBody, params) {
|
|
109
|
+
const status = params.status || 500;
|
|
110
|
+
const responseBody = Buffer.isBuffer(params.responseBody) ? params.responseBody.toString() : params.responseBody;
|
|
111
|
+
super(JSON.stringify({
|
|
112
|
+
response: {
|
|
113
|
+
status,
|
|
114
|
+
body: responseBody
|
|
115
|
+
},
|
|
116
|
+
request: { body: requestBody }
|
|
117
|
+
}));
|
|
118
|
+
this.requestBody = requestBody;
|
|
119
|
+
this.status = status;
|
|
120
|
+
this.responseBody = responseBody;
|
|
121
|
+
}
|
|
122
|
+
errorMessage() {
|
|
123
|
+
return {
|
|
124
|
+
response: {
|
|
125
|
+
status: this.status,
|
|
126
|
+
body: this.responseBody
|
|
127
|
+
},
|
|
128
|
+
request: { body: this.requestBody }
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
get response() {
|
|
132
|
+
return {
|
|
133
|
+
status: this.status,
|
|
134
|
+
body: this.responseBody
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
get request() {
|
|
138
|
+
return { body: this.requestBody };
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
function toFailsafeOutput({ error, requestBody }) {
|
|
142
|
+
if (error instanceof HttpError) return error.errorMessage();
|
|
143
|
+
return {
|
|
144
|
+
response: {
|
|
145
|
+
status: 0,
|
|
146
|
+
body: error instanceof Error ? error.message : String(error)
|
|
147
|
+
},
|
|
148
|
+
request: { body: requestBody }
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
//#endregion
|
|
153
|
+
//#region upstream/common/lib/http/core/http-method.ts
|
|
154
|
+
let HttpMethod = /* @__PURE__ */ function(HttpMethod) {
|
|
155
|
+
HttpMethod["GET"] = "GET";
|
|
156
|
+
HttpMethod["POST"] = "POST";
|
|
157
|
+
HttpMethod["PATCH"] = "PATCH";
|
|
158
|
+
HttpMethod["PUT"] = "PUT";
|
|
159
|
+
HttpMethod["DELETE"] = "DELETE";
|
|
160
|
+
HttpMethod["HEAD"] = "HEAD";
|
|
161
|
+
return HttpMethod;
|
|
162
|
+
}({});
|
|
163
|
+
|
|
164
|
+
//#endregion
|
|
165
|
+
//#region upstream/common/lib/http/core/fetch-http-client.ts
|
|
166
|
+
var FetchHttpClient = class extends BaseHttpClient {
|
|
167
|
+
constructor(baseUrl = "", authenticationConverter = new DelegatingAuthenticationConverter()) {
|
|
168
|
+
super(baseUrl, authenticationConverter);
|
|
169
|
+
}
|
|
170
|
+
async sendRequest(request, options) {
|
|
171
|
+
const { urlWithoutQueryParams, queryParams: urlQueryParams } = this.getUrl(request);
|
|
172
|
+
const headers = this.getHeaders(request);
|
|
173
|
+
const queryParams = request.queryParams ?? {};
|
|
174
|
+
for (const [key, value] of Object.entries(queryParams)) urlQueryParams.append(key, value);
|
|
175
|
+
const queryString = urlQueryParams.toString();
|
|
176
|
+
const finalUrl = queryString ? `${urlWithoutQueryParams}?${queryString}` : urlWithoutQueryParams;
|
|
177
|
+
const responseType = request.responseType ?? "json";
|
|
178
|
+
const followRedirects = request.followRedirects ?? true;
|
|
179
|
+
const retries = request.retries ?? 0;
|
|
180
|
+
const { body, extraHeaders, isStream } = acceptsRequestBody(request.method) ? serializeBody(request.body, headers) : {
|
|
181
|
+
body: void 0,
|
|
182
|
+
extraHeaders: {},
|
|
183
|
+
isStream: false
|
|
184
|
+
};
|
|
185
|
+
const finalHeaders = normalizeHeaders({
|
|
186
|
+
...headers,
|
|
187
|
+
...extraHeaders
|
|
188
|
+
});
|
|
189
|
+
const response = await sendWithRetries(async () => {
|
|
190
|
+
const controller = new AbortController();
|
|
191
|
+
const timeoutId = request.timeout && request.timeout > 0 ? setTimeout(() => controller.abort(), request.timeout) : void 0;
|
|
192
|
+
try {
|
|
193
|
+
const init = {
|
|
194
|
+
method: request.method.toString(),
|
|
195
|
+
headers: finalHeaders,
|
|
196
|
+
body,
|
|
197
|
+
redirect: followRedirects ? "follow" : "manual",
|
|
198
|
+
signal: controller.signal
|
|
199
|
+
};
|
|
200
|
+
if (isStream) init.duplex = "half";
|
|
201
|
+
if (options?.dispatcher !== void 0) init.dispatcher = options.dispatcher;
|
|
202
|
+
return await fetch(finalUrl, init);
|
|
203
|
+
} finally {
|
|
204
|
+
if (timeoutId !== void 0) clearTimeout(timeoutId);
|
|
205
|
+
}
|
|
206
|
+
}, isStream ? 0 : retries);
|
|
207
|
+
const successCeiling = followRedirects ? 300 : 400;
|
|
208
|
+
if (response.status < 200 || response.status >= successCeiling) {
|
|
209
|
+
const errorBody = await parseResponseBody(response, responseType === "stream" ? "text" : responseType);
|
|
210
|
+
throw new HttpError(request.body, {
|
|
211
|
+
status: response.status,
|
|
212
|
+
responseBody: errorBody
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
const responseBody = await parseResponseBody(response, responseType);
|
|
216
|
+
return {
|
|
217
|
+
status: response.status,
|
|
218
|
+
headers: toHttpHeaders(response.headers),
|
|
219
|
+
body: responseBody
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
function acceptsRequestBody(method) {
|
|
224
|
+
return method !== HttpMethod.GET && method !== HttpMethod.HEAD;
|
|
225
|
+
}
|
|
226
|
+
function serializeBody(body, headers) {
|
|
227
|
+
if (isNil(body)) return {
|
|
228
|
+
body: void 0,
|
|
229
|
+
extraHeaders: {},
|
|
230
|
+
isStream: false
|
|
231
|
+
};
|
|
232
|
+
if (isNodeFormData(body)) {
|
|
233
|
+
const buffered = bufferFormDataIfSafe(body);
|
|
234
|
+
if (buffered !== null) return {
|
|
235
|
+
body: buffered,
|
|
236
|
+
extraHeaders: body.getHeaders(),
|
|
237
|
+
isStream: false
|
|
238
|
+
};
|
|
239
|
+
const stream = new PassThrough();
|
|
240
|
+
body.on("error", (error) => stream.destroy(error));
|
|
241
|
+
body.pipe(stream);
|
|
242
|
+
return {
|
|
243
|
+
body: stream,
|
|
244
|
+
extraHeaders: body.getHeaders(),
|
|
245
|
+
isStream: true
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
if (body instanceof Readable) return {
|
|
249
|
+
body,
|
|
250
|
+
extraHeaders: {},
|
|
251
|
+
isStream: true
|
|
252
|
+
};
|
|
253
|
+
if (typeof body === "string" || Buffer.isBuffer(body) || body instanceof URLSearchParams || body instanceof ArrayBuffer || typeof FormData !== "undefined" && body instanceof FormData || typeof Blob !== "undefined" && body instanceof Blob) return {
|
|
254
|
+
body,
|
|
255
|
+
extraHeaders: {},
|
|
256
|
+
isStream: false
|
|
257
|
+
};
|
|
258
|
+
if ((headers["Content-Type"] ?? headers["content-type"] ?? "").includes("application/x-www-form-urlencoded")) return {
|
|
259
|
+
body: new URLSearchParams(body).toString(),
|
|
260
|
+
extraHeaders: {},
|
|
261
|
+
isStream: false
|
|
262
|
+
};
|
|
263
|
+
return {
|
|
264
|
+
body: JSON.stringify(body),
|
|
265
|
+
extraHeaders: {},
|
|
266
|
+
isStream: false
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
async function parseResponseBody(response, responseType) {
|
|
270
|
+
switch (responseType) {
|
|
271
|
+
case "arraybuffer": return Buffer.from(await response.arrayBuffer());
|
|
272
|
+
case "stream": return isNil(response.body) ? Readable.from([]) : Readable.fromWeb(response.body);
|
|
273
|
+
case "blob": return await response.blob();
|
|
274
|
+
case "text": return await response.text();
|
|
275
|
+
default: {
|
|
276
|
+
const text = await response.text();
|
|
277
|
+
if (text.length === 0) return;
|
|
278
|
+
try {
|
|
279
|
+
return JSON.parse(text);
|
|
280
|
+
} catch {
|
|
281
|
+
return text;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
async function sendWithRetries(fn, retries) {
|
|
287
|
+
let lastError;
|
|
288
|
+
for (let attempt = 0; attempt <= retries; attempt++) try {
|
|
289
|
+
const response = await fn();
|
|
290
|
+
if (response.status >= 500 && attempt < retries) {
|
|
291
|
+
await backoff(attempt);
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
return response;
|
|
295
|
+
} catch (error) {
|
|
296
|
+
lastError = error;
|
|
297
|
+
if (attempt < retries) {
|
|
298
|
+
await backoff(attempt);
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
throw error;
|
|
302
|
+
}
|
|
303
|
+
throw lastError;
|
|
304
|
+
}
|
|
305
|
+
function backoff(attempt) {
|
|
306
|
+
const delayMs = Math.min(1e3 * 2 ** attempt, 3e4);
|
|
307
|
+
return new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
308
|
+
}
|
|
309
|
+
function normalizeHeaders(headers) {
|
|
310
|
+
const entriesByLowerCaseKey = /* @__PURE__ */ new Map();
|
|
311
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
312
|
+
if (value === void 0) continue;
|
|
313
|
+
entriesByLowerCaseKey.set(key.toLowerCase(), [key, Array.isArray(value) ? value.join(", ") : value]);
|
|
314
|
+
}
|
|
315
|
+
return Object.fromEntries(entriesByLowerCaseKey.values());
|
|
316
|
+
}
|
|
317
|
+
function toHttpHeaders(headers) {
|
|
318
|
+
const result = {};
|
|
319
|
+
headers.forEach((value, key) => {
|
|
320
|
+
result[key] = value;
|
|
321
|
+
});
|
|
322
|
+
return result;
|
|
323
|
+
}
|
|
324
|
+
function bufferFormDataIfSafe(body) {
|
|
325
|
+
if (!body.hasKnownLength() || body.getLengthSync() > MAX_BUFFERED_FORM_DATA_BYTES) return null;
|
|
326
|
+
const { data } = tryCatchSync(() => body.getBuffer());
|
|
327
|
+
return data;
|
|
328
|
+
}
|
|
329
|
+
function isNodeFormData(body) {
|
|
330
|
+
return typeof body === "object" && body !== null && typeof body.getHeaders === "function" && typeof body.pipe === "function" && typeof body.on === "function";
|
|
331
|
+
}
|
|
332
|
+
function isNil(value) {
|
|
333
|
+
return value === null || value === void 0;
|
|
334
|
+
}
|
|
335
|
+
const MAX_BUFFERED_FORM_DATA_BYTES = 100 * 1024 * 1024;
|
|
336
|
+
|
|
337
|
+
//#endregion
|
|
338
|
+
//#region upstream/common/lib/http/core/http-client.ts
|
|
339
|
+
const httpClient = new FetchHttpClient();
|
|
340
|
+
|
|
341
|
+
//#endregion
|
|
342
|
+
//#region upstream/common/lib/helpers/index.ts
|
|
343
|
+
const CONTENT_TYPE_EXTENSIONS = {
|
|
344
|
+
"application/json": "json",
|
|
345
|
+
"application/pdf": "pdf",
|
|
346
|
+
"application/xml": "xml",
|
|
347
|
+
"text/xml": "xml",
|
|
348
|
+
"application/zip": "zip",
|
|
349
|
+
"application/gzip": "gz",
|
|
350
|
+
"application/x-tar": "tar",
|
|
351
|
+
"application/octet-stream": "bin",
|
|
352
|
+
"application/msword": "doc",
|
|
353
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
|
|
354
|
+
"application/vnd.ms-excel": "xls",
|
|
355
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx",
|
|
356
|
+
"application/vnd.ms-powerpoint": "ppt",
|
|
357
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation": "pptx",
|
|
358
|
+
"application/rtf": "rtf",
|
|
359
|
+
"application/javascript": "js",
|
|
360
|
+
"application/x-www-form-urlencoded": "bin",
|
|
361
|
+
"text/plain": "txt",
|
|
362
|
+
"text/html": "html",
|
|
363
|
+
"text/css": "css",
|
|
364
|
+
"text/csv": "csv",
|
|
365
|
+
"text/calendar": "ics",
|
|
366
|
+
"text/markdown": "md",
|
|
367
|
+
"image/png": "png",
|
|
368
|
+
"image/jpeg": "jpeg",
|
|
369
|
+
"image/jpg": "jpg",
|
|
370
|
+
"image/gif": "gif",
|
|
371
|
+
"image/webp": "webp",
|
|
372
|
+
"image/svg+xml": "svg",
|
|
373
|
+
"image/bmp": "bmp",
|
|
374
|
+
"image/tiff": "tiff",
|
|
375
|
+
"image/x-icon": "ico",
|
|
376
|
+
"image/vnd.microsoft.icon": "ico",
|
|
377
|
+
"image/heic": "heic",
|
|
378
|
+
"audio/mpeg": "mp3",
|
|
379
|
+
"audio/mp4": "m4a",
|
|
380
|
+
"audio/wav": "wav",
|
|
381
|
+
"audio/x-wav": "wav",
|
|
382
|
+
"audio/ogg": "ogg",
|
|
383
|
+
"audio/webm": "weba",
|
|
384
|
+
"video/mp4": "mp4",
|
|
385
|
+
"video/mpeg": "mpeg",
|
|
386
|
+
"video/webm": "webm",
|
|
387
|
+
"video/quicktime": "mov",
|
|
388
|
+
"video/x-msvideo": "avi",
|
|
389
|
+
"font/woff": "woff",
|
|
390
|
+
"font/woff2": "woff2",
|
|
391
|
+
"font/ttf": "ttf",
|
|
392
|
+
"font/otf": "otf"
|
|
393
|
+
};
|
|
394
|
+
function contentTypeToExtension(contentType) {
|
|
395
|
+
return CONTENT_TYPE_EXTENSIONS[contentType.split(";")[0].trim().toLowerCase()] ?? "";
|
|
396
|
+
}
|
|
397
|
+
const getAccessTokenOrThrow = (auth) => {
|
|
398
|
+
const accessToken = auth?.access_token;
|
|
399
|
+
if (accessToken === void 0) throw new Error("Invalid bearer token");
|
|
400
|
+
return accessToken;
|
|
401
|
+
};
|
|
402
|
+
const joinBaseUrlWithRelativePath = ({ baseUrl, relativePath }) => {
|
|
403
|
+
return `${baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`}${relativePath.startsWith("/") ? relativePath.slice(1) : relativePath}`;
|
|
404
|
+
};
|
|
405
|
+
const getBaseUrlForDescription = (baseUrl, auth) => {
|
|
406
|
+
const exampleBaseUrl = `https://api.example.com`;
|
|
407
|
+
try {
|
|
408
|
+
const baseUrlValue = auth ? baseUrl(auth) : void 0;
|
|
409
|
+
return (baseUrlValue?.endsWith("/") ? baseUrlValue.slice(0, -1) : baseUrlValue) ?? exampleBaseUrl;
|
|
410
|
+
} catch (error) {
|
|
411
|
+
return exampleBaseUrl;
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
function createCustomApiCallAction({ auth, baseUrl, authMapping, description, displayName, name, props, extraProps, authLocation = "headers", classification = "WRITE" }) {
|
|
415
|
+
return createAction({
|
|
416
|
+
audience: "human",
|
|
417
|
+
name: name ? name : "custom_api_call",
|
|
418
|
+
classification,
|
|
419
|
+
displayName: displayName ? displayName : "Custom API Call",
|
|
420
|
+
description: description ? description : "Make a custom API call to a specific endpoint",
|
|
421
|
+
auth,
|
|
422
|
+
requireAuth: auth ? true : false,
|
|
423
|
+
props: {
|
|
424
|
+
url: Property.DynamicProperties({
|
|
425
|
+
auth,
|
|
426
|
+
displayName: "",
|
|
427
|
+
required: true,
|
|
428
|
+
refreshers: [],
|
|
429
|
+
props: async ({ auth }) => {
|
|
430
|
+
return { url: Property.ShortText({
|
|
431
|
+
displayName: "URL",
|
|
432
|
+
description: `Full URL, or a path relative to ${getBaseUrlForDescription(baseUrl, auth)}`,
|
|
433
|
+
required: true,
|
|
434
|
+
placeholder: "/resource",
|
|
435
|
+
defaultValue: auth ? baseUrl(auth) : "",
|
|
436
|
+
...props?.url ?? {}
|
|
437
|
+
}) };
|
|
438
|
+
}
|
|
439
|
+
}),
|
|
440
|
+
method: Property.StaticDropdown({
|
|
441
|
+
displayName: "Method",
|
|
442
|
+
required: true,
|
|
443
|
+
defaultValue: HttpMethod.GET,
|
|
444
|
+
options: { options: Object.values(HttpMethod).map((v) => {
|
|
445
|
+
return {
|
|
446
|
+
label: v,
|
|
447
|
+
value: v
|
|
448
|
+
};
|
|
449
|
+
}) },
|
|
450
|
+
...props?.method ?? {}
|
|
451
|
+
}),
|
|
452
|
+
headers: Property.Object({
|
|
453
|
+
displayName: "Headers",
|
|
454
|
+
description: "Authorization headers are injected automatically from your connection.",
|
|
455
|
+
required: false,
|
|
456
|
+
...props?.headers ?? {}
|
|
457
|
+
}),
|
|
458
|
+
queryParams: Property.Object({
|
|
459
|
+
displayName: "Query Parameters",
|
|
460
|
+
description: "Appended to the URL as ?key=value.",
|
|
461
|
+
required: false,
|
|
462
|
+
...props?.queryParams ?? {}
|
|
463
|
+
}),
|
|
464
|
+
body_type: Property.Dropdown({
|
|
465
|
+
auth,
|
|
466
|
+
displayName: "Body Type",
|
|
467
|
+
required: false,
|
|
468
|
+
defaultValue: "none",
|
|
469
|
+
refreshers: ["method"],
|
|
470
|
+
options: async ({ method }) => {
|
|
471
|
+
if (!acceptsRequestBody(method)) return {
|
|
472
|
+
disabled: true,
|
|
473
|
+
placeholder: "Not available for GET or HEAD requests",
|
|
474
|
+
options: []
|
|
475
|
+
};
|
|
476
|
+
return {
|
|
477
|
+
disabled: false,
|
|
478
|
+
options: [
|
|
479
|
+
{
|
|
480
|
+
label: "None",
|
|
481
|
+
value: "none"
|
|
482
|
+
},
|
|
483
|
+
{
|
|
484
|
+
label: "JSON",
|
|
485
|
+
value: "json"
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
label: "Form Data",
|
|
489
|
+
value: "form_data"
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
label: "Raw",
|
|
493
|
+
value: "raw"
|
|
494
|
+
}
|
|
495
|
+
]
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
}),
|
|
499
|
+
body: Property.DynamicProperties({
|
|
500
|
+
auth,
|
|
501
|
+
displayName: "Body",
|
|
502
|
+
refreshers: ["body_type", "method"],
|
|
503
|
+
required: false,
|
|
504
|
+
props: async ({ body_type, method }) => {
|
|
505
|
+
if (!body_type || !acceptsRequestBody(method)) return {};
|
|
506
|
+
const bodyTypeInput = body_type;
|
|
507
|
+
const fields = {};
|
|
508
|
+
switch (bodyTypeInput) {
|
|
509
|
+
case "none": break;
|
|
510
|
+
case "json":
|
|
511
|
+
fields["data"] = Property.Json({
|
|
512
|
+
displayName: "JSON Body",
|
|
513
|
+
required: true,
|
|
514
|
+
...props?.body ?? {}
|
|
515
|
+
});
|
|
516
|
+
break;
|
|
517
|
+
case "raw":
|
|
518
|
+
fields["data"] = Property.LongText({
|
|
519
|
+
displayName: "Raw Body",
|
|
520
|
+
required: true
|
|
521
|
+
});
|
|
522
|
+
break;
|
|
523
|
+
case "form_data":
|
|
524
|
+
fields["data"] = Property.Array({
|
|
525
|
+
displayName: "Form Data",
|
|
526
|
+
required: true,
|
|
527
|
+
properties: {
|
|
528
|
+
fieldName: Property.ShortText({
|
|
529
|
+
displayName: "Field Name",
|
|
530
|
+
required: true
|
|
531
|
+
}),
|
|
532
|
+
fieldType: Property.StaticDropdown({
|
|
533
|
+
displayName: "Field Type",
|
|
534
|
+
required: true,
|
|
535
|
+
options: {
|
|
536
|
+
disabled: false,
|
|
537
|
+
options: [{
|
|
538
|
+
label: "Text",
|
|
539
|
+
value: "text"
|
|
540
|
+
}, {
|
|
541
|
+
label: "File",
|
|
542
|
+
value: "file"
|
|
543
|
+
}]
|
|
544
|
+
}
|
|
545
|
+
}),
|
|
546
|
+
textFieldValue: Property.LongText({
|
|
547
|
+
displayName: "Text Field Value",
|
|
548
|
+
required: false
|
|
549
|
+
}),
|
|
550
|
+
fileFieldValue: Property.File({
|
|
551
|
+
displayName: "File Field Value",
|
|
552
|
+
required: false
|
|
553
|
+
})
|
|
554
|
+
}
|
|
555
|
+
});
|
|
556
|
+
break;
|
|
557
|
+
}
|
|
558
|
+
return fields;
|
|
559
|
+
}
|
|
560
|
+
}),
|
|
561
|
+
response_is_binary: Property.Checkbox({
|
|
562
|
+
displayName: "Response is Binary",
|
|
563
|
+
description: "Enable for files like PDFs, images, etc.",
|
|
564
|
+
required: false,
|
|
565
|
+
defaultValue: false,
|
|
566
|
+
advanced: true,
|
|
567
|
+
...props?.response_is_binary ?? {}
|
|
568
|
+
}),
|
|
569
|
+
failsafe: Property.Checkbox({
|
|
570
|
+
displayName: "Return Error as Output",
|
|
571
|
+
description: "On a failed request, output the error instead of failing the step.",
|
|
572
|
+
required: false,
|
|
573
|
+
advanced: true,
|
|
574
|
+
...props?.failsafe ?? {}
|
|
575
|
+
}),
|
|
576
|
+
timeout: Property.Number({
|
|
577
|
+
displayName: "Timeout",
|
|
578
|
+
description: "Seconds to wait for a response. Empty: up to the flow limit (10 min).",
|
|
579
|
+
required: false,
|
|
580
|
+
advanced: true,
|
|
581
|
+
...props?.timeout ?? {}
|
|
582
|
+
}),
|
|
583
|
+
followRedirects: Property.Checkbox({
|
|
584
|
+
displayName: "Follow redirects",
|
|
585
|
+
description: "Follow 3xx redirects instead of returning them as the response.",
|
|
586
|
+
required: false,
|
|
587
|
+
defaultValue: false,
|
|
588
|
+
advanced: true,
|
|
589
|
+
...props?.followRedirects ?? {}
|
|
590
|
+
}),
|
|
591
|
+
...extraProps
|
|
592
|
+
},
|
|
593
|
+
run: async (context) => {
|
|
594
|
+
const { method, url, headers, queryParams, body, body_type, failsafe, timeout, response_is_binary, followRedirects } = context.propsValue;
|
|
595
|
+
assertNotNullOrUndefined(method, "Method");
|
|
596
|
+
assertNotNullOrUndefined(url, "URL");
|
|
597
|
+
const authValue = !isNil$1(authMapping) ? await authMapping(context.auth, context.propsValue) : {};
|
|
598
|
+
const urlValue = url["url"];
|
|
599
|
+
const request = {
|
|
600
|
+
method,
|
|
601
|
+
url: urlValue.startsWith("http://") || urlValue.startsWith("https://") ? urlValue : joinBaseUrlWithRelativePath({
|
|
602
|
+
baseUrl: baseUrl(context.auth),
|
|
603
|
+
relativePath: urlValue
|
|
604
|
+
}),
|
|
605
|
+
headers: {
|
|
606
|
+
...headers ?? {},
|
|
607
|
+
...authLocation === "headers" ? authValue : {}
|
|
608
|
+
},
|
|
609
|
+
queryParams: {
|
|
610
|
+
...authLocation === "queryParams" ? authValue : {},
|
|
611
|
+
...queryParams ?? {}
|
|
612
|
+
},
|
|
613
|
+
timeout: timeout ? timeout * 1e3 : 0,
|
|
614
|
+
followRedirects
|
|
615
|
+
};
|
|
616
|
+
if (response_is_binary) request.responseType = "arraybuffer";
|
|
617
|
+
if (body) {
|
|
618
|
+
if (body_type && body_type !== "none") {
|
|
619
|
+
const bodyInput = body["data"];
|
|
620
|
+
if (body_type === "form_data") {
|
|
621
|
+
const formBodyInput = bodyInput;
|
|
622
|
+
const formData = new FormData$1();
|
|
623
|
+
for (const { fieldName, fieldType, textFieldValue, fileFieldValue } of formBodyInput) if (fieldType === "text" && !isEmpty(textFieldValue)) formData.append(fieldName, textFieldValue);
|
|
624
|
+
else if (fieldType === "file" && !isEmpty(fileFieldValue)) formData.append(fieldName, fileFieldValue.data, { filename: fileFieldValue?.filename });
|
|
625
|
+
request.body = formData;
|
|
626
|
+
request.headers = {
|
|
627
|
+
...request.headers,
|
|
628
|
+
...formData.getHeaders()
|
|
629
|
+
};
|
|
630
|
+
} else request.body = bodyInput;
|
|
631
|
+
} else if (!body_type) request.body = body;
|
|
632
|
+
}
|
|
633
|
+
try {
|
|
634
|
+
const response = await httpClient.sendRequest(request);
|
|
635
|
+
return await handleBinaryResponse(context.files, response.body, response.status, response.headers, response_is_binary);
|
|
636
|
+
} catch (error) {
|
|
637
|
+
if (failsafe) return toFailsafeOutput({
|
|
638
|
+
error,
|
|
639
|
+
requestBody: request.body
|
|
640
|
+
});
|
|
641
|
+
throw error;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
function is_chromium_installed() {
|
|
647
|
+
return fs.existsSync("/usr/bin/chromium");
|
|
648
|
+
}
|
|
649
|
+
const handleBinaryResponse = async (files, bodyContent, status, headers, isBinary) => {
|
|
650
|
+
let body;
|
|
651
|
+
if (isBinary && isBinaryBody(bodyContent)) {
|
|
652
|
+
const fileExtension = contentTypeToExtension((Array.isArray(headers?.["content-type"]) ? headers["content-type"][0] : headers?.["content-type"]) ?? "") || "txt";
|
|
653
|
+
let bufferData;
|
|
654
|
+
if (bodyContent instanceof ArrayBuffer) bufferData = Buffer.from(new Uint8Array(bodyContent));
|
|
655
|
+
else if (Buffer.isBuffer(bodyContent)) bufferData = bodyContent;
|
|
656
|
+
else bufferData = Buffer.from(bodyContent);
|
|
657
|
+
body = await files.write({
|
|
658
|
+
fileName: `output.${fileExtension}`,
|
|
659
|
+
data: bufferData
|
|
660
|
+
});
|
|
661
|
+
} else body = bodyContent;
|
|
662
|
+
return {
|
|
663
|
+
status,
|
|
664
|
+
headers,
|
|
665
|
+
body
|
|
666
|
+
};
|
|
667
|
+
};
|
|
668
|
+
const isBinaryBody = (body) => {
|
|
669
|
+
return body instanceof ArrayBuffer || Buffer.isBuffer(body);
|
|
670
|
+
};
|
|
671
|
+
|
|
672
|
+
//#endregion
|
|
673
|
+
//#region upstream/common/lib/polling/index.ts
|
|
674
|
+
let DedupeStrategy = /* @__PURE__ */ function(DedupeStrategy) {
|
|
675
|
+
DedupeStrategy[DedupeStrategy["TIMEBASED"] = 0] = "TIMEBASED";
|
|
676
|
+
DedupeStrategy[DedupeStrategy["LAST_ITEM"] = 1] = "LAST_ITEM";
|
|
677
|
+
return DedupeStrategy;
|
|
678
|
+
}({});
|
|
679
|
+
const pollingHelper = {
|
|
680
|
+
async poll(polling, { store, auth, propsValue, maxItemsToPoll, files, server }) {
|
|
681
|
+
switch (polling.strategy) {
|
|
682
|
+
case DedupeStrategy.TIMEBASED: {
|
|
683
|
+
const lastEpochMilliSeconds = await store.get("lastPoll");
|
|
684
|
+
if (isNil$1(lastEpochMilliSeconds)) throw new Error("lastPoll doesn't exist in the store.");
|
|
685
|
+
const items = await polling.items({
|
|
686
|
+
store,
|
|
687
|
+
auth,
|
|
688
|
+
propsValue,
|
|
689
|
+
lastFetchEpochMS: lastEpochMilliSeconds,
|
|
690
|
+
server
|
|
691
|
+
});
|
|
692
|
+
const newLastEpochMilliSeconds = items.reduce((acc, item) => Math.max(acc, item.epochMilliSeconds), lastEpochMilliSeconds);
|
|
693
|
+
await store.put("lastPoll", newLastEpochMilliSeconds);
|
|
694
|
+
return items.filter((f) => f.epochMilliSeconds > lastEpochMilliSeconds).map((item) => item.data);
|
|
695
|
+
}
|
|
696
|
+
case DedupeStrategy.LAST_ITEM: {
|
|
697
|
+
const lastItemId = await store.get("lastItem");
|
|
698
|
+
const items = await polling.items({
|
|
699
|
+
store,
|
|
700
|
+
auth,
|
|
701
|
+
propsValue,
|
|
702
|
+
lastItemId,
|
|
703
|
+
files,
|
|
704
|
+
server
|
|
705
|
+
});
|
|
706
|
+
const lastItemIndex = items.findIndex((f) => f.id === lastItemId);
|
|
707
|
+
let newItems = [];
|
|
708
|
+
if (isNil$1(lastItemId) || lastItemIndex == -1) newItems = items ?? [];
|
|
709
|
+
else newItems = items?.slice(0, lastItemIndex) ?? [];
|
|
710
|
+
if (!isNil$1(maxItemsToPoll)) newItems = newItems.slice(-maxItemsToPoll);
|
|
711
|
+
const newLastItem = newItems?.[0]?.id;
|
|
712
|
+
if (!isNil$1(newLastItem)) await store.put("lastItem", newLastItem);
|
|
713
|
+
return newItems.map((item) => item.data);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
},
|
|
717
|
+
async onEnable(polling, { store, auth, propsValue, server, isRepublish }) {
|
|
718
|
+
switch (polling.strategy) {
|
|
719
|
+
case DedupeStrategy.TIMEBASED:
|
|
720
|
+
if (isRepublish && !isNil$1(await store.get("lastPoll"))) break;
|
|
721
|
+
await store.put("lastPoll", Date.now());
|
|
722
|
+
break;
|
|
723
|
+
case DedupeStrategy.LAST_ITEM: {
|
|
724
|
+
if (isRepublish && !isNil$1(await store.get("lastItem"))) break;
|
|
725
|
+
const lastItemId = (await polling.items({
|
|
726
|
+
store,
|
|
727
|
+
auth,
|
|
728
|
+
propsValue,
|
|
729
|
+
lastItemId: null,
|
|
730
|
+
server
|
|
731
|
+
}))?.[0]?.id;
|
|
732
|
+
if (!isNil$1(lastItemId)) await store.put("lastItem", lastItemId);
|
|
733
|
+
else await store.delete("lastItem");
|
|
734
|
+
break;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
},
|
|
738
|
+
async onDisable(polling, params) {
|
|
739
|
+
switch (polling.strategy) {
|
|
740
|
+
case DedupeStrategy.TIMEBASED:
|
|
741
|
+
case DedupeStrategy.LAST_ITEM: return;
|
|
742
|
+
}
|
|
743
|
+
},
|
|
744
|
+
async test(polling, { auth, propsValue, store, files, server }) {
|
|
745
|
+
let items = [];
|
|
746
|
+
switch (polling.strategy) {
|
|
747
|
+
case DedupeStrategy.TIMEBASED:
|
|
748
|
+
items = await polling.items({
|
|
749
|
+
store,
|
|
750
|
+
auth,
|
|
751
|
+
propsValue,
|
|
752
|
+
lastFetchEpochMS: 0,
|
|
753
|
+
server
|
|
754
|
+
});
|
|
755
|
+
break;
|
|
756
|
+
case DedupeStrategy.LAST_ITEM:
|
|
757
|
+
items = await polling.items({
|
|
758
|
+
store,
|
|
759
|
+
auth,
|
|
760
|
+
propsValue,
|
|
761
|
+
lastItemId: null,
|
|
762
|
+
files,
|
|
763
|
+
server
|
|
764
|
+
});
|
|
765
|
+
break;
|
|
766
|
+
}
|
|
767
|
+
return getFirstFiveOrAll(items.map((item) => item.data));
|
|
768
|
+
}
|
|
769
|
+
};
|
|
770
|
+
function getFirstFiveOrAll(array) {
|
|
771
|
+
if (array.length <= 5) return array;
|
|
772
|
+
else return array.slice(0, 5);
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
//#endregion
|
|
776
|
+
//#region upstream/common/lib/stream/index.ts
|
|
777
|
+
function toStreamingBody(file) {
|
|
778
|
+
if ("body" in file) return {
|
|
779
|
+
body: file.body,
|
|
780
|
+
size: file.size
|
|
781
|
+
};
|
|
782
|
+
return {
|
|
783
|
+
body: Readable.from(file.data),
|
|
784
|
+
size: file.data.length
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
async function* readChunks({ readable, chunkSize }) {
|
|
788
|
+
let pending = [];
|
|
789
|
+
let pendingLength = 0;
|
|
790
|
+
if (!Number.isInteger(chunkSize) || chunkSize <= 0) throw new Error("chunkSize must be a positive integer");
|
|
791
|
+
for await (const data of readable) {
|
|
792
|
+
pending.push(Buffer.isBuffer(data) ? data : Buffer.from(data));
|
|
793
|
+
pendingLength += pending[pending.length - 1].length;
|
|
794
|
+
while (pendingLength >= chunkSize) {
|
|
795
|
+
const combined = pending.length === 1 ? pending[0] : Buffer.concat(pending);
|
|
796
|
+
yield combined.subarray(0, chunkSize);
|
|
797
|
+
const rest = combined.subarray(chunkSize);
|
|
798
|
+
pending = rest.length > 0 ? [rest] : [];
|
|
799
|
+
pendingLength = rest.length;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
if (pendingLength > 0) yield pending.length === 1 ? pending[0] : Buffer.concat(pending);
|
|
803
|
+
}
|
|
804
|
+
const streamUtils = {
|
|
805
|
+
readChunks,
|
|
806
|
+
toStreamingBody
|
|
807
|
+
};
|
|
808
|
+
|
|
809
|
+
//#endregion
|
|
810
|
+
//#region upstream/common/lib/validation/index.ts
|
|
811
|
+
const propsValidation = { async validateZod(props, schema) {
|
|
812
|
+
const schemaObj = z.object(Object.entries(schema).reduce((acc, [key, value]) => ({
|
|
813
|
+
...acc,
|
|
814
|
+
[key]: value
|
|
815
|
+
}), {}));
|
|
816
|
+
const result = await z.safeParseAsync(schemaObj, props);
|
|
817
|
+
if (!result.success) {
|
|
818
|
+
const errors = result.error.issues.reduce((acc, issue) => ({
|
|
819
|
+
...acc,
|
|
820
|
+
[issue.path.join(".")]: issue.message
|
|
821
|
+
}), {});
|
|
822
|
+
throw new Error(JSON.stringify({ errors }, null, 2));
|
|
823
|
+
}
|
|
824
|
+
} };
|
|
825
|
+
|
|
826
|
+
//#endregion
|
|
827
|
+
export { AuthenticationType, FetchHttpClient as AxiosHttpClient, FetchHttpClient, BaseHttpClient, DedupeStrategy, DelegatingAuthenticationConverter, HttpError, HttpHeader, HttpMethod, MediaType, acceptsRequestBody, createCustomApiCallAction, getAccessTokenOrThrow, httpClient, is_chromium_installed, pollingHelper, propsValidation, streamUtils, toFailsafeOutput };
|
|
828
|
+
//# sourceMappingURL=common.js.map
|