harproxyserver
Advanced tools
Comparing version 0.0.13 to 0.0.14
@@ -0,1 +1,2 @@ | ||
#!/usr/bin/env node | ||
'use strict'; | ||
@@ -645,3 +646,3 @@ | ||
var name = "harproxyserver"; | ||
var version = "0.0.12"; | ||
var version = "0.0.14"; | ||
var description = "A simple proxy server that records and plays back HTTP requests and responses in HAR format."; | ||
@@ -755,18 +756,33 @@ var author = "Yaacov Zamir <kobi.zamir@gmail.com>"; | ||
/** | ||
* Finds the HAR entry in the given log with the matching HTTP method, base URL, and query parameters. | ||
* Finds the HAR entry in the given log with the matching HTTP method and endpoint. | ||
* | ||
* @param {Log} harLog - The HAR log to search through. | ||
* @param {string} method - The HTTP method of the desired entry. | ||
* @param {string} baseUrl - The base URL of the desired entry. | ||
* @param {string} endpoint - The endpoint (pathname and search) of the desired entry, e.g., "/users?id=123". | ||
* @param {RegExp} [endpointRegex] - Optional regular expression to match the endpoint against. For example, to match endpoints that start with "/users" followed by a number, use `/^\/users\d+/`. | ||
* @param {boolean} [ignoreSearch=false] - Optional flag to ignore the search part of the URL when matching endpoints. | ||
* @param {string} [prefixToRemove] - Optional prefix to remove from the beginning of the `entry.request.path` property before matching the endpoint. | ||
* @returns {Entry | null} The matching HAR entry if found, or null if not found. | ||
*/ | ||
function findHarEntry(harLog, method, baseUrl) { | ||
for (const entry of harLog.entries) { | ||
const urlObject = new URL(entry.request.url); | ||
const pathname = baseUrl || '/'; | ||
if (entry.request.method === method && urlObject.pathname === pathname) { | ||
return entry; | ||
function findHarEntry(harLog, method, endpoint, endpointRegex, ignoreSearch = false, prefixToRemove) { | ||
if (!harLog) { | ||
return null; | ||
} | ||
const normalizedMethod = method.toUpperCase(); | ||
const normalizedEndpoint = endpoint || '/'; | ||
const matchingEntry = harLog.entries.find((entry) => { | ||
const urlObject = getValidUrl(entry); | ||
if (!urlObject) { | ||
return false; // skip this entry if URL is malformed | ||
} | ||
} | ||
return null; | ||
let entryEndpoint = ignoreSearch ? urlObject.pathname : `${urlObject.pathname}${urlObject.search}`; | ||
entryEndpoint = removePrefixIfNeeded(entryEndpoint, prefixToRemove); | ||
if (!entryEndpoint) { | ||
return false; // skip this entry if entryEndpoint is null (meaning it doesn't start with prefixToRemove) | ||
} | ||
const methodMatch = entry.request.method.toUpperCase() === normalizedMethod; | ||
const endpointMatch = endpointRegex ? entryEndpoint.match(endpointRegex) : entryEndpoint === normalizedEndpoint; | ||
return methodMatch && endpointMatch; | ||
}); | ||
return matchingEntry || null; | ||
} | ||
@@ -816,2 +832,31 @@ /** | ||
} | ||
/** | ||
* Returns a URL object if the given entry has a valid URL, otherwise returns null. | ||
* @param {Entry} entry - The HAR entry to check. | ||
* @returns {URL | null} - A URL object if the URL is valid, null otherwise. | ||
*/ | ||
function getValidUrl(entry) { | ||
try { | ||
const urlObject = new URL(entry.request.url); | ||
return urlObject; | ||
} | ||
catch (error) { | ||
return null; | ||
} | ||
} | ||
/** | ||
* Removes the prefix from the entry's endpoint if needed. | ||
* @param {string} entryEndpoint - The entry's endpoint. | ||
* @param {string} prefixToRemove - The prefix to remove from the endpoint. | ||
* @returns {string | null} - The modified endpoint or null if the entryEndpoint doesn't start with the prefix. | ||
*/ | ||
function removePrefixIfNeeded(entryEndpoint, prefixToRemove) { | ||
if (prefixToRemove) { | ||
if (entryEndpoint.startsWith(prefixToRemove)) { | ||
return entryEndpoint.slice(prefixToRemove.length); | ||
} | ||
return null; | ||
} | ||
return entryEndpoint; | ||
} | ||
@@ -818,0 +863,0 @@ /** |
@@ -1,2 +0,2 @@ | ||
import{StatusCodes as e}from"http-status-codes";function t(e,t,n){for(const o of e.entries){const e=new URL(o.request.url),r=n||"/";if(o.request.method===t&&e.pathname===r)return o}return null}function n(t){return{startedDateTime:(new Date).toISOString(),cache:{},request:{method:t.requestMethod||"GET",url:`${t.baseUrl}${t.endpoint}`,httpVersion:"HTTP/1.1",cookies:[],headers:[],queryString:[],headersSize:-1,bodySize:-1},response:{status:t.statusCode||e.OK,statusText:"",httpVersion:"HTTP/1.1",cookies:[],headers:t.headers||[],content:{size:t.text.length,text:t.text,mimeType:t.mimeType||"application/json"},redirectURL:"",headersSize:-1,bodySize:-1},time:0,timings:{send:0,wait:0,receive:0}}} | ||
import{StatusCodes as e}from"http-status-codes";function t(e,t,n,r,o=!1,s){if(!e)return null;const i=t.toUpperCase(),c=n||"/",a=e.entries.find((e=>{const t=function(e){try{return new URL(e.request.url)}catch(e){return null}}(e);if(!t)return!1;let n=o?t.pathname:`${t.pathname}${t.search}`;if(n=function(e,t){if(t)return e.startsWith(t)?e.slice(t.length):null;return e} | ||
/*! ***************************************************************************** | ||
@@ -15,3 +15,3 @@ Copyright (c) Microsoft Corporation. | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */function o(e,t,n,o){return new(n||(n=Promise))((function(r,s){function i(e){try{a(o.next(e))}catch(e){s(e)}}function c(e){try{a(o.throw(e))}catch(e){s(e)}}function a(e){var t;e.done?r(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,c)}a((o=o.apply(e,t||[])).next())}))}const r=(e,n,r)=>(s,i,c)=>o(void 0,void 0,void 0,(function*(){try{const o=yield n(e),a=s.baseUrl.slice(r.length),u=s.method,d=t(o.log,u,a);if(!d)return c();{const{status:e,content:t}=d.response;i.status(e).set("Content-Type",t.mimeType),i.send(t.text)}}catch(e){return console.error("Error:",e),c()}})),s=(t,r,s)=>(c,a,u)=>{const d=(new Date).getTime(),h=function(t,o,r){const s={baseUrl:t,endpoint:r.originalUrl,text:"",mimeType:o.headers["content-type"]||"text/plain",requestMethod:r.method,statusCode:o.statusCode||e.BAD_GATEWAY,headers:i(o.headers)};return n(s)}(s,c,a);c.on("data",(e=>{!function(e,t,n){var o,r;const s=(new Date).getTime();e.time=s-t,e.timings.receive=e.time,e.response.content.text=(null===(o=e.response.content.text)||void 0===o?void 0:o.concat(n))||"",e.response.content.size=(null===(r=e.response.content.text)||void 0===r?void 0:r.length)||0}(h,d,e)})),c.on("end",(()=>o(void 0,void 0,void 0,(function*(){var e;yield r(h,t);const n=(null===(e=h.response.content)||void 0===e?void 0:e.text)||"";u.setHeader("Content-Length",Buffer.byteLength(n)),u.end(n)}))))};function i(e){const t=[];return Object.entries(e).filter((([,e])=>"string"==typeof e||Array.isArray(e))).forEach((([e,n])=>{t.push(...function(e,t){return(Array.isArray(t)?t:[t]).map((t=>function(e,t){return{name:e,value:t}}(e,t)))}(e,n))})),t}export{n as createHarEntryFromText,t as findHarEntry,r as recordedHarMiddleware,s as recorderHarMiddleware}; | ||
***************************************************************************** */(n,s),!n)return!1;const a=e.request.method.toUpperCase()===i,u=r?n.match(r):n===c;return a&&u}));return a||null}function n(t){return{startedDateTime:(new Date).toISOString(),cache:{},request:{method:t.requestMethod||"GET",url:`${t.baseUrl}${t.endpoint}`,httpVersion:"HTTP/1.1",cookies:[],headers:[],queryString:[],headersSize:-1,bodySize:-1},response:{status:t.statusCode||e.OK,statusText:"",httpVersion:"HTTP/1.1",cookies:[],headers:t.headers||[],content:{size:t.text.length,text:t.text,mimeType:t.mimeType||"application/json"},redirectURL:"",headersSize:-1,bodySize:-1},time:0,timings:{send:0,wait:0,receive:0}}}function r(e,t,n,r){return new(n||(n=Promise))((function(o,s){function i(e){try{a(r.next(e))}catch(e){s(e)}}function c(e){try{a(r.throw(e))}catch(e){s(e)}}function a(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,c)}a((r=r.apply(e,t||[])).next())}))}const o=(e,n,o)=>(s,i,c)=>r(void 0,void 0,void 0,(function*(){try{const r=yield n(e),a=s.baseUrl.slice(o.length),u=s.method,d=t(r.log,u,a);if(!d)return c();{const{status:e,content:t}=d.response;i.status(e).set("Content-Type",t.mimeType),i.send(t.text)}}catch(e){return console.error("Error:",e),c()}})),s=(t,o,s)=>(c,a,u)=>{const d=(new Date).getTime(),l=function(t,r,o){const s={baseUrl:t,endpoint:o.originalUrl,text:"",mimeType:r.headers["content-type"]||"text/plain",requestMethod:o.method,statusCode:r.statusCode||e.BAD_GATEWAY,headers:i(r.headers)};return n(s)}(s,c,a);c.on("data",(e=>{!function(e,t,n){var r,o;const s=(new Date).getTime();e.time=s-t,e.timings.receive=e.time,e.response.content.text=(null===(r=e.response.content.text)||void 0===r?void 0:r.concat(n))||"",e.response.content.size=(null===(o=e.response.content.text)||void 0===o?void 0:o.length)||0}(l,d,e)})),c.on("end",(()=>r(void 0,void 0,void 0,(function*(){var e;yield o(l,t);const n=(null===(e=l.response.content)||void 0===e?void 0:e.text)||"";u.setHeader("Content-Length",Buffer.byteLength(n)),u.end(n)}))))};function i(e){const t=[];return Object.entries(e).filter((([,e])=>"string"==typeof e||Array.isArray(e))).forEach((([e,n])=>{t.push(...function(e,t){return(Array.isArray(t)?t:[t]).map((t=>function(e,t){return{name:e,value:t}}(e,t)))}(e,n))})),t}export{n as createHarEntryFromText,t as findHarEntry,o as recordedHarMiddleware,s as recorderHarMiddleware}; | ||
//# sourceMappingURL=index.min.js.map |
@@ -0,1 +1,2 @@ | ||
#!/usr/bin/env node | ||
export {}; |
@@ -22,10 +22,13 @@ import { Entry, Har, Header, Log } from 'har-format'; | ||
/** | ||
* Finds the HAR entry in the given log with the matching HTTP method, base URL, and query parameters. | ||
* Finds the HAR entry in the given log with the matching HTTP method and endpoint. | ||
* | ||
* @param {Log} harLog - The HAR log to search through. | ||
* @param {string} method - The HTTP method of the desired entry. | ||
* @param {string} baseUrl - The base URL of the desired entry. | ||
* @param {string} endpoint - The endpoint (pathname and search) of the desired entry, e.g., "/users?id=123". | ||
* @param {RegExp} [endpointRegex] - Optional regular expression to match the endpoint against. For example, to match endpoints that start with "/users" followed by a number, use `/^\/users\d+/`. | ||
* @param {boolean} [ignoreSearch=false] - Optional flag to ignore the search part of the URL when matching endpoints. | ||
* @param {string} [prefixToRemove] - Optional prefix to remove from the beginning of the `entry.request.path` property before matching the endpoint. | ||
* @returns {Entry | null} The matching HAR entry if found, or null if not found. | ||
*/ | ||
export declare function findHarEntry(harLog: Log, method: string, baseUrl: string): Entry | null; | ||
export declare function findHarEntry(harLog: Log | undefined | null, method: string, endpoint: string, endpointRegex?: RegExp, ignoreSearch?: boolean, prefixToRemove?: string): Entry | null; | ||
/** | ||
@@ -41,21 +44,9 @@ * Type for the parameter object of the createHarEntryFromText function. | ||
text: string; | ||
/** | ||
* The MIME type of the response body (default: 'application/json'). | ||
* Optional. | ||
*/ | ||
/** The MIME type of the response body (default: 'application/json'). Optional. */ | ||
mimeType?: string; | ||
/** | ||
* The HTTP method used for the request (default: 'GET'). | ||
* Optional. | ||
*/ | ||
/** The HTTP method used for the request (default: 'GET'). Optional. */ | ||
requestMethod?: string; | ||
/** | ||
* The HTTP status code of the response (default: StatusCodes.OK). | ||
* Optional. | ||
*/ | ||
/** The HTTP status code of the response (default: StatusCodes.OK). Optional. */ | ||
statusCode?: number; | ||
/** | ||
* The response headers (default: an empty array). | ||
* Optional. | ||
*/ | ||
/** The response headers (default: an empty array). Optional. */ | ||
headers?: Header[]; | ||
@@ -62,0 +53,0 @@ }; |
{ | ||
"name": "harproxyserver", | ||
"version": "0.0.13", | ||
"version": "0.0.14", | ||
"description": "A simple proxy server that records and plays back HTTP requests and responses in HAR format.", | ||
@@ -5,0 +5,0 @@ "author": "Yaacov Zamir <kobi.zamir@gmail.com>", |
Sorry, the diff of this file is not supported yet
91561
1246