@rudderhq/server 0.7.18 → 0.7.19-canary.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/dist/agent-runtimes/registry.d.ts.map +1 -1
- package/dist/agent-runtimes/registry.js +2 -1
- package/dist/agent-runtimes/registry.js.map +1 -1
- package/dist/file-system-durability.d.ts +5 -0
- package/dist/file-system-durability.d.ts.map +1 -0
- package/dist/file-system-durability.js +39 -0
- package/dist/file-system-durability.js.map +1 -0
- package/dist/home-paths.d.ts +1 -0
- package/dist/home-paths.d.ts.map +1 -1
- package/dist/home-paths.js +705 -102
- package/dist/home-paths.js.map +1 -1
- package/dist/routes/chats.d.ts.map +1 -1
- package/dist/routes/chats.js +2 -0
- package/dist/routes/chats.js.map +1 -1
- package/dist/routes/issues.d.ts.map +1 -1
- package/dist/routes/issues.js +27 -5
- package/dist/routes/issues.js.map +1 -1
- package/dist/routes/issues.mutations.d.ts.map +1 -1
- package/dist/routes/issues.mutations.js +10 -6
- package/dist/routes/issues.mutations.js.map +1 -1
- package/dist/routes/orgs.d.ts.map +1 -1
- package/dist/routes/orgs.js +28 -7
- package/dist/routes/orgs.js.map +1 -1
- package/dist/routes/rudder-plugins.d.ts +5 -0
- package/dist/routes/rudder-plugins.d.ts.map +1 -1
- package/dist/routes/rudder-plugins.js +21 -1
- package/dist/routes/rudder-plugins.js.map +1 -1
- package/dist/routes/rudder-plugins.test.d.ts +2 -0
- package/dist/routes/rudder-plugins.test.d.ts.map +1 -0
- package/dist/routes/rudder-plugins.test.js +42 -0
- package/dist/routes/rudder-plugins.test.js.map +1 -0
- package/dist/routes/run-intelligence.d.ts.map +1 -1
- package/dist/routes/run-intelligence.js +8 -0
- package/dist/routes/run-intelligence.js.map +1 -1
- package/dist/services/agent-issue-creation.d.ts.map +1 -1
- package/dist/services/agent-issue-creation.js +2 -0
- package/dist/services/agent-issue-creation.js.map +1 -1
- package/dist/services/chat-assistant.d.ts.map +1 -1
- package/dist/services/chat-assistant.helpers.d.ts +4 -2
- package/dist/services/chat-assistant.helpers.d.ts.map +1 -1
- package/dist/services/chat-assistant.helpers.js +5 -0
- package/dist/services/chat-assistant.helpers.js.map +1 -1
- package/dist/services/chat-assistant.js +31 -8
- package/dist/services/chat-assistant.js.map +1 -1
- package/dist/services/chat-inline-annotations.test.js +6 -3
- package/dist/services/chat-inline-annotations.test.js.map +1 -1
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js.map +1 -1
- package/dist/services/issue-references.d.ts +10 -0
- package/dist/services/issue-references.d.ts.map +1 -0
- package/dist/services/issue-references.js +141 -0
- package/dist/services/issue-references.js.map +1 -0
- package/dist/services/issues.d.ts +1 -1
- package/dist/services/issues.d.ts.map +1 -1
- package/dist/services/issues.helpers.d.ts +4 -0
- package/dist/services/issues.helpers.d.ts.map +1 -1
- package/dist/services/issues.helpers.js.map +1 -1
- package/dist/services/issues.js +164 -97
- package/dist/services/issues.js.map +1 -1
- package/dist/services/organization-workspace-browser.d.ts +6 -2
- package/dist/services/organization-workspace-browser.d.ts.map +1 -1
- package/dist/services/organization-workspace-browser.js +212 -47
- package/dist/services/organization-workspace-browser.js.map +1 -1
- package/dist/services/plugin-archive-native.d.ts +10 -0
- package/dist/services/plugin-archive-native.d.ts.map +1 -0
- package/dist/services/plugin-archive-native.js +170 -0
- package/dist/services/plugin-archive-native.js.map +1 -0
- package/dist/services/plugin-archive-node.d.ts +3 -0
- package/dist/services/plugin-archive-node.d.ts.map +1 -0
- package/dist/services/plugin-archive-node.js +97 -0
- package/dist/services/plugin-archive-node.js.map +1 -0
- package/dist/services/rudder-plugins.d.ts +1 -1
- package/dist/services/rudder-plugins.d.ts.map +1 -1
- package/dist/services/rudder-plugins.js +54 -93
- package/dist/services/rudder-plugins.js.map +1 -1
- package/dist/services/rudder-plugins.test.js +51 -0
- package/dist/services/rudder-plugins.test.js.map +1 -1
- package/dist/services/run-intelligence.d.ts +1 -0
- package/dist/services/run-intelligence.d.ts.map +1 -1
- package/dist/services/run-intelligence.js +1 -1
- package/dist/services/run-intelligence.js.map +1 -1
- package/dist/services/run-log-store.d.ts +1 -0
- package/dist/services/run-log-store.d.ts.map +1 -1
- package/dist/services/run-log-store.js +123 -4
- package/dist/services/run-log-store.js.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.d.ts +1 -0
- package/dist/services/runtime-kernel/heartbeat.d.ts.map +1 -1
- package/dist/services/runtime-kernel/heartbeat.js.map +1 -1
- package/dist/services/runtime-kernel/model-fallback.d.ts.map +1 -1
- package/dist/services/runtime-kernel/model-fallback.js +56 -11
- package/dist/services/runtime-kernel/model-fallback.js.map +1 -1
- package/dist/services/workspace-backup-v2.d.ts +1 -0
- package/dist/services/workspace-backup-v2.d.ts.map +1 -1
- package/dist/services/workspace-backup-v2.js +16 -0
- package/dist/services/workspace-backup-v2.js.map +1 -1
- package/dist/services/workspace-backups.d.ts.map +1 -1
- package/dist/services/workspace-backups.js +4 -2
- package/dist/services/workspace-backups.js.map +1 -1
- package/dist/services/workspace-files-native.d.ts +16 -0
- package/dist/services/workspace-files-native.d.ts.map +1 -0
- package/dist/services/workspace-files-native.js +212 -0
- package/dist/services/workspace-files-native.js.map +1 -0
- package/dist/services/workspace-manifest-native.d.ts +1 -1
- package/dist/services/workspace-manifest-native.d.ts.map +1 -1
- package/dist/services/workspace-manifest-native.js +49 -6
- package/dist/services/workspace-manifest-native.js.map +1 -1
- package/dist/services/workspace-runtime.helpers.d.ts.map +1 -1
- package/dist/services/workspace-runtime.helpers.js +13 -11
- package/dist/services/workspace-runtime.helpers.js.map +1 -1
- package/package.json +14 -14
- package/resources/bundled-skills/rudder-docs/SKILL.md +12 -12
- package/resources/bundled-skills/rudder-docs/references/source-map.md +7 -31
- package/skills/rudder-docs/SKILL.md +12 -12
- package/skills/rudder-docs/references/source-map.md +7 -31
- package/ui-dist/assets/{LibraryLiveSurface-BHneB__U.js → LibraryLiveSurface-D-6Puw4N.js} +1 -1
- package/ui-dist/assets/{abnfDiagram-VRR7QNED-GUoY9rTt.js → abnfDiagram-VRR7QNED-DjgQ9iD_.js} +1 -1
- package/ui-dist/assets/{addon-fit-CqXXE0-1.js → addon-fit-OOCvZY14.js} +1 -1
- package/ui-dist/assets/{arc-BD7m_r6l.js → arc-D6yqUjH4.js} +1 -1
- package/ui-dist/assets/{architectureDiagram-ZJ3FMSHR-nEufXAY_.js → architectureDiagram-ZJ3FMSHR-eF-Es2a-.js} +1 -1
- package/ui-dist/assets/{blockDiagram-677ZJIJ3-D3qUEbL5.js → blockDiagram-677ZJIJ3-B7G2uxR7.js} +1 -1
- package/ui-dist/assets/{c4Diagram-LMCZKHZV-7SPUxKgx.js → c4Diagram-LMCZKHZV-YhY4bz85.js} +1 -1
- package/ui-dist/assets/channel-DISxdJMI.js +1 -0
- package/ui-dist/assets/{chunk-2Q5K7J3B-6o3ETzOY.js → chunk-2Q5K7J3B-D7QxbIUK.js} +1 -1
- package/ui-dist/assets/{chunk-32BRIVSS-Efd566e8.js → chunk-32BRIVSS-CArPDsLy.js} +1 -1
- package/ui-dist/assets/{chunk-5VM5RSS4-BA4X4gzU.js → chunk-5VM5RSS4-ByyAjdOI.js} +1 -1
- package/ui-dist/assets/{chunk-EX3LRPZG-BD7K-mPD.js → chunk-EX3LRPZG-B6Z9cEKa.js} +1 -1
- package/ui-dist/assets/{chunk-JWPE2WC7-DXv6iHxr.js → chunk-JWPE2WC7-L5jYy4CI.js} +1 -1
- package/ui-dist/assets/{chunk-MOJQB5TN-dQ6gk-_u.js → chunk-MOJQB5TN-BBTZZsOQ.js} +1 -1
- package/ui-dist/assets/{chunk-RYQCIY6F-xEk6bTb7.js → chunk-RYQCIY6F-DyV9CaPT.js} +1 -1
- package/ui-dist/assets/{chunk-V7JOEXUC-zlvz5Y5q.js → chunk-V7JOEXUC-CNztgBrF.js} +1 -1
- package/ui-dist/assets/{chunk-VR4S4FIN--zCSWk5F.js → chunk-VR4S4FIN-Bv62Xmto.js} +1 -1
- package/ui-dist/assets/{chunk-XXDRQBXY-CZ2QWPRe.js → chunk-XXDRQBXY-B5AzJDaz.js} +1 -1
- package/ui-dist/assets/classDiagram-OUVF2IWQ-BssC8UiF.js +1 -0
- package/ui-dist/assets/classDiagram-v2-EOCWNBFH-BssC8UiF.js +1 -0
- package/ui-dist/assets/{cose-bilkent-JH36ORCC-DrRNgFzR.js → cose-bilkent-JH36ORCC-DrzyjyO_.js} +1 -1
- package/ui-dist/assets/{cynefin-VYW2F7L2-T9PONuTh.js → cynefin-VYW2F7L2-ChoChVKW.js} +1 -1
- package/ui-dist/assets/{cynefinDiagram-TSTJHNR4-Dkop4mS3.js → cynefinDiagram-TSTJHNR4-Fv4ecj_f.js} +1 -1
- package/ui-dist/assets/{dagre-VKFMJZFB-Chc8Imxx.js → dagre-VKFMJZFB-Zd466k0O.js} +1 -1
- package/ui-dist/assets/{diagram-FQU43EPY-n4pgnJYP.js → diagram-FQU43EPY-BgL3Uu7z.js} +1 -1
- package/ui-dist/assets/{diagram-G47NLZAW-DnjvVsj5.js → diagram-G47NLZAW-Bcbg2TZF.js} +1 -1
- package/ui-dist/assets/{diagram-NH7WQ7WH-kHZ9astC.js → diagram-NH7WQ7WH-YS4gl6dx.js} +1 -1
- package/ui-dist/assets/{diagram-OA4YK3LP-BAMly3yv.js → diagram-OA4YK3LP-C-A8A6Xi.js} +1 -1
- package/ui-dist/assets/{diagram-WEI45ONY-BTFQhBrp.js → diagram-WEI45ONY-mqkaxwes.js} +1 -1
- package/ui-dist/assets/{ebnfDiagram-CCIWWBDH-c2T4DORg.js → ebnfDiagram-CCIWWBDH-CvH1cI4K.js} +1 -1
- package/ui-dist/assets/{erDiagram-Q63AITRT-BXLi1JHT.js → erDiagram-Q63AITRT-Duhw1MUB.js} +1 -1
- package/ui-dist/assets/{flowDiagram-23GEKE2U-CHzX7naH.js → flowDiagram-23GEKE2U-DUkAECUs.js} +1 -1
- package/ui-dist/assets/{ganttDiagram-NO4QXBWP-BqUKeoDF.js → ganttDiagram-NO4QXBWP-B3cINaqn.js} +1 -1
- package/ui-dist/assets/{gitGraphDiagram-IHSO6WYX-DM4K-DoE.js → gitGraphDiagram-IHSO6WYX-BMEHvYy5.js} +1 -1
- package/ui-dist/assets/{graph-BDejhZe_.js → graph-B1-dUGRC.js} +1 -1
- package/ui-dist/assets/{index-BJ-hTdyx.js → index-BFmYzGL9.js} +1 -1
- package/ui-dist/assets/{index-DSAl1a-M.js → index-BGAEBJze.js} +1 -1
- package/ui-dist/assets/{index-CH8tOJZ9.js → index-BMfPEMCH.js} +1 -1
- package/ui-dist/assets/{index-BuCCxdIU.js → index-BglV2AAc.js} +1 -1
- package/ui-dist/assets/{index-CV0k_zvK.js → index-Blix7pGb.js} +1 -1
- package/ui-dist/assets/{index-XnCv8P5f.js → index-CBrXXiQ_.js} +1 -1
- package/ui-dist/assets/{index-CIbvFYbV.js → index-CSMCUMYP.js} +1 -1
- package/ui-dist/assets/index-CUW-AUBO.css +32 -0
- package/ui-dist/assets/{index-Bni14R_J.js → index-CaveK_TY.js} +1 -1
- package/ui-dist/assets/{index-WbyFmgaS.js → index-DHcvu8nk.js} +1 -1
- package/ui-dist/assets/{index-DAM3EGbv.js → index-DSz4Tjbh.js} +1 -1
- package/ui-dist/assets/{index-DVDu5Nwd.js → index-DgNZ8Oto.js} +1 -1
- package/ui-dist/assets/{index-DZBZIqJI.js → index-Drmy6GaQ.js} +1 -1
- package/ui-dist/assets/{index-B4zWD5-i.js → index-DvrowL98.js} +1 -1
- package/ui-dist/assets/{index-BN90mN5Z.js → index-DxHCQu-4.js} +1 -1
- package/ui-dist/assets/{index-DHzaZSPM.js → index-IJhIHwGp.js} +546 -546
- package/ui-dist/assets/{infoDiagram-FWYZ7A6U-PcFBrZTu.js → infoDiagram-FWYZ7A6U-BJ7smuOx.js} +1 -1
- package/ui-dist/assets/{ishikawaDiagram-FXEZZL3T-BF2qBweH.js → ishikawaDiagram-FXEZZL3T-Bn7jPYRy.js} +1 -1
- package/ui-dist/assets/{journeyDiagram-5HDEW3XC-D3TqAoEB.js → journeyDiagram-5HDEW3XC-D5NYECBN.js} +1 -1
- package/ui-dist/assets/{kanban-definition-HUTT4EX6-CUiHrckR.js → kanban-definition-HUTT4EX6-CcrYvDYt.js} +1 -1
- package/ui-dist/assets/{layout-DMKAzTyC.js → layout-32M7EWAw.js} +1 -1
- package/ui-dist/assets/{linear-D8C0WdTA.js → linear-DT9kJUfH.js} +1 -1
- package/ui-dist/assets/{map-DUCHGq8e.js → map-C2crE4Bv.js} +1 -1
- package/ui-dist/assets/{mermaid.core-C-eoqr77.js → mermaid.core-B9y8ebhy.js} +4 -4
- package/ui-dist/assets/{mindmap-definition-LN4V7U3C-B54nV_Hu.js → mindmap-definition-LN4V7U3C-CaFsY4LT.js} +1 -1
- package/ui-dist/assets/{pegDiagram-2B236MQR-CcIDNzTo.js → pegDiagram-2B236MQR-BMTtqHzV.js} +1 -1
- package/ui-dist/assets/{pieDiagram-ENE6RG2P-BU4swrSE.js → pieDiagram-ENE6RG2P-DRl32AMI.js} +1 -1
- package/ui-dist/assets/{quadrantDiagram-ABIIQ3AL-CnniDL18.js → quadrantDiagram-ABIIQ3AL-pXeC4qE5.js} +1 -1
- package/ui-dist/assets/{railroadDiagram-RFXS5EU6-CiBY7wpV.js → railroadDiagram-RFXS5EU6-tGzWZNPI.js} +1 -1
- package/ui-dist/assets/{requirementDiagram-TGXJPOKE-C7c_tTqS.js → requirementDiagram-TGXJPOKE-DEqEN1a0.js} +1 -1
- package/ui-dist/assets/{sankeyDiagram-HTMAVEWB-DJuTS99d.js → sankeyDiagram-HTMAVEWB-DjVDCNO4.js} +1 -1
- package/ui-dist/assets/{sequenceDiagram-DBY2YBRQ-BxhtY70W.js → sequenceDiagram-DBY2YBRQ-CRKMhKhd.js} +1 -1
- package/ui-dist/assets/{sizeCapture-X5ZJPWSS-0A0Kww03.js → sizeCapture-X5ZJPWSS-CWl0gYed.js} +1 -1
- package/ui-dist/assets/{stateDiagram-2N3HPSRC-DPw4bytW.js → stateDiagram-2N3HPSRC-BH6FVEBD.js} +1 -1
- package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-DFWkP3y3.js +1 -0
- package/ui-dist/assets/{swimlanes-5IMT3BWC-D6MMDWrs.js → swimlanes-5IMT3BWC-BZdn1cQ5.js} +2 -2
- package/ui-dist/assets/swimlanesDiagram-G3AALYLV-BwA91U1K.js +8 -0
- package/ui-dist/assets/{timeline-definition-FHXFAJF6-gNKDUxQx.js → timeline-definition-FHXFAJF6-CMofE9DN.js} +1 -1
- package/ui-dist/assets/{vennDiagram-L72KCM5P-BpZCM-ST.js → vennDiagram-L72KCM5P-CszussGd.js} +1 -1
- package/ui-dist/assets/{wardleyDiagram-EHGQE667-CvR0dYqn.js → wardleyDiagram-EHGQE667-C1Op8a5q.js} +1 -1
- package/ui-dist/assets/{xterm-CEksOm0P.js → xterm-BM41mI-I.js} +1 -1
- package/ui-dist/assets/{xychartDiagram-FW5EYKEG-C6_4sxeI.js → xychartDiagram-FW5EYKEG-zi-IHNrX.js} +1 -1
- package/ui-dist/index.html +2 -2
- package/ui-dist/assets/channel-Czz1OwXA.js +0 -1
- package/ui-dist/assets/classDiagram-OUVF2IWQ-C_ooAkuA.js +0 -1
- package/ui-dist/assets/classDiagram-v2-EOCWNBFH-C_ooAkuA.js +0 -1
- package/ui-dist/assets/index-BsB7Sc7m.css +0 -32
- package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-ANI7JZ72.js +0 -1
- package/ui-dist/assets/swimlanesDiagram-G3AALYLV-CxjGCcz5.js +0 -8
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { resolveNativeCommand } from "@rudderhq/agent-runtime-utils";
|
|
2
|
+
import { execFile } from "node:child_process";
|
|
3
|
+
import { existsSync, promises as fs } from "node:fs";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import { promisify } from "node:util";
|
|
8
|
+
const execFileAsync = promisify(execFile);
|
|
9
|
+
const PROTOCOL_VERSION = 1;
|
|
10
|
+
// HTTP accepts a 10 MiB compressed ZIP; PLUGIN.IMPORT.001 allows 100 MiB after expansion.
|
|
11
|
+
const MAX_ARCHIVE_BYTES = 10 * 1024 * 1024;
|
|
12
|
+
const MAX_PLUGIN_BYTES = 100 * 1024 * 1024;
|
|
13
|
+
const MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
14
|
+
const MAX_FILES = 500;
|
|
15
|
+
const MAX_EXPANSION_RATIO = 100;
|
|
16
|
+
const MAX_OUTPUT_BYTES = 170 * 1024 * 1024;
|
|
17
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
18
|
+
const INPUT_ERROR_CODES = new Set([
|
|
19
|
+
"plugin_archive_size_limit",
|
|
20
|
+
"plugin_archive_invalid",
|
|
21
|
+
"plugin_archive_path_invalid",
|
|
22
|
+
"plugin_archive_path_unsafe",
|
|
23
|
+
"plugin_archive_file_count_limit",
|
|
24
|
+
"plugin_archive_file_size_limit",
|
|
25
|
+
"plugin_archive_expansion_limit",
|
|
26
|
+
"plugin_archive_total_size_limit",
|
|
27
|
+
"plugin_archive_duplicate_path",
|
|
28
|
+
"plugin_archive_size_mismatch",
|
|
29
|
+
"plugin_archive_read_failed",
|
|
30
|
+
"plugin_archive_empty",
|
|
31
|
+
]);
|
|
32
|
+
export class PluginArchiveNativeError extends Error {
|
|
33
|
+
code;
|
|
34
|
+
fallbackAllowed;
|
|
35
|
+
inputRejected;
|
|
36
|
+
constructor(code, fallbackAllowed, inputRejected) {
|
|
37
|
+
super(`Native Plugin archive inspection failed: ${code}`);
|
|
38
|
+
this.code = code;
|
|
39
|
+
this.fallbackAllowed = fallbackAllowed;
|
|
40
|
+
this.inputRejected = inputRejected;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function decodeBase64(value) {
|
|
44
|
+
const compact = value.replace(/\s/g, "");
|
|
45
|
+
if (!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(compact)) {
|
|
46
|
+
throw new PluginArchiveNativeError("plugin_archive_base64_invalid", false, true);
|
|
47
|
+
}
|
|
48
|
+
return Buffer.from(compact, "base64");
|
|
49
|
+
}
|
|
50
|
+
export function resolveNativePluginArchiveBinary() {
|
|
51
|
+
const configured = process.env.RUDDER_NATIVE_PLUGIN_ARCHIVE_PATH?.trim()
|
|
52
|
+
|| process.env.RUDDER_NATIVE_ARCHIVE_PATH?.trim();
|
|
53
|
+
if (configured)
|
|
54
|
+
return path.resolve(configured);
|
|
55
|
+
const binaryName = process.platform === "win32" ? "rudder-native.exe" : "rudder-native";
|
|
56
|
+
const moduleDir = path.dirname(fileURLToPath(import.meta.url));
|
|
57
|
+
const target = process.platform === "darwin"
|
|
58
|
+
? `${process.arch === "arm64" ? "aarch64" : "x86_64"}-apple-darwin`
|
|
59
|
+
: process.platform === "win32"
|
|
60
|
+
? `${process.arch === "arm64" ? "aarch64" : "x86_64"}-pc-windows-msvc`
|
|
61
|
+
: `${process.arch === "arm64" ? "aarch64" : "x86_64"}-unknown-linux-gnu`;
|
|
62
|
+
const resourcesPath = process.env.RUDDER_DESKTOP_RESOURCES_PATH?.trim()
|
|
63
|
+
|| (typeof process.resourcesPath === "string"
|
|
64
|
+
? process.resourcesPath
|
|
65
|
+
: "");
|
|
66
|
+
const candidates = [
|
|
67
|
+
path.resolve(moduleDir, "../../../native/target/debug", binaryName),
|
|
68
|
+
path.resolve(moduleDir, "../../../../native/target/debug", binaryName),
|
|
69
|
+
path.resolve(moduleDir, "../../../native", target, binaryName),
|
|
70
|
+
resourcesPath ? path.resolve(resourcesPath, "native", target, binaryName) : "",
|
|
71
|
+
].filter(Boolean);
|
|
72
|
+
return candidates.find((candidate) => existsSync(candidate)) ?? candidates[0];
|
|
73
|
+
}
|
|
74
|
+
function timeoutMs() {
|
|
75
|
+
const configured = Number(process.env.RUDDER_NATIVE_PLUGIN_ARCHIVE_TIMEOUT_MS ?? DEFAULT_TIMEOUT_MS);
|
|
76
|
+
return Number.isFinite(configured) ? Math.max(10, Math.min(DEFAULT_TIMEOUT_MS, Math.floor(configured))) : DEFAULT_TIMEOUT_MS;
|
|
77
|
+
}
|
|
78
|
+
function parseFiles(response) {
|
|
79
|
+
if (response.ok !== true
|
|
80
|
+
|| response.operation !== "inspectPluginArchive"
|
|
81
|
+
|| response.protocolVersion !== PROTOCOL_VERSION
|
|
82
|
+
|| !Array.isArray(response.files)) {
|
|
83
|
+
throw new PluginArchiveNativeError("plugin_archive_envelope_mismatch", true, false);
|
|
84
|
+
}
|
|
85
|
+
return response.files.map((file) => {
|
|
86
|
+
if (!file || typeof file !== "object" || Array.isArray(file)) {
|
|
87
|
+
throw new PluginArchiveNativeError("plugin_archive_file_envelope_invalid", true, false);
|
|
88
|
+
}
|
|
89
|
+
const record = file;
|
|
90
|
+
if (typeof record.path !== "string" || typeof record.content !== "string" || record.encoding !== "base64") {
|
|
91
|
+
throw new PluginArchiveNativeError("plugin_archive_file_envelope_invalid", true, false);
|
|
92
|
+
}
|
|
93
|
+
return { path: record.path, content: record.content, encoding: "base64" };
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
export async function inspectPluginArchiveNative(input, signal) {
|
|
97
|
+
const archive = decodeBase64(input.content);
|
|
98
|
+
if (archive.byteLength > MAX_ARCHIVE_BYTES) {
|
|
99
|
+
throw new PluginArchiveNativeError("plugin_archive_size_limit", false, true);
|
|
100
|
+
}
|
|
101
|
+
const staging = await fs.mkdtemp(path.join(os.tmpdir(), "rudder-plugin-archive-"));
|
|
102
|
+
const archivePath = path.join(staging, "input.zip");
|
|
103
|
+
try {
|
|
104
|
+
await fs.writeFile(archivePath, archive);
|
|
105
|
+
const command = resolveNativeCommand(resolveNativePluginArchiveBinary(), [
|
|
106
|
+
"plugin",
|
|
107
|
+
"inspect-archive",
|
|
108
|
+
archivePath,
|
|
109
|
+
String(MAX_ARCHIVE_BYTES),
|
|
110
|
+
String(MAX_FILE_BYTES),
|
|
111
|
+
String(MAX_PLUGIN_BYTES),
|
|
112
|
+
String(MAX_FILES),
|
|
113
|
+
String(MAX_EXPANSION_RATIO),
|
|
114
|
+
]);
|
|
115
|
+
let stdout;
|
|
116
|
+
let stderr;
|
|
117
|
+
try {
|
|
118
|
+
const result = await execFileAsync(command.command, command.args, {
|
|
119
|
+
encoding: "utf8",
|
|
120
|
+
timeout: timeoutMs(),
|
|
121
|
+
maxBuffer: MAX_OUTPUT_BYTES,
|
|
122
|
+
windowsHide: true,
|
|
123
|
+
signal,
|
|
124
|
+
});
|
|
125
|
+
stdout = result.stdout;
|
|
126
|
+
stderr = result.stderr;
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
const details = error;
|
|
130
|
+
const output = typeof details.stdout === "string" ? details.stdout : "";
|
|
131
|
+
const lines = output.trim().split(/\r?\n/).filter(Boolean);
|
|
132
|
+
if (lines.length === 1) {
|
|
133
|
+
try {
|
|
134
|
+
const parsed = JSON.parse(lines[0]);
|
|
135
|
+
if (typeof parsed.errorCode === "string") {
|
|
136
|
+
const inputRejected = INPUT_ERROR_CODES.has(parsed.errorCode);
|
|
137
|
+
throw new PluginArchiveNativeError(parsed.errorCode, !inputRejected, inputRejected);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch (parsedError) {
|
|
141
|
+
if (parsedError instanceof PluginArchiveNativeError)
|
|
142
|
+
throw parsedError;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (details.name === "AbortError")
|
|
146
|
+
throw new PluginArchiveNativeError("plugin_archive_cancelled", false, false);
|
|
147
|
+
if (details.killed || details.signal === "SIGTERM" || details.code === "ETIMEDOUT") {
|
|
148
|
+
throw new PluginArchiveNativeError("plugin_archive_timeout", true, false);
|
|
149
|
+
}
|
|
150
|
+
throw new PluginArchiveNativeError("plugin_archive_process_failed", true, false);
|
|
151
|
+
}
|
|
152
|
+
if (stderr.trim())
|
|
153
|
+
throw new PluginArchiveNativeError("plugin_archive_unexpected_stderr", true, false);
|
|
154
|
+
const lines = stdout.trim().split(/\r?\n/).filter(Boolean);
|
|
155
|
+
if (lines.length !== 1)
|
|
156
|
+
throw new PluginArchiveNativeError("plugin_archive_response_line_count", true, false);
|
|
157
|
+
let response;
|
|
158
|
+
try {
|
|
159
|
+
response = JSON.parse(lines[0]);
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
throw new PluginArchiveNativeError("plugin_archive_malformed_json", true, false);
|
|
163
|
+
}
|
|
164
|
+
return parseFiles(response);
|
|
165
|
+
}
|
|
166
|
+
finally {
|
|
167
|
+
await fs.rm(staging, { recursive: true, force: true });
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=plugin-archive-native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-archive-native.js","sourceRoot":"","sources":["../../src/services/plugin-archive-native.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-archive-node.d.ts","sourceRoot":"","sources":["../../src/services/plugin-archive-node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAmBrE,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,GAAG,4BAA4B,EAAE,CAuE/H"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Unzip, UnzipInflate, UnzipPassThrough } from "fflate";
|
|
2
|
+
import { unprocessable } from "../errors.js";
|
|
3
|
+
// HTTP accepts a 10 MiB compressed ZIP; PLUGIN.IMPORT.001 allows 100 MiB after expansion.
|
|
4
|
+
const MAX_ARCHIVE_BYTES = 10 * 1024 * 1024;
|
|
5
|
+
const MAX_PLUGIN_BYTES = 100 * 1024 * 1024;
|
|
6
|
+
const MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
7
|
+
const MAX_PATH_CHARS = 1_024;
|
|
8
|
+
const MAX_ARCHIVE_RATIO = 100;
|
|
9
|
+
function decodeBase64(value, label) {
|
|
10
|
+
const compact = value.replace(/\s/g, "");
|
|
11
|
+
if (!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(compact)) {
|
|
12
|
+
throw unprocessable(`Invalid base64 content for ${label}`);
|
|
13
|
+
}
|
|
14
|
+
return Buffer.from(compact, "base64");
|
|
15
|
+
}
|
|
16
|
+
export function unzipPluginPackageNode(content, label, stripPluginRoot) {
|
|
17
|
+
const archive = decodeBase64(content, label);
|
|
18
|
+
if (archive.byteLength > MAX_ARCHIVE_BYTES)
|
|
19
|
+
throw unprocessable("Plugin archive exceeds the 10 MiB transport limit");
|
|
20
|
+
const files = [];
|
|
21
|
+
let totalBytes = 0;
|
|
22
|
+
let failure = null;
|
|
23
|
+
const unzip = new Unzip((file) => {
|
|
24
|
+
if (failure || file.name.endsWith("/"))
|
|
25
|
+
return;
|
|
26
|
+
if (Array.from(file.name).length > MAX_PATH_CHARS || /[\u0000-\u001f\u007f-\u009f]/u.test(file.name)) {
|
|
27
|
+
failure = new Error(`Plugin archive path is invalid: ${file.name}`);
|
|
28
|
+
file.terminate();
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (files.length >= 500) {
|
|
32
|
+
failure = new Error("Plugin archive exceeds the 500-file V1 limit");
|
|
33
|
+
file.terminate();
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (file.originalSize !== undefined && file.originalSize > MAX_FILE_BYTES) {
|
|
37
|
+
failure = new Error(`Plugin archive entry exceeds 2 MiB: ${file.name}`);
|
|
38
|
+
file.terminate();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (file.size && file.originalSize && file.originalSize / file.size > MAX_ARCHIVE_RATIO) {
|
|
42
|
+
failure = new Error(`Plugin archive entry exceeds the ${MAX_ARCHIVE_RATIO}:1 expansion limit: ${file.name}`);
|
|
43
|
+
file.terminate();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const chunks = [];
|
|
47
|
+
let entryBytes = 0;
|
|
48
|
+
file.ondata = (error, data, final) => {
|
|
49
|
+
if (failure)
|
|
50
|
+
return;
|
|
51
|
+
if (error) {
|
|
52
|
+
failure = error;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
entryBytes += data.byteLength;
|
|
56
|
+
totalBytes += data.byteLength;
|
|
57
|
+
if (entryBytes > MAX_FILE_BYTES || totalBytes > MAX_PLUGIN_BYTES) {
|
|
58
|
+
failure = new Error(entryBytes > MAX_FILE_BYTES
|
|
59
|
+
? `Plugin archive entry exceeds 2 MiB: ${file.name}`
|
|
60
|
+
: "Plugin archive exceeds the 100 MiB expansion limit");
|
|
61
|
+
file.terminate();
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
chunks.push(Buffer.from(data));
|
|
65
|
+
if (final) {
|
|
66
|
+
files.push({ path: file.name, content: Buffer.concat(chunks).toString("base64"), encoding: "base64" });
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
file.start();
|
|
70
|
+
});
|
|
71
|
+
unzip.register(UnzipInflate);
|
|
72
|
+
unzip.register(UnzipPassThrough);
|
|
73
|
+
try {
|
|
74
|
+
unzip.push(archive, true);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
throw unprocessable(`Invalid ZIP Plugin archive: ${error instanceof Error ? error.message : String(error)}`);
|
|
78
|
+
}
|
|
79
|
+
const archiveFailure = failure;
|
|
80
|
+
if (archiveFailure)
|
|
81
|
+
throw unprocessable(archiveFailure.message);
|
|
82
|
+
if (files.length === 0)
|
|
83
|
+
throw unprocessable("Invalid ZIP Plugin archive: archive contains no files");
|
|
84
|
+
if (totalBytes > archive.byteLength * MAX_ARCHIVE_RATIO) {
|
|
85
|
+
throw unprocessable(`Plugin archive exceeds the ${MAX_ARCHIVE_RATIO}:1 expansion limit`);
|
|
86
|
+
}
|
|
87
|
+
if (!stripPluginRoot || files.some((file) => file.path === ".codex-plugin/plugin.json"))
|
|
88
|
+
return files;
|
|
89
|
+
const manifests = files.filter((file) => file.path.endsWith("/.codex-plugin/plugin.json"));
|
|
90
|
+
if (manifests.length !== 1)
|
|
91
|
+
return files;
|
|
92
|
+
const prefix = manifests[0].path.slice(0, -".codex-plugin/plugin.json".length);
|
|
93
|
+
if (!files.every((file) => file.path.startsWith(prefix)))
|
|
94
|
+
return files;
|
|
95
|
+
return files.map((file) => ({ ...file, path: file.path.slice(prefix.length) }));
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=plugin-archive-node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-archive-node.js","sourceRoot":"","sources":["../../src/services/plugin-archive-node.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,0FAA0F;AAC1F,MAAM,iBAAiB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAC3C,MAAM,gBAAgB,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AAC3C,MAAM,cAAc,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AACvC,MAAM,cAAc,GAAG,KAAK,CAAC;AAC7B,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAE9B,SAAS,YAAY,CAAC,KAAa,EAAE,KAAa;IAChD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACzC,IAAI,CAAC,kEAAkE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACtF,MAAM,aAAa,CAAC,8BAA8B,KAAK,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAAe,EAAE,KAAa,EAAE,eAAwB;IAC7F,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC7C,IAAI,OAAO,CAAC,UAAU,GAAG,iBAAiB;QAAE,MAAM,aAAa,CAAC,mDAAmD,CAAC,CAAC;IACrH,MAAM,KAAK,GAAmC,EAAE,CAAC;IACjD,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,OAAO,GAAiB,IAAI,CAAC;IACjC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE;QAC/B,IAAI,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO;QAC/C,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,cAAc,IAAI,+BAA+B,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACrG,OAAO,GAAG,IAAI,KAAK,CAAC,mCAAmC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YACpE,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;YACxB,OAAO,GAAG,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;YACpE,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,IAAI,IAAI,CAAC,YAAY,GAAG,cAAc,EAAE,CAAC;YAC1E,OAAO,GAAG,IAAI,KAAK,CAAC,uCAAuC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YACxE,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,GAAG,iBAAiB,EAAE,CAAC;YACxF,OAAO,GAAG,IAAI,KAAK,CAAC,oCAAoC,iBAAiB,uBAAuB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAC7G,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;YACnC,IAAI,OAAO;gBAAE,OAAO;YACpB,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,GAAG,KAAK,CAAC;gBAChB,OAAO;YACT,CAAC;YACD,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC;YAC9B,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC;YAC9B,IAAI,UAAU,GAAG,cAAc,IAAI,UAAU,GAAG,gBAAgB,EAAE,CAAC;gBACjE,OAAO,GAAG,IAAI,KAAK,CAAC,UAAU,GAAG,cAAc;oBAC7C,CAAC,CAAC,uCAAuC,IAAI,CAAC,IAAI,EAAE;oBACpD,CAAC,CAAC,oDAAoD,CAAC,CAAC;gBAC1D,IAAI,CAAC,SAAS,EAAE,CAAC;gBACjB,OAAO;YACT,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAC/B,IAAI,KAAK,EAAE,CAAC;gBACV,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;YACzG,CAAC;QACH,CAAC,CAAC;QACF,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC7B,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IACjC,IAAI,CAAC;QACH,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,aAAa,CAAC,+BAA+B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC/G,CAAC;IACD,MAAM,cAAc,GAAG,OAAuB,CAAC;IAC/C,IAAI,cAAc;QAAE,MAAM,aAAa,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IAChE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,aAAa,CAAC,uDAAuD,CAAC,CAAC;IACrG,IAAI,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,iBAAiB,EAAE,CAAC;QACxD,MAAM,aAAa,CAAC,8BAA8B,iBAAiB,oBAAoB,CAAC,CAAC;IAC3F,CAAC;IACD,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,2BAA2B,CAAC;QAAE,OAAO,KAAK,CAAC;IACtG,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,4BAA4B,CAAC,CAAC,CAAC;IAC3F,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACzC,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,2BAA2B,CAAC,MAAM,CAAC,CAAC;IAChF,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACvE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;AAClF,CAAC"}
|
|
@@ -88,7 +88,7 @@ export declare function rudderPluginService(db: Db, mcpOptions: ManagedMcpConnec
|
|
|
88
88
|
locator?: string | null;
|
|
89
89
|
metadata?: Record<string, unknown>;
|
|
90
90
|
}) => Promise<RudderPluginImportReport>>[2]) => Promise<RudderPluginImportReport>;
|
|
91
|
-
inspectArchive: (orgId: string, input: InspectRudderPluginArchive) => Promise<RudderPluginImportReport>;
|
|
91
|
+
inspectArchive: (orgId: string, input: InspectRudderPluginArchive, signal?: AbortSignal) => Promise<RudderPluginImportReport>;
|
|
92
92
|
install: (orgId: string, reportId: string, enabled?: boolean, confirmAccessExpansion?: boolean, skillConflictStrategy?: RudderPluginSkillConflictStrategy) => Promise<RudderInstalledPlugin>;
|
|
93
93
|
listInstalled: (orgId: string) => Promise<RudderInstalledPlugin[]>;
|
|
94
94
|
listMcpUiResources: (orgId: string, pluginId: string, componentId: string) => Promise<RudderMcpUiResource[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rudder-plugins.d.ts","sourceRoot":"","sources":["../../src/services/rudder-plugins.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAavC,OAAO,KAAK,EACV,gCAAgC,EAChC,mBAAmB,EACnB,0BAA0B,EAC1B,qBAAqB,EAErB,mBAAmB,EAGnB,qBAAqB,EAErB,wBAAwB,EAExB,iCAAiC,EAClC,MAAM,kBAAkB,CAAC;AAO1B,OAAO,KAAK,EAAE,kCAAkC,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"rudder-plugins.d.ts","sourceRoot":"","sources":["../../src/services/rudder-plugins.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAavC,OAAO,KAAK,EACV,gCAAgC,EAChC,mBAAmB,EACnB,0BAA0B,EAC1B,qBAAqB,EAErB,mBAAmB,EAGnB,qBAAqB,EAErB,wBAAwB,EAExB,iCAAiC,EAClC,MAAM,kBAAkB,CAAC;AAO1B,OAAO,KAAK,EAAE,kCAAkC,EAAE,MAAM,8BAA8B,CAAC;AAqBvF,KAAK,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,CAAC;AAC1E,KAAK,YAAY,GAAG,IAAI,CAAC,wBAAwB,EAAE,IAAI,GAAG,OAAO,GAAG,WAAW,GAAG,YAAY,GAAG,aAAa,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAC,CAAC;AA2epJ,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,mBAAmB;;eAxc5D,YAAY,EAAE;eACd,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;oBACd,MAAM;gBACV,MAAM;;;cAodU;;;;;;;;;QAAkB;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;;EAG5E;AAED,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,0BAA0B;;eA5d1E,YAAY,EAAE;eACd,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;oBACd,MAAM;gBACV,MAAM;;;cAodU;;;;;;;;;QAAkB;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;;EAY5E;AAuBD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,kCAAkC;wCA89BvC,MAAM,YAAY,MAAM;kCA9yB9B,MAAM,SAAS,gCAAgC;0BAu8BvD,MAAM,YAAY,MAAM,eAAe,MAAM,SAAS;QAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;6BArDtG,MAAM,YAAY,MAAM,YAAY,MAAM,EAAE;4BAsB7C,MAAM,YAAY,MAAM,eAAe,MAAM;;;;;;;;;;;;;;;;;;uBArIlD,MAAM,KAAG,OAAO,CAAC,qBAAqB,CAAC;6BA9pBjC,MAAM,YAAY,MAAM;0BAie3B,MAAM,YAAY,MAAM;qBA5oB7B,MAAM,SAAS,mBAAmB,WAAW,UAAU,SApI5E,MAAM,SACN,mBAAmB,UAClB;QACN,IAAI,EAAE,wBAAwB,CAAC,YAAY,CAAC,CAAC;QAC7C,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACpC,KACA,OAAO,CAAC,wBAAwB,CAAC,CA4H2E,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,wBAAwB,CAAC;4BAIjH,MAAM,SAAS,0BAA0B,WAAW,WAAW;qBAqX3F,MAAM,YACH,MAAM,+EAGQ,iCAAiC,KACxD,OAAO,CAAC,qBAAqB,CAAC;2BAwMG,MAAM,KAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC;gCA+cpE,MAAM,YACH,MAAM,eACH,MAAM,KAClB,OAAO,CAAC,mBAAmB,EAAE,CAAC;+BAuBxB,MAAM,YACH,MAAM,eACH,MAAM,OACd,MAAM;;;;;;;sBAoDkB,MAAM,YAAY,MAAM;wBA3OtB,MAAM,YAAY,MAAM,WAAW,OAAO;;2BA3O/B,MAAM;uBAqclB,MAAM,YAAY,MAAM;;;;EAkDzD"}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { agentEnabledSkills, agents, appBuilderApps, installedPlugins, mcpConnections as mcpConnectionRows, organizationSkills, pluginComponentLinks, pluginImportReports, pluginPackages, pluginSources, } from "@rudderhq/db";
|
|
2
|
+
import { resolveRudderNativeCapability } from "@rudderhq/shared";
|
|
2
3
|
import { and, asc, eq, inArray, ne } from "drizzle-orm";
|
|
3
|
-
import { Unzip, UnzipInflate, UnzipPassThrough } from "fflate";
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { conflict, notFound, unprocessable } from "../errors.js";
|
|
7
7
|
import { agentEnabledSkillsService } from "./agent-enabled-skills.js";
|
|
8
8
|
import { managedMcpConnectionService } from "./mcp/managed-connections.js";
|
|
9
9
|
import { organizationSkillService } from "./organization-skills.js";
|
|
10
|
+
import { inspectPluginArchiveNative, PluginArchiveNativeError, } from "./plugin-archive-native.js";
|
|
11
|
+
import { unzipPluginPackageNode } from "./plugin-archive-node.js";
|
|
10
12
|
import { enabledAgentIdsFromMetadata, inheritedPluginSkillAgentIds, organizationSkillSelectionKey, organizationSkillSelectionKeys, selectedAgentIdsForSkill, } from "./rudder-plugin-agent-bindings.js";
|
|
11
|
-
const MAX_PLUGIN_BYTES =
|
|
13
|
+
const MAX_PLUGIN_BYTES = 100 * 1024 * 1024;
|
|
12
14
|
const MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
13
|
-
const MAX_ARCHIVE_RATIO = 100;
|
|
14
15
|
const MAX_MCP_UI_HTML_BYTES = 2 * 1024 * 1024;
|
|
15
16
|
const SENSITIVE_KEY = /(?:authorization|api[_-]?key|password|secret|token|cookie)/i;
|
|
16
17
|
function asRecord(value) {
|
|
@@ -37,89 +38,6 @@ function decodeInputFile(file) {
|
|
|
37
38
|
}
|
|
38
39
|
return Buffer.from(compact, "base64");
|
|
39
40
|
}
|
|
40
|
-
function decodeBase64(value, label) {
|
|
41
|
-
const compact = value.replace(/\s/g, "");
|
|
42
|
-
if (!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(compact)) {
|
|
43
|
-
throw unprocessable(`Invalid base64 content for ${label}`);
|
|
44
|
-
}
|
|
45
|
-
return Buffer.from(compact, "base64");
|
|
46
|
-
}
|
|
47
|
-
function unzipPackageFiles(content, label, stripPluginRoot) {
|
|
48
|
-
const archive = decodeBase64(content, label);
|
|
49
|
-
if (archive.byteLength > MAX_PLUGIN_BYTES)
|
|
50
|
-
throw unprocessable("Plugin archive exceeds the 10 MiB V1 limit");
|
|
51
|
-
const files = [];
|
|
52
|
-
let totalBytes = 0;
|
|
53
|
-
let failure = null;
|
|
54
|
-
const unzip = new Unzip((file) => {
|
|
55
|
-
if (failure || file.name.endsWith("/"))
|
|
56
|
-
return;
|
|
57
|
-
if (files.length >= 500) {
|
|
58
|
-
failure = new Error("Plugin archive exceeds the 500-file V1 limit");
|
|
59
|
-
file.terminate();
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
if (file.originalSize !== undefined && file.originalSize > MAX_FILE_BYTES) {
|
|
63
|
-
failure = new Error(`Plugin archive entry exceeds 2 MiB: ${file.name}`);
|
|
64
|
-
file.terminate();
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
if (file.size && file.originalSize && file.originalSize / file.size > MAX_ARCHIVE_RATIO) {
|
|
68
|
-
failure = new Error(`Plugin archive entry exceeds the ${MAX_ARCHIVE_RATIO}:1 expansion limit: ${file.name}`);
|
|
69
|
-
file.terminate();
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
const chunks = [];
|
|
73
|
-
let entryBytes = 0;
|
|
74
|
-
file.ondata = (error, data, final) => {
|
|
75
|
-
if (failure)
|
|
76
|
-
return;
|
|
77
|
-
if (error) {
|
|
78
|
-
failure = error;
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
entryBytes += data.byteLength;
|
|
82
|
-
totalBytes += data.byteLength;
|
|
83
|
-
if (entryBytes > MAX_FILE_BYTES || totalBytes > MAX_PLUGIN_BYTES) {
|
|
84
|
-
failure = new Error(entryBytes > MAX_FILE_BYTES
|
|
85
|
-
? `Plugin archive entry exceeds 2 MiB: ${file.name}`
|
|
86
|
-
: "Plugin archive exceeds the 10 MiB V1 expansion limit");
|
|
87
|
-
file.terminate();
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
chunks.push(Buffer.from(data));
|
|
91
|
-
if (final) {
|
|
92
|
-
files.push({ path: file.name, content: Buffer.concat(chunks).toString("base64"), encoding: "base64" });
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
file.start();
|
|
96
|
-
});
|
|
97
|
-
unzip.register(UnzipInflate);
|
|
98
|
-
unzip.register(UnzipPassThrough);
|
|
99
|
-
try {
|
|
100
|
-
unzip.push(archive, true);
|
|
101
|
-
}
|
|
102
|
-
catch (error) {
|
|
103
|
-
throw unprocessable(`Invalid ZIP Plugin archive: ${error instanceof Error ? error.message : String(error)}`);
|
|
104
|
-
}
|
|
105
|
-
const archiveFailure = failure;
|
|
106
|
-
if (archiveFailure)
|
|
107
|
-
throw unprocessable(archiveFailure.message);
|
|
108
|
-
if (files.length === 0)
|
|
109
|
-
throw unprocessable("Invalid ZIP Plugin archive: archive contains no files");
|
|
110
|
-
if (totalBytes > archive.byteLength * MAX_ARCHIVE_RATIO) {
|
|
111
|
-
throw unprocessable(`Plugin archive exceeds the ${MAX_ARCHIVE_RATIO}:1 expansion limit`);
|
|
112
|
-
}
|
|
113
|
-
if (!stripPluginRoot || files.some((file) => file.path === ".codex-plugin/plugin.json"))
|
|
114
|
-
return files;
|
|
115
|
-
const manifests = files.filter((file) => file.path.endsWith("/.codex-plugin/plugin.json"));
|
|
116
|
-
if (manifests.length !== 1)
|
|
117
|
-
return files;
|
|
118
|
-
const prefix = manifests[0].path.slice(0, -".codex-plugin/plugin.json".length);
|
|
119
|
-
if (!files.every((file) => file.path.startsWith(prefix)))
|
|
120
|
-
return files;
|
|
121
|
-
return files.map((file) => ({ ...file, path: file.path.slice(prefix.length) }));
|
|
122
|
-
}
|
|
123
41
|
function normalizeFiles(input) {
|
|
124
42
|
if (input.files.length > 500)
|
|
125
43
|
throw unprocessable("Plugin package exceeds the 500-file V1 limit");
|
|
@@ -150,7 +68,7 @@ function normalizeFiles(input) {
|
|
|
150
68
|
throw unprocessable(`Plugin file exceeds 2 MiB: ${normalized}`);
|
|
151
69
|
totalBytes += content.byteLength;
|
|
152
70
|
if (totalBytes > MAX_PLUGIN_BYTES)
|
|
153
|
-
throw unprocessable("Plugin package exceeds the
|
|
71
|
+
throw unprocessable("Plugin package exceeds the 100 MiB limit");
|
|
154
72
|
bytes.set(normalized, content);
|
|
155
73
|
}
|
|
156
74
|
const hash = createHash("sha256");
|
|
@@ -578,10 +496,30 @@ export function inspectRudderPluginArchivePackage(input) {
|
|
|
578
496
|
return inspectRudderPluginPackage({
|
|
579
497
|
sourceType: "local_upload",
|
|
580
498
|
sourceLabel: input.sourceLabel,
|
|
581
|
-
files:
|
|
499
|
+
files: unzipPluginPackageNode(input.content, input.filename, true)
|
|
582
500
|
.map((file) => ({ ...file, encoding: file.encoding ?? "utf8" })),
|
|
583
501
|
});
|
|
584
502
|
}
|
|
503
|
+
function pluginArchiveInputError(error) {
|
|
504
|
+
switch (error.code) {
|
|
505
|
+
case "plugin_archive_size_limit":
|
|
506
|
+
return unprocessable("Plugin archive exceeds the 10 MiB transport limit");
|
|
507
|
+
case "plugin_archive_file_count_limit":
|
|
508
|
+
return unprocessable("Plugin archive exceeds the 500-file V1 limit");
|
|
509
|
+
case "plugin_archive_file_size_limit":
|
|
510
|
+
return unprocessable("Plugin archive entry exceeds 2 MiB");
|
|
511
|
+
case "plugin_archive_expansion_limit":
|
|
512
|
+
return unprocessable("Plugin archive exceeds the 100:1 expansion limit");
|
|
513
|
+
case "plugin_archive_total_size_limit":
|
|
514
|
+
return unprocessable("Plugin archive exceeds the 100 MiB expansion limit");
|
|
515
|
+
case "plugin_archive_path_unsafe":
|
|
516
|
+
return unprocessable("Unsafe Plugin file path in archive");
|
|
517
|
+
case "plugin_archive_duplicate_path":
|
|
518
|
+
return unprocessable("Plugin package contains duplicate or case-colliding path");
|
|
519
|
+
default:
|
|
520
|
+
return unprocessable(`Invalid ZIP Plugin archive: ${error.code}`);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
585
523
|
export function rudderPluginService(db, mcpOptions) {
|
|
586
524
|
const skills = organizationSkillService(db);
|
|
587
525
|
const enabledSkills = agentEnabledSkillsService(db);
|
|
@@ -693,8 +631,31 @@ export function rudderPluginService(db, mcpOptions) {
|
|
|
693
631
|
async function inspect(orgId, input, source) {
|
|
694
632
|
return inspectFromSource(orgId, input, source ?? { type: "local_upload", label: input.sourceLabel });
|
|
695
633
|
}
|
|
696
|
-
async function inspectArchive(orgId, input) {
|
|
697
|
-
|
|
634
|
+
async function inspectArchive(orgId, input, signal) {
|
|
635
|
+
signal?.throwIfAborted();
|
|
636
|
+
const policy = resolveRudderNativeCapability({
|
|
637
|
+
capability: "plugin-archive",
|
|
638
|
+
env: process.env,
|
|
639
|
+
legacyToggleEnvs: ["RUDDER_NATIVE_PLUGIN_ARCHIVE"],
|
|
640
|
+
});
|
|
641
|
+
let files;
|
|
642
|
+
if (policy.enabled) {
|
|
643
|
+
try {
|
|
644
|
+
files = await inspectPluginArchiveNative(input, signal);
|
|
645
|
+
}
|
|
646
|
+
catch (error) {
|
|
647
|
+
if (error instanceof PluginArchiveNativeError && error.inputRejected) {
|
|
648
|
+
throw pluginArchiveInputError(error);
|
|
649
|
+
}
|
|
650
|
+
if (!policy.fallbackAllowed || signal?.aborted)
|
|
651
|
+
throw error;
|
|
652
|
+
files = unzipPluginPackageNode(input.content, input.filename, true);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
else {
|
|
656
|
+
files = unzipPluginPackageNode(input.content, input.filename, true);
|
|
657
|
+
}
|
|
658
|
+
signal?.throwIfAborted();
|
|
698
659
|
return inspectFromSource(orgId, {
|
|
699
660
|
sourceType: "local_upload",
|
|
700
661
|
sourceLabel: input.sourceLabel,
|
|
@@ -729,12 +690,12 @@ export function rudderPluginService(db, mcpOptions) {
|
|
|
729
690
|
throw unprocessable(`Pinned Git marketplace fetch failed with HTTP ${response.status}`);
|
|
730
691
|
const contentLength = Number(response.headers.get("content-length") ?? "0");
|
|
731
692
|
if (Number.isFinite(contentLength) && contentLength > MAX_PLUGIN_BYTES) {
|
|
732
|
-
throw unprocessable("Pinned Git marketplace archive exceeds the
|
|
693
|
+
throw unprocessable("Pinned Git marketplace archive exceeds the 100 MiB limit");
|
|
733
694
|
}
|
|
734
695
|
const archive = Buffer.from(await response.arrayBuffer());
|
|
735
696
|
if (archive.byteLength > MAX_PLUGIN_BYTES)
|
|
736
|
-
throw unprocessable("Pinned Git marketplace archive exceeds the
|
|
737
|
-
sourceFiles =
|
|
697
|
+
throw unprocessable("Pinned Git marketplace archive exceeds the 100 MiB limit");
|
|
698
|
+
sourceFiles = unzipPluginPackageNode(archive.toString("base64"), `${repo}@${input.github.commit}.zip`, true);
|
|
738
699
|
sourceType = "git";
|
|
739
700
|
locator = `${repository.toString().replace(/\/$/, "")}#${input.github.commit}`;
|
|
740
701
|
provenance = { repository: repository.toString(), commit: input.github.commit, immutable: true };
|