mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-28 15:14:06 +00:00
feat(common): add patternHasher utility for hashing and restoring string from special characters (#6032)
* feat: add patternHasher utility for variable hashing This utility function hashes input strings containing variables and allows for restoration of the original string. It includes support for custom matchers and handles cases where no variables are matched. * Update packages/bruno-common/src/utils/template-hasher.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Sid <siddharth@usebruno.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
1719cee440
commit
68b2625259
32
packages/bruno-common/src/utils/template-hasher.spec.ts
Normal file
32
packages/bruno-common/src/utils/template-hasher.spec.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { describe, it, expect } from '@jest/globals';
|
||||
import { patternHasher } from './template-hasher';
|
||||
|
||||
describe('patternHasher', () => {
|
||||
it('hashes and restore are mathematically reproducible', () => {
|
||||
const originalUrl = '{{host}}.example.com';
|
||||
const { hashed, restore } = patternHasher(originalUrl);
|
||||
expect(hashed).toMatchInlineSnapshot(`"bruno-var-hash--163450413.example.com"`);
|
||||
expect(restore(hashed)).toEqual(originalUrl);
|
||||
});
|
||||
|
||||
it('hashes more than once', () => {
|
||||
const originalUrl = '{{host}}.example.{{new}}';
|
||||
const { hashed, restore } = patternHasher(originalUrl);
|
||||
expect(hashed).toMatchInlineSnapshot(`"bruno-var-hash--163450413.example.bruno-var-hash-652560383"`);
|
||||
expect(restore(hashed)).toEqual(originalUrl);
|
||||
});
|
||||
|
||||
it('allows custom matchers', () => {
|
||||
const originalUrl = '$name.example.com';
|
||||
const { hashed, restore } = patternHasher(originalUrl, /\$(\w+)/);
|
||||
expect(hashed).toMatchInlineSnapshot(`"bruno-var-hash-180907786.example.com"`);
|
||||
expect(restore(hashed)).toEqual(originalUrl);
|
||||
});
|
||||
|
||||
it('ignore unless matched', () => {
|
||||
const originalUrl = '$name.example.com';
|
||||
const { hashed, restore } = patternHasher(originalUrl);
|
||||
expect(hashed).toMatchInlineSnapshot(`"$name.example.com"`);
|
||||
expect(restore(hashed)).toEqual(originalUrl);
|
||||
});
|
||||
});
|
||||
49
packages/bruno-common/src/utils/template-hasher.ts
Normal file
49
packages/bruno-common/src/utils/template-hasher.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
const VARIABLE_REGEX = /\{\{([^}]+)\}\}/g;
|
||||
|
||||
/**
|
||||
* Was implemented specifically for request.url where the url might have variables
|
||||
* that might need to be sanitised before being passed to a URL validator that doesn't
|
||||
* allow special characters that bruno uses as variables (`{{var_name}}`)
|
||||
*
|
||||
* The function replaces the input string with a unique hash that can be restored
|
||||
* later by the helper returned by this function
|
||||
*/
|
||||
export function patternHasher(input: string, pattern: string | RegExp = VARIABLE_REGEX) {
|
||||
const usableRegex = new RegExp(pattern, 'g');
|
||||
function hash(toHash: string) {
|
||||
let hash = 5381;
|
||||
let c;
|
||||
for (let i = 0; i < toHash.length; i++) {
|
||||
c = toHash.charCodeAt(i);
|
||||
hash = ((hash << 5) + hash + c) | 0;
|
||||
}
|
||||
return '' + hash;
|
||||
}
|
||||
|
||||
const prefix = `bruno-var-hash-`;
|
||||
const hashToOriginal: Record<string, string> = {};
|
||||
let result = input;
|
||||
let hashed = false;
|
||||
if (usableRegex.test(input)) {
|
||||
hashed = true;
|
||||
result = input.replace(usableRegex, function (matchedVar) {
|
||||
const hashedValue = `${prefix}${hash(matchedVar)}`;
|
||||
hashToOriginal[hashedValue] = matchedVar;
|
||||
return hashedValue;
|
||||
});
|
||||
}
|
||||
return {
|
||||
hashed: result,
|
||||
restore(current: string) {
|
||||
if (!hashed) {
|
||||
return current;
|
||||
}
|
||||
let clone = current;
|
||||
for (const hash in hashToOriginal) {
|
||||
const value = hashToOriginal[hash];
|
||||
clone = clone.replace(hash, value);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user