@adonis-agora/filter
Version:
Server-side query filtering/sorting/pagination for AdonisJS — Spatie-style input, a Lucid adapter, and field allow-listing. Part of the Agora ecosystem.
61 lines • 2.14 kB
JavaScript
const BLOCKED_KEYS = new Set(['__proto__', 'constructor', 'prototype', 'toString', 'valueOf']);
/**
* Normalize a decoded input object's top-level keys — case-transforming them via
* the chosen {@link InputNormalizer}, optionally stripping `Id` suffixes and
* empty values — into a null-prototype object.
*
* Prototype-pollution keys (`__proto__`, `constructor`, `prototype`, `toString`,
* `valueOf`) are dropped both before and after normalization, and the result has
* a null prototype, so a hostile key can never reach `Object.prototype`. Nested
* values are left untouched — only top-level keys are normalized.
*/
export function normalizeInput(input, options) {
if (input == null || typeof input !== 'object')
return {};
const norm = pickNormalizer(options.normalizer);
const drop = options.dropId === true;
const strip = options.stripEmpty !== false;
const out = Object.create(null);
for (const [rawKey, value] of Object.entries(input)) {
if (BLOCKED_KEYS.has(rawKey))
continue;
if (strip && (value === null || value === undefined || value === ''))
continue;
let key = norm(rawKey);
if (BLOCKED_KEYS.has(key))
continue;
if (drop)
key = stripId(key);
if (key.length === 0)
continue;
out[key] = value;
}
return out;
}
function pickNormalizer(spec) {
if (typeof spec === 'function')
return spec;
if (spec === 'camelCase')
return toCamelCase;
return toSnakeCase;
}
function toCamelCase(key) {
const result = key.replace(/[_-](\w)/g, (_, c) => c.toUpperCase());
return result.charAt(0).toLowerCase() + result.slice(1);
}
function toSnakeCase(key) {
return key
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
.replace(/([a-z0-9])([A-Z])/g, '$1_$2')
.toLowerCase();
}
function stripId(key) {
if (key.endsWith('Id'))
return key.slice(0, -2);
if (key.endsWith('_id'))
return key.slice(0, -3);
if (key === 'id')
return '';
return key;
}
//# sourceMappingURL=normalizer.js.map