UNPKG

@tmlmobilidade/interfaces

Version:

This package provides SDK-style connectors for interacting with databases (e.g., stops, plans, rides, alerts) and external providers (e.g., authentication, storage). It simplifies data access and integration across projects.

88 lines (87 loc) 3.4 kB
/* * */ import { parseSamsDeviceSearch, parseSamsVehicleSearch } from './regex-search.js'; import { PermissionCatalog } from '@tmlmobilidade/types'; /* * */ /** * Escapes a regex string. */ function escapeRegex(value) { return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } /** * Reserved query fields that are not used in the aggregation pipeline. */ const RESERVED_QUERY_FIELDS = new Set(['agency_ids', 'search']); const RANGE_QUERY_FIELDS = { seen_first_at: { field: 'seen_first_at', operator: '$gte' }, seen_last_at: { field: 'seen_last_at', operator: '$lte' }, }; /** * Builds `$match` AND clauses for SAM list / export from a parsed batch query (same semantics as the controller list). */ export function buildSamsMatch(parsedQuery, options = {}) { const { includeApexVersionFilter = true } = options; const matchAnd = []; const agencyIdsForMatch = parsedQuery.agency_ids.filter(id => id !== PermissionCatalog.ALLOW_ALL_FLAG); if (agencyIdsForMatch.length > 0) { matchAnd.push({ agency_id: { $in: agencyIdsForMatch } }); } const searchRaw = parsedQuery.search?.trim() ?? ''; if (searchRaw.length > 0) { const vehicleIds = parseSamsVehicleSearch(searchRaw); if (vehicleIds.length > 0) { matchAnd.push({ $or: [ { vehicle_id: { $in: vehicleIds } }, { 'analysis.vehicle_id': { $in: vehicleIds } }, ], }); } else { const deviceIds = parseSamsDeviceSearch(searchRaw); if (deviceIds.length > 0) { matchAnd.push({ $or: [ { device_id: { $in: deviceIds } }, { 'analysis.device_id': { $in: deviceIds } }, ], }); } else { const escaped = escapeRegex(searchRaw); matchAnd.push({ $or: [ { $expr: { $regexMatch: { input: { $toString: '$_id' }, options: 'i', regex: escaped } } }, { agency_id: { $options: 'i', $regex: escaped } }, { 'analysis.first_transaction_id': { $options: 'i', $regex: escaped } }, { 'analysis.last_transaction_id': { $options: 'i', $regex: escaped } }, ], }); } } } for (const [key, value] of Object.entries(parsedQuery)) { if (RESERVED_QUERY_FIELDS.has(key) || value === undefined || value === null || value === '') continue; if (!includeApexVersionFilter && key === 'latest_apex_version') continue; if (key in RANGE_QUERY_FIELDS) { const rangeKey = key; const rangeConfig = RANGE_QUERY_FIELDS[rangeKey]; matchAnd.push({ [rangeConfig.field]: { [rangeConfig.operator]: value } }); continue; } if (Array.isArray(value)) { if (value.length > 0) { if (key === 'latest_apex_version') { matchAnd.push({ latest_apex_version: { $in: value } }); continue; } matchAnd.push({ [key]: { $in: value } }); } continue; } matchAnd.push({ [key]: value }); } return matchAnd; }