@tachybase/module-workflow
Version:
A powerful BPM tool that provides foundational support for business automation, with the capability to extend unlimited triggers and nodes.
208 lines (207 loc) • 8.19 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var RequestInstruction_exports = {};
__export(RequestInstruction_exports, {
default: () => RequestInstruction_default
});
module.exports = __toCommonJS(RequestInstruction_exports);
var import_node_fs = __toESM(require("node:fs"));
var import_node_os = __toESM(require("node:os"));
var import_node_path = __toESM(require("node:path"));
var import_server = require("@tego/server");
var import_axios = __toESM(require("axios"));
var import_form_data = __toESM(require("form-data"));
var import_lodash = __toESM(require("lodash"));
var import_mime_types = __toESM(require("mime-types"));
var import__ = require("../..");
async function downloadToStream(resourceUrl, Headers, param, body) {
try {
const response = await (0, import_axios.default)({
method: "GET",
url: resourceUrl,
headers: Headers,
params: param,
data: body,
responseType: "stream"
});
const ext = import_mime_types.default.extension(Headers["Content-Type"]);
let tempFileName;
do {
tempFileName = `${(0, import_server.uid)()}.${ext}`;
} while (import_node_fs.default.existsSync(tempFileName));
const tempFilePath = import_node_path.default.join(import_node_os.default.tmpdir(), tempFileName);
const writeStream = import_node_fs.default.createWriteStream(tempFilePath);
response.data.pipe(writeStream);
return new Promise((resolve, reject) => {
writeStream.on("finish", () => {
resolve(import_node_fs.default.createReadStream(tempFilePath));
});
writeStream.on("error", (error) => {
import_node_fs.default.unlinkSync(tempFilePath);
reject(error);
});
});
} catch (error) {
console.error("\u4E0B\u8F7D\u6587\u4EF6\u65F6\u51FA\u9519:", error);
throw error;
}
}
async function request(config, context) {
var _a;
const { token, origin } = context;
const { method = "POST", needAuthorization = true, data, timeout = 5e3 } = config;
const originUrl = ((_a = config.url) == null ? void 0 : _a.trim()) || "";
const url = originUrl.startsWith("http") ? originUrl : `${origin}${originUrl}`;
let headers = (config.headers ?? []).reduce((result, header) => {
return Object.assign(result, { [header.name]: header.value });
}, {});
const params = (config.params ?? []).reduce(
(result, param) => Object.assign(result, { [param.name]: param.value }),
{}
);
const requestParams = {
url,
method,
headers,
params,
data,
timeout
};
if (needAuthorization) {
requestParams.headers = {
Authorization: "Bearer " + token,
...headers
};
}
if (headers["Content-Type"] === "multipart/form-data") {
const formData = new import_form_data.default();
for (const [key, value] of Object.entries(data)) {
if (key === "file") {
let { url: resourceUrl, params: resourceParams, headers: resourceHeader, body: resourceBody } = data[key];
resourceUrl = (resourceUrl == null ? void 0 : resourceUrl.trim()) || "";
if (resourceHeader["Content-Type"] === "multipart/form-data" && resourceBody) {
const formData2 = new import_form_data.default();
Object.entries(resourceBody).forEach(([key2, value2]) => {
formData2.append(key2, value2);
});
config.data = formData2;
} else {
config.data = resourceBody;
}
const stream = await downloadToStream(resourceUrl, resourceHeader, resourceParams, resourceBody);
formData.append("file", stream);
headers = { ...formData.getHeaders() };
} else {
formData.append(key, data[key]);
}
}
requestParams.data = formData;
} else {
headers["Content-Type"] = "application/json";
}
return import_axios.default.request(requestParams);
}
class RequestInstruction_default extends import__.Instruction {
async run(node, prevJob, processor) {
var _a, _b;
const userId = import_lodash.default.get(processor.getScope(node.id), "$context.user.id", "");
const origin = import_server.Gateway.getInstance().runAtLoop;
const token = this.workflow.app.authManager.jwt.sign({ userId });
const context = { token, origin };
const config = processor.getParsedValue(node.config, node.id);
const requestParams = JSON.parse(JSON.stringify(config));
const { workflow } = processor.execution;
const sync = this.workflow.isWorkflowSync(workflow);
const loopData = prevJob.result;
if (loopData["length"]) {
config.params.push(
{ name: "loopLength", value: loopData["length"] },
{ name: "loopIndex", value: loopData["index"] }
);
}
if (sync) {
try {
const response = await request(config, context);
response.data = {
requestParams: { ...requestParams, headers: { ...requestParams.headers, ...(_a = response.config) == null ? void 0 : _a.headers } },
...response.data
};
return {
status: import__.JOB_STATUS.RESOLVED,
result: response.data
};
} catch (error) {
return {
status: import__.JOB_STATUS.FAILED,
result: {
requestParams: { ...requestParams, headers: { ...requestParams.headers, ...(_b = error.config) == null ? void 0 : _b.headers } },
error: error.isAxiosError ? error.toJSON() : error.message
}
};
}
}
const job = await processor.saveJob({
status: import__.JOB_STATUS.PENDING,
nodeId: node.id,
nodeKey: node.key,
upstreamId: (prevJob == null ? void 0 : prevJob.id) ?? null
});
request(config, context).then((response) => {
var _a2;
response.data = {
requestParams: { ...requestParams, headers: { ...requestParams.headers, ...(_a2 = response.config) == null ? void 0 : _a2.headers } },
...response.data
};
job.set({
status: import__.JOB_STATUS.RESOLVED,
result: response.data
});
}).catch((error) => {
var _a2;
job.set({
status: import__.JOB_STATUS.FAILED,
result: {
requestParams: { ...requestParams, headers: { ...requestParams.headers, ...(_a2 = error.config) == null ? void 0 : _a2.headers } },
error: error.isAxiosError ? error.toJSON() : error.message
}
});
}).finally(() => {
processor.logger.info(`request (#${node.id}) response received, status: ${job.get("status")}`);
this.workflow.resume(job);
});
processor.logger.info(`request (#${node.id}) sent to "${config.url}", waiting for response...`);
return processor.exit();
}
async resume(node, job, processor) {
const { ignoreFail } = node.config;
if (ignoreFail) {
job.set("status", import__.JOB_STATUS.RESOLVED);
}
return job;
}
}