mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-25 13:45:52 +00:00
Refactoring and fixes in _Mock Variables Interpolation_ feature
This commit is contained in:
18
package-lock.json
generated
18
package-lock.json
generated
@@ -26279,6 +26279,7 @@
|
||||
"version": "2.0.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/credential-providers": "3.750.0",
|
||||
"@faker-js/faker": "^9.5.1",
|
||||
"@usebruno/common": "0.1.0",
|
||||
"@usebruno/js": "0.12.0",
|
||||
"@usebruno/lang": "0.12.0",
|
||||
@@ -26786,6 +26787,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"packages/bruno-electron/node_modules/@faker-js/faker": {
|
||||
"version": "9.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-9.5.1.tgz",
|
||||
"integrity": "sha512-0fzMEDxkExR2cn731kpDaCCnBGBUOIXEi2S1N5l8Hltp6aPf4soTMJ+g4k8r2sI5oB+rpwIW8Uy/6jkwGpnWPg==",
|
||||
"deprecated": "Please update to a newer version",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fakerjs"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18.0.0",
|
||||
"npm": ">=9.0.0"
|
||||
}
|
||||
},
|
||||
"packages/bruno-electron/node_modules/@smithy/abort-controller": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.0.1.tgz",
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/credential-providers": "3.750.0",
|
||||
"@faker-js/faker": "^9.5.1",
|
||||
"@usebruno/common": "0.1.0",
|
||||
"@usebruno/js": "0.12.0",
|
||||
"@usebruno/lang": "0.12.0",
|
||||
@@ -60,7 +61,6 @@
|
||||
"socks-proxy-agent": "^8.0.2",
|
||||
"tough-cookie": "^4.1.3",
|
||||
"uuid": "^9.0.0",
|
||||
"@faker-js/faker": "^9.5.0",
|
||||
"yup": "^0.32.11"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
|
||||
127
packages/bruno-electron/src/ipc/network/faker-functions.js
Normal file
127
packages/bruno-electron/src/ipc/network/faker-functions.js
Normal file
@@ -0,0 +1,127 @@
|
||||
const { faker } = require('@faker-js/faker');
|
||||
|
||||
const mockDataFunctions = {
|
||||
guid: () => faker.string.uuid(),
|
||||
timestamp: () => faker.date.anytime().getTime().toString(),
|
||||
isoTimestamp: () => faker.date.anytime().toISOString(),
|
||||
randomUUID: () => faker.string.uuid(),
|
||||
randomAlphaNumeric: () => faker.string.alphanumeric(),
|
||||
randomBoolean: () => faker.datatype.boolean(),
|
||||
randomInt: () => faker.number.int(),
|
||||
randomColor: () => faker.color.human(),
|
||||
randomHexColor: () => faker.internet.color(),
|
||||
randomAbbreviation: () => faker.hacker.abbreviation(),
|
||||
randomIP: () => faker.internet.ip(),
|
||||
randomIPV4: () => faker.internet.ipv4(),
|
||||
randomIPV6: () => faker.internet.ipv6(),
|
||||
randomMACAddress: () => faker.internet.mac(),
|
||||
randomPassword: () => faker.internet.password(),
|
||||
randomLocale: () => faker.location.countryCode(),
|
||||
randomUserAgent: () => faker.internet.userAgent(),
|
||||
randomProtocol: () => faker.internet.protocol(),
|
||||
randomSemver: () => faker.system.semver(),
|
||||
randomFirstName: () => faker.person.firstName(),
|
||||
randomLastName: () => faker.person.lastName(),
|
||||
randomFullName: () => faker.person.fullName(),
|
||||
randomNamePrefix: () => faker.person.prefix(),
|
||||
randomNameSuffix: () => faker.person.suffix(),
|
||||
randomJobArea: () => faker.person.jobArea(),
|
||||
randomJobDescriptor: () => faker.person.jobDescriptor(),
|
||||
randomJobTitle: () => faker.person.jobTitle(),
|
||||
randomJobType: () => faker.person.jobType(),
|
||||
randomPhoneNumber: () => faker.phone.number(),
|
||||
randomPhoneNumberExt: () => faker.phone.number(),
|
||||
randomCity: () => faker.location.city(),
|
||||
randomStreetName: () => faker.location.street(),
|
||||
randomStreetAddress: () => faker.location.streetAddress(),
|
||||
randomCountry: () => faker.location.country(),
|
||||
randomCountryCode: () => faker.location.countryCode(),
|
||||
randomLatitude: () => faker.location.latitude(),
|
||||
randomLongitude: () => faker.location.longitude(),
|
||||
randomAvatarImage: () => faker.image.avatar(),
|
||||
randomImageUrl: () => faker.image.url(),
|
||||
randomAbstractImage: () => faker.image.urlLoremFlickr({ category: 'abstract' }),
|
||||
randomAnimalsImage: () => faker.image.urlLoremFlickr({ category: 'animals' }),
|
||||
randomBusinessImage: () => faker.image.urlLoremFlickr({ category: 'business' }),
|
||||
randomCatsImage: () => faker.image.urlLoremFlickr({ category: 'cats' }),
|
||||
randomCityImage: () => faker.image.urlLoremFlickr({ category: 'city' }),
|
||||
randomFoodImage: () => faker.image.urlLoremFlickr({ category: 'food' }),
|
||||
randomNightlifeImage: () => faker.image.urlLoremFlickr({ category: 'nightlife' }),
|
||||
randomFashionImage: () => faker.image.urlLoremFlickr({ category: 'fashion' }),
|
||||
randomPeopleImage: () => faker.image.urlLoremFlickr({ category: 'people' }),
|
||||
randomNatureImage: () => faker.image.urlLoremFlickr({ category: 'nature' }),
|
||||
randomSportsImage: () => faker.image.urlLoremFlickr({ category: 'sports' }),
|
||||
randomTransportImage: () => faker.image.urlLoremFlickr({ category: 'transport' }),
|
||||
randomImageDataUri: () => faker.image.dataUri(),
|
||||
randomBankAccount: () => faker.finance.accountNumber(),
|
||||
randomBankAccountName: () => faker.finance.accountName(),
|
||||
randomCreditCardMask: () => faker.finance.iban().replace(/(?<=.{4})\w(?=.{2})/g, '*'),
|
||||
randomBankAccountBic: () => faker.finance.bic(),
|
||||
randomBankAccountIban: () => faker.finance.iban(),
|
||||
randomTransactionType: () => faker.finance.transactionType(),
|
||||
randomCurrencyCode: () => faker.finance.currencyCode(),
|
||||
randomCurrencyName: () => faker.finance.currencyName(),
|
||||
randomCurrencySymbol: () => faker.finance.currencySymbol(),
|
||||
randomBitcoin: () => faker.finance.bitcoinAddress(),
|
||||
randomCompanyName: () => faker.company.name(),
|
||||
randomCompanySuffix: () => faker.company.name(),
|
||||
randomBs: () => faker.company.buzzPhrase(),
|
||||
randomBsAdjective: () => faker.company.buzzAdjective(),
|
||||
randomBsBuzz: () => faker.company.buzzVerb(),
|
||||
randomBsNoun: () => faker.company.buzzNoun(),
|
||||
randomCatchPhrase: () => faker.company.catchPhrase(),
|
||||
randomCatchPhraseAdjective: () => faker.company.catchPhraseAdjective(),
|
||||
randomCatchPhraseDescriptor: () => faker.company.catchPhraseDescriptor(),
|
||||
randomCatchPhraseNoun: () => faker.company.catchPhraseNoun(),
|
||||
randomDatabaseColumn: () => faker.database.column(),
|
||||
randomDatabaseType: () => faker.database.type(),
|
||||
randomDatabaseCollation: () => faker.database.collation(),
|
||||
randomDatabaseEngine: () => faker.database.engine(),
|
||||
randomDateFuture: () => faker.date.future().toISOString(),
|
||||
randomDatePast: () => faker.date.past().toISOString(),
|
||||
randomDateRecent: () => faker.date.recent().toISOString(),
|
||||
randomWeekday: () => faker.date.weekday(),
|
||||
randomMonth: () => faker.date.month(),
|
||||
randomDomainName: () => faker.internet.domainName(),
|
||||
randomDomainSuffix: () => faker.internet.domainSuffix(),
|
||||
randomDomainWord: () => faker.internet.domainWord(),
|
||||
randomEmail: () => faker.internet.email(),
|
||||
randomExampleEmail: () => faker.internet.exampleEmail(),
|
||||
randomUserName: () => faker.internet.username(),
|
||||
randomUrl: () => faker.internet.url(),
|
||||
randomFileName: () => faker.system.fileName(),
|
||||
randomFileType: () => faker.system.fileType(),
|
||||
randomFileExt: () => faker.system.fileExt(),
|
||||
randomCommonFileName: () => faker.system.commonFileName(),
|
||||
randomCommonFileType: () => faker.system.commonFileType(),
|
||||
randomCommonFileExt: () => faker.system.commonFileExt(),
|
||||
randomFilePath: () => faker.system.filePath(),
|
||||
randomDirectoryPath: () => faker.system.directoryPath(),
|
||||
randomMimeType: () => faker.system.mimeType(),
|
||||
randomPrice: () => faker.commerce.price(),
|
||||
randomProduct: () => faker.commerce.product(),
|
||||
randomProductAdjective: () => faker.commerce.productAdjective(),
|
||||
randomProductMaterial: () => faker.commerce.productMaterial(),
|
||||
randomProductName: () => faker.commerce.productName(),
|
||||
randomDepartment: () => faker.commerce.department(),
|
||||
randomNoun: () => faker.hacker.noun(),
|
||||
randomVerb: () => faker.hacker.verb(),
|
||||
randomIngverb: () => faker.hacker.ingverb(),
|
||||
randomAdjective: () => faker.hacker.adjective(),
|
||||
randomWord: () => faker.hacker.noun(),
|
||||
randomWords: () => faker.lorem.words(),
|
||||
randomPhrase: () => faker.hacker.phrase(),
|
||||
randomLoremWord: () => faker.lorem.word(),
|
||||
randomLoremWords: () => faker.lorem.words(),
|
||||
randomLoremSentence: () => faker.lorem.sentence(),
|
||||
randomLoremSentences: () => faker.lorem.sentences(),
|
||||
randomLoremParagraph: () => faker.lorem.paragraph(),
|
||||
randomLoremParagraphs: () => faker.lorem.paragraphs(),
|
||||
randomLoremText: () => faker.lorem.text(),
|
||||
randomLoremSlug: () => faker.lorem.slug(),
|
||||
randomLoremLines: () => faker.lorem.lines()
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
mockDataFunctions
|
||||
};
|
||||
@@ -12,7 +12,6 @@ const { ipcMain } = require('electron');
|
||||
const { each, get, extend, cloneDeep } = require('lodash');
|
||||
const { NtlmClient } = require('axios-ntlm');
|
||||
const { VarsRuntime, AssertRuntime, ScriptRuntime, TestRuntime } = require('@usebruno/js');
|
||||
const interpolateRandom = require('./interpolate-random');
|
||||
const { interpolateString } = require('./interpolate-string');
|
||||
const { resolveAwsV4Credentials, addAwsV4Interceptor } = require('./awsv4auth-helper');
|
||||
const { addDigestInterceptor } = require('./digestauth-helper');
|
||||
@@ -371,9 +370,6 @@ const registerNetworkIpc = (mainWindow) => {
|
||||
collection.globalEnvironmentVariables = scriptResult.globalEnvironmentVariables;
|
||||
}
|
||||
|
||||
// interpolate random/dynamic values inside request
|
||||
interpolateRandom(request);
|
||||
|
||||
// interpolate variables inside request
|
||||
interpolateVars(request, envVars, runtimeVariables, processEnvVars);
|
||||
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
// Import faker.js
|
||||
const { faker } = require('@faker-js/faker');
|
||||
const { each, forOwn } = require('lodash');
|
||||
const FormData = require('form-data');
|
||||
|
||||
const getContentType = (headers = {}) => {
|
||||
let contentType = '';
|
||||
forOwn(headers, (value, key) => {
|
||||
if (key && key.toLowerCase() === 'content-type') {
|
||||
contentType = value;
|
||||
}
|
||||
});
|
||||
|
||||
return contentType;
|
||||
};
|
||||
|
||||
const interpolateRandom = (request) => {
|
||||
|
||||
const _interpolate = (str) => {
|
||||
if (!str || !str.length || typeof str !== 'string') {
|
||||
return str;
|
||||
}
|
||||
|
||||
let resultStr = str;
|
||||
let matchFound = true;
|
||||
|
||||
while (matchFound) {
|
||||
const patternRegex = /\{\{\$([^}]+)\}\}/g;
|
||||
matchFound = false;
|
||||
resultStr = resultStr.replace(patternRegex, (_, placeholder) => {
|
||||
const replacement = getRandomValue(placeholder);
|
||||
matchFound = true;
|
||||
return replacement;
|
||||
});
|
||||
}
|
||||
|
||||
return resultStr;
|
||||
};
|
||||
|
||||
request.url = _interpolate(request.url);
|
||||
|
||||
const contentType = getContentType(request.headers);
|
||||
|
||||
if (contentType.includes('json')) {
|
||||
if (typeof request.data === 'string') {
|
||||
if (request.data.length) {
|
||||
request.data = _interpolate(request.data);
|
||||
}
|
||||
} else if (typeof request.data === 'object') {
|
||||
try {
|
||||
let parsed = JSON.stringify(request.data);
|
||||
parsed = _interpolate(parsed);
|
||||
request.data = JSON.parse(parsed);
|
||||
} catch (err) {}
|
||||
}
|
||||
} else if (contentType === 'application/x-www-form-urlencoded') {
|
||||
if (typeof request.data === 'object') {
|
||||
try {
|
||||
forOwn(request?.data, (value, key) => {
|
||||
request.data[key] = _interpolate(value);
|
||||
});
|
||||
} catch (err) {}
|
||||
}
|
||||
} else if (contentType === 'multipart/form-data') {
|
||||
if (typeof request.data === 'object' && !(request.data instanceof FormData)) {
|
||||
try {
|
||||
forOwn(request?.data, (value, key) => {
|
||||
request.data[key] = _interpolate(value);
|
||||
});
|
||||
} catch (err) {}
|
||||
}
|
||||
} else {
|
||||
request.data = _interpolate(request.data);
|
||||
}
|
||||
|
||||
each(request.pathParams, (param) => {
|
||||
param.value = _interpolate(param.value);
|
||||
});
|
||||
|
||||
if (request?.pathParams?.length) {
|
||||
let url = request.url;
|
||||
|
||||
if (!url.startsWith('http://') && !url.startsWith('https://')) {
|
||||
url = `http://${url}`;
|
||||
}
|
||||
|
||||
try {
|
||||
url = new URL(url);
|
||||
} catch (e) {
|
||||
throw { message: 'Invalid URL format', originalError: e.message };
|
||||
}
|
||||
|
||||
const urlPathnameInterpolatedWithPathParams = url.pathname
|
||||
.split('/')
|
||||
.filter((path) => path !== '')
|
||||
.map((path) => {
|
||||
if (path[0] !== ':') {
|
||||
return '/' + path;
|
||||
} else {
|
||||
const name = path.slice(1);
|
||||
const existingPathParam = request.pathParams.find((param) => param.type === 'path' && param.name === name);
|
||||
return existingPathParam ? '/' + existingPathParam.value : '';
|
||||
}
|
||||
})
|
||||
.join('');
|
||||
|
||||
const trailingSlash = url.pathname.endsWith('/') ? '/' : '';
|
||||
request.url = url.origin + urlPathnameInterpolatedWithPathParams + trailingSlash + url.search;
|
||||
}
|
||||
|
||||
return request;
|
||||
};
|
||||
|
||||
// Function to get random values based on the variable name
|
||||
function getRandomValue(variableName) {
|
||||
switch(variableName) {
|
||||
case "guid":
|
||||
return faker.datatype.uuid(); // Generates a UUID
|
||||
case "timestamp":
|
||||
return Math.floor(Date.now() / 1000); // Current UNIX timestamp
|
||||
case "isoTimestamp":
|
||||
return new Date().toISOString(); // Current ISO timestamp
|
||||
case "randomUUID":
|
||||
return faker.string.uuid(); // Random 36-character UUID
|
||||
case "randomAlphaNumeric":
|
||||
return faker.string.alphanumeric(1); // Random alphanumeric character
|
||||
case "randomBoolean":
|
||||
return faker.datatype.boolean(); // Random boolean
|
||||
case "randomInt":
|
||||
return faker.number.int({ min: 0, max: 1000 }); // Random integer between 0 and 1000
|
||||
case "randomColor":
|
||||
return faker.color.human(); // Random color name (human-readable)
|
||||
case "randomHexColor":
|
||||
return faker.color.rgb(); // Random hex color code
|
||||
case "randomAbbreviation":
|
||||
return faker.helpers.arrayElement(['SQL', 'PCI', 'JSON', 'HTTP', 'XML']); // Random abbreviation
|
||||
case "randomIP":
|
||||
return faker.network.ipv4(); // Random IPv4 address
|
||||
case "randomIPV6":
|
||||
return faker.network.ipv6(); // Random IPv6 address
|
||||
case "randomMACAddress":
|
||||
return faker.network.mac(); // Random MAC address
|
||||
case "randomPassword":
|
||||
return faker.internet.password(); // Random password (default 8 characters)
|
||||
case "randomLocale":
|
||||
return faker.locale; // Random two-letter language code (ISO 639-1)
|
||||
case "randomUserAgent":
|
||||
return faker.internet.userAgent(); // Random user agent string
|
||||
case "randomProtocol":
|
||||
return faker.internet.protocol(); // Random internet protocol (http, https)
|
||||
case "randomSemver":
|
||||
return faker.system.semver(); // Random semantic version
|
||||
case "randomFirstName":
|
||||
return faker.person.firstName(); // Random first name
|
||||
case "randomLastName":
|
||||
return faker.person.lastName(); // Random last name
|
||||
case "randomFullName":
|
||||
return faker.person.fullName(); // Random full name
|
||||
case "randomNamePrefix":
|
||||
return faker.person.prefix(); // Random name prefix (e.g., Mr., Ms.)
|
||||
case "randomNameSuffix":
|
||||
return faker.person.suffix(); // Random name suffix (e.g., MD, Jr.)
|
||||
case "randomPhoneNumber":
|
||||
return faker.phone.number(); // Random phone number
|
||||
case "randomCity":
|
||||
return faker.location.city(); // Random city name
|
||||
case "randomStreetName":
|
||||
return faker.location.streetName(); // Random street name
|
||||
case "randomStreetAddress":
|
||||
return faker.location.streetAddress(); // Random street address
|
||||
case "randomCountry":
|
||||
return faker.location.country(); // Random country name
|
||||
case "randomCountryCode":
|
||||
return faker.location.countryCode(); // Random two-letter country code
|
||||
case "randomLatitude":
|
||||
return faker.location.latitude(); // Random latitude coordinate
|
||||
case "randomLongitude":
|
||||
return faker.location.longitude(); // Random longitude coordinate
|
||||
case "randomAvatarImage":
|
||||
return faker.image.avatar(); // Random avatar image URL
|
||||
case "randomImageUrl":
|
||||
return faker.image.url(); // Random image URL
|
||||
case "randomPrice":
|
||||
return faker.commerce.price(); // Random price between 0.00 and 1000.00
|
||||
case "randomProduct":
|
||||
return faker.commerce.product(); // Random product name
|
||||
case "randomCompanyName":
|
||||
return faker.company.name(); // Random company name
|
||||
case "randomEmail":
|
||||
return faker.internet.email(); // Random email address
|
||||
default:
|
||||
return null; // If no match found, return null
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = interpolateRandom;
|
||||
@@ -1,6 +1,7 @@
|
||||
const { interpolate } = require('@usebruno/common');
|
||||
const { each, forOwn, cloneDeep, find } = require('lodash');
|
||||
const FormData = require('form-data');
|
||||
const { mockDataFunctions } = require('./faker-functions');
|
||||
|
||||
const getContentType = (headers = {}) => {
|
||||
let contentType = '';
|
||||
@@ -13,6 +14,14 @@ const getContentType = (headers = {}) => {
|
||||
return contentType;
|
||||
};
|
||||
|
||||
const interpolateMockVars = (str) => {
|
||||
const patternRegex = /\{\{\$(\w+)\}\}/g;
|
||||
return str.replace(patternRegex, (match, keyword) => {
|
||||
const replacement = mockDataFunctions[keyword]?.();
|
||||
return replacement || match;
|
||||
});
|
||||
};
|
||||
|
||||
const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, processEnvVars = {}) => {
|
||||
const globalEnvironmentVariables = request?.globalEnvironmentVariables || {};
|
||||
const oauth2CredentialVariables = request?.oauth2CredentialVariables || {};
|
||||
@@ -55,7 +64,7 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc
|
||||
}
|
||||
};
|
||||
|
||||
return interpolate(str, combinedVars);
|
||||
return interpolateMockVars(interpolate(str, combinedVars));
|
||||
};
|
||||
|
||||
request.url = _interpolate(request.url);
|
||||
@@ -239,7 +248,6 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc
|
||||
request.wsse.password = _interpolate(request.wsse.password) || '';
|
||||
}
|
||||
|
||||
|
||||
// interpolate vars for ntlmConfig auth
|
||||
if (request.ntlmConfig) {
|
||||
request.ntlmConfig.username = _interpolate(request.ntlmConfig.username) || '';
|
||||
|
||||
Reference in New Issue
Block a user