Skip to content

Commit

Permalink
Merge pull request #26 from jordanwalsh23/feat/cache-reset
Browse files Browse the repository at this point in the history
Feat/cache reset endpoint
  • Loading branch information
jordanwalsh23 authored Jul 19, 2024
2 parents ac5fa73 + ce26f65 commit b6da22e
Show file tree
Hide file tree
Showing 7 changed files with 357 additions and 424 deletions.
1 change: 0 additions & 1 deletion bin/postman-local-cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ async function main() {
serverOptions = {
cache: true,
cacheOptions: {
debug: true,
defaultDuration: cliOptions.cacheTTL
}
}
Expand Down
186 changes: 106 additions & 80 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class PostmanMockServer {
options = {};
}


//stop any running instances.
this.stop()

Expand All @@ -52,6 +53,17 @@ class PostmanMockServer {
app.use(express.json())

if (options.cache) {

if(!options.cacheOptions) {
options.cacheOptions = {};
}

if(!options.cacheOptions.debug) {
options.cacheOptions.debug = this.debug;
}

this.debug && console.log("Cache options:", options.cacheOptions);

//reinitialze the cache instance to stop sharing information
this.cache = initCache(options.cacheOptions);

Expand All @@ -76,111 +88,125 @@ class PostmanMockServer {

dynamicApiRouter.all("*", (req, res) => {

let bestMatchedResponse = getMatchedResponse(req, responses, this.debug)
if (options.cache && req.path && req.path.toLowerCase() == "/cache" && req.method && req.method.toLowerCase() == "delete") {
this.debug && console.log("resetting the cache")

if (bestMatchedResponse) {
//We've got a response!
//reinitialze the cache instance to stop sharing information
this.cache = initCache(options.cacheOptions);

//Create a copy before we start modifying for the response.
let responseToSend = _.cloneDeep(bestMatchedResponse)
//cache requests for 1 minute
app.use(this.cache());

if (this.debug) {
res.status(204).send();

responseToSend.headers.members.push({
key: 'x-mock-matched-score',
value: bestMatchedResponse['score'] || 0
});
} else {

responseToSend.headers.members.push({
key: 'x-mock-matched-response-name',
value: bestMatchedResponse['name'] || ''
})
}
let bestMatchedResponse = getMatchedResponse(req, responses, this.debug)

//204 has a null body
if (!responseToSend.body) {
responseToSend.body = ''
}
if (bestMatchedResponse) {
//We've got a response!

//Let's parse out any faker data.
let replacements = responseToSend.body.match(/{{\$.+}}/g) || []

this.debug &&
console.log('Variable replacements count:', replacements.length)

//Replace the faker data and the contextual response elements
replacements.forEach((replacement) => {
let replacementPath = replacement
.replace('{{', '')
.replace('}}', '')
let replacementValue = getReplacementValue(replacementPath, req)
this.debug && console.log(`${replacementPath}: ${replacementValue}`)
responseToSend.body = responseToSend.body.replace(
replacement,
replacementValue
)
})
//Create a copy before we start modifying for the response.
let responseToSend = _.cloneDeep(bestMatchedResponse)

if (this.debug) {

//Let's parse out any wildcard variables.
let wildcards = responseToSend.body.match(/{{.+}}/g) || []
responseToSend.headers.members.push({
key: 'x-mock-matched-score',
value: bestMatchedResponse['score'] || 0
});

this.debug &&
console.log('Wildcard replacements count:', wildcards.length)
responseToSend.headers.members.push({
key: 'x-mock-matched-response-name',
value: bestMatchedResponse['name'] || ''
})
}

//204 has a null body
if (!responseToSend.body) {
responseToSend.body = ''
}

wildcards.forEach((wildcard) => {
//Find the location in the URL of the wildcard.
let wildcardIndex = responseToSend.originalRequest.url.path.indexOf(wildcard);
//Let's parse out any faker data.
let replacements = responseToSend.body.match(/{{\$.+}}/g) || []

if (wildcardIndex > -1) {
//it's on the path
let wildcardValue = req.path.split("/");
this.debug &&
console.log('Variable replacements count:', replacements.length)

//Replace the faker data and the contextual response elements
replacements.forEach((replacement) => {
let replacementPath = replacement
.replace('{{', '')
.replace('}}', '')
let replacementValue = getReplacementValue(replacementPath, req)
this.debug && console.log(`${replacementPath}: ${replacementValue}`)
responseToSend.body = responseToSend.body.replace(
wildcard,
wildcardValue[wildcardIndex + 1]
replacement,
replacementValue
)
} else {
//Check they query parameters
let param = responseToSend.originalRequest.url.query.find(param => param.value == wildcard);
})

if (param) {
//Get the value from the current request
let wildcardValue = req.query[param.key] || "";
//Let's parse out any wildcard variables.
let wildcards = responseToSend.body.match(/{{.+}}/g) || []

this.debug &&
console.log('Wildcard replacements count:', wildcards.length)

wildcards.forEach((wildcard) => {
//Find the location in the URL of the wildcard.
let wildcardIndex = responseToSend.originalRequest.url.path.indexOf(wildcard);

if (wildcardIndex > -1) {
//it's on the path
let wildcardValue = req.path.split("/");

responseToSend.body = responseToSend.body.replace(
wildcard,
wildcardValue
wildcardValue[wildcardIndex + 1]
)
} else {
//Check they query parameters
let param = responseToSend.originalRequest.url.query.find(param => param.value == wildcard);

if (param) {
//Get the value from the current request
let wildcardValue = req.query[param.key] || "";

responseToSend.body = responseToSend.body.replace(
wildcard,
wildcardValue
)
}
}
})

if (responseToSend.code) {
this.debug && console.log('Returning status:', responseToSend.code)
res.status(responseToSend.code)
}
})

if (responseToSend.code) {
this.debug && console.log('Returning status:', responseToSend.code)
res.status(responseToSend.code)
}
responseToSend && responseToSend.headers
? responseToSend.headers.members.every(header => {
//Encoding is not supported so we just skip this header.
if (header.key.toLowerCase() == 'content-encoding') {
return true
}

responseToSend && responseToSend.headers
? responseToSend.headers.members.every(header => {
//Encoding is not supported so we just skip this header.
if (header.key.toLowerCase() == 'content-encoding') {
return true
}
this.debug && console.log(`Setting: `, header.key, header.value)

this.debug && console.log(`Setting: `, header.key, header.value)
res.set(header.key, header.value)
return true
})
: false

res.set(header.key, header.value)
return true
res.send(responseToSend.body)
} else {
res.status(404).json({
result: 'Error',
message:
'Could not find a matching response based on your request parameters.'
})
: false

res.send(responseToSend.body)
} else {
res.status(404).json({
result: 'Error',
message:
'Could not find a matching response based on your request parameters.'
})
}
}

});
Expand Down Expand Up @@ -243,7 +269,7 @@ function findResponses(items, responses) {

if (items && items.members && items.members.length > 0) {
for (let item of items.members) {

//Check if this is a folder. If so we need to use recursion.
if (item.items) {
findResponses(item.items, responses)
Expand Down
Loading

0 comments on commit b6da22e

Please sign in to comment.