{"version":3,"file":"index.mjs","names":["descend"],"sources":["../src/helpers/value.ts","../src/parameter/filters/compiler.ts","../src/parameter/filters/binding.ts","../src/parameter/filters/module.ts","../src/parameter/fields/condition.ts","../src/parameter/fields/module.ts","../src/parameter/pagination/module.ts","../src/parameter/relations/module.ts","../src/parameter/sorts/module.ts","../src/query/module.ts","../src/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { isObject, isPropertySet, toDate } from '@rapiq/core';\nimport { isEqual } from 'smob';\n\n/**\n * SQL knows a single absent value; unify undefined and null to null\n * so every downstream test only reasons about null.\n */\nexport function normalizeValue(input: unknown) : unknown {\n    return input === undefined ? null : input;\n}\n\n/**\n * Read the operand of a date comparison as the instant it denotes.\n *\n * A `Date` never crosses the wire, so a record value that *is* a Date\n * meeting a *string* operand identifies that operand as a serialized\n * date and nothing else — which is the one thing this backend knows\n * that the serializing adapters have to ask their metadata for. Only\n * that asymmetric pair coerces: two strings stay strings (a varchar\n * column may well hold ISO text), and a number stays incomparable\n * against a date (unlike the adapters which are *told* the field is\n * temporal, this one only infers it from the value, so an epoch number\n * would be a guess). A string denoting no instant is left alone and\n * falls through to the usual incomparable/unequal verdict.\n */\nfunction alignDates(a: unknown, b: unknown) : [unknown, unknown] {\n    if (a instanceof Date) {\n        return typeof b === 'string' ? [a, toDate(b) ?? b] : [a, b];\n    }\n\n    if (b instanceof Date && typeof a === 'string') {\n        return [toDate(a) ?? a, b];\n    }\n\n    return [a, b];\n}\n\n/**\n * Deep value equality after null-unification. `smob`'s `isEqual`\n * covers primitives, `Date` (by time) and structural object/array\n * equality — so an object- or array-valued field is compared by\n * value rather than by reference.\n */\nexport function isValueEqual(a: unknown, b: unknown) : boolean {\n    const [left, right] = alignDates(normalizeValue(a), normalizeValue(b));\n\n    return isEqual(left, right);\n}\n\n/**\n * Compare two values of the same comparable type\n * (number, string, boolean, Date); undefined marks\n * the pair as incomparable.\n */\nexport function compareValues(a: unknown, b: unknown) : number | undefined {\n    const [first, second] = alignDates(a, b);\n\n    const bothDates = first instanceof Date && second instanceof Date;\n    const left = bothDates ? (first as Date).getTime() : first;\n    const right = bothDates ? (second as Date).getTime() : second;\n\n    if (typeof left === 'number' && typeof right === 'number') {\n        if (Number.isNaN(left) || Number.isNaN(right)) {\n            return undefined;\n        }\n\n        if (left === right) {\n            return 0;\n        }\n\n        return left < right ? -1 : 1;\n    }\n\n    if (\n        (typeof left === 'string' && typeof right === 'string') ||\n        (typeof left === 'boolean' && typeof right === 'boolean')\n    ) {\n        if (left === right) {\n            return 0;\n        }\n\n        return left < right ? -1 : 1;\n    }\n\n    return undefined;\n}\n\n/**\n * The textual form of a value for string matching\n * (contains/startsWith/endsWith/regex); undefined\n * marks the value as non-textual.\n */\nexport function toText(input: unknown) : string | undefined {\n    if (typeof input === 'string') {\n        return input;\n    }\n\n    if (typeof input === 'number' && Number.isFinite(input)) {\n        return `${input}`;\n    }\n\n    return undefined;\n}\n\n/**\n * Read an own property off a record-like parent; anything else\n * (null, scalars, arrays, inherited properties) resolves to the\n * absent value.\n */\nexport function resolveProperty(parent: unknown, name: string) : unknown {\n    if (!isObject(parent) || !isPropertySet(parent, name)) {\n        return null;\n    }\n\n    return normalizeValue(parent[name]);\n}\n\n/**\n * Resolve a dotted path by plain object traversal;\n * arrays on the path resolve to the absent value.\n */\nexport function resolvePath(input: unknown, path: string) : unknown {\n    if (!path.includes('.')) {\n        return resolveProperty(input, path);\n    }\n\n    const segments = path.split('.');\n\n    let current : unknown = input;\n    for (const segment of segments) {\n        current = resolveProperty(current, segment as string);\n    }\n\n    return current;\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type {\n    ComparePlan,\n    CompoundPlan,\n    ConstantPlan,\n    ElemMatchPlan,\n    IPlanInterpreter,\n    MatchPlan,\n    ModPlan,\n    NullCheckPlan,\n    OneOfPlan,\n    SizePlan,\n} from '@rapiq/core';\nimport {\n    AdapterError,\n    FILTER_OPERATOR_SEMANTICS,\n    ITSELF,\n    interpretPlan,\n} from '@rapiq/core';\nimport {\n    compareValues,\n    isValueEqual,\n    normalizeValue,\n    resolveProperty,\n    toText,\n} from '../../helpers';\nimport { BINDING_ELEMENT_FLAG, BINDING_SCOPE_SEPARATOR } from './constants';\nimport type { ConditionEval, ValueTest } from './types';\n\n/**\n * Positive leaf tests treat an array value by element\n * (membership semantics where SQL has no array columns).\n */\nfunction anyValue(test: ValueTest) : ValueTest {\n    return (value) => {\n        if (Array.isArray(value)) {\n            return value.some((element) => test(normalizeValue(element)));\n        }\n\n        return test(value);\n    };\n}\n\n/**\n * Compiles a condition plan into per-binding evaluation functions and\n * collects the relation paths the tree references. Operator semantics\n * (complement law, IN decomposition, case-fold policy, pattern\n * derivation, value validation) are decided by the core lowering —\n * this interpreter only compiles primitives into value tests. Field\n * prefixes compose through elemMatch exactly like the SQL adapter, so\n * conditions sharing a relation path bind to the same array element.\n */\nexport class FiltersCompiler implements IPlanInterpreter<ConditionEval> {\n    public readonly paths : Set<string>;\n\n    public readonly itself = true;\n\n    protected bindingPrefix : string;\n\n    protected scopeSequence : number;\n\n    constructor() {\n        this.paths = new Set();\n        this.bindingPrefix = '';\n        this.scopeSequence = 0;\n    }\n\n    // -----------------------------------------------------------\n\n    compound(plan: CompoundPlan) : ConditionEval {\n        const children = plan.children.map(\n            (child) => interpretPlan(child, this),\n        );\n\n        let combined : ConditionEval;\n        if (plan.operator === 'or') {\n            combined = (ctx, root) => children.some((child) => child(ctx, root));\n        } else {\n            combined = (ctx, root) => children.every((child) => child(ctx, root));\n        }\n\n        if (plan.negated) {\n            return (ctx, root) => !combined(ctx, root);\n        }\n\n        return combined;\n    }\n\n    constant(plan: ConstantPlan) : ConditionEval {\n        return () => plan.verdict;\n    }\n\n    nullCheck(plan: NullCheckPlan) : ConditionEval {\n        const base : ValueTest = (value) => normalizeValue(value) === null;\n        const test = plan.elementwise ? anyValue(base) : base;\n\n        return this.leaf(plan.field, this.negate(test, plan.negated));\n    }\n\n    compare(plan: ComparePlan) : ConditionEval {\n        if (plan.op === 'eq') {\n            const test = anyValue(this.buildValueEqualTest(plan.value, plan.caseFold));\n\n            return this.leaf(plan.field, this.negate(test, plan.negated));\n        }\n\n        const range = FILTER_OPERATOR_SEMANTICS[plan.op].compare;\n\n        return this.leaf(plan.field, this.buildCompareTest(plan.value, range.min, range.max));\n    }\n\n    oneOf(plan: OneOfPlan) : ConditionEval {\n        const tests = plan.values.map(\n            (value) => this.buildValueEqualTest(value, plan.caseFold),\n        );\n        if (plan.includesNull) {\n            tests.push((value) => isValueEqual(value, null));\n        }\n\n        const test = anyValue(\n            (value) => tests.some((item) => item(value)),\n        );\n\n        return this.leaf(plan.field, this.negate(test, plan.negated));\n    }\n\n    match(plan: MatchPlan) : ConditionEval {\n        let regex : RegExp;\n        if (plan.pattern.mode === 'regex') {\n            try {\n                regex = new RegExp(plan.pattern.source, plan.pattern.flags);\n            } catch {\n                throw AdapterError.featureUnsupported('filters:regex:value');\n            }\n        } else {\n            regex = new RegExp(plan.regexSource, plan.ignoreCase ? 'i' : '');\n        }\n\n        const test = anyValue((value) => {\n            const text = toText(value);\n            if (text === undefined) {\n                return false;\n            }\n\n            return regex.test(text);\n        });\n\n        return this.leaf(plan.field, this.negate(test, plan.negated));\n    }\n\n    mod(plan: ModPlan) : ConditionEval {\n        return this.leaf(plan.field, anyValue(\n            (value) => typeof value === 'number' &&\n                Number.isFinite(value) &&\n                value % plan.divisor === plan.remainder,\n        ));\n    }\n\n    size(plan: SizePlan) : ConditionEval {\n        if (plan.count === null) {\n            return this.leaf(plan.field, () => false);\n        }\n\n        const { count } = plan;\n\n        // the condition addresses the array itself, not its elements —\n        // missing or non-array values never match (mongo parity).\n        return this.leaf(plan.field, (value) => Array.isArray(value) &&\n            value.length === count);\n    }\n\n    elemMatch(plan: ElemMatchPlan) : ConditionEval {\n        const oldBindingPrefix = this.bindingPrefix;\n\n        // every elemMatch opens its own quantifier scope: the\n        // discriminated segment gives this interior an element binding\n        // of its own, so two elemMatches on one field quantify\n        // independently (e.g. one per $all value).\n        this.scopeSequence += 1;\n        this.bindingPrefix = `${oldBindingPrefix}${plan.field}${BINDING_SCOPE_SEPARATOR}${this.scopeSequence}.`;\n\n        try {\n            return interpretPlan(plan.condition, this);\n        } finally {\n            this.bindingPrefix = oldBindingPrefix;\n        }\n    }\n\n    // -----------------------------------------------------------\n\n    protected leaf(field: string, test: ValueTest) : ConditionEval {\n        if (field === ITSELF) {\n            // the marker addresses the element bound by the enclosing\n            // elemMatch scope; outside one it has no referent.\n            if (!this.bindingPrefix) {\n                throw AdapterError.featureUnsupported('filters:itself');\n            }\n\n            const path = this.bindingPrefix.slice(0, -1);\n            const flag = `${path}${BINDING_ELEMENT_FLAG}`;\n\n            this.registerPath(path);\n\n            return (ctx) => ctx.get(flag) === true &&\n                test(normalizeValue(ctx.get(path)));\n        }\n\n        const key = `${this.bindingPrefix}${field}`;\n        const separatorIndex = key.lastIndexOf('.');\n\n        if (separatorIndex === -1) {\n            return (_ctx, root) => test(resolveProperty(root, key));\n        }\n\n        const path = key.slice(0, separatorIndex);\n        const name = key.slice(separatorIndex + 1);\n\n        this.registerPath(path);\n\n        return (ctx) => test(resolveProperty(ctx.get(path), name));\n    }\n\n    protected registerPath(path: string) : void {\n        const segments = path.split('.');\n\n        for (let i = 0; i < segments.length; i++) {\n            this.paths.add(segments.slice(0, i + 1).join('.'));\n        }\n    }\n\n    // -----------------------------------------------------------\n\n    /**\n     * Complement law: the negation wraps OUTSIDE element\n     * quantification, so a negated leaf is the exact complement of\n     * its positive twin — null/missing values match.\n     */\n    protected negate(test: ValueTest, negated: boolean) : ValueTest {\n        if (negated) {\n            return (value) => !test(value);\n        }\n\n        return test;\n    }\n\n    /**\n     * Single-value equality: `caseFold` carries the settled policy\n     * verdict (string condition, field not opted out) — string\n     * comparisons then fold on both sides, mirroring the SQL\n     * adapter's lower()-wrapped rendering.\n     *\n     * Folding only ever governs a string *value*: anything else falls\n     * through to plain value equality, which is where a date value\n     * reads a string operand as the instant it denotes. The SQL side\n     * reaches the same place through `isCaseFoldable`, which exempts\n     * non-string columns from the fold.\n     */\n    protected buildValueEqualTest(input: unknown, caseFold: boolean) : ValueTest {\n        const condition = normalizeValue(input);\n\n        if (\n            caseFold &&\n            typeof condition === 'string'\n        ) {\n            const lowered = condition.toLowerCase();\n\n            return (value) => (\n                typeof value === 'string' ?\n                    value.toLowerCase() === lowered :\n                    isValueEqual(value, condition)\n            );\n        }\n\n        return (value) => isValueEqual(value, condition);\n    }\n\n    protected buildCompareTest(input: unknown, min: number, max: number) : ValueTest {\n        const condition = normalizeValue(input);\n\n        return anyValue((value) => {\n            const result = compareValues(value, condition);\n            if (result === undefined) {\n                return false;\n            }\n\n            return result >= min && result <= max;\n        });\n    }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { ITSELF } from '@rapiq/core';\nimport { resolveProperty } from '../../helpers';\nimport type { Predicate } from '../../types';\nimport { BINDING_ELEMENT_FLAG, BINDING_SCOPE_SEPARATOR } from './constants';\nimport type { BindingContext, ConditionEval } from './types';\n\nconst EMPTY_CONTEXT : BindingContext = new Map();\n\n/**\n * The source value a binding-path segment reads off its parent\n * binding. elemMatch segments carry a scope discriminator that is\n * stripped before property resolution; an ITSELF segment (an\n * elemMatch on the element itself) re-reads the parent binding.\n */\nfunction bindingSource(parent: unknown, segment: string) : unknown {\n    const separatorIndex = segment.indexOf(BINDING_SCOPE_SEPARATOR);\n    const name = separatorIndex === -1 ?\n        segment :\n        segment.slice(0, separatorIndex);\n\n    if (name === ITSELF) {\n        return parent;\n    }\n\n    return resolveProperty(parent, name);\n}\n\n/**\n * The join-row candidates a binding path contributes: every element\n * of an array, the object itself, or a single NULL row when the\n * value is absent or the array is empty.\n */\nfunction bindingCandidates(raw: unknown) : unknown[] {\n    if (Array.isArray(raw)) {\n        return raw.length > 0 ? raw : [null];\n    }\n\n    return [raw];\n}\n\n/**\n * Quantify a compiled condition tree over all assignments of\n * elements to binding paths (LEFT-join row semantics): the input\n * matches if some assignment satisfies the whole tree.\n */\nexport function createBoundPredicate(\n    evaluate: ConditionEval,\n    paths: Set<string>,\n) : Predicate {\n    if (paths.size === 0) {\n        return (input) => evaluate(EMPTY_CONTEXT, input);\n    }\n\n    // lexicographic order puts every path after its prefix,\n    // so parent bindings exist before child candidates are built.\n    const ordered = [...paths].sort();\n\n    return (input) => {\n        const ctx : BindingContext = new Map();\n\n        const enumerate = (index: number) : boolean => {\n            if (index === ordered.length) {\n                return evaluate(ctx, input);\n            }\n\n            const path = ordered[index] as string;\n            const separatorIndex = path.lastIndexOf('.');\n            const parent = separatorIndex === -1 ?\n                input :\n                ctx.get(path.slice(0, separatorIndex));\n            const segment = separatorIndex === -1 ?\n                path :\n                path.slice(separatorIndex + 1);\n\n            const raw = bindingSource(parent, segment);\n\n            // ITSELF leaves only match real array elements — never a\n            // to-one object, a scalar or the NULL row.\n            ctx.set(`${path}${BINDING_ELEMENT_FLAG}`, Array.isArray(raw) && raw.length > 0);\n\n            const candidates = bindingCandidates(raw);\n            for (const candidate of candidates) {\n                ctx.set(path, candidate);\n\n                if (enumerate(index + 1)) {\n                    return true;\n                }\n            }\n\n            ctx.delete(path);\n            ctx.delete(`${path}${BINDING_ELEMENT_FLAG}`);\n\n            return false;\n        };\n\n        return enumerate(0);\n    };\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type {\n    ICondition,\n    IFilter,\n    IFilterVisitor,\n    IFilters,\n    IFiltersVisitor,\n} from '@rapiq/core';\nimport {\n    interpretPlan,\n    planCondition,\n} from '@rapiq/core';\nimport type { Predicate } from '../../types';\nimport { createBoundPredicate } from './binding';\nimport { FiltersCompiler } from './compiler';\nimport type { FiltersVisitorOptions } from './types';\n\nexport class FiltersVisitor implements IFiltersVisitor<Predicate>, IFilterVisitor<Predicate> {\n    protected options : FiltersVisitorOptions;\n\n    constructor(options: FiltersVisitorOptions = {}) {\n        this.options = options;\n    }\n\n    visitFilters(expr: IFilters) : Predicate {\n        return this.compile(expr);\n    }\n\n    visitFilter(expr: IFilter) : Predicate {\n        return this.compile(expr);\n    }\n\n    // -----------------------------------------------------------\n\n    /**\n     * Compile a built-in leaf or group held through {@link ICondition} into a\n     * {@link Predicate}. Dispatch happens in `planCondition`, so callers holding\n     * built-in output abstractly need no cast. A custom condition needs a\n     * consumer that understands its semantics.\n     */\n    compile(expr: ICondition) : Predicate {\n        const plan = planCondition(expr, { caseSensitive: this.options.caseSensitive });\n        if (!plan) {\n            return () => true;\n        }\n\n        const compiler = this.createCompiler();\n        const evaluate = interpretPlan(plan, compiler);\n\n        return createBoundPredicate(evaluate, compiler.paths);\n    }\n\n    protected createCompiler() : FiltersCompiler {\n        return new FiltersCompiler();\n    }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { IField } from '@rapiq/core';\nimport { isObject, isPropertySet } from '@rapiq/core';\nimport type { Predicate, Projector } from '../../types';\nimport { FiltersVisitor } from '../filters';\nimport type { FiltersVisitorOptions } from '../filters';\n\n/**\n * The visibility gates of one relation level: a predicate per gated\n * property name, plus the deeper levels reached by a dotted field name.\n */\ntype GateNode = {\n    gates: Map<string, Predicate>,\n    children: Map<string, GateNode>\n};\n\nfunction createGateNode() : GateNode {\n    return {\n        gates: new Map(),\n        children: new Map(),\n    };\n}\n\nfunction descend(node: GateNode, segments: string[]) : GateNode {\n    let current = node;\n\n    for (const segment_ of segments) {\n        const segment = segment_ as string;\n\n        let child = current.children.get(segment);\n        if (!child) {\n            child = createGateNode();\n            current.children.set(segment, child);\n        }\n\n        current = child;\n    }\n\n    return current;\n}\n\n/**\n * Redact one level: a gated property is dropped from the output when\n * the record it is read from fails the gate condition. Copy-on-write:\n * a record with nothing to hide is passed through by reference.\n */\nfunction redact(node: GateNode, input: unknown) : unknown {\n    if (Array.isArray(input)) {\n        let changed = false;\n\n        const output = input.map((element) => {\n            const value = redact(node, element);\n            if (value !== element) {\n                changed = true;\n            }\n\n            return value;\n        });\n\n        return changed ? output : input;\n    }\n\n    if (!isObject(input)) {\n        return input;\n    }\n\n    let output : Record<string, any> = input;\n    const detach = () : Record<string, any> => {\n        if (output === input) {\n            // keep the prototype: on the sql/typeorm post-fetch path the\n            // inputs are entity class instances, and a redacted row must\n            // not silently degrade to a plain object while its untouched\n            // siblings stay instances.\n            output = Object.assign(\n                Object.create(Object.getPrototypeOf(input)),\n                input,\n            );\n        }\n\n        return output;\n    };\n\n    // the gates read from the untouched input, so a redacted\n    // sibling can never influence another gate's verdict.\n    node.gates.forEach((predicate, name) => {\n        if (isPropertySet(input, name) && !predicate(input)) {\n            delete detach()[name];\n        }\n    });\n\n    node.children.forEach((child, segment) => {\n        // presence is checked on OUTPUT: a property this level's own gate\n        // just deleted must stay deleted; descending via the input would\n        // resurrect it in child-redacted form.\n        if (!isPropertySet(output, segment)) {\n            return;\n        }\n\n        const value = redact(child, input[segment]);\n        if (value !== input[segment]) {\n            detach()[segment] = value;\n        }\n    });\n\n    return output;\n}\n\n/**\n * Compile the visibility gates carried by the given field nodes into a\n * single redactor, or `undefined` if no field is gated.\n *\n * A gate condition is evaluated against the record the gated property is\n * read from. For a dotted name (`client.secret`) that is the related\n * record, so the condition's own field names stay relative to it, matching\n * how the projector resolves the same path. Every element of a to-many\n * relation is gated on its own.\n */\nexport function createFieldConditionRedactor<T = Record<string, any>>(\n    fields: IField[],\n    options: FiltersVisitorOptions = {},\n) : Projector<T> | undefined {\n    const root = createGateNode();\n    let count = 0;\n\n    const visitor = new FiltersVisitor(options);\n\n    for (const field of fields) {\n        if (!field.condition) {\n            continue;\n        }\n\n        const segments = field.name.split('.');\n        const name = segments.pop() as string;\n\n        // compiled once, never per record.\n        descend(root, segments).gates.set(name, visitor.compile(field.condition));\n        count++;\n    }\n\n    if (count === 0) {\n        return undefined;\n    }\n\n    return (input) => redact(root, input) as T;\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { IField, IFields, IFieldsVisitor } from '@rapiq/core';\nimport { FieldOperator, isObject, isPropertySet } from '@rapiq/core';\nimport type { Projector } from '../../types';\nimport { createFieldConditionRedactor } from './condition';\nimport type { FieldsVisitorOptions } from './types';\n\ntype KeepNode = {\n    keepAll: boolean,\n    picks: Set<string>,\n    children: Map<string, KeepNode>\n};\n\nfunction createKeepNode() : KeepNode {\n    return {\n        keepAll: false,\n        picks: new Set(),\n        children: new Map(),\n    };\n}\n\nfunction descend(node: KeepNode, segments: string[]) : KeepNode {\n    let current = node;\n\n    for (const segment_ of segments) {\n        const segment = segment_ as string;\n\n        let child = current.children.get(segment);\n        if (!child) {\n            child = createKeepNode();\n            current.children.set(segment, child);\n        }\n\n        current = child;\n    }\n\n    return current;\n}\n\nfunction project(node: KeepNode, input: unknown) : unknown {\n    // a widened node without narrowed descendants passes the subtree\n    // through by reference.\n    if (node.keepAll && node.children.size === 0) {\n        return input;\n    }\n\n    if (Array.isArray(input)) {\n        return input\n            .map((element) => project(node, element))\n            .filter((element) => typeof element !== 'undefined');\n    }\n\n    if (!isObject(input)) {\n        if (node.keepAll) {\n            return input;\n        }\n\n        // a refined node only lets the absent value through —\n        // any other unpicked scalar would leak.\n        if (input === null || typeof input === 'undefined') {\n            return input;\n        }\n\n        return undefined;\n    }\n\n    if (node.keepAll) {\n        // a widened node keeps every member, but a descendant carrying its\n        // own picks still projects sparsely (#847): `include=role` +\n        // `fields[role.realm]=id` keeps the whole role except realm.\n        const output : Record<string, any> = { ...input };\n\n        node.children.forEach((child, segment) => {\n            if (!isPropertySet(input, segment)) {\n                return;\n            }\n\n            const value = project(child, input[segment]);\n            if (typeof value !== 'undefined') {\n                output[segment] = value;\n            } else {\n                delete output[segment];\n            }\n        });\n\n        return output;\n    }\n\n    const output : Record<string, any> = {};\n\n    node.children.forEach((child, segment) => {\n        if (!isPropertySet(input, segment)) {\n            return;\n        }\n\n        const value = project(child, input[segment]);\n        if (typeof value !== 'undefined') {\n            output[segment] = value;\n        }\n    });\n\n    // a pick of the property itself wins over a refinement of it.\n    node.picks.forEach((name) => {\n        if (isPropertySet(input, name)) {\n            output[name] = input[name];\n        }\n    });\n\n    return output;\n}\n\nexport class FieldsVisitor<T = Record<string, any>> implements IFieldsVisitor<Projector<T>> {\n    protected options : FieldsVisitorOptions;\n\n    constructor(options: FieldsVisitorOptions = {}) {\n        this.options = options;\n    }\n\n    visitFields(expr: IFields) : Projector<T> {\n        // the gates run BEFORE the projection: a gate condition may read\n        // a property the field selection does not keep.\n        const redactor = createFieldConditionRedactor<T>(\n            expr.value,\n            this.options.filters,\n        );\n\n        const picks = expr.value.filter(\n            (field) => field.operator !== FieldOperator.EXCLUDE,\n        );\n\n        if (picks.length === 0) {\n            return redactor || ((input) => input);\n        }\n\n        const root = createKeepNode();\n\n        for (const pick of picks) {\n            const segments = (pick as IField).name.split('.');\n            const name = segments.pop() as string;\n\n            descend(root, segments).picks.add(name);\n        }\n\n        // An included relation widens to its whole subtree UNLESS the\n        // selection carries direct picks for it — then the fieldset governs\n        // (#847). Every traversed prefix of an included path is itself\n        // included, so each prefix node widens under the same veto.\n        const relations = this.options.relations || [];\n        for (const relation of relations) {\n            const segments = (relation as string).split('.');\n\n            for (let i = 1; i <= segments.length; i++) {\n                const node = descend(root, segments.slice(0, i));\n                if (node.picks.size === 0) {\n                    node.keepAll = true;\n                }\n            }\n        }\n\n        if (redactor) {\n            return (input) => project(root, redactor(input)) as T;\n        }\n\n        return (input) => project(root, input) as T;\n    }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { IPagination, IPaginationVisitor } from '@rapiq/core';\nimport type { Slicer } from '../../types';\n\nexport class PaginationVisitor implements IPaginationVisitor<Slicer> {\n    visitPagination(expr: IPagination) : Slicer {\n        const { limit, offset } = expr;\n\n        return (data) => {\n            let output = data;\n\n            if (offset && offset > 0) {\n                output = output.slice(offset);\n            }\n\n            if (typeof limit === 'number' && limit >= 0) {\n                output = output.slice(0, limit);\n            }\n\n            return output;\n        };\n    }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type {\n    IRelation,\n    IRelationVisitor,\n    IRelations,\n    IRelationsVisitor,\n} from '@rapiq/core';\n\nexport class RelationsVisitor implements IRelationsVisitor<string[]>, IRelationVisitor<string> {\n    visitRelations(expr: IRelations) : string[] {\n        return expr.value.map((relation) => relation.accept<string>(this));\n    }\n\n    visitRelation(expr: IRelation) : string {\n        return expr.name;\n    }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { \n    ISort, \n    ISortVisitor, \n    ISorts, \n    ISortsVisitor, \n} from '@rapiq/core';\nimport { SortDirection } from '@rapiq/core';\nimport { compareValues, resolvePath } from '../../helpers';\nimport type { Comparator } from '../../types';\n\nexport class SortsVisitor<T = Record<string, any>> implements ISortsVisitor<Comparator<T>>,\n    ISortVisitor<Comparator<T>> {\n    visitSorts(expr: ISorts) : Comparator<T> {\n        const comparators = expr.value.map(\n            (sort) => sort.accept<Comparator<T>>(this),\n        );\n\n        return (a, b) => {\n            for (const comparator of comparators) {\n                const result = comparator(a, b);\n                if (result !== 0) {\n                    return result;\n                }\n            }\n\n            return 0;\n        };\n    }\n\n    visitSort(expr: ISort) : Comparator<T> {\n        const desc = expr.operator === SortDirection.DESC;\n\n        return (a, b) => {\n            const left = resolvePath(a, expr.name);\n            const right = resolvePath(b, expr.name);\n\n            // absent values sort as largest: last ascending,\n            // first descending (pg semantics).\n            if (left === null || right === null) {\n                if (left === right) {\n                    return 0;\n                }\n\n                if (left === null) {\n                    return desc ? -1 : 1;\n                }\n\n                return desc ? 1 : -1;\n            }\n\n            const result = compareValues(left, right);\n            if (result === undefined || result === 0) {\n                return 0;\n            }\n\n            return desc ? -result : result;\n        };\n    }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type {\n    ApplyOutput,\n    Comparator,\n    Predicate,\n    Projector,\n    Slicer,\n} from '../types';\nimport type { CompiledQueryContext } from './types';\n\nexport class CompiledQuery<T = Record<string, any>> {\n    public readonly predicate : Predicate;\n\n    public readonly comparator : Comparator<T> | undefined;\n\n    public readonly projector : Projector<T> | undefined;\n\n    public readonly pagination : { limit?: number, offset?: number };\n\n    protected slicer : Slicer;\n\n    constructor(ctx: CompiledQueryContext<T>) {\n        this.predicate = ctx.predicate;\n        this.comparator = ctx.comparator;\n        this.projector = ctx.projector;\n        this.slicer = ctx.slicer;\n        this.pagination = ctx.pagination;\n    }\n\n    /**\n     * Evaluate the filters parameter against a single input.\n     */\n    matches(input: unknown) : boolean {\n        return this.predicate(input);\n    }\n\n    /**\n     * Apply the whole query to a collection:\n     * filter, sort, paginate, project. The input array\n     * is never mutated.\n     */\n    apply(data: T[]) : ApplyOutput<T> {\n        let output = data.filter((item) => this.predicate(item));\n\n        const total = output.length;\n\n        if (this.comparator) {\n            output.sort(this.comparator);\n        }\n\n        output = this.slicer(output);\n\n        if (this.projector) {\n            output = output.map(this.projector);\n        }\n\n        return {\n            data: output,\n            total,\n            pagination: { ...this.pagination },\n        };\n    }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type {\n    ICondition,\n    IFields,\n    IPagination,\n    IQuery,\n    IQueryVisitor,\n    ISorts,\n} from '@rapiq/core';\nimport { FieldOperator } from '@rapiq/core';\nimport type { FieldsVisitorOptions, FiltersVisitorOptions } from './parameter';\nimport {\n    FieldsVisitor,\n    FiltersVisitor,\n    PaginationVisitor,\n    RelationsVisitor,\n    SortsVisitor,\n    createFieldConditionRedactor,\n} from './parameter';\nimport { CompiledQuery } from './query';\nimport type {\n    ApplyOutput,\n    Comparator,\n    Predicate,\n    Projector,\n    Slicer,\n} from './types';\n\nexport type QueryVisitorOptions = {\n    /**\n     * Field keys whose equality (eq/ne/in/nin) and anchored\n     * (startsWith/endsWith/contains) comparisons stay\n     * case-sensitive instead of the case-insensitive default;\n     * `true` opts every field out. Typically forwarded from a\n     * schema's `filters.caseSensitive` list.\n     */\n    caseSensitive?: string[] | boolean,\n};\n\nexport class QueryVisitor<T = Record<string, any>> implements IQueryVisitor<CompiledQuery<T>> {\n    protected options : QueryVisitorOptions;\n\n    constructor(options: QueryVisitorOptions = {}) {\n        this.options = options;\n    }\n\n    visitQuery(expr: IQuery) : CompiledQuery<T> {\n        const relations = expr.relations.accept(new RelationsVisitor());\n\n        let projector : Projector<T> | undefined;\n        const hasPicks = expr.fields.value.some(\n            (field) => field.operator !== FieldOperator.EXCLUDE,\n        );\n        // a gated field needs the projector even without a pick,\n        // to redact it out of the otherwise untouched record.\n        const hasConditions = expr.fields.value.some(\n            (field) => !!field.condition,\n        );\n        if (hasPicks || hasConditions) {\n            projector = expr.fields.accept(new FieldsVisitor<T>({\n                relations,\n                filters: { caseSensitive: this.options.caseSensitive },\n            }));\n        }\n\n        let comparator : Comparator<T> | undefined;\n        if (expr.sorts.value.length > 0) {\n            comparator = expr.sorts.accept(new SortsVisitor<T>());\n        }\n\n        return new CompiledQuery<T>({\n            predicate: expr.filters.accept(new FiltersVisitor({ caseSensitive: this.options.caseSensitive })),\n            comparator,\n            projector,\n            slicer: expr.pagination.accept(new PaginationVisitor()),\n            pagination: {\n                limit: expr.pagination.limit,\n                offset: expr.pagination.offset,\n            },\n        });\n    }\n}\n\n// -----------------------------------------------------------\n\nexport function compileQuery<T = Record<string, any>>(\n    query: IQuery,\n    options: QueryVisitorOptions = {},\n) : CompiledQuery<T> {\n    return query.accept(new QueryVisitor<T>(options));\n}\n\nexport function applyQuery<T = Record<string, any>>(\n    query: IQuery,\n    data: T[],\n    options: QueryVisitorOptions = {},\n) : ApplyOutput<T> {\n    return compileQuery<T>(query, options).apply(data);\n}\n\nexport function compileFilters(\n    input: ICondition,\n    options: FiltersVisitorOptions = {},\n) : Predicate {\n    return new FiltersVisitor(options).compile(input);\n}\n\nexport function compileSorts<T = Record<string, any>>(input: ISorts) : Comparator<T> {\n    return input.accept(new SortsVisitor<T>());\n}\n\nexport function compileFields<T = Record<string, any>>(\n    input: IFields,\n    options: FieldsVisitorOptions = {},\n) : Projector<T> {\n    return input.accept(new FieldsVisitor<T>(options));\n}\n\nexport function compilePagination(input: IPagination) : Slicer {\n    return input.accept(new PaginationVisitor());\n}\n\n/**\n * Compile the visibility gates carried by a fields parameter\n * (`Field.condition`) into a redactor for a single record.\n *\n * A gated field is only visible on records satisfying its condition; on a\n * record that fails it, the key is omitted from the output. The condition\n * never removes the record itself. Records with nothing to hide are\n * returned by reference; otherwise a shallow redacted copy is built along\n * the affected path. The input is never mutated.\n *\n * `@rapiq/adapter-memory`'s own projector applies this automatically. It is\n * exported for `@rapiq/adapter-sql` / `@rapiq/adapter-typeorm` consumers, which project\n * the column unconditionally (a selection must stay a bare column for\n * entity hydration) and therefore have to enforce the gates after the\n * fetch. See {@link applyFieldConditions} for the array form.\n */\nexport function compileFieldConditions<T = Record<string, any>>(\n    input: IFields,\n    options: FiltersVisitorOptions = {},\n) : Projector<T> {\n    const redactor = createFieldConditionRedactor<T>(input.value, options);\n\n    return redactor || ((record) => record);\n}\n\n/**\n * Apply the visibility gates carried by a fields parameter\n * (`Field.condition`) to already-fetched records.\n *\n * Returns a new array; each record is either passed through by reference\n * (nothing to hide) or replaced by a redacted copy with the failing keys\n * omitted. No record is ever removed and the input is never mutated.\n *\n * ```ts\n * const entities = await queryBuilder.getMany();\n * const output = applyFieldConditions(query.fields, entities);\n * ```\n */\nexport function applyFieldConditions<T = Record<string, any>>(\n    input: IFields,\n    data: T[],\n    options: FiltersVisitorOptions = {},\n) : T[] {\n    const redactor = createFieldConditionRedactor<T>(input.value, options);\n    if (!redactor) {\n        return [...data];\n    }\n\n    return data.map(redactor);\n}\n"],"mappings":"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"}