(
query: { orderBy?: OrderBy; limit?: number; offset?: number },
alias: string,
)
| 394 | * be scoped to the given alias (e.g. cross-collection refs or aggregates). |
| 395 | */ |
| 396 | export function computeSubscriptionOrderByHints( |
| 397 | query: { orderBy?: OrderBy; limit?: number; offset?: number }, |
| 398 | alias: string, |
| 399 | ): { orderBy: OrderBy | undefined; limit: number | undefined } { |
| 400 | const { orderBy, limit, offset } = query |
| 401 | const effectiveLimit = |
| 402 | limit !== undefined && offset !== undefined ? limit + offset : limit |
| 403 | |
| 404 | const normalizedOrderBy = orderBy |
| 405 | ? normalizeOrderByPaths(orderBy, alias) |
| 406 | : undefined |
| 407 | |
| 408 | // Only pass orderBy when it is scoped to this alias and uses simple refs, |
| 409 | // to avoid leaking cross-collection paths into backend-specific compilers. |
| 410 | const canPassOrderBy = |
| 411 | normalizedOrderBy?.every((clause) => { |
| 412 | const exp = clause.expression |
| 413 | if (exp.type !== `ref`) return false |
| 414 | const path = exp.path |
| 415 | return Array.isArray(path) && path.length === 1 |
| 416 | }) ?? false |
| 417 | |
| 418 | return { |
| 419 | orderBy: canPassOrderBy ? normalizedOrderBy : undefined, |
| 420 | limit: canPassOrderBy ? effectiveLimit : undefined, |
| 421 | } |
| 422 | } |
| 423 | |
| 424 | /** |
| 425 | * Compute the cursor for loading the next batch of ordered data. |
no test coverage detected