@powerduck/request 0.1.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/index.cjs +1 -0
- package/dist/index.d.cts +124 -0
- package/dist/index.d.ts +124 -0
- package/dist/index.js +1 -0
- package/dist/protocol-58EyJAsY.d.cts +372 -0
- package/dist/protocol-58EyJAsY.d.ts +372 -0
- package/dist/protocols/http/index.cjs +1 -0
- package/dist/protocols/http/index.d.cts +86 -0
- package/dist/protocols/http/index.d.ts +86 -0
- package/dist/protocols/http/index.js +1 -0
- package/dist/protocols/ws/index.cjs +1 -0
- package/dist/protocols/ws/index.d.cts +53 -0
- package/dist/protocols/ws/index.d.ts +53 -0
- package/dist/protocols/ws/index.js +1 -0
- package/package.json +83 -0
- package/readme.md +463 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(r,n=0){if(!r||"object"!=typeof r||n>12)return null;if(void 0!==r.example)return r.example;if(void 0!==r.examples){if(Array.isArray(r.examples)&&r.examples.length)return r.examples[0];if("object"==typeof r.examples){const e=Object.values(r.examples)[0];if(void 0!==e)return e&&"object"==typeof e&&"value"in e?e.value:e}}if(void 0!==r.default)return r.default;if(void 0!==r.const)return r.const;if(Array.isArray(r.enum)&&r.enum.length)return r.enum[0];if(Array.isArray(r.allOf)&&r.allOf.length)return r.allOf.reduce((t,r)=>{const o=e(r,n+1);return o&&"object"==typeof o&&!Array.isArray(o)?{...t,...o}:null!=o?o:t},{});for(const t of["oneOf","anyOf"])if(Array.isArray(r[t])&&r[t].length)return e(r[t][0],n+1);switch((Array.isArray(r.type)?r.type.find(e=>"null"!==e)??"null":r.type)??(r.properties?"object":r.items?"array":(r.format,"string"))){case"object":{const t={},o=Array.isArray(r.required)?r.required:[],s=r.properties&&"object"==typeof r.properties?r.properties:{};for(const[r,i]of Object.entries(s))i&&!0===i.readOnly||n>2&&o.length&&!o.includes(r)||(t[r]=e(i,n+1));return!Object.keys(t).length&&r.additionalProperties&&"object"==typeof r.additionalProperties&&(t.key=e(r.additionalProperties,n+1)),t}case"array":{const t=Math.max(1,Math.min(Number(r.minItems)||1,2));return Array.from({length:t},()=>e(r.items,n+1))}case"integer":return t(r,Math.trunc(r.minimum??0));case"number":return t(r,r.minimum??0);case"boolean":return!1;case"null":return null;default:return function(e){switch(e.format){case"date-time":return(new Date).toISOString();case"date":return(new Date).toISOString().slice(0,10);case"time":return(new Date).toISOString().slice(11,19);case"uuid":return"00000000-0000-4000-8000-000000000000";case"email":return"user@example.com";case"hostname":return"example.com";case"ipv4":return"127.0.0.1";case"ipv6":return"::1";case"uri":case"url":case"uri-reference":return"https://example.com";case"byte":case"binary":return"";case"password":return"password";default:{if("string"==typeof e.pattern)return"";const t=Number(e.minLength)||0,r="string";return t>r.length?r.padEnd(t,"x"):r}}}(r)}}function t(e,t){let r=t;return"number"==typeof e.minimum&&r<e.minimum&&(r=e.minimum),"number"==typeof e.maximum&&r>e.maximum&&(r=e.maximum),r}var r=/(token|secret|password|passwd|apikey|api_key|credential|private)/i;function n(e,t){if(t.serverUrl)return o(t.serverUrl);const r=Array.isArray(e)&&e.length?e[0]:{url:"/"};let n="string"==typeof r?.url&&r.url?r.url:"/";const s=r?.variables&&"object"==typeof r.variables?r.variables:{};for(const[e,r]of Object.entries(s)){const o=t.serverVariables?.[e],s=r?.default??(Array.isArray(r?.enum)&&r.enum.length?r.enum[0]:""),i=void 0!==o?o:s;n=n.split(`{${e}}`).join(String(i??""))}return n=n.replace(/\{[^}]*\}/g,""),o(n)}function o(e){return e.replace(/\/+$/,"")||e}function s(e,t,n={}){const o=[{key:"baseUrl",value:t,type:"default",enabled:!0},...Object.entries(n??{}).filter(([e])=>"baseUrl"!==e).map(([e,t])=>({key:e,value:null==t?"":String(t),type:r.test(e)?"secret":"default",enabled:!0}))];return{id:`protokit-env-${Date.now().toString(36)}`,name:e,values:o,_postman_variable_scope:"environment",_postman_exported_at:(new Date).toISOString()}}var i=["text/event-stream","application/json-seq","application/x-ndjson","application/ndjson","application/jsonl"];function a(e,t){const r=Object.entries(t?.header??{}).find(([e])=>"accept"===e.toLowerCase())?.[1];if("string"==typeof r&&r.toLowerCase().includes("text/event-stream"))return!0;const n=e?.responses;if(!n||"object"!=typeof n)return!1;for(const e of Object.values(n)){const t=e?.content;if(t&&"object"==typeof t)for(const[e,r]of Object.entries(t)){const t=e.toLowerCase();if(t.startsWith("text/event-stream"))return!0;if(r&&"object"==typeof r.itemSchema&&i.some(e=>t.startsWith(e)))return!0}}return!1}function c(e){return!!e&&/text\/event-stream/i.test(e)}function u(e){if(!e)return!1;const t=e.toLowerCase();return i.some(e=>t.includes(e))}function l(e){if(!e)return[];return(Array.isArray(e)?e:[e]).filter(e=>!!e&&null!=e.exec)}function p(e,t){return t.map((t,r)=>{return{listen:e,script:{id:t.id??`protokit-${e}-${r}`,type:"text/javascript",exec:(n=t.exec,Array.isArray(n)?n.map(e=>String(e)):String(n).split(/\r?\n/))}};var n}).filter(e=>e.script.exec.some(e=>e.trim().length>0))}function f(e){const t=e?.["x-postman-scripts"];if(!t||"object"!=typeof t)return{pre:[],test:[]};const r=e=>null==e?[]:"string"==typeof e?[{exec:e}]:Array.isArray(e)?e.length?"string"==typeof e[0]?[{exec:e}]:e.filter(e=>e&&null!=e.exec):[]:"object"==typeof e&&null!=e.exec?[e]:[];return{pre:r(t.preRequest??t.prerequest??t.collectionPreRequest),test:r(t.test??t.tests??t.collectionTest)}}var d=new Set(["GET","PUT","POST","DELETE","OPTIONS","HEAD","PATCH","TRACE"]);function m(e,t){const r=e.name,n=e.style??"form",o=e.explode??"form"===n;if(Array.isArray(t)){if(o)return t.map(e=>({key:r,value:y(e)}));const e="spaceDelimited"===n?" ":"pipeDelimited"===n?"|":",";return[{key:r,value:t.map(y).join(e)}]}if(t&&"object"==typeof t){const e=Object.entries(t);return"deepObject"===n?e.map(([e,t])=>({key:`${r}[${e}]`,value:y(t)})):o?e.map(([e,t])=>({key:e,value:y(t)})):[{key:r,value:e.flatMap(([e,t])=>[e,y(t)]).join(",")}]}return[{key:r,value:y(t)}]}function y(e){if(null==e)return"";if("object"==typeof e)try{return JSON.stringify(e)}catch{return String(e)}return String(e)}function h(t,r,o){const s=o.values??{},i=n(t.servers,o),a=function(e,t){if(t?.contentType)return t.contentType;const r=e?.requestBody?.content;if(!r||"object"!=typeof r)return;const n=Object.keys(r);return n.length?n.find(e=>e.includes("json"))??n[0]:void 0}(t.operation,s),c=[];for(const r of t.parameters.filter(e=>"path"===e.in)){const t=s.path?.[r.name],n=void 0!==t?t:e(r.schema??{});c.push({key:r.name,value:y(n)})}const u=t.path.replace(/^\//,"").split("/").filter(e=>e.length>0).map(e=>e.replace(/\{([^}]+)\}/g,(e,t)=>`:${t}`)),h=[],b=new Set;for(const r of t.parameters.filter(e=>"query"===e.in)){b.add(r.name);const t=null!=s.query&&Object.prototype.hasOwnProperty.call(s.query,r.name)?s.query[r.name]:r.required?e(r.schema??{}):void 0;null!=t?h.push(...m(r,t)):r.required||h.push({key:r.name,value:"",disabled:!0})}for(const[e,t]of Object.entries(s.query??{}))b.has(e)||null==t||h.push({key:e,value:y(t)});const v=[],j=new Set,w=(e,t)=>{const r=e.toLowerCase();j.has(r)||(j.add(r),v.push({key:e,value:t}))};for(const[e,t]of Object.entries(s.header??{}))null!=t&&w(e,y(t));for(const r of t.parameters.filter(e=>"header"===e.in)){if(/^(accept|content-type|authorization)$/i.test(r.name))continue;const t=r.required?e(r.schema??{}):void 0;null!=t&&""!==t&&w(r.name,y(t))}a&&w("Content-Type",a);const A=function(e){const t=new Set,r=e?.responses;if(!r||"object"!=typeof r)return;for(const e of Object.values(r))for(const r of Object.keys(e?.content??{}))"*/*"!==r&&t.add(r);if(!t.size)return;const n=Array.from(t);return n.sort((e,t)=>Number(t.toLowerCase().startsWith("text/event-stream"))-Number(e.toLowerCase().startsWith("text/event-stream"))),n.slice(0,8).join(", ")}(t.operation);A&&w("Accept",A);const S=t.parameters.filter(e=>"cookie"===e.in),O=[];for(const t of S){const r=s.cookie?.[t.name],n=void 0!==r?r:t.required?e(t.schema??{}):void 0;null!=n&&O.push(`${t.name}=${encodeURIComponent(y(n))}`)}for(const[e,t]of Object.entries(s.cookie??{}))S.some(t=>t.name===e)||null==t||O.push(`${e}=${encodeURIComponent(y(t))}`);let k;O.length&&w("Cookie",O.join("; "));const x=t.operation.requestBody;if(x&&a){const t=x.content?.[a]?.schema,r=void 0!==s.body?s.body:e(t??{});k=a.includes("json")?{mode:"raw",raw:"string"==typeof r?r:JSON.stringify(r??{},null,2),options:{raw:{language:"json"}}}:a.includes("x-www-form-urlencoded")?{mode:"urlencoded",urlencoded:g(r).map(([e,t])=>({key:e,value:y(t),type:"text"}))}:a.includes("multipart/form-data")?{mode:"formdata",formdata:g(r).map(([e,t])=>t&&"object"==typeof t&&"__file"in t?{key:e,type:"file",src:String(t.__file)}:{key:e,type:"text",value:y(t)})}:a.includes("xml")||a.startsWith("text/")?{mode:"raw",raw:"string"==typeof r?r:y(r)}:{mode:"raw",raw:y(r)}}const q=h.filter(e=>!e.disabled);let E=`{{baseUrl}}/${u.join("/")}`;const T=[q.map(e=>`${encodeURIComponent(e.key)}=${encodeURIComponent(e.value)}`).join("&"),s.querystring?String(s.querystring).replace(/^\?/,""):""].filter(Boolean).join("&");T&&(E+=`?${T}`);const $={raw:E,host:["{{baseUrl}}"],path:u};h.length&&($.query=h),c.length&&($.variable=c);const I=t.method.toUpperCase(),C={method:I,header:v,url:$,description:t.operation.description??t.operation.summary};k&&(C.body=k);const D=function(e,t){const r=!1===t?.fromSpecExtensions?{pre:[],test:[]}:f(e);return[...p("prerequest",[...r.pre,...l(t?.preRequest)]),...p("test",[...r.test,...l(t?.test)])]}(t.operation,o.scripts),_=function(e,t){const r=!1===t?.fromSpecExtensions?{pre:[],test:[]}:f(e);return[...p("prerequest",[...r.pre,...l(t?.collectionPreRequest)]),...p("test",[...r.test,...l(t?.collectionTest)])]}(r,o.scripts),P=function(e){if(e&&"none"!==e.type)switch(e.type){case"bearer":return{type:"bearer",bearer:[{key:"token",value:e.token??"",type:"string"}]};case"basic":return{type:"basic",basic:[{key:"username",value:e.username??"",type:"string"},{key:"password",value:e.password??"",type:"string"}]};case"apikey":return{type:"apikey",apikey:[{key:"key",value:e.key??"X-API-Key",type:"string"},{key:"value",value:e.value??"",type:"string"},{key:"in",value:e.in??"header",type:"string"}]};default:return}}(o.auth),N={info:{_postman_id:`protokit-${Date.now().toString(36)}`,name:r?.info?.title??"OpenAPI Debug Session",description:r?.info?.description,schema:"https://schema.getpostman.com/json/collection/v2.1.0/collection.json"},item:[{name:t.operation.operationId??`${I} ${t.path}`,...D.length?{event:D}:{},request:C,response:[]}],variable:[{key:"baseUrl",value:i}]};return P&&(N.auth=P),_.length&&(N.event=_),{collection:N,baseUrl:i,contentType:a,isCustomMethod:!d.has(I)}}function g(e){return!e||"object"!=typeof e||Array.isArray(e)?[]:Object.entries(e)}import b from"postman-runtime";import v from"postman-collection";var j=class e extends Error{code;details;constructor(t,r,n){super(t),this.name="ProtoKitError",this.code=r,this.details=n,Object.setPrototypeOf(this,e.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,e)}};function w(e,t,r){return new j(t,e,r)}function A(e){if(e instanceof j)return{message:e.message,code:e.code,name:e.name};if(e instanceof Error)return{message:e.message,code:e.code,name:e.name};if("string"==typeof e)return{message:e};try{return{message:JSON.stringify(e)}}catch{return{message:String(e)}}}function S(e){const t=new WeakSet;return JSON.parse(JSON.stringify(e,(e,r)=>{if(r&&"object"==typeof r){if(t.has(r))return;t.add(r)}return r}))}function O(e,t){if(!t)return e;const r={...e};for(const[e,n]of Object.entries(t)){if(void 0===n)continue;const t=r[e];k(t)&&k(n)?r[e]=O(t,n):r[e]=n}return r}function k(e){if(null===e||"object"!=typeof e||Array.isArray(e))return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}function x(e){if(e)try{clearTimeout(e)}catch{}return null}var q=new Set(["[DONE]","DONE"]),E=class{buffer="";decoder=new TextDecoder("utf-8");lastEventId;sequence=0;push(e){if(null==e)return[];if("string"==typeof e)this.buffer+=e;else{const t=e instanceof Uint8Array?e:new Uint8Array(e);this.buffer+=this.decoder.decode(t,{stream:!0})}0===this.sequence&&65279===this.buffer.charCodeAt(0)&&(this.buffer=this.buffer.slice(1));const t=[],r=/\r\n\r\n|\n\n|\r\r/;for(;;){const e=r.exec(this.buffer);if(!e)break;const n=this.buffer.slice(0,e.index);this.buffer=this.buffer.slice(e.index+e[0].length);const o=this.parseBlock(n);o&&t.push(o)}return t}flush(){try{this.buffer+=this.decoder.decode()}catch{}const e=this.buffer;if(this.buffer="",!e.trim())return[];const t=this.parseBlock(e);return t?[t]:[]}reset(){this.buffer="",this.lastEventId=void 0,this.sequence=0}parseBlock(e){const t=e.split(/\r\n|\n|\r/),r=[],n={data:"",receivedAt:Date.now(),direction:"in"};let o=!1;for(const e of t){if(""===e)continue;if(e.startsWith(":"))continue;const t=e.indexOf(":"),s=-1===t?e:e.slice(0,t);let i=-1===t?"":e.slice(t+1);switch(i.startsWith(" ")&&(i=i.slice(1)),s){case"data":r.push(i),o=!0;break;case"event":n.event=i,o=!0;break;case"id":i.includes("\0")||(n.id=i,this.lastEventId=i),o=!0;break;case"retry":{const e=Number(i);Number.isInteger(e)&&e>=0&&(n.retry=e),o=!0;break}}}if(!o)return null;n.data=r.join("\n"),void 0===n.id&&void 0!==this.lastEventId&&(n.id=this.lastEventId);const s=n.data.trim();if(s&&!q.has(s))try{n.parsed=JSON.parse(n.data)}catch{}return this.sequence+=1,n}};import T from"postman-collection";function $(e,t=[]){const r=[...t,...Object.entries(e??{}).map(([e,t])=>({key:e,value:null==t?"":String(t)}))],n=new Map;for(const e of r)n.set(e.key,e);return new T.VariableScope({values:Array.from(n.values())})}function I(e,t){const r=e.runner?.timeout?.request??e.timeout??3e4,n=O({iterationCount:1,stopOnError:!1,abortOnError:!1,stopOnFailure:!1,abortOnFailure:!1,timeout:{request:r,script:15e3,global:r+(t.streaming?e.maxStreamMs??3e4:0)+15e3},delay:{item:0,iteration:0},script:{serializeLogs:!1},ignoreProxyEnvironmentVariables:!1,requester:{strictSSL:!0,followRedirects:!0,followOriginalHttpMethod:!1,maxRedirects:10,useWhatWGUrlParser:!0,removeRefererHeaderOnRedirect:!1,insecureHTTPParser:!1,timings:!0,verbose:!0,implicitCacheControl:!0,implicitTraceHeader:!0,disableCookies:!1,protocolVersion:"http1",maxInvokableNestedRequests:5}},{}),o=O(n,e.runner??{});return o.environment||(o.environment=$(e.variables,[{key:"baseUrl",value:t.baseUrl}])),!o.globals&&e.globals&&(o.globals=$(e.globals)),!o.localVariables&&e.localVariables&&(o.localVariables=$(e.localVariables)),Array.isArray(o.data)&&o.data.length&&void 0===e.runner?.iterationCount&&(o.iterationCount=o.data.length),o}function C(e){const t={},r="function"==typeof e?.all?e.all():[];for(const e of r??[]){if(!e||e.disabled)continue;const r=String(e.key??"");r&&(t[r]=t[r]?`${t[r]}, ${String(e.value??"")}`:String(e.value??""))}return t}function D(e){if(e)try{const t=e.values??e,r="function"==typeof t.toJSON?t.toJSON():t;if(!Array.isArray(r))return;const n={};for(const e of r)e&&!1!==e.enabled&&null!=e.key&&(n[String(e.key)]=null==e.value?"":String(e.value));return n}catch{return}}function _(e){const t=e?.body;if(t)try{if("raw"===t.mode)return t.raw;if("function"==typeof t.toString){return t.toString()||void 0}return S(t)}catch{return}}function P(e,t){const r=function(){let e,t,r=!1;return{promise:new Promise((r,n)=>{e=r,t=n}),get settled(){return r},resolve(t){r||(r=!0,e(t))},reject(e){r||(r=!0,t(e))}}}(),n=Date.now();let o,s=e.streamingHint,i=!1,a=!1;const l=new E,p=[],f=[];let d=0;const m={prerequest:[],test:[],assertions:[],console:[],passed:!0,skipped:!1},y=[];let h=null,g=null,j=null,O=null;const k=t.maxEvents??100,q=t.maxStreamMs??3e4,T=t.runner?.timeout?.request??t.timeout??3e4,$=e=>{if(!i){i=!0,a=!0,m.console.push({level:"debug",messages:[`[protokit] stream sampling stopped: ${e}`],at:Date.now()});try{g?.abort?.()}catch{}}},P=(e,t)=>({target:t,scriptId:e?.script?.id??e?.event?.script?.id,error:e?.error?{name:e.error.name,message:e.error.message}:void 0,environment:D(e?.result?.environment),globals:D(e?.result?.globals),return:e?.result?.return}),M=()=>{if(j=x(j),O=x(O),s)for(const e of l.flush())p.length<k&&(p.push(e),N(()=>t.onEvent?.(e)));if(h)s&&(h.response.events=p,a&&(h.response.truncated=!0));else{const e=Date.now();h={protocol:s?"sse":"http",request:{method:"",url:"",headers:{}},response:{status:i&&p.length?200:0,statusText:i?"Stream sampling stopped":"No response received",headers:{},contentType:s?"text/event-stream":void 0,...s?{events:p}:{},timings:{startedAt:n,endedAt:e,durationMs:e-n,firstByteMs:o?o-n:void 0},sizeBytes:d,...a?{truncated:!0}:{}},...i&&p.length?{}:{error:{message:"Runner finished without a response"}}}}h.scripts=m,r.resolve(h)};let L,J,W;O=setTimeout(()=>{if(!r.settled){m.console.push({level:"error",messages:["[protokit] hard timeout reached, forcing completion"],at:Date.now()});try{g?.abort?.()}catch{}a=!0,M()}},T+q+3e4),"object"==typeof O&&"function"==typeof O.unref&&O.unref();try{L=new v.Collection(S(e.collectionJson))}catch(e){return O=x(O),Promise.reject(w("BAD_COLLECTION",`Failed to construct collection: ${A(e).message}`,e))}try{J=I(t,{baseUrl:e.baseUrl,streaming:e.streamingHint})}catch(e){return O=x(O),Promise.reject(w("BAD_RUN_OPTIONS",`Failed to build runtime options: ${A(e).message}`,e))}try{W=new b.Runner}catch(e){return O=x(O),Promise.reject(w("RUNTIME_INIT",`Failed to create runner: ${A(e).message}`,e))}return W.run(L,J,(e,b)=>{if(e)return O=x(O),void r.reject(w("RUNTIME_INIT",e.message??"Runner initialization failed",e));g=b,b.start({console(e,r,...n){const o={level:"string"==typeof r?r:"log",messages:n,at:Date.now()};m.console.push(o),N(()=>t.onConsole?.(o))},assertion(e,r){for(const e of r??[]){const r={name:e?.name??"assertion",passed:!e?.error&&!e?.skipped,skipped:!!e?.skipped,index:"number"==typeof e?.index?e.index:0,error:e?.error?{name:e.error.name,message:e.error.message??String(e.error),stack:e.error.stack}:void 0};r.passed||r.skipped||(m.passed=!1),m.assertions.push(r),N(()=>t.onAssertion?.(r))}},prerequest(e,t,r){for(const e of r??[])m.prerequest.push(P(e,"prerequest"))},test(e,t,r){for(const e of r??[])m.test.push(P(e,"test"))},item(e,t,r,n,o){o?.isSkipped&&(m.skipped=!0)},responseStart(e,r,n){o=Date.now();const i=U(n,"content-type");(c(i)||u(i))&&(s=!0),N(()=>t.onResponseStart?.({status:n?.code??0,headers:C(n?.headers),contentType:i})),s&&!j&&(j=setTimeout(()=>$("maxStreamMs reached"),q),"object"==typeof j&&"function"==typeof j.unref&&j.unref())},responseData(e,r){if(i||null==r)return;let n;try{n=Buffer.isBuffer(r)?r:Buffer.from(r)}catch{return}if(d+=n.length,s)for(const e of l.push(n)){if(p.length>=k)return void $("maxEvents reached");if(p.push(e),N(()=>t.onEvent?.(e)),p.length>=k)return void $("maxEvents reached")}else f.push(n)},request(e,t,r,i,l,m){const g=Date.now(),b={method:i?.method??"",url:B(i),headers:C(i?.headers),body:_(i)};if(e)return void(h={protocol:s?"sse":"http",request:b,response:{status:0,statusText:"Request failed",headers:{},timings:{startedAt:n,endedAt:g,durationMs:g-n},sizeBytes:d},error:A(e),replays:y});const v=U(r,"content-type");let j,w;if((c(v)||u(v))&&(s=!0),!s){const e=f.length?Buffer.concat(f):r?.stream?Buffer.from(r.stream):Buffer.alloc(0);j=function(e){const t=Math.min(e.length,1024);for(let r=0;r<t;r+=1)if(0===e[r])return!0;return!1}(e)?void 0:e.toString("utf8"),w=function(e,t){if(!e)return;if(t&&!/json/i.test(t))return;const r=e.trim();if(r&&/^[[{"\-\d]|^(true|false|null)$/.test(r))try{return JSON.parse(r)}catch{return}}(j,v)}h={protocol:s?"sse":"http",request:b,response:{status:"number"==typeof r?.code?r.code:0,statusText:R(r),headers:C(r?.headers),contentType:v,...s?{events:p}:{body:w,text:j},timings:{startedAt:n,endedAt:g,durationMs:"number"==typeof r?.responseTime?r.responseTime:g-n,firstByteMs:o?o-n:void 0},sizeBytes:d||r?.responseSize||0,...a?{truncated:!0}:{}},cookies:Array.isArray(m)?m.map(e=>({name:String(e?.name??""),value:String(e?.value??""),domain:e?.domain,path:e?.path})):[],replays:y}},io(e,t,r,n,o){"http"===r?.type&&r.source&&"collection"!==r.source&&y.push({url:B(o),method:o?.method??"",status:"number"==typeof n?.code?n.code:0,reason:String(r.source)})},exception(e,t){m.console.push({level:"error",messages:[`[exception] ${A(t).message}`],at:Date.now()})},done(e){if(e&&!h&&!i)return j=x(j),O=x(O),void r.reject(w("RUNTIME_RUN",e.message??"Run failed",e));M()}})}),r.promise}function N(e){try{e()}catch{}}function U(e,t){try{const r=e?.headers?.get?.(t);return null==r?void 0:String(r)}catch{return}}function R(e){try{return String("function"==typeof e?.reason?e.reason()??"":e?.status??"")}catch{return""}}function B(e){try{return"function"==typeof e?.url?.toString?e.url.toString():""}catch{return""}}var M="__protokit_cycle__";function L(e){const t=new Map;function r(t){if("string"!=typeof t||!t.startsWith("#/"))throw w("EXTERNAL_REF",`Only local $ref pointers are supported, got: ${t}`);let r=e;const n=t.slice(2).split("/");for(const e of n){if(null==r||"object"!=typeof r)throw w("BAD_REF",`Cannot resolve pointer "${t}"`);r=r[decodeURIComponent(e).replace(/~1/g,"/").replace(/~0/g,"~")]}if(void 0===r)throw w("BAD_REF",`Pointer "${t}" resolves to undefined`);return r}function n(e){let t=e;const n=new Set;let o=0;for(;t&&"object"==typeof t&&"string"==typeof t.$ref;){if(n.has(t.$ref)||++o>100)return{type:"object",[M]:!0};n.add(t.$ref),t=r(t.$ref)}return t}function o(e,t=0,r=new Set){if(null==e||"object"!=typeof e)return e;if(t>32)return{type:"object"};const s=n(e);if(null==s||"object"!=typeof s)return s;if(s[M])return{type:"object"};if(r.has(s))return{type:"object"};const i=new Set(r);if(i.add(s),Array.isArray(s))return s.map(e=>o(e,t+1,i));const a={};for(const[e,r]of Object.entries(s))e!==M&&(a[e]=o(r,t+1,i));return a}return{deref:n,deepDeref:function(e){const r=e&&"object"==typeof e?e.$ref:void 0;if("string"==typeof r&&t.has(r))return t.get(r);const n=o(e);return"string"==typeof r&&t.set(r,n),n},byPointer:r}}var J=["get","put","post","delete","options","head","patch","trace","query"];function W(e,t){if(!e||"object"!=typeof e)throw w("BAD_SPEC","spec must be an object");if("string"!=typeof e.openapi)throw w("BAD_SPEC","spec.openapi version string is required");if(!t||"object"!=typeof t)throw w("BAD_TARGET","target is required");const r=L(e),n=e.paths;if(!n||"object"!=typeof n)throw w("BAD_SPEC","spec.paths is missing or invalid");const o=[];for(const[e,t]of Object.entries(n)){let n;try{n=r.deref(t)}catch{continue}if(!n||"object"!=typeof n)continue;for(const t of J)n[t]&&"object"==typeof n[t]&&o.push({path:e,method:t,rawOperation:n[t],pathItem:n,isCustomMethod:!1});const s=n.additionalOperations;if(s&&"object"==typeof s)for(const[t,r]of Object.entries(s))r&&"object"==typeof r&&o.push({path:e,method:t.toLowerCase(),rawOperation:r,pathItem:n,isCustomMethod:!0})}if(!o.length)throw w("EMPTY_SPEC","The document does not declare any operation");let s;if(t.operationId){if(s=o.find(e=>{try{return r.deref(e.rawOperation)?.operationId===t.operationId}catch{return!1}}),!s)throw w("OP_NOT_FOUND",`operationId "${t.operationId}" was not found`)}else{if(!t.path||!t.method)throw w("BAD_TARGET","Provide either operationId, or both path and method");const e=String(t.method).toLowerCase();if(s=o.find(r=>r.path===t.path&&r.method===e),!s)throw w("OP_NOT_FOUND",`Operation "${String(t.method).toUpperCase()} ${t.path}" was not found`)}const i=r.deepDeref(s.rawOperation)??{},a=r.deref(s.pathItem)??{},c=new Map,u=e=>{if(Array.isArray(e))for(const t of e){let e;try{e=r.deepDeref(t)}catch{continue}e&&"string"==typeof e.name&&"string"==typeof e.in&&c.set(`${e.in}:${e.name}`,e)}};u(a.parameters),u(s.rawOperation.parameters);const l=Array.isArray(i.servers)&&i.servers.length&&i.servers||Array.isArray(a.servers)&&a.servers.length&&a.servers||Array.isArray(e.servers)&&e.servers.length&&e.servers||[{url:"/"}];return{path:s.path,method:s.method,isCustomMethod:s.isCustomMethod,operation:i,pathItem:a,parameters:Array.from(c.values()),servers:l,security:i.security??e.security}}var F=class{name="http";supports(e){const t=e.located.operation?.["x-protocol"];return"string"==typeof t&&"http"!==t&&"sse"!==t?0:1}plan(e){const t=h(e.located,e.spec,e.options);return{...t,environment:s(`${e.spec?.info?.title??"API"} Environment`,t.baseUrl,e.options.variables),streaming:a(e.located.operation,e.options.values)}}execute(e,t){return P({collectionJson:e.collection,baseUrl:e.baseUrl,streamingHint:e.streaming},t)}};export{F as HttpAdapter,E as SseParser,h as buildCollection,s as buildEnvironment,I as buildRunOptions,L as createResolver,W as locateOperation,n as resolveServerUrl,P as runWithPostman};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e,t=Object.create,r=Object.defineProperty,o=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,s=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,i=(e,t,s,i)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of n(t))a.call(e,c)||c===s||r(e,c,{get:()=>t[c],enumerable:!(i=o(t,c))||i.enumerable});return e},c={};function l(e){return e.replace(/\/+$/,"")||e}function u(e,t){const r=null==e?"":String(e);return-1===r.indexOf("{{")?r:r.replace(/\{\{\s*([\w.$-]+)\s*\}\}/g,(e,r)=>Object.prototype.hasOwnProperty.call(t,r)?t[r]:e)}function p(e){if(e)try{clearTimeout(e)}catch{}return null}((e,t)=>{for(var o in t)r(e,o,{get:t[o],enumerable:!0})})(c,{WebSocketAdapter:()=>S,resolveWsConfig:()=>y,runWebSocket:()=>b}),module.exports=(e=c,i(r({},"__esModule",{value:!0}),e));var f=class e extends Error{code;details;constructor(t,r,o){super(t),this.name="ProtoKitError",this.code=r,this.details=o,Object.setPrototypeOf(this,e.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,e)}};function d(e){if(e instanceof f)return{message:e.message,code:e.code,name:e.name};if(e instanceof Error)return{message:e.message,code:e.code,name:e.name};if("string"==typeof e)return{message:e};try{return{message:JSON.stringify(e)}}catch{return{message:String(e)}}}function y(e,t,r){const o=r.websocket??{},n=e.operation?.["x-websocket"]??{},s={...r.variables??{}};let a;if(o.url)a=o.url;else if("string"==typeof n.url&&n.url)a=n.url;else{const t=function(e){return/^wss?:\/\//i.test(e)?e:/^https:\/\//i.test(e)?e.replace(/^https:/i,"wss:"):/^http:\/\//i.test(e)?e.replace(/^http:/i,"ws:"):`wss://${e.replace(/^\/+/,"")}`}(function(e,t){if(t.serverUrl)return l(t.serverUrl);const r=Array.isArray(e)&&e.length?e[0]:{url:"/"};let o="string"==typeof r?.url&&r.url?r.url:"/";const n=r?.variables&&"object"==typeof r.variables?r.variables:{};for(const[e,r]of Object.entries(n)){const n=t.serverVariables?.[e],s=r?.default??(Array.isArray(r?.enum)&&r.enum.length?r.enum[0]:""),a=void 0!==n?n:s;o=o.split(`{${e}}`).join(String(a??""))}return o=o.replace(/\{[^}]*\}/g,""),l(o)}(e.servers,r)),o=e.path.replace(/\{([^}]+)\}/g,(e,t)=>{const o=r.values?.path?.[t];return null==o?e:encodeURIComponent(String(o))});a=`${t.replace(/\/+$/,"")}/${o.replace(/^\//,"")}`}a=u(a,{baseUrl:"",...s});try{const e=new URL(a);for(const[t,o]of Object.entries(r.values?.query??{}))null!=o&&e.searchParams.set(t,String(o));"apikey"===r.auth?.type&&"query"===r.auth.in&&e.searchParams.set(r.auth.key??"api_key",r.auth.value??""),a=e.toString()}catch{throw new f(`Resolved WebSocket URL is invalid: ${a}`,"BAD_WS_URL",i)}var i;const c={};for(const[e,t]of Object.entries(r.values?.header??{}))null!=t&&(c[e]=String(t));for(const[e,t]of Object.entries(n.headers??{}))null!=t&&(c[e]=u(String(t),s));for(const[e,t]of Object.entries(o.headers??{}))null!=t&&(c[e]=u(String(t),s));const p=r.auth;if(p&&"none"!==p.type&&!Object.keys(c).some(e=>"authorization"===e.toLowerCase()))if("bearer"===p.type)c.Authorization=`Bearer ${p.token??""}`;else if("basic"===p.type){const e=`${p.username??""}:${p.password??""}`;c.Authorization=`Basic ${Buffer.from(e,"utf8").toString("base64")}`}else"apikey"===p.type&&"header"===(p.in??"header")&&(c[p.key??"X-API-Key"]=p.value??"");const d=o.send??n.send??[],y=(Array.isArray(d)?d:[d]).map(e=>function(e){if(null==e)return null;if("string"==typeof e)return e;if(e instanceof Uint8Array)return e;try{return JSON.stringify(e)}catch{return null}}("string"==typeof e?u(e,s):e)).filter(e=>null!==e),m=o.keepAlive??n.keepAlive;return{url:a,subprotocols:o.subprotocols??n.subprotocols??[],headers:c,send:y,sendDelayMs:h(o.sendDelayMs,0),maxMessages:h(o.maxMessages??r.maxEvents,100),maxSessionMs:h(o.maxSessionMs??r.maxStreamMs,3e4),idleTimeoutMs:h(o.idleTimeoutMs,0),keepAlive:m?{intervalMs:h(m.intervalMs,15e3),payload:String(m.payload??"ping")}:void 0,closeCode:o.closeCode??1e3,closeReason:o.closeReason??"Client finished sampling",rejectUnauthorized:!1!==o.rejectUnauthorized,maxPayloadBytes:h(o.maxPayloadBytes,262144),clientOptions:o.clientOptions??{}}}function h(e,t){const r=Number(e);return!Number.isFinite(r)||r<0?t:r}var m=((e,o,n)=>(n=null!=e?t(s(e)):{},i(!o&&e&&e.__esModule?n:r(n,"default",{value:e,enumerable:!0}),e)))(require("ws"),1),g=new Set([1e3,1001,1005]);function b(e,t){const r=function(){let e,t,r=!1;return{promise:new Promise((r,o)=>{e=r,t=o}),get settled(){return r},resolve(t){r||(r=!0,e(t))},reject(e){r||(r=!0,t(e))}}}(),o=Date.now();let n,s=0,a=0,i=0,c=!1,l=!1;const u=[],f={};let y,h,b=0,S=null,w=null,k=null;const j=[];let O;try{O=new m.default(e.url,e.subprotocols,{headers:e.headers,handshakeTimeout:Math.max(5e3,Math.min(e.maxSessionMs,3e4)),rejectUnauthorized:e.rejectUnauthorized,maxPayload:4*e.maxPayloadBytes,...e.clientOptions})}catch(e){return Promise.resolve(A(d(e)))}function A(t){const r=Date.now(),s=!t&&b>0&&b<400;return{protocol:"websocket",request:{method:"GET",url:e.url,headers:{...e.headers,Upgrade:"websocket",Connection:"Upgrade",...e.subprotocols.length?{"Sec-WebSocket-Protocol":e.subprotocols.join(", ")}:{}},body:e.send.length?e.send.map(e=>"string"==typeof e?e:`<binary ${e.byteLength} bytes>`):void 0},response:{status:b||(t?0:101),statusText:t?"WebSocket error":s?"Switching Protocols":"Connection closed",headers:f,contentType:"application/json",events:u,timings:{startedAt:o,endedAt:r,durationMs:r-o,firstByteMs:n?n-o:void 0},sizeBytes:i,...c?{truncated:!0}:{}},...y?{cookies:[]}:{},...t?{error:t}:{}}}const x=e=>{r.settled||((()=>{if(S=p(S),w=p(w),k){try{clearInterval(k)}catch{}k=null}for(const e of j.splice(0))p(e)})(),r.resolve(A(e??h)))},M=t=>{if(l)return;l=!0,c=!0;try{O.readyState===m.default.OPEN?O.close(e.closeCode,`${e.closeReason}: ${t}`.slice(0,120)):O.terminate()}catch{}const r=setTimeout(()=>{try{O.terminate()}catch{}x()},3e3);"object"==typeof r&&"function"==typeof r.unref&&r.unref(),j.push(r)},P=()=>{e.idleTimeoutMs&&(w=p(w),w=setTimeout(()=>M("idle timeout"),e.idleTimeoutMs),"object"==typeof w&&"function"==typeof w.unref&&w.unref())},$=e=>{u.push(e);try{t.onEvent?.(e)}catch{}};return O.on("upgrade",e=>{b=e?.statusCode??101;for(const[t,r]of Object.entries(e?.headers??{}))f[t]=Array.isArray(r)?r.join(", "):String(r)}),O.on("unexpected-response",(e,t)=>{b=t?.statusCode??0;for(const[e,r]of Object.entries(t?.headers??{}))f[e]=Array.isArray(r)?r.join(", "):String(r);h={message:`Handshake rejected with HTTP ${b}`,code:"WS_HANDSHAKE_FAILED"};try{t?.destroy?.()}catch{}x(h)}),O.on("open",()=>{n=Date.now(),y=O.protocol||void 0,b||(b=101);try{t.onOpen?.({url:e.url,protocol:y,headers:f})}catch{}e.send.forEach((t,r)=>{const o=()=>{O.readyState===m.default.OPEN&&O.send(t,e=>{e?h=h??d(e):(a+=1,$({id:String(a),event:"string"==typeof t?"text":"binary",data:"string"==typeof t?t:`<binary ${t.byteLength} bytes>`,parsed:"string"==typeof t?v(t):void 0,receivedAt:Date.now(),direction:"out"}))})},n=e.sendDelayMs*r;if(n<=0)o();else{const e=setTimeout(o,n);"object"==typeof e&&"function"==typeof e.unref&&e.unref(),j.push(e)}}),e.keepAlive&&(k=setInterval(()=>{if(O.readyState===m.default.OPEN)try{O.ping(e.keepAlive.payload)}catch{}},e.keepAlive.intervalMs),"object"==typeof k&&"function"==typeof k.unref&&k.unref()),P()}),O.on("message",(t,r)=>{if(l)return;const o=function(e){return Buffer.isBuffer(e)?e:Array.isArray(e)?Buffer.concat(e):Buffer.from(e)}(t);i+=o.length,a+=1,s+=1;const n=o.length>e.maxPayloadBytes,c=r?`<binary ${o.length} bytes>`:n?`${o.subarray(0,e.maxPayloadBytes).toString("utf8")}...`:o.toString("utf8");$({id:String(a),event:r?"binary":"text",data:c,parsed:r||n?void 0:v(c),receivedAt:Date.now(),direction:"in"}),P(),s>=e.maxMessages&&M("maxMessages reached")}),O.on("ping",e=>{a+=1,$({id:String(a),event:"ping",data:e?.length?e.toString("utf8"):"",receivedAt:Date.now(),direction:"in"}),P()}),O.on("error",e=>{h=h??d(e),O.readyState===m.default.CLOSED&&x(h)}),O.on("close",(e,t)=>{const r=t?.length?t.toString("utf8"):"";h||g.has(e)||l||(h={message:`Connection closed with code ${e}${r?`: ${r}`:""}`,code:String(e)}),x(h)}),S=setTimeout(()=>M("maxSessionMs reached"),e.maxSessionMs),"object"==typeof S&&"function"==typeof S.unref&&S.unref(),r.promise}function v(e){const t=e.trim();if(t&&/^[[{"\-\d]|^(true|false|null)$/.test(t))try{return JSON.parse(t)}catch{return}}var S=class{name="websocket";supports(e){const t=e.located.operation??{};return"websocket"===t["x-protocol"]||"ws"===t["x-protocol"]?20:t["x-websocket"]&&"object"==typeof t["x-websocket"]||e.options.websocket?.url?15:"websocket"===e.located.pathItem?.["x-protocol"]?12:0}plan(e){const t=y(e.located,e.spec,e.options);return{config:t,environment:{id:`protokit-ws-env-${Date.now().toString(36)}`,name:`${e.spec?.info?.title??"API"} WebSocket Environment`,values:[{key:"wsUrl",value:t.url,type:"default",enabled:!0},...Object.entries(e.options.variables??{}).map(([e,t])=>({key:e,value:String(t??""),type:/token|secret|password|apikey/i.test(e)?"secret":"default",enabled:!0}))],_postman_variable_scope:"environment"}}}execute(e,t){return b(e.config,t)}};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { L as LocatedOperation, a as SendOptions, E as ExecResult, P as ProtocolAdapter, A as AdapterContext } from '../../protocol-58EyJAsY.cjs';
|
|
2
|
+
|
|
3
|
+
interface ResolvedWsConfig {
|
|
4
|
+
url: string;
|
|
5
|
+
subprotocols: string[];
|
|
6
|
+
headers: Record<string, string>;
|
|
7
|
+
send: Array<string | Uint8Array>;
|
|
8
|
+
sendDelayMs: number;
|
|
9
|
+
maxMessages: number;
|
|
10
|
+
maxSessionMs: number;
|
|
11
|
+
idleTimeoutMs: number;
|
|
12
|
+
keepAlive?: {
|
|
13
|
+
intervalMs: number;
|
|
14
|
+
payload: string;
|
|
15
|
+
};
|
|
16
|
+
closeCode: number;
|
|
17
|
+
closeReason: string;
|
|
18
|
+
rejectUnauthorized: boolean;
|
|
19
|
+
maxPayloadBytes: number;
|
|
20
|
+
clientOptions: Record<string, unknown>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Resolve the effective WebSocket configuration.
|
|
24
|
+
*
|
|
25
|
+
* Precedence: options.websocket.url > operation['x-websocket'].url > server URL + path.
|
|
26
|
+
*/
|
|
27
|
+
declare function resolveWsConfig(located: LocatedOperation, spec: any, options: SendOptions): ResolvedWsConfig;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Open a WebSocket session, send the configured messages, and collect
|
|
31
|
+
* inbound frames until a sampling limit or a close event is reached.
|
|
32
|
+
*/
|
|
33
|
+
declare function runWebSocket(config: ResolvedWsConfig, options: SendOptions): Promise<ExecResult>;
|
|
34
|
+
|
|
35
|
+
interface WsPlan {
|
|
36
|
+
config: ResolvedWsConfig;
|
|
37
|
+
/** Environment document mirroring the HTTP adapter's output shape. */
|
|
38
|
+
environment: Record<string, any>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* WebSocket adapter.
|
|
42
|
+
*
|
|
43
|
+
* An operation is claimed when it declares `x-protocol: websocket`,
|
|
44
|
+
* carries an `x-websocket` extension, or the caller passes `websocket.url`.
|
|
45
|
+
*/
|
|
46
|
+
declare class WebSocketAdapter implements ProtocolAdapter<WsPlan> {
|
|
47
|
+
readonly name = "websocket";
|
|
48
|
+
supports(ctx: AdapterContext): number;
|
|
49
|
+
plan(ctx: AdapterContext): WsPlan;
|
|
50
|
+
execute(plan: WsPlan, options: SendOptions): Promise<ExecResult>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { type ResolvedWsConfig, WebSocketAdapter, type WsPlan, resolveWsConfig, runWebSocket };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { L as LocatedOperation, a as SendOptions, E as ExecResult, P as ProtocolAdapter, A as AdapterContext } from '../../protocol-58EyJAsY.js';
|
|
2
|
+
|
|
3
|
+
interface ResolvedWsConfig {
|
|
4
|
+
url: string;
|
|
5
|
+
subprotocols: string[];
|
|
6
|
+
headers: Record<string, string>;
|
|
7
|
+
send: Array<string | Uint8Array>;
|
|
8
|
+
sendDelayMs: number;
|
|
9
|
+
maxMessages: number;
|
|
10
|
+
maxSessionMs: number;
|
|
11
|
+
idleTimeoutMs: number;
|
|
12
|
+
keepAlive?: {
|
|
13
|
+
intervalMs: number;
|
|
14
|
+
payload: string;
|
|
15
|
+
};
|
|
16
|
+
closeCode: number;
|
|
17
|
+
closeReason: string;
|
|
18
|
+
rejectUnauthorized: boolean;
|
|
19
|
+
maxPayloadBytes: number;
|
|
20
|
+
clientOptions: Record<string, unknown>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Resolve the effective WebSocket configuration.
|
|
24
|
+
*
|
|
25
|
+
* Precedence: options.websocket.url > operation['x-websocket'].url > server URL + path.
|
|
26
|
+
*/
|
|
27
|
+
declare function resolveWsConfig(located: LocatedOperation, spec: any, options: SendOptions): ResolvedWsConfig;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Open a WebSocket session, send the configured messages, and collect
|
|
31
|
+
* inbound frames until a sampling limit or a close event is reached.
|
|
32
|
+
*/
|
|
33
|
+
declare function runWebSocket(config: ResolvedWsConfig, options: SendOptions): Promise<ExecResult>;
|
|
34
|
+
|
|
35
|
+
interface WsPlan {
|
|
36
|
+
config: ResolvedWsConfig;
|
|
37
|
+
/** Environment document mirroring the HTTP adapter's output shape. */
|
|
38
|
+
environment: Record<string, any>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* WebSocket adapter.
|
|
42
|
+
*
|
|
43
|
+
* An operation is claimed when it declares `x-protocol: websocket`,
|
|
44
|
+
* carries an `x-websocket` extension, or the caller passes `websocket.url`.
|
|
45
|
+
*/
|
|
46
|
+
declare class WebSocketAdapter implements ProtocolAdapter<WsPlan> {
|
|
47
|
+
readonly name = "websocket";
|
|
48
|
+
supports(ctx: AdapterContext): number;
|
|
49
|
+
plan(ctx: AdapterContext): WsPlan;
|
|
50
|
+
execute(plan: WsPlan, options: SendOptions): Promise<ExecResult>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { type ResolvedWsConfig, WebSocketAdapter, type WsPlan, resolveWsConfig, runWebSocket };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e){return e.replace(/\/+$/,"")||e}function t(e,t){const r=null==e?"":String(e);return-1===r.indexOf("{{")?r:r.replace(/\{\{\s*([\w.$-]+)\s*\}\}/g,(e,r)=>Object.prototype.hasOwnProperty.call(t,r)?t[r]:e)}function r(e){if(e)try{clearTimeout(e)}catch{}return null}var n=class e extends Error{code;details;constructor(t,r,n){super(t),this.name="ProtoKitError",this.code=r,this.details=n,Object.setPrototypeOf(this,e.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,e)}};function o(e){if(e instanceof n)return{message:e.message,code:e.code,name:e.name};if(e instanceof Error)return{message:e.message,code:e.code,name:e.name};if("string"==typeof e)return{message:e};try{return{message:JSON.stringify(e)}}catch{return{message:String(e)}}}function s(r,o,s){const i=s.websocket??{},c=r.operation?.["x-websocket"]??{},l={...s.variables??{}};let u;if(i.url)u=i.url;else if("string"==typeof c.url&&c.url)u=c.url;else{const t=function(e){return/^wss?:\/\//i.test(e)?e:/^https:\/\//i.test(e)?e.replace(/^https:/i,"wss:"):/^http:\/\//i.test(e)?e.replace(/^http:/i,"ws:"):`wss://${e.replace(/^\/+/,"")}`}(function(t,r){if(r.serverUrl)return e(r.serverUrl);const n=Array.isArray(t)&&t.length?t[0]:{url:"/"};let o="string"==typeof n?.url&&n.url?n.url:"/";const s=n?.variables&&"object"==typeof n.variables?n.variables:{};for(const[e,t]of Object.entries(s)){const n=r.serverVariables?.[e],s=t?.default??(Array.isArray(t?.enum)&&t.enum.length?t.enum[0]:""),a=void 0!==n?n:s;o=o.split(`{${e}}`).join(String(a??""))}return o=o.replace(/\{[^}]*\}/g,""),e(o)}(r.servers,s)),n=r.path.replace(/\{([^}]+)\}/g,(e,t)=>{const r=s.values?.path?.[t];return null==r?e:encodeURIComponent(String(r))});u=`${t.replace(/\/+$/,"")}/${n.replace(/^\//,"")}`}u=t(u,{baseUrl:"",...l});try{const e=new URL(u);for(const[t,r]of Object.entries(s.values?.query??{}))null!=r&&e.searchParams.set(t,String(r));"apikey"===s.auth?.type&&"query"===s.auth.in&&e.searchParams.set(s.auth.key??"api_key",s.auth.value??""),u=e.toString()}catch{throw new n(`Resolved WebSocket URL is invalid: ${u}`,"BAD_WS_URL",p)}var p;const d={};for(const[e,t]of Object.entries(s.values?.header??{}))null!=t&&(d[e]=String(t));for(const[e,r]of Object.entries(c.headers??{}))null!=r&&(d[e]=t(String(r),l));for(const[e,r]of Object.entries(i.headers??{}))null!=r&&(d[e]=t(String(r),l));const f=s.auth;if(f&&"none"!==f.type&&!Object.keys(d).some(e=>"authorization"===e.toLowerCase()))if("bearer"===f.type)d.Authorization=`Bearer ${f.token??""}`;else if("basic"===f.type){const e=`${f.username??""}:${f.password??""}`;d.Authorization=`Basic ${Buffer.from(e,"utf8").toString("base64")}`}else"apikey"===f.type&&"header"===(f.in??"header")&&(d[f.key??"X-API-Key"]=f.value??"");const y=i.send??c.send??[],h=(Array.isArray(y)?y:[y]).map(e=>function(e){if(null==e)return null;if("string"==typeof e)return e;if(e instanceof Uint8Array)return e;try{return JSON.stringify(e)}catch{return null}}("string"==typeof e?t(e,l):e)).filter(e=>null!==e),m=i.keepAlive??c.keepAlive;return{url:u,subprotocols:i.subprotocols??c.subprotocols??[],headers:d,send:h,sendDelayMs:a(i.sendDelayMs,0),maxMessages:a(i.maxMessages??s.maxEvents,100),maxSessionMs:a(i.maxSessionMs??s.maxStreamMs,3e4),idleTimeoutMs:a(i.idleTimeoutMs,0),keepAlive:m?{intervalMs:a(m.intervalMs,15e3),payload:String(m.payload??"ping")}:void 0,closeCode:i.closeCode??1e3,closeReason:i.closeReason??"Client finished sampling",rejectUnauthorized:!1!==i.rejectUnauthorized,maxPayloadBytes:a(i.maxPayloadBytes,262144),clientOptions:i.clientOptions??{}}}function a(e,t){const r=Number(e);return!Number.isFinite(r)||r<0?t:r}import i from"ws";var c=new Set([1e3,1001,1005]);function l(e,t){const n=function(){let e,t,r=!1;return{promise:new Promise((r,n)=>{e=r,t=n}),get settled(){return r},resolve(t){r||(r=!0,e(t))},reject(e){r||(r=!0,t(e))}}}(),s=Date.now();let a,l=0,p=0,d=0,f=!1,y=!1;const h=[],m={};let g,b,v=0,S=null,w=null,k=null;const x=[];let A;try{A=new i(e.url,e.subprotocols,{headers:e.headers,handshakeTimeout:Math.max(5e3,Math.min(e.maxSessionMs,3e4)),rejectUnauthorized:e.rejectUnauthorized,maxPayload:4*e.maxPayloadBytes,...e.clientOptions})}catch(e){return Promise.resolve(j(o(e)))}function j(t){const r=Date.now(),n=!t&&v>0&&v<400;return{protocol:"websocket",request:{method:"GET",url:e.url,headers:{...e.headers,Upgrade:"websocket",Connection:"Upgrade",...e.subprotocols.length?{"Sec-WebSocket-Protocol":e.subprotocols.join(", ")}:{}},body:e.send.length?e.send.map(e=>"string"==typeof e?e:`<binary ${e.byteLength} bytes>`):void 0},response:{status:v||(t?0:101),statusText:t?"WebSocket error":n?"Switching Protocols":"Connection closed",headers:m,contentType:"application/json",events:h,timings:{startedAt:s,endedAt:r,durationMs:r-s,firstByteMs:a?a-s:void 0},sizeBytes:d,...f?{truncated:!0}:{}},...g?{cookies:[]}:{},...t?{error:t}:{}}}const O=e=>{n.settled||((()=>{if(S=r(S),w=r(w),k){try{clearInterval(k)}catch{}k=null}for(const e of x.splice(0))r(e)})(),n.resolve(j(e??b)))},$=t=>{if(y)return;y=!0,f=!0;try{A.readyState===i.OPEN?A.close(e.closeCode,`${e.closeReason}: ${t}`.slice(0,120)):A.terminate()}catch{}const r=setTimeout(()=>{try{A.terminate()}catch{}O()},3e3);"object"==typeof r&&"function"==typeof r.unref&&r.unref(),x.push(r)},M=()=>{e.idleTimeoutMs&&(w=r(w),w=setTimeout(()=>$("idle timeout"),e.idleTimeoutMs),"object"==typeof w&&"function"==typeof w.unref&&w.unref())},P=e=>{h.push(e);try{t.onEvent?.(e)}catch{}};return A.on("upgrade",e=>{v=e?.statusCode??101;for(const[t,r]of Object.entries(e?.headers??{}))m[t]=Array.isArray(r)?r.join(", "):String(r)}),A.on("unexpected-response",(e,t)=>{v=t?.statusCode??0;for(const[e,r]of Object.entries(t?.headers??{}))m[e]=Array.isArray(r)?r.join(", "):String(r);b={message:`Handshake rejected with HTTP ${v}`,code:"WS_HANDSHAKE_FAILED"};try{t?.destroy?.()}catch{}O(b)}),A.on("open",()=>{a=Date.now(),g=A.protocol||void 0,v||(v=101);try{t.onOpen?.({url:e.url,protocol:g,headers:m})}catch{}e.send.forEach((t,r)=>{const n=()=>{A.readyState===i.OPEN&&A.send(t,e=>{e?b=b??o(e):(p+=1,P({id:String(p),event:"string"==typeof t?"text":"binary",data:"string"==typeof t?t:`<binary ${t.byteLength} bytes>`,parsed:"string"==typeof t?u(t):void 0,receivedAt:Date.now(),direction:"out"}))})},s=e.sendDelayMs*r;if(s<=0)n();else{const e=setTimeout(n,s);"object"==typeof e&&"function"==typeof e.unref&&e.unref(),x.push(e)}}),e.keepAlive&&(k=setInterval(()=>{if(A.readyState===i.OPEN)try{A.ping(e.keepAlive.payload)}catch{}},e.keepAlive.intervalMs),"object"==typeof k&&"function"==typeof k.unref&&k.unref()),M()}),A.on("message",(t,r)=>{if(y)return;const n=function(e){return Buffer.isBuffer(e)?e:Array.isArray(e)?Buffer.concat(e):Buffer.from(e)}(t);d+=n.length,p+=1,l+=1;const o=n.length>e.maxPayloadBytes,s=r?`<binary ${n.length} bytes>`:o?`${n.subarray(0,e.maxPayloadBytes).toString("utf8")}...`:n.toString("utf8");P({id:String(p),event:r?"binary":"text",data:s,parsed:r||o?void 0:u(s),receivedAt:Date.now(),direction:"in"}),M(),l>=e.maxMessages&&$("maxMessages reached")}),A.on("ping",e=>{p+=1,P({id:String(p),event:"ping",data:e?.length?e.toString("utf8"):"",receivedAt:Date.now(),direction:"in"}),M()}),A.on("error",e=>{b=b??o(e),A.readyState===i.CLOSED&&O(b)}),A.on("close",(e,t)=>{const r=t?.length?t.toString("utf8"):"";b||c.has(e)||y||(b={message:`Connection closed with code ${e}${r?`: ${r}`:""}`,code:String(e)}),O(b)}),S=setTimeout(()=>$("maxSessionMs reached"),e.maxSessionMs),"object"==typeof S&&"function"==typeof S.unref&&S.unref(),n.promise}function u(e){const t=e.trim();if(t&&/^[[{"\-\d]|^(true|false|null)$/.test(t))try{return JSON.parse(t)}catch{return}}var p=class{name="websocket";supports(e){const t=e.located.operation??{};return"websocket"===t["x-protocol"]||"ws"===t["x-protocol"]?20:t["x-websocket"]&&"object"==typeof t["x-websocket"]||e.options.websocket?.url?15:"websocket"===e.located.pathItem?.["x-protocol"]?12:0}plan(e){const t=s(e.located,e.spec,e.options);return{config:t,environment:{id:`protokit-ws-env-${Date.now().toString(36)}`,name:`${e.spec?.info?.title??"API"} WebSocket Environment`,values:[{key:"wsUrl",value:t.url,type:"default",enabled:!0},...Object.entries(e.options.variables??{}).map(([e,t])=>({key:e,value:String(t??""),type:/token|secret|password|apikey/i.test(e)?"secret":"default",enabled:!0}))],_postman_variable_scope:"environment"}}}execute(e,t){return l(e.config,t)}};export{p as WebSocketAdapter,s as resolveWsConfig,l as runWebSocket};
|
package/package.json
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@powerduck/request",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "OpenAPI 3.2 to Postman collection debugger with HTTP, SSE and WebSocket support, plus response write-back",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
},
|
|
15
|
+
"./http": {
|
|
16
|
+
"types": "./dist/protocols/http/index.d.ts",
|
|
17
|
+
"import": "./dist/protocols/http/index.js",
|
|
18
|
+
"require": "./dist/protocols/http/index.cjs"
|
|
19
|
+
},
|
|
20
|
+
"./ws": {
|
|
21
|
+
"types": "./dist/protocols/ws/index.d.ts",
|
|
22
|
+
"import": "./dist/protocols/ws/index.js",
|
|
23
|
+
"require": "./dist/protocols/ws/index.cjs"
|
|
24
|
+
},
|
|
25
|
+
"./openapi": {
|
|
26
|
+
"types": "./dist/openapi/index.d.ts",
|
|
27
|
+
"import": "./dist/openapi/index.js",
|
|
28
|
+
"require": "./dist/openapi/index.cjs"
|
|
29
|
+
},
|
|
30
|
+
"./package.json": "./package.json"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"README.md",
|
|
35
|
+
"LICENSE"
|
|
36
|
+
],
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=18.17.0"
|
|
39
|
+
},
|
|
40
|
+
"sideEffects": false,
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsup",
|
|
43
|
+
"dev": "tsup --watch",
|
|
44
|
+
"typecheck": "tsc --noEmit",
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"test:unit": "vitest run tests/unit",
|
|
47
|
+
"test:integration": "vitest run tests/integration",
|
|
48
|
+
"test:coverage": "vitest run --coverage",
|
|
49
|
+
"test:watch": "vitest",
|
|
50
|
+
"lint": "eslint src --ext .ts",
|
|
51
|
+
"prepublishOnly": "npm run typecheck && npm run test && npm run build"
|
|
52
|
+
},
|
|
53
|
+
"keywords": [
|
|
54
|
+
"openapi",
|
|
55
|
+
"openapi-3.2",
|
|
56
|
+
"postman",
|
|
57
|
+
"postman-runtime",
|
|
58
|
+
"sse",
|
|
59
|
+
"websocket",
|
|
60
|
+
"api-debugger"
|
|
61
|
+
],
|
|
62
|
+
"license": "MIT",
|
|
63
|
+
"dependencies": {
|
|
64
|
+
"postman-collection": "^5.3.1",
|
|
65
|
+
"postman-runtime": "^7.56.1",
|
|
66
|
+
"ws": "^8.21.3"
|
|
67
|
+
},
|
|
68
|
+
"devDependencies": {
|
|
69
|
+
"@types/node": "^22.10.0",
|
|
70
|
+
"@types/postman-collection": "^3.5.11",
|
|
71
|
+
"@types/ws": "^8.5.13",
|
|
72
|
+
"tsup": "^8.3.5",
|
|
73
|
+
"typecheck": "tsc --noEmit",
|
|
74
|
+
"typescript": "^5.7.2",
|
|
75
|
+
"terser": "^5.51.2",
|
|
76
|
+
"vitest": "^2.1.8"
|
|
77
|
+
},
|
|
78
|
+
"peerDependenciesMeta": {
|
|
79
|
+
"ws": {
|
|
80
|
+
"optional": true
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|