@voiden/runner 0.1.0-beta.6 → 2.1.1

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.
Files changed (46) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/bundled-runners/package.json +3 -0
  3. package/bundled-runners/simple-assertions-runner.js +1 -0
  4. package/bundled-runners/versions.json +9 -0
  5. package/bundled-runners/voiden-advanced-auth-runner.js +1 -0
  6. package/bundled-runners/voiden-faker-runner.js +16 -0
  7. package/bundled-runners/voiden-graphql-runner.js +1 -0
  8. package/bundled-runners/voiden-rest-api-runner.js +1 -0
  9. package/bundled-runners/voiden-scripting-runner.js +397 -0
  10. package/bundled-runners/voiden-sockets-grpcs-runner.js +1 -0
  11. package/dist/cliElectron.d.ts +1 -1
  12. package/dist/index.js +267 -26
  13. package/dist/index.js.map +1 -1
  14. package/dist/plugins/community.d.ts +4 -3
  15. package/dist/plugins/community.d.ts.map +1 -1
  16. package/dist/plugins/community.js +32 -21
  17. package/dist/plugins/community.js.map +1 -1
  18. package/dist/plugins/loader.d.ts +9 -0
  19. package/dist/plugins/loader.d.ts.map +1 -1
  20. package/dist/plugins/loader.js +93 -8
  21. package/dist/plugins/loader.js.map +1 -1
  22. package/dist/plugins/registry.d.ts +30 -21
  23. package/dist/plugins/registry.d.ts.map +1 -1
  24. package/dist/plugins/registry.js +111 -46
  25. package/dist/plugins/registry.js.map +1 -1
  26. package/dist/plugins/registryCache.d.ts +30 -0
  27. package/dist/plugins/registryCache.d.ts.map +1 -0
  28. package/dist/plugins/registryCache.js +95 -0
  29. package/dist/plugins/registryCache.js.map +1 -0
  30. package/dist/plugins/store.d.ts +6 -1
  31. package/dist/plugins/store.d.ts.map +1 -1
  32. package/dist/plugins/store.js +21 -1
  33. package/dist/plugins/store.js.map +1 -1
  34. package/dist/plugins/updateCheck.d.ts +19 -0
  35. package/dist/plugins/updateCheck.d.ts.map +1 -0
  36. package/dist/plugins/updateCheck.js +60 -0
  37. package/dist/plugins/updateCheck.js.map +1 -0
  38. package/dist/runner.d.ts +1 -1
  39. package/dist/runner.d.ts.map +1 -1
  40. package/dist/runner.js +19 -2
  41. package/dist/runner.js.map +1 -1
  42. package/dist/runtimeVars.d.ts +5 -0
  43. package/dist/runtimeVars.d.ts.map +1 -1
  44. package/dist/runtimeVars.js +36 -2
  45. package/dist/runtimeVars.js.map +1 -1
  46. package/package.json +13 -6
@@ -0,0 +1 @@
1
+ "use strict";var d=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var w=Object.prototype.hasOwnProperty;var S=(r,e)=>{for(var n in e)d(r,n,{get:e[n],enumerable:!0})},v=(r,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of k(e))!w.call(r,a)&&a!==n&&d(r,a,{get:()=>e[a],enumerable:!(o=A(e,a))||o.enumerable});return r};var B=r=>v(d({},"__esModule",{value:!0}),r);var N={};S(N,{buildRequest:()=>R,default:()=>x});module.exports=B(N);function R(r){let e=r.find(t=>t.type==="gqlquery");if(!e)return null;let n=e.content?.find(t=>t.type==="gqlbody")||"",o=n.attrs?.body||"";if(!o.trim())return{errorMessage:"GraphQL query is empty"};let a=n.attrs?.operationType||"query",i=n.attrs?.operationName;if(!i){let t=o.match(/^\s*(query|mutation|subscription)\s+([\w]+)?/);t&&(a=t[1],i=t[2])}let p={},f=r.find(t=>t.type==="gqlvariables");if(f?.attrs?.body)try{p=JSON.parse(f.attrs.body)}catch{}let y="",l=e;if(l&&Array.isArray(l.content)){let t=l.content.find(s=>s.type==="gqlurl");t&&typeof t.content=="string"&&(y=t.content.trim())}if(y||(y=e.attrs?.endpoint||e.attrs?.schemaUrl||""),!y)return{errorMessage:"GraphQL url is empty"};let u=[{key:"Content-Type",value:"application/json",enabled:!0}],c=r.find(t=>t.type==="headers-table");if(c&&Array.isArray(c.content)){for(let t of c.content)if(t.type==="table"&&Array.isArray(t.rows)){for(let s of t.rows)if(!s.attrs?.disabled&&Array.isArray(s.row)&&s.row[0]){let m=String(s.row[0]).trim(),q=String(s.row[1]??"").trim(),g=u.findIndex(h=>h.key.toLowerCase()===m.toLowerCase());g>=0?u[g].value=q:u.push({key:m,value:q,enabled:!0})}}}let b={query:o,variables:p};return i&&(b.operationName=i),{method:"POST",url:y,headers:u,queryParams:[],pathParams:[],body:JSON.stringify(b),contentType:"application/json",metadata:{operationType:a,operationName:i}}}var C=r=>({onload(){r.onBuildRequest((e,n)=>R(n)??e)}}),x=C;0&&(module.exports={buildRequest});
@@ -0,0 +1 @@
1
+ "use strict";var d=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var g=(e,n)=>{for(var r in n)d(e,r,{get:n[r],enumerable:!0})},q=(e,n,r,o)=>{if(n&&typeof n=="object"||typeof n=="function")for(let a of R(n))!b.call(e,a)&&a!==r&&d(e,a,{get:()=>n[a],enumerable:!(o=x(n,a))||o.enumerable});return e};var h=e=>q(d({},"__esModule",{value:!0}),e);var A={};g(A,{buildRequest:()=>m,default:()=>w});module.exports=h(A);function f(e){let n=[];if(!Array.isArray(e.content))return n;for(let r of e.content)if(r.type==="table"&&Array.isArray(r.rows))for(let o of r.rows){let a=o.attrs?.disabled===!0;if(Array.isArray(o.row)&&o.row.length>=2){let i=String(o.row[0]??"").trim(),u=String(o.row[1]??"").trim();i&&n.push({key:i,value:u,enabled:!a})}}return n}function m(e){if(e.some(t=>t.type==="gqlquery")||e.some(t=>t.type==="socket-request"))return null;let n=e.find(t=>t.type==="request");if(!n)return null;let r="GET",o="";if(Array.isArray(n.content))for(let t of n.content)t.type==="method"&&typeof t.content=="string"&&(r=t.content.trim().toUpperCase()||"GET"),t.type==="url"&&typeof t.content=="string"&&(o=t.content.trim());if(!o)return null;let a=f(e.find(t=>t.type==="headers-table")??{}),i=f(e.find(t=>t.type==="query-table")??{}),u=f(e.find(t=>t.type==="path-table")??{}),y,s,c=e.find(t=>t.type==="json_body");if(c?.attrs?.body){y=String(c.attrs.body);let t=c.attrs.contentType;s=t==="html"?"text/html":t==="text"?"text/plain":"application/json"}let l=e.find(t=>t.type==="xml_body");l?.attrs?.body&&(y=String(l.attrs.body),s=["application/xml","text/xml","application/xhtml+xml"].includes(l.attrs.contentType)?l.attrs.contentType:"application/xml");let p=e.find(t=>t.type==="yml_body");return p?.attrs?.body&&(y=String(p.attrs.body),s=["application/x-yaml","application/yaml","text/yaml","text/x-yaml"].includes(p.attrs.contentType)?p.attrs.contentType:"application/x-yaml"),{method:r,url:o,headers:a,queryParams:i,pathParams:u,body:y,contentType:s,metadata:{}}}var T=e=>({onload(){e.onBuildRequest((n,r)=>m(r)??n)}}),w=T;0&&(module.exports={buildRequest});
@@ -0,0 +1,397 @@
1
+ "use strict";var O=Object.defineProperty;var te=Object.getOwnPropertyDescriptor;var re=Object.getOwnPropertyNames;var se=Object.prototype.hasOwnProperty;var q=(e,r)=>()=>(e&&(r=e(e=0)),r);var P=(e,r)=>{for(var n in r)O(e,n,{get:r[n],enumerable:!0})},ne=(e,r,n,s)=>{if(r&&typeof r=="object"||typeof r=="function")for(let t of re(r))!se.call(e,t)&&t!==n&&O(e,t,{get:()=>r[t],enumerable:!(s=te(r,t))||s.enumerable});return e};var ae=e=>ne(O({},"__esModule",{value:!0}),e);function T(e){return"'"+String(e).replace(/'/g,"'\\''")+"'"}function F(e){let{request:r,response:n,envVars:s,variables:t,logFile:i,varFile:o,assertFile:l,cancelFile:d,reqFile:u,respFile:y,userScriptFile:p}=e,m=Object.entries(s).map(([f,c])=>`_VD_ENV_${f.replace(/[^A-Za-z0-9_]/g,"_")}=${T(String(c))}`).join(`
2
+ `)||"# (no env vars)",b=Object.entries(t).map(([f,c])=>`_VD_VAR_${f.replace(/[^A-Za-z0-9_]/g,"_")}=${T(String(c))}`).join(`
3
+ `)||"# (no variables)",g=!!n,a=T;return["#!/bin/bash","set +e",`_VD_LOG_FILE=${a(i)}`,`_VD_VAR_FILE=${a(o)}`,`_VD_ASSERT_FILE=${a(l)}`,`_VD_CANCEL_FILE=${a(d)}`,`_VD_REQUEST_FILE=${a(u)}`,`_VD_RESPONSE_FILE=${a(y)}`,`_VD_USERSCRIPT_FILE=${a(p)}`,'touch "$_VD_LOG_FILE" "$_VD_VAR_FILE" "$_VD_ASSERT_FILE" "$_VD_REQUEST_FILE" "$_VD_RESPONSE_FILE"','_vd_b64() { printf "%s" "$1" | base64 | tr -d "\\n"; }',"voiden_log() {",' local _level="log"',' case "$1" in log|info|debug|warn|warning|error) _level="$1"; shift;; esac',' [ "$_level" = "warning" ] && _level="warn"',' printf "%s\\t%s\\n" "$(_vd_b64 "$_level")" "$(_vd_b64 "$*")" >> "$_VD_LOG_FILE"',"}",'voiden_env_get() { local _k="_VD_ENV_${1//[^A-Za-z0-9_]/_}"; printf "%s" "${!_k}"; }','voiden_variables_get() { local _k="_VD_VAR_${1//[^A-Za-z0-9_]/_}"; printf "%s" "${!_k}"; }',"voiden_variables_set() {",' local _key="$1" _val="$2"',' local _k="_VD_VAR_${_key//[^A-Za-z0-9_]/_}"',' export "${_k}=${_val}"',' printf "%s\\t%s\\n" "$(_vd_b64 "$_key")" "$(_vd_b64 "$_val")" >> "$_VD_VAR_FILE"',"}",'voiden_cancel() { touch "$_VD_CANCEL_FILE"; }',"","# voiden.* dot-notation aliases (same API as JS / Python)",'voiden.log() { voiden_log "$@"; }','voiden.env.get() { voiden_env_get "$@"; }','voiden.variables.get() { voiden_variables_get "$@"; }','voiden.variables.set() { voiden_variables_set "$@"; }','voiden.assert() { voiden_assert "$@"; }',"voiden.cancel() { voiden_cancel; }","# request getters / setters","# Supports both call styles:",'# voiden.request.url "https://new.com" (bash style)','# voiden.request.url = "https://new.com" (JS-like style \u2014 = is treated as separator)','_vd_val() { [ "$1" = "=" ] && printf "%s" "$2" || printf "%s" "$1"; }','voiden.request.url() { [ $# -gt 0 ] && export VOIDEN_REQUEST_URL="$(_vd_val "$@")" || printf "%s" "$VOIDEN_REQUEST_URL"; }','voiden.request.method() { [ $# -gt 0 ] && export VOIDEN_REQUEST_METHOD="$(_vd_val "$@")" || printf "%s" "$VOIDEN_REQUEST_METHOD"; }','voiden.request.body() { [ $# -gt 0 ] && export VOIDEN_REQUEST_BODY="$(_vd_val "$@")" || printf "%s" "$VOIDEN_REQUEST_BODY"; }',"# shared entry builder \u2014 stores result in $_VD_KV_ENTRY","_vd_build_kv_entry() {",` local _Q='"' _k _v`,' _k="${1//$_Q/\\\\$_Q}"',' _v="${2//$_Q/\\\\$_Q}"',` printf -v _VD_KV_ENTRY '{"key":"%s","value":"%s","enabled":true}' "$_k" "$_v"`,"}","# _vd_set_kv: replace the array with a single entry","_vd_set_kv() {",' local _var="$1"',' _vd_build_kv_entry "$2" "$3"',` printf -v "$_var" '[%s]' "$_VD_KV_ENTRY"`,' export "$_var"',"}","# _vd_push_kv: append an entry to the existing array","_vd_push_kv() {",' local _var="$1" _cur',' _vd_build_kv_entry "$2" "$3"',' _cur="${!_var}"',' if [ -z "$_cur" ] || [ "$_cur" = "[]" ]; then',` printf -v "$_var" '[%s]' "$_VD_KV_ENTRY"`," else",` printf -v "$_var" '%s,%s]' "\${_cur%]}" "$_VD_KV_ENTRY"`," fi",' export "$_var"',"}","# collection setters: 2 args = set as single {key,value}; 1 arg = raw JSON; 0 args = getter",'voiden.request.headers() { if [ $# -ge 2 ]; then _vd_set_kv VOIDEN_REQUEST_HEADERS "$1" "$2"; elif [ $# -gt 0 ]; then export VOIDEN_REQUEST_HEADERS="$(_vd_val "$@")"; else printf "%s" "$VOIDEN_REQUEST_HEADERS"; fi; }','voiden.request.queryParams() { if [ $# -ge 2 ]; then _vd_set_kv VOIDEN_REQUEST_QUERY_PARAMS "$1" "$2"; elif [ $# -gt 0 ]; then export VOIDEN_REQUEST_QUERY_PARAMS="$(_vd_val "$@")"; else printf "%s" "$VOIDEN_REQUEST_QUERY_PARAMS"; fi; }','voiden.request.pathParams() { if [ $# -ge 2 ]; then _vd_set_kv VOIDEN_REQUEST_PATH_PARAMS "$1" "$2"; elif [ $# -gt 0 ]; then export VOIDEN_REQUEST_PATH_PARAMS="$(_vd_val "$@")"; else printf "%s" "$VOIDEN_REQUEST_PATH_PARAMS"; fi; }','voiden.request.headers.push() { _vd_push_kv VOIDEN_REQUEST_HEADERS "$1" "$2"; }','voiden.request.queryParams.push() { _vd_push_kv VOIDEN_REQUEST_QUERY_PARAMS "$1" "$2"; }','voiden.request.pathParams.push() { _vd_push_kv VOIDEN_REQUEST_PATH_PARAMS "$1" "$2"; }',"# response getters and writable setters (status, statusText, body)",'voiden.response.status() { [ $# -gt 0 ] && export VOIDEN_RESPONSE_STATUS="$(_vd_val "$@")" || printf "%s" "$VOIDEN_RESPONSE_STATUS"; }','voiden.response.statusText() { [ $# -gt 0 ] && export VOIDEN_RESPONSE_STATUS_TEXT="$(_vd_val "$@")" || printf "%s" "$VOIDEN_RESPONSE_STATUS_TEXT"; }','voiden.response.body() { [ $# -gt 0 ] && export VOIDEN_RESPONSE_BODY="$(_vd_val "$@")" || printf "%s" "$VOIDEN_RESPONSE_BODY"; }',"# response read-only fields",'voiden.response.headers() { printf "%s" "$VOIDEN_RESPONSE_HEADERS"; }','voiden.response.time() { printf "%s" "$VOIDEN_RESPONSE_TIME"; }','voiden.response.size() { printf "%s" "$VOIDEN_RESPONSE_SIZE"; }',"","voiden_assert() {",' local _actual="$1" _op="$2" _expected="$3" _msg="${4:-}" _passed="false"',' case "$_op" in',' "=="|eq|equal) [ "$_actual" = "$_expected" ] && _passed="true" ;;',' "===") [ "$_actual" = "$_expected" ] && _passed="true" ;;',' "!="|neq|notequal) [ "$_actual" != "$_expected" ] && _passed="true" ;;',' "!==") [ "$_actual" != "$_expected" ] && _passed="true" ;;',' contains|includes) case "$_actual" in *"$_expected"*) _passed="true";; esac ;;',' matches|regex) printf "%s" "$_actual" | grep -qE "$_expected" 2>/dev/null && _passed="true"; true ;;',' truthy) [ -n "$_actual" ] && _passed="true" ;;',' falsy) [ -z "$_actual" ] && _passed="true" ;;',' ">"|greater|greaterthan) (( _actual > _expected )) 2>/dev/null && _passed="true"; true ;;',' ">="|gte) (( _actual >= _expected )) 2>/dev/null && _passed="true"; true ;;',' "<"|less|lessthan) (( _actual < _expected )) 2>/dev/null && _passed="true"; true ;;',' "<="|lte) (( _actual <= _expected )) 2>/dev/null && _passed="true"; true ;;'," esac",' printf "%s\\t%s\\t%s\\t%s\\t%s\\n" "$(_vd_b64 "$_passed")" "$(_vd_b64 "$_actual")" "$(_vd_b64 "$_op")" "$(_vd_b64 "$_expected")" "$(_vd_b64 "$_msg")" >> "$_VD_ASSERT_FILE"',"}","","# Pre-loaded env vars",m,"","# Pre-loaded variables",b,"",`export VOIDEN_REQUEST_URL=${a(r?.url??"")}`,`export VOIDEN_REQUEST_METHOD=${a(r?.method??"GET")}`,`export VOIDEN_REQUEST_BODY=${a(r?.body!=null?typeof r.body=="object"?JSON.stringify(r.body):String(r.body):"")}`,`export VOIDEN_REQUEST_HEADERS=${a(JSON.stringify(r?.headers??[]))}`,`export VOIDEN_REQUEST_QUERY_PARAMS=${a(JSON.stringify(r?.queryParams??[]))}`,`export VOIDEN_REQUEST_PATH_PARAMS=${a(JSON.stringify(r?.pathParams??[]))}`,`export VOIDEN_RESPONSE_STATUS=${a(g?String(n?.status??""):"")}`,`export VOIDEN_RESPONSE_STATUS_TEXT=${a(g?String(n?.statusText??""):"")}`,`export VOIDEN_RESPONSE_BODY=${a(g&&n?.body!=null?typeof n.body=="object"?JSON.stringify(n.body):String(n.body):"")}`,`export VOIDEN_RESPONSE_HEADERS=${a(g?JSON.stringify(n?.headers??{}):"{}")}`,`export VOIDEN_RESPONSE_TIME=${a(g?String(n?.time??0):"0")}`,`export VOIDEN_RESPONSE_SIZE=${a(g?String(n?.size??0):"0")}`,"","# --- User Script (sourced from separate file; errors are caught) ---",'. "$_VD_USERSCRIPT_FILE" || true',"# --- End User Script ---","",'printf "%s\\t%s\\n" "$(_vd_b64 "url")" "$(_vd_b64 "$VOIDEN_REQUEST_URL")" >> "$_VD_REQUEST_FILE"','printf "%s\\t%s\\n" "$(_vd_b64 "method")" "$(_vd_b64 "$VOIDEN_REQUEST_METHOD")" >> "$_VD_REQUEST_FILE"','printf "%s\\t%s\\n" "$(_vd_b64 "body")" "$(_vd_b64 "$VOIDEN_REQUEST_BODY")" >> "$_VD_REQUEST_FILE"','printf "%s\\t%s\\n" "$(_vd_b64 "headers")" "$(_vd_b64 "$VOIDEN_REQUEST_HEADERS")" >> "$_VD_REQUEST_FILE"','printf "%s\\t%s\\n" "$(_vd_b64 "queryParams")" "$(_vd_b64 "$VOIDEN_REQUEST_QUERY_PARAMS")" >> "$_VD_REQUEST_FILE"','printf "%s\\t%s\\n" "$(_vd_b64 "pathParams")" "$(_vd_b64 "$VOIDEN_REQUEST_PATH_PARAMS")" >> "$_VD_REQUEST_FILE"',"# Write modified response fields (only when a response exists)",`[ -n ${a(g?"1":"")} ] && {`,'printf "%s\\t%s\\n" "$(_vd_b64 "status")" "$(_vd_b64 "$VOIDEN_RESPONSE_STATUS")" >> "$_VD_RESPONSE_FILE"','printf "%s\\t%s\\n" "$(_vd_b64 "statusText")" "$(_vd_b64 "$VOIDEN_RESPONSE_STATUS_TEXT")" >> "$_VD_RESPONSE_FILE"','printf "%s\\t%s\\n" "$(_vd_b64 "body")" "$(_vd_b64 "$VOIDEN_RESPONSE_BODY")" >> "$_VD_RESPONSE_FILE"',"}","true"].join(`
4
+ `)}var A,I,L,U=q(()=>{"use strict";A=`
5
+ const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor;
6
+
7
+ let requestState = null;
8
+ let responseState = null;
9
+ let _envData = {};
10
+ let _variablesData = {};
11
+ const _modifiedVariables = {};
12
+ const logs = [];
13
+ const assertions = [];
14
+ let cancelled = false;
15
+
16
+ function _normalizeLevel(value) {
17
+ if (typeof value !== 'string') return null;
18
+ const lowered = value.toLowerCase();
19
+ if (lowered === 'warning') return 'warn';
20
+ if (lowered === 'log' || lowered === 'info' || lowered === 'debug' || lowered === 'warn' || lowered === 'error') return lowered;
21
+ return null;
22
+ }
23
+
24
+ function _pushLog(level, args) {
25
+ logs.push({ level, args });
26
+ self.postMessage({ type: 'log', args });
27
+ }
28
+
29
+ function _serializeAssertionValue(val) {
30
+ try { return JSON.parse(JSON.stringify(val)); } catch { return String(val); }
31
+ }
32
+
33
+ function _toConditionText(val) {
34
+ if (typeof val === 'string') return JSON.stringify(val);
35
+ try { return JSON.stringify(val); } catch { return String(val); }
36
+ }
37
+
38
+ function _normalizeOperator(op) {
39
+ if (typeof op !== 'string') return null;
40
+ const key = op.trim().toLowerCase().replace(/\\s+/g, '');
41
+ const map = {
42
+ '==':'==','===':'===','eq':'==','equal':'==',
43
+ '!=':'!=','!==':'!==','neq':'!=','notequal':'!=',
44
+ 'greater':'>','greaterthan':'>','gte':'>=',
45
+ 'less':'<','lessthan':'<','lte':'<=',
46
+ '>':'>','>=':'>=','<':'<','<=':'<=',
47
+ 'contains':'contains','includes':'contains',
48
+ 'matches':'matches','regex':'matches',
49
+ 'truthy':'truthy','falsy':'falsy',
50
+ };
51
+ return map[key] || null;
52
+ }
53
+
54
+ function _evaluateAssertion(actual, operator, expected) {
55
+ switch (operator) {
56
+ case '==': return actual == expected;
57
+ case '===': return actual === expected;
58
+ case '!=': return actual != expected;
59
+ case '!==': return actual !== expected;
60
+ case '>': return actual > expected;
61
+ case '>=': return actual >= expected;
62
+ case '<': return actual < expected;
63
+ case '<=': return actual <= expected;
64
+ case 'contains':
65
+ if (typeof actual === 'string') return actual.includes(String(expected));
66
+ if (Array.isArray(actual)) return actual.includes(expected);
67
+ return false;
68
+ case 'matches':
69
+ try { return new RegExp(String(expected)).test(String(actual)); } catch { return false; }
70
+ case 'truthy': return Boolean(actual);
71
+ case 'falsy': return !actual;
72
+ default: return Boolean(actual);
73
+ }
74
+ }
75
+
76
+ self.onmessage = async (event) => {
77
+ const data = event.data;
78
+ if (data && data.type === 'start') {
79
+ requestState = data.request;
80
+ responseState = data.response;
81
+ _envData = data.envData || {};
82
+ _variablesData = Object.assign({}, data.variablesData || {});
83
+ const scriptBody = data.script;
84
+
85
+ const voiden = {
86
+ request: requestState,
87
+ response: responseState,
88
+ env: { get: function(key) { return _envData[key]; } },
89
+ variables: {
90
+ get: function(key) { return _variablesData[key]; },
91
+ set: function(key, value) { _variablesData[key] = value; _modifiedVariables[key] = value; },
92
+ },
93
+ log: function(levelOrMessage) {
94
+ const rest = Array.prototype.slice.call(arguments, 1);
95
+ const normalized = _normalizeLevel(levelOrMessage);
96
+ if (normalized) { _pushLog(normalized, rest); return; }
97
+ _pushLog('log', [levelOrMessage].concat(rest));
98
+ },
99
+ assert: function(actual, operator, expected, message) {
100
+ const rawOperator = String(operator);
101
+ const normalizedOperator = _normalizeOperator(operator);
102
+ if (!normalizedOperator) {
103
+ assertions.push({ passed: false, message: message ? String(message) : '', reason: 'Unsupported operator: ' + rawOperator, condition: _toConditionText(actual) + ' ' + rawOperator + ' ' + _toConditionText(expected), actualValue: _serializeAssertionValue(actual), operator: rawOperator, expectedValue: _serializeAssertionValue(expected) });
104
+ return;
105
+ }
106
+ const passed = _evaluateAssertion(actual, normalizedOperator, expected);
107
+ assertions.push({ passed, message: message ? String(message) : '', condition: _toConditionText(actual) + ' ' + normalizedOperator + ' ' + _toConditionText(expected), actualValue: _serializeAssertionValue(actual), operator: normalizedOperator, expectedValue: _serializeAssertionValue(expected) });
108
+ },
109
+ cancel: function() { cancelled = true; },
110
+ };
111
+
112
+ try {
113
+ const _require = typeof require !== 'undefined' ? require : undefined;
114
+ const fn = new AsyncFunction('voiden', 'vd', 'require', scriptBody);
115
+ await fn(voiden, voiden, _require);
116
+ self.postMessage({ type: 'done', success: true, cancelled, logs, assertions, modifiedRequest: voiden.request, modifiedResponse: voiden.response, modifiedVariables: _modifiedVariables });
117
+ } catch (error) {
118
+ self.postMessage({ type: 'done', success: false, cancelled, logs, assertions, modifiedRequest: voiden.request, modifiedResponse: voiden.response, modifiedVariables: _modifiedVariables, error: (error && (error.stack || error.message)) ? String(error.stack || error.message) : String(error) });
119
+ }
120
+ }
121
+ };
122
+ `,I=`
123
+ 'use strict';
124
+ var Worker = require('worker_threads').Worker;
125
+ var _chunks = [];
126
+ process.stdin.on('data', function(c) { _chunks.push(c); });
127
+ process.stdin.on('end', function() {
128
+ var _input = JSON.parse(Buffer.concat(_chunks).toString('utf-8'));
129
+ var _workerSource = _input.workerSource;
130
+ var _envData = _input.envVars || {};
131
+ var _variablesData = _input.variables || {};
132
+
133
+ var _shim = [
134
+ "var workerThreads = require('worker_threads');",
135
+ "var self = { postMessage: function(data) { workerThreads.parentPort.postMessage(data); } };",
136
+ "workerThreads.parentPort.on('message', function(data) { if (self.onmessage) self.onmessage({ data: data }); });",
137
+ ""
138
+ ].join('\\n');
139
+
140
+ var _worker = new Worker(_shim + _workerSource, { eval: true });
141
+
142
+ var _timeout = setTimeout(function() {
143
+ _worker.terminate();
144
+ process.stdout.write(JSON.stringify({ success: false, logs: [], error: 'Script execution timed out after 10000ms', cancelled: false, modifiedVariables: {} }) + '\\n');
145
+ process.exit(1);
146
+ }, 10000);
147
+
148
+ _worker.on('message', function(msg) {
149
+ if (msg.type === 'done') {
150
+ clearTimeout(_timeout);
151
+ process.stdout.write(JSON.stringify({ success: msg.success, logs: msg.logs || [], assertions: msg.assertions || [], cancelled: msg.cancelled || false, error: msg.error, modifiedRequest: msg.modifiedRequest, modifiedResponse: msg.modifiedResponse, modifiedVariables: msg.modifiedVariables || {} }) + '\\n');
152
+ _worker.terminate();
153
+ process.exit(msg.success ? 0 : 1);
154
+ }
155
+ });
156
+
157
+ _worker.on('error', function(err) {
158
+ clearTimeout(_timeout);
159
+ process.stdout.write(JSON.stringify({ success: false, logs: [], error: err.stack || err.message || String(err), cancelled: false, modifiedVariables: {} }) + '\\n');
160
+ process.exit(1);
161
+ });
162
+
163
+ _worker.postMessage({ type: 'start', script: _input.scriptBody, request: _input.request || {}, response: _input.response || null, envData: _envData, variablesData: _variablesData });
164
+ });
165
+ `,L=`
166
+ import sys, json
167
+ import traceback
168
+
169
+ def main():
170
+ input_data = json.loads(sys.stdin.read())
171
+
172
+ script_body = input_data["scriptBody"]
173
+
174
+ request_data = input_data.get("request", {})
175
+ response_data = input_data.get("response", None)
176
+ env_data = input_data.get("envVars", {})
177
+ variables_data = input_data.get("variables", {})
178
+
179
+ logs = []
180
+ assertions = []
181
+ cancelled = False
182
+ modified_variables = {}
183
+
184
+ class _List:
185
+ def __init__(self, values=None):
186
+ self._items = []
187
+ if values:
188
+ for v in values:
189
+ self._items.append(_wrap(v))
190
+
191
+ def push(self, *values):
192
+ if len(values) == 2 and isinstance(values[0], str) and not isinstance(values[1], (dict, list, tuple)):
193
+ key = values[0].strip()
194
+ if key:
195
+ self._items.append(_wrap({"key": key, "value": str(values[1]), "enabled": True}))
196
+ return len(self._items)
197
+ for v in values:
198
+ if isinstance(v, dict) and "key" in v and "value" in v:
199
+ key = str(v.get("key", "")).strip()
200
+ if not key: continue
201
+ self._items.append(_wrap({"key": key, "value": str(v.get("value", "")), "enabled": v.get("enabled", True) is not False}))
202
+ continue
203
+ if isinstance(v, dict):
204
+ for mk, mv in v.items():
205
+ mkey = str(mk).strip()
206
+ if not mkey: continue
207
+ self._items.append(_wrap({"key": mkey, "value": str(mv), "enabled": True}))
208
+ continue
209
+ self._items.append(_wrap(v))
210
+ return len(self._items)
211
+
212
+ def append(self, value): self._items.append(_wrap(value))
213
+ def extend(self, values):
214
+ for v in values: self._items.append(_wrap(v))
215
+ def __iter__(self): return iter(self._items)
216
+ def __len__(self): return len(self._items)
217
+ def __getitem__(self, index): return self._items[index]
218
+ def __setitem__(self, index, value): self._items[index] = _wrap(value)
219
+ def __repr__(self): return repr(self._items)
220
+
221
+ def _wrap(val):
222
+ if isinstance(val, dict): return _Obj(val)
223
+ if isinstance(val, list): return _List(val)
224
+ if isinstance(val, tuple): return tuple(_wrap(v) for v in val)
225
+ return val
226
+
227
+ _REQUEST_COLLECTION_FIELDS = {"headers", "queryParams", "pathParams"}
228
+
229
+ class _Obj:
230
+ def __init__(self, data, normalize_collections=False):
231
+ object.__setattr__(self, '_normalize_collections', normalize_collections)
232
+ for k, v in data.items(): setattr(self, k, v)
233
+
234
+ def __setattr__(self, key, value):
235
+ if key == '_normalize_collections':
236
+ object.__setattr__(self, key, value)
237
+ return
238
+ if object.__getattribute__(self, '_normalize_collections') and key in _REQUEST_COLLECTION_FIELDS:
239
+ object.__setattr__(self, key, _List(_normalize_kv_collection(value)))
240
+ return
241
+ object.__setattr__(self, key, _wrap(value))
242
+
243
+ def __getitem__(self, key): return getattr(self, key)
244
+ def __setitem__(self, key, value): setattr(self, key, value)
245
+ def get(self, key, default=None): return getattr(self, key, default)
246
+ def items(self): return ((k, v) for k, v in self.__dict__.items() if k != '_normalize_collections')
247
+
248
+ def _normalize_kv_collection(value):
249
+ items = []
250
+ if isinstance(value, list):
251
+ for item in value:
252
+ if isinstance(item, dict) and "key" in item and "value" in item:
253
+ key = str(item.get("key", "")).strip()
254
+ if not key: continue
255
+ items.append({"key": key, "value": str(item.get("value", "")), "enabled": item.get("enabled", True) is not False})
256
+ elif isinstance(item, dict):
257
+ for mk, mv in item.items():
258
+ mkey = str(mk).strip()
259
+ if not mkey: continue
260
+ items.append({"key": mkey, "value": str(mv), "enabled": True})
261
+ return items
262
+ if isinstance(value, dict):
263
+ if "key" in value and "value" in value:
264
+ key = str(value.get("key", "")).strip()
265
+ if not key: return []
266
+ return [{"key": key, "value": str(value.get("value", "")), "enabled": value.get("enabled", True) is not False}]
267
+ for mk, mv in value.items():
268
+ mkey = str(mk).strip()
269
+ if not mkey: continue
270
+ items.append({"key": mkey, "value": str(mv), "enabled": True})
271
+ return items
272
+ return []
273
+
274
+ class _Variables:
275
+ def get(self, key): return variables_data.get(key)
276
+ def set(self, key, value):
277
+ serialized = _serialize(value)
278
+ variables_data[key] = serialized
279
+ modified_variables[key] = serialized
280
+
281
+ class _Env:
282
+ def get(self, key): return env_data.get(key)
283
+
284
+ class _Vd:
285
+ def __init__(self):
286
+ self.request = _Obj(request_data, normalize_collections=True)
287
+ self.response = _Obj(response_data) if response_data else None
288
+ self.env = _Env()
289
+ self.variables = _Variables()
290
+
291
+ def log(self, *args):
292
+ level = "log"
293
+ payload = args
294
+ if len(args) >= 1 and isinstance(args[0], str):
295
+ lowered = args[0].lower()
296
+ if lowered == "warning": lowered = "warn"
297
+ if lowered in ("log", "info", "debug", "warn", "error"):
298
+ level = lowered
299
+ payload = args[1:]
300
+ logs.append({"level": level, "args": [_serialize(a) for a in payload]})
301
+
302
+ def assert_(self, actual, operator, expected, message=""):
303
+ normalized_operator = _normalize_operator(operator)
304
+ if normalized_operator is None:
305
+ raw_operator = str(operator)
306
+ assertions.append({"passed": False, "message": str(message), "reason": "Unsupported operator: " + raw_operator, "condition": _to_condition_text(actual) + " " + raw_operator + " " + _to_condition_text(expected), "actualValue": _serialize(actual), "operator": raw_operator, "expectedValue": _serialize(expected)})
307
+ return
308
+ passed = _evaluate_assertion(actual, normalized_operator, expected)
309
+ assertions.append({"passed": bool(passed), "message": str(message), "condition": _to_condition_text(actual) + " " + str(normalized_operator) + " " + _to_condition_text(expected), "actualValue": _serialize(actual), "operator": str(normalized_operator), "expectedValue": _serialize(expected)})
310
+
311
+ def cancel(self):
312
+ nonlocal cancelled
313
+ cancelled = True
314
+
315
+ def _serialize(val):
316
+ if isinstance(val, _List): return [_serialize(v) for v in val]
317
+ if isinstance(val, _Obj): return {k: _serialize(v) for k, v in val.__dict__.items() if k != '_normalize_collections'}
318
+ if isinstance(val, dict): return {k: _serialize(v) for k, v in val.items()}
319
+ if isinstance(val, (list, tuple)): return [_serialize(v) for v in val]
320
+ try:
321
+ json.dumps(val)
322
+ return val
323
+ except (TypeError, ValueError): return str(val)
324
+
325
+ def _extract(obj, keys):
326
+ result = {}
327
+ for k in keys:
328
+ if hasattr(obj, k): result[k] = _serialize(getattr(obj, k))
329
+ return result
330
+
331
+ def _json_equal(a, b):
332
+ try: return json.dumps(a, sort_keys=True) == json.dumps(b, sort_keys=True)
333
+ except Exception: return False
334
+
335
+ def _normalize_operator(op):
336
+ if not isinstance(op, str): return None
337
+ key = "".join(op.strip().lower().split())
338
+ mapping = {"==":"==","===":"===","eq":"==","equal":"==","!=":"!=","!==":"!==","neq":"!=","notequal":"!=","greater":">","greaterthan":">","gte":">=","less":"<","lessthan":"<","lte":"<=",">":">",">=":">=","<":"<","<=":"<=","contains":"contains","includes":"contains","matches":"matches","regex":"matches","truthy":"truthy","falsy":"falsy"}
339
+ return mapping.get(key)
340
+
341
+ def _to_condition_text(value):
342
+ if isinstance(value, str): return json.dumps(value)
343
+ try: return json.dumps(value)
344
+ except Exception: return str(value)
345
+
346
+ def _evaluate_assertion(actual, operator, expected):
347
+ try:
348
+ if operator == "==": return actual == expected
349
+ if operator == "===": return type(actual) == type(expected) and actual == expected
350
+ if operator == "!=": return actual != expected
351
+ if operator == "!==": return not (type(actual) == type(expected) and actual == expected)
352
+ if operator == ">": return actual > expected
353
+ if operator == ">=": return actual >= expected
354
+ if operator == "<": return actual < expected
355
+ if operator == "<=": return actual <= expected
356
+ if operator == "contains":
357
+ if isinstance(actual, str): return str(expected) in actual
358
+ if isinstance(actual, (list, tuple)): return expected in actual
359
+ return False
360
+ if operator == "matches":
361
+ import re
362
+ return re.search(str(expected), str(actual)) is not None
363
+ if operator == "truthy": return bool(actual)
364
+ if operator == "falsy": return not bool(actual)
365
+ except Exception: return False
366
+ return bool(actual)
367
+
368
+ voiden = _Vd()
369
+
370
+ try:
371
+ script_body = script_body.replace('voiden.assert(', 'voiden.assert_(')
372
+ script_body = script_body.replace('vd.assert(', 'vd.assert_(')
373
+ exec(script_body, {"voiden": voiden, "vd": voiden, "__builtins__": __builtins__})
374
+
375
+ mod_request = _extract(voiden.request, ["url", "method", "headers", "body", "queryParams", "pathParams"])
376
+ mod_response = None
377
+ if voiden.response is not None:
378
+ candidate_response = _extract(voiden.response, ["status", "statusText", "headers", "body", "time", "size"])
379
+ original_response = _serialize(response_data) if response_data is not None else None
380
+ if original_response is None or not _json_equal(candidate_response, original_response):
381
+ mod_response = candidate_response
382
+
383
+ result = {"success": True, "logs": logs, "assertions": assertions, "cancelled": cancelled, "modifiedRequest": mod_request, "modifiedResponse": mod_response, "modifiedVariables": modified_variables}
384
+ except Exception as e:
385
+ result = {"success": False, "logs": logs, "assertions": assertions, "cancelled": cancelled, "error": traceback.format_exc(), "modifiedVariables": _serialize(modified_variables)}
386
+
387
+ print(json.dumps(result))
388
+ sys.exit(0 if result.get("success") else 1)
389
+
390
+ main()
391
+ `});var w={};P(w,{executeHeadlessScript:()=>ye,getPythonBin:()=>j,isNodeAvailable:()=>oe,loadHeadlessVariables:()=>ie});function j(){if(h!==void 0)return h;for(let e of["python3","python"])try{return(0,R.execFileSync)(e,["--version"],{stdio:"pipe",timeout:3e3}),h=e,e}catch{}return h=null,null}function oe(){try{return require("worker_threads"),!0}catch{return!1}}function ie(){let e=(0,v.join)((0,k.homedir)(),".voiden",".process.env.json");if(!(0,_.existsSync)(e))return{};try{return JSON.parse((0,_.readFileSync)(e,"utf-8"))}catch{return{}}}function C(e,r,n){return new Promise(s=>{let t=(0,R.spawn)(e,r,{stdio:["pipe","pipe","pipe"]}),i="",o="";t.stdout.on("data",d=>{i+=d.toString()}),t.stderr.on("data",d=>{o+=d.toString()});let l=setTimeout(()=>{t.kill("SIGKILL"),s({stdout:"",stderr:`Timed out after ${V}ms`,code:-1})},V);t.on("close",d=>{clearTimeout(l),s({stdout:i,stderr:o,code:d})}),t.stdin.write(n,"utf-8"),t.stdin.end()})}function z(e,r,n){let s=e.trim().split(`
392
+ `).pop()??"";try{let t=JSON.parse(s);return{success:!!t.success,logs:Array.isArray(t.logs)?t.logs:[],assertions:Array.isArray(t.assertions)?t.assertions:[],cancelled:!!t.cancelled,error:t.error,exitCode:n??0,modifiedRequest:t.modifiedRequest,modifiedResponse:t.modifiedResponse}}catch{let t=r.trim()||`Script output could not be parsed: ${s.slice(0,300)}`;return{success:!1,logs:[],error:t,cancelled:!1,exitCode:n??1}}}async function le(e,r,n,s,t){let i=Object.getPrototypeOf(async function(){}).constructor,o=[],l=[],d=!1,u={...t},y={},p=a=>({"==":"==","===":"===",eq:"==",equal:"==","!=":"!=","!==":"!==",neq:"!=",notequal:"!=",">":">",">=":">=","<":"<","<=":"<=",greater:">",greaterthan:">",gte:">=",less:"<",lessthan:"<",lte:"<=",contains:"contains",includes:"contains",matches:"matches",regex:"matches",truthy:"truthy",falsy:"falsy"})[a.trim().toLowerCase().replace(/\s+/g,"")]??null,m=(a,f,c)=>{try{switch(f){case"==":return a==c;case"===":return a===c;case"!=":return a!=c;case"!==":return a!==c;case">":return a>c;case">=":return a>=c;case"<":return a<c;case"<=":return a<=c;case"contains":return typeof a=="string"?a.includes(String(c)):Array.isArray(a)&&a.includes(c);case"matches":return new RegExp(String(c)).test(String(a));case"truthy":return!!a;case"falsy":return!a;default:return!!a}}catch{return!1}},b=a=>{try{return JSON.stringify(a)}catch{return String(a)}},g={request:r,response:n,env:{get:a=>s[a]},variables:{get:a=>u[a],set:(a,f)=>{u[a]=f,y[a]=f}},log:(a,...f)=>{let S=typeof a=="string"&&["log","info","debug","warn","warning","error"].includes(a.toLowerCase()),E=S?a==="warning"?"warn":a:"log";o.push({level:E,args:S?f:[a,...f]})},assert:(a,f,c,S)=>{let E=p(f);if(!E){l.push({passed:!1,message:S??"",reason:`Unsupported operator: ${f}`,actualValue:a,operator:f,expectedValue:c});return}l.push({passed:m(a,E,c),message:S??"",condition:`${b(a)} ${E} ${b(c)}`,actualValue:a,operator:E,expectedValue:c})},cancel:()=>{d=!0}};try{return await new i("voiden","vd",e)(g,g),{success:!0,logs:o,assertions:l,cancelled:d,exitCode:0,modifiedRequest:g.request,modifiedResponse:g.response,modifiedVariables:y}}catch(a){return{success:!1,logs:o,assertions:l,error:String(a?.stack||a?.message||a),cancelled:d,exitCode:1,modifiedVariables:y}}}async function ce(e,r,n,s,t){let i=JSON.stringify({scriptBody:e,workerSource:A,request:r??{},response:n??null,envVars:s,variables:t}),{stdout:o,stderr:l,code:d}=await C("node",["-e",I],i);return z(o,l,d)}async function ue(e,r,n,s,t){let i=j();if(!i)return{success:!1,logs:[],error:"python3 not found in PATH. Install Python 3 to run Python scripts in voiden-runner.",cancelled:!1,exitCode:-1};let o=JSON.stringify({scriptBody:e,request:r??{},response:n??null,envVars:s,variables:t}),{stdout:l,stderr:d,code:u}=await C(i,["-c",L],o);return z(l,d,u)}async function de(e,r,n,s,t){let i=`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`,o=(0,v.join)((0,k.tmpdir)(),`voiden-runner-${i}`);(0,_.mkdirSync)(o,{recursive:!0});let l=(0,v.join)(o,"log.tsv"),d=(0,v.join)(o,"vars.tsv"),u=(0,v.join)(o,"assertions.tsv"),y=(0,v.join)(o,"cancel"),p=(0,v.join)(o,"request.tsv"),m=(0,v.join)(o,"response.tsv"),b=(0,v.join)(o,"user.sh"),g=(0,v.join)(o,"wrapper.sh");(0,_.writeFileSync)(b,e,"utf-8");for(let c of[l,d,u,p,m])(0,_.writeFileSync)(c,"","utf-8");let a=F({request:r??{},response:n??null,envVars:s,variables:t,logFile:l,varFile:d,assertFile:u,cancelFile:y,reqFile:p,respFile:m,userScriptFile:b});return(0,_.writeFileSync)(g,a,"utf-8"),new Promise(c=>{let S=(0,R.spawn)("bash",[g],{stdio:["ignore","pipe","pipe"]}),E=setTimeout(()=>{S.kill("SIGKILL"),f(),c({success:!1,logs:[],error:`Shell script timed out after ${V}ms`,cancelled:!1,exitCode:-1})},V);S.on("close",N=>{clearTimeout(E);let G=_e(l),K=pe(u),Z=fe(p,r),X=ge(m,n),ee=(0,_.existsSync)(y);f(),c({success:N===0,logs:G,assertions:K,cancelled:ee,exitCode:N??0,modifiedRequest:Z,modifiedResponse:X})})});function f(){try{(0,_.rmSync)(o,{recursive:!0,force:!0})}catch{}}}function $(e){return Buffer.from(e??"","base64").toString("utf-8")}function _e(e){return(0,_.existsSync)(e)?(0,_.readFileSync)(e,"utf-8").split(`
393
+ `).filter(Boolean).map(r=>{let[n,s]=r.split(" ");return{level:$(n)||"log",args:[$(s)]}}):[]}function pe(e){return(0,_.existsSync)(e)?(0,_.readFileSync)(e,"utf-8").split(`
394
+ `).filter(Boolean).map(r=>{let n=r.split(" ").map($),[s,t,i,o,l]=n;return{passed:s==="true",actualValue:t,operator:i,expectedValue:o,message:l??""}}):[]}function fe(e,r){if(!(0,_.existsSync)(e))return r;let n={...r};return(0,_.readFileSync)(e,"utf-8").split(`
395
+ `).filter(Boolean).forEach(s=>{let[t,i]=s.split(" "),o=$(t),l=$(i);if(o)if(["headers","queryParams","pathParams"].includes(o))try{n[o]=JSON.parse(l)}catch{n[o]=l}else n[o]=l}),n}function ge(e,r){if(!(0,_.existsSync)(e)||!r)return r;let n={...r};return(0,_.readFileSync)(e,"utf-8").split(`
396
+ `).filter(Boolean).forEach(s=>{let[t,i]=s.split(" "),o=$(t),l=$(i);if(o)if(o==="status")n[o]=parseInt(l,10)||0;else if(o==="body")try{n[o]=JSON.parse(l)}catch{n[o]=l}else n[o]=l}),n}async function ye(e,r,n,s,t={},i={},o=!1){return r==="python"?ue(e,n,s,t,i):r==="shell"?de(e,n,s,t,i):o?ce(e,n,s,t,i):le(e,n,s,t,i)}var R,_,v,k,V,h,D=q(()=>{"use strict";R=require("child_process"),_=require("fs"),v=require("path"),k=require("os");U();V=1e4});var Re={};P(Re,{default:()=>$e});module.exports=ae(Re);var J=require("@voiden/sdk/shared"),x=require("fs"),Y=require("path"),W=require("os");function Q(e,r){if(!e?.content)return null;let n=null,s=t=>{t.type===r&&t.attrs?.body&&(n={body:t.attrs.body,language:t.attrs.language??"javascript"}),t.content?.forEach?.(i=>s(i))};return s(e),n}function M(e,r){return r==="python"?e.replace(/#.*$/gm,"").trim():e.replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,"").trim()}function H(){let e=(0,Y.join)((0,W.homedir)(),".voiden",".process.env.json");if(!(0,x.existsSync)(e))return{};try{return JSON.parse((0,x.readFileSync)(e,"utf-8"))}catch{return{}}}function B(e){let r=n=>Array.isArray(n)?n:n&&typeof n=="object"?Object.entries(n).map(([s,t])=>({key:s,value:String(t),enabled:!0})):[];return{url:e.url??"",method:e.method??"GET",headers:r(e.headers),body:e.body,queryParams:r(e.queryParams),pathParams:r(e.pathParams)}}function ve(e){let r=e.headers??[],n={},s=[];r.forEach(i=>{i.key.toLowerCase()==="set-cookie"?s.push(i.value):n[i.key]=i.value}),s.length>0&&(n["set-cookie"]=s.join(`
397
+ `));let t=(0,J.parseCookies)(r);return{status:e.status,statusText:e.statusText,headers:n,cookies:t,body:e.body,time:e.durationMs??0,size:e.size??0}}function me(e,r){r.url=e.url,r.method=e.method;let n=s=>Array.isArray(s)?s:s&&typeof s=="object"?Object.entries(s).map(([t,i])=>({key:t,value:String(i),enabled:!0})):[];if(r.headers=n(e.headers),r.queryParams=n(e.queryParams),r.pathParams=n(e.pathParams),e.body!=null&&typeof e.body=="object")try{r.body=JSON.stringify(e.body)}catch{r.body=String(e.body)}else r.body=e.body}function Se(e,r){e.status!==void 0&&(r.status=e.status),e.statusText!==void 0&&(r.statusText=e.statusText),e.body!==void 0&&(r.body=e.body)}function Ee(e,r,n){Array.isArray(e.reportEntries)||(e.reportEntries=[]);let s=e.reportEntries;for(let t of r.assertions??[])s.push({type:"assertion",message:t.message||t.condition||"Script assertion",passed:t.passed,actual:t.actualValue,expected:t.expectedValue,operator:t.operator});for(let t of n){let i=Array.isArray(t.args)?t.args.map(o=>typeof o=="object"?JSON.stringify(o):String(o)).join(" "):String(t.args??"");i&&s.push({type:"log",message:i,level:t.level??"log"})}r.error&&s.push({type:"log",message:`Script error: ${r.error}`,level:"error"})}var be=e=>({onload(){let r=null,n={};e.pipeline.registerHook("pre-processing",s=>{if(!s.editor)return;s.requestState.metadata||(s.requestState.metadata={});let t=s.editor.getJSON();s.requestState.metadata.editorDocument=t,r=t,n=s.editor.__cliEnv??{},s.requestState.metadata._cliVarsRef=s.editor.__cliVars??{}},5),e.pipeline.registerHook("pre-send",async s=>{if(!r)return;let t=Q(r,"pre_script");if(!t||!M(t.body,t.language))return;let{executeHeadlessScript:i}=await Promise.resolve().then(()=>(D(),w)),o=s.requestState.metadata?._cliVarsRef??{},l={...H(),...o},d=B(s.requestState),u=await i(t.body,t.language,d,null,n,l);if(u.success&&u.modifiedRequest&&me(u.modifiedRequest,s.requestState),u.modifiedVariables&&Object.assign(o,u.modifiedVariables),s.requestState.metadata||(s.requestState.metadata={}),s.requestState.metadata.preScriptLogs=u.logs??[],s.requestState.metadata.preScriptAssertions=u.assertions??[],u.error&&(s.requestState.metadata.preScriptError=u.error),u.cancelled)throw s.requestState.metadata.scriptCancelled=!0,new Error("Request cancelled by pre-request script")},15),e.pipeline.registerHook("post-processing",async s=>{s.responseState.metadata||(s.responseState.metadata={});let t=s.responseState.metadata;if(!r)return;let i=Q(r,"post_script");if(!i||!M(i.body,i.language))return;let{executeHeadlessScript:o}=await Promise.resolve().then(()=>(D(),w)),l=s.requestState?.metadata?._cliVarsRef??{},d={...H(),...l},u=B(s.requestState),y=ve(s.responseState),p=await o(i.body,i.language,u,y,n,d);p.success&&p.modifiedResponse&&Se(p.modifiedResponse,s.responseState),p.modifiedVariables&&Object.assign(l,p.modifiedVariables),t.postScriptLogs=p.logs??[],t.postScriptAssertions=p.assertions??[],p.error&&(t.postScriptError=p.error),r=null},25),e.pipeline.registerHook("post-processing",s=>{let t=s.responseState;if(!t)return;t.metadata||(t.metadata={});let i=s.requestState?.metadata?.preScriptLogs??[],o=s.requestState?.metadata?.preScriptAssertions??[],l=t.metadata.postScriptLogs??[],d=t.metadata.postScriptAssertions??[],u=s.requestState?.metadata?.preScriptError,y=t.metadata.postScriptError,p={assertions:[...o,...d],error:y??u},m=[...i,...l];Ee(t.metadata,p,m)},60)}}),$e=be;
@@ -0,0 +1 @@
1
+ "use strict";var f=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var m=(o,e)=>{for(var a in e)f(o,a,{get:e[a],enumerable:!0})},w=(o,e,a,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of g(e))!h.call(o,s)&&s!==a&&f(o,s,{get:()=>e[s],enumerable:!(r=p(e,s))||r.enumerable});return o};var R=o=>w(f({},"__esModule",{value:!0}),o);var C={};m(C,{buildRequest:()=>y,default:()=>k});module.exports=R(C);function y(o){let e=o.find(t=>t.type==="socket-request");if(!e)return null;let a="";if(Array.isArray(e.content))for(let t of e.content)t.type==="surl"&&typeof t.content=="string"&&(a=t.content.trim());if(!a)return null;let r=a.toLowerCase(),s="ws";r.startsWith("wss://")?s="wss":r.startsWith("ws://")?s="ws":r.startsWith("grpcs://")?s="grpcs":r.startsWith("grpc://")&&(s="grpc");let l=o.find(t=>t.type==="headers-table"),d=[];if(l&&Array.isArray(l.content)){for(let t of l.content)if(t.type==="table"&&Array.isArray(t.rows))for(let c of t.rows)!c.attrs?.disabled&&Array.isArray(c.row)&&c.row[0]&&d.push({key:String(c.row[0]).trim(),value:String(c.row[1]??"").trim(),enabled:!0})}let u=e.content?.find?.(t=>t.type==="proto"),i={};if(u?.attrs){let t=u.attrs;t.protoFilePath&&(i.protoFilePath=t.protoFilePath),t.service&&(i.service=t.service),t.method&&(i.method=t.method),t.package&&(i.package=t.package),t.callType&&(i.callType=t.callType)}return{method:s.toUpperCase(),url:a,headers:d,queryParams:[],pathParams:[],grpc:Object.keys(i).length?i:void 0,metadata:{protocol:s}}}var b=o=>({onload(){o.onBuildRequest((e,a)=>y(a)??e),o.onProcessResponse(async e=>{let a=e?.metadata?.handoff;if(!a)return;let{protocol:r,url:s,headers:l,grpc:d,body:u}=a,i=Object.entries(l).map(([t,c])=>({key:t,value:c,enabled:!0}));if(r==="ws"||r==="wss"){let t=await o.protocols?.executeWebSocket({protocol:r,url:s,headers:i});if(!t)return;let c={connected:t.connected??!1,protocol:r,url:s,durationMs:t.durationMs,...t.error?{error:t.error}:{}},n=e;n.statusCode=t.connected?101:0,n.statusMessage=t.connected?"Switching Protocols":t.error??"Connection Failed",n.status=n.statusCode,n.statusText=n.statusMessage,e.body=JSON.stringify(c,null,2),e.metadata&&delete e.metadata.handoff}else if(r==="grpc"||r==="grpcs"){let t=await o.protocols?.executeGrpc({protocol:r,url:s,metadata:l,body:u,...d??{}});if(!t)return;let c={connected:t.connected??!1,protocol:r,url:s,durationMs:t.durationMs,...d?.service?{service:d.service}:{},...d?.method?{method:d.method}:{},...t.error?{error:t.error}:{}},n=e;n.statusCode=t.connected?200:0,n.statusMessage=t.connected?"Connected":t.error??"Connection Failed",n.status=n.statusCode,n.statusText=n.statusMessage,e.body=JSON.stringify(c,null,2),e.metadata&&delete e.metadata.handoff}})}}),k=b;0&&(module.exports={buildRequest});
@@ -40,7 +40,7 @@ export declare function createCliElectron(env: Record<string, string>, runtimeVa
40
40
  * .voiden/.process.env.json. In CLI we have no project dir, so just return
41
41
  * the state as-is. Pass --env to cover the same variables.
42
42
  */
43
- preSendProcess: (state: RestApiRequestState) => Promise<any>;
43
+ preSendProcess: (state: RestApiRequestState) => Promise<RestApiRequestState>;
44
44
  /** replaceProcessVariablesInText equivalent — identity in CLI */
45
45
  replaceVar: (text: string) => Promise<string>;
46
46
  /** expandLinkedBlocksInDoc equivalent — no linked blocks in CLI */