fix: transform pattern regression

This commit is contained in:
Kamil Myśliwiec
2026-02-20 11:25:23 +01:00
parent cd7501b5c8
commit ca7d95a219
2 changed files with 25 additions and 18 deletions

View File

@@ -124,14 +124,14 @@ describe('transformPatternToRoute', () => {
describe('when gets value exceeding max depth or max keys', () => {
it('should return special string indicating the limit was reached', () => {
const deepNestedPattern = {
a: { b: { c: { d: { e: { f: 'too deep' } } } } },
a: { b: { c: { d: { e: { f: { g: 'too deep' } } } } } },
};
const tooManyKeysPattern = Object.fromEntries(
Array.from({ length: 25 }, (_, i) => [`key${i}`, `value${i}`]),
);
expect(transformPatternToRoute(deepNestedPattern)).to.be.equal(
'{"a":{"b":{"c":{"d":{"e":"[MAX_DEPTH_REACHED]"}}}}}',
'{"a":{"b":{"c":{"d":{"e":{"f":[MAX_DEPTH_REACHED]}}}}}}',
);
expect(transformPatternToRoute(tooManyKeysPattern)).to.be.equal(
'"[TOO_MANY_KEYS]"',

View File

@@ -23,38 +23,45 @@ export function transformPatternToRoute(
maxDepth = DEFAULT_MAX_DEPTH,
maxKeys = DEFAULT_MAX_KEYS,
): string {
// Prevent excessively deep recursion
if (depth > maxDepth) {
return '"[MAX_DEPTH_REACHED]"';
}
if (isString(pattern) || isNumber(pattern)) {
return `${pattern}`;
}
if (!isObject(pattern)) {
return `"${String(pattern)}"`;
// For non-string, non-number, non-object values
return pattern;
}
if (depth > maxDepth) {
return '[MAX_DEPTH_REACHED]';
}
const keys = Object.keys(pattern);
// Limit number of keys to prevent huge objects
if (keys.length > maxKeys) {
return '"[TOO_MANY_KEYS]"';
return '[TOO_MANY_KEYS]';
}
const sortedKeys = keys.sort((a, b) => ('' + a).localeCompare(b));
const sortedPatternParams = sortedKeys.map(key => {
const parts = sortedKeys.map(key => {
const value = pattern[key];
const partialRoute = `"${key}":${transformPatternToRoute(
value,
depth + 1,
maxDepth,
maxKeys,
)}`;
let partialRoute = `"${key}":`;
// Only quote strings, numbers and objects are handled recursively
if (isString(value)) {
partialRoute += `"${transformPatternToRoute(value, depth + 1, maxDepth, maxKeys)}"`;
} else {
partialRoute += transformPatternToRoute(
value,
depth + 1,
maxDepth,
maxKeys,
);
}
return partialRoute;
});
return `{${sortedPatternParams.join(',')}}`;
return `{${parts.join(',')}}`;
}