UNPKG

@golemio/parkings

Version:
331 lines • 19.4 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.v2ParkingRouter = void 0; const ParamSanitizerHelper_1 = require("../../helpers/ParamSanitizerHelper"); const Di_1 = require("../../ioc/Di"); const ModuleContainerToken_1 = require("../../ioc/ModuleContainerToken"); const models_1 = require("../../models"); const constants_1 = require("../constants"); const ParkingsTransformationFabric_1 = require("../../transformations/ParkingsTransformationFabric"); const CoreToken_1 = require("@golemio/core/dist/helpers/ioc/CoreToken"); const AbstractRouter_1 = require("@golemio/core/dist/helpers/routing/AbstractRouter"); const output_gateway_1 = require("@golemio/core/dist/output-gateway"); const ioc_1 = require("@golemio/core/dist/output-gateway/ioc"); const express_validator_1 = require("@golemio/core/dist/shared/express-validator"); const golemio_errors_1 = require("@golemio/core/dist/shared/golemio-errors"); const PaginationHelper_1 = __importDefault(require("../../helpers/PaginationHelper")); class V2ParkingRouter extends AbstractRouter_1.AbstractRouter { constructor() { super(constants_1.RouteVersion.v2, "parking"); this.getLocations = async (req, res, next) => { try { const { latlng, range, limit, offset, source, sourceId, category, updatedSince, minutesBefore } = (0, express_validator_1.matchedData)(req); if (updatedSince && minutesBefore) { throw new golemio_errors_1.GeneralError("Query should not contain both updatedSince and minutesBefore", this.constructor.name, undefined, 400); } const paymentsConfig = await this.parkingSourcesRepository.getParkingPaymentsConfig({ isRestrictedToOpenData: false, }); const parkingsTransformationFabric = new ParkingsTransformationFabric_1.ParkingsTransformationFabric(paymentsConfig, this.logger); const coords = await (0, output_gateway_1.parseCoordinates)(latlng, range); const options = { ...coords, source, sourceId, category, limit: limit ? Number(limit) : undefined, offset: offset ? Number(offset) : 0, minutesBefore: minutesBefore ? Number(minutesBefore) : undefined, updatedSince: updatedSince ? new Date(updatedSince) : undefined, }; const data = await this.ParkingsModel.GetAll(options); const collection = parkingsTransformationFabric.buildFeatureCollection(data); res.status(200).send(collection); } catch (err) { next(err); } }; this.getLocationById = async (req, res, next) => { try { const paymentsConfig = await this.parkingSourcesRepository.getParkingPaymentsConfig({ isRestrictedToOpenData: false, }); const parkingsTransformationFabric = new ParkingsTransformationFabric_1.ParkingsTransformationFabric(paymentsConfig, this.logger); const data = await this.ParkingsModel.GetOne(req.params.id); if (!data) { throw new golemio_errors_1.GeneralError(`Id ${req.params.id} not found`, this.constructor.name, undefined, 404); } const { measurements, parking_payments, parking_tariffs_relation, ...rest } = data; const resultFeature = parkingsTransformationFabric.buildFeatureItem({ ...rest, ...measurements, ...parking_payments, ...parking_tariffs_relation, }); res.status(200).send(resultFeature); } catch (err) { next(err); } }; this.getDetailedLocations = async (req, res, next) => { const queryData = (0, express_validator_1.matchedData)(req); const { latlng, range, limit, offset, source, sourceId, category, updatedSince, minutesBefore } = queryData; if (updatedSince && minutesBefore) { throw new golemio_errors_1.GeneralError("Query should not contain both updatedSince and minutesBefore", this.constructor.name, undefined, 400); } try { const coords = await (0, output_gateway_1.parseCoordinates)(latlng, range); const paymentsConfig = await this.parkingSourcesRepository.getParkingPaymentsConfig({ isRestrictedToOpenData: false, }); const parkingsTransformationFabric = new ParkingsTransformationFabric_1.ParkingsTransformationFabric(paymentsConfig, this.logger); const options = { ...coords, source, sourceId, category, limit: limit ? Number(limit) : undefined, offset: offset ? Number(offset) : 0, minutesBefore: minutesBefore ? Number(minutesBefore) : undefined, updatedSince: updatedSince ? new Date(updatedSince) : undefined, zoneType: queryData.zoneType, parkingType: queryData.parkingType, }; const data = await this.ParkingsModel.GetAllDetail(options); const collection = parkingsTransformationFabric.buildFeatureCollection(data); res.status(200).send(collection); } catch (err) { next(err); } }; this.getDetailedLocationById = async (req, res, next) => { try { const paymentsConfig = await this.parkingSourcesRepository.getParkingPaymentsConfig({ isRestrictedToOpenData: false, }); const parkingsTransformationFabric = new ParkingsTransformationFabric_1.ParkingsTransformationFabric(paymentsConfig, this.logger); const data = await this.ParkingsModel.GetOneDetail(req.params.id); if (!data) { throw new golemio_errors_1.GeneralError(`Id ${req.params.id} not found`, this.constructor.name, undefined, 404); } const { measurements, parking_payments, parking_tariffs_relation, ...rest } = data; const resultFeature = parkingsTransformationFabric.buildFeatureItem({ ...rest, ...measurements, ...parking_payments, ...parking_tariffs_relation, }); res.status(200).send(resultFeature); } catch (err) { next(err); } }; this.getTariffs = async (req, res, next) => { const { source } = (0, express_validator_1.matchedData)(req); try { const options = { source }; const data = await this.ParkingsTariffsModel.GetAll(options); const dataNormalized = await this.normalizeTariffs(data); res.status(200).send(dataNormalized); } catch (err) { next(err); } }; this.normalizeTariff = async (data) => { const charges = []; const paymentsConfig = await this.parkingSourcesRepository.getParkingPaymentsConfig({ isRestrictedToOpenData: false, }); const parkingsTransformationFabric = new ParkingsTransformationFabric_1.ParkingsTransformationFabric(paymentsConfig, this.logger); for (const element of data) { charges.push(parkingsTransformationFabric.getChargeData(element)); } const paymentMethods = []; if (data[0].accepts_payment_card) paymentMethods.push("card_offline"); if (data[0].accepts_cash) paymentMethods.push("cash"); if (data[0].accepts_mobile_payment) paymentMethods.push("mobile_app"); if (data[0].accepts_litacka) paymentMethods.push("litacka"); let tariffNormalized = { tariff_id: data[0].tariff_id, source: data[0].source, last_updated: data[0].last_updated, payment_mode: data[0].payment_mode, payment_additional_description: data[0].payment_additional_description, free_of_charge: data[0].free_of_charge, url_link_address: data[0].url_link_address, charge_band_name: data[0].charge_band_name, payment_methods: paymentMethods, charge_currency: data[0].charge_currency, allowed_vehicle_type: data[0].allowed_vehicle_type, allowed_fuel_type: data[0].allowed_fuel_type, charges, // For future integration MPLA: reservation_url: null, }; return tariffNormalized; }; this.normalizeTariffs = async (data) => { const tariffGroups = data.reduce((acc, item) => { acc[item.tariff_id] = acc[item.tariff_id] || []; acc[item.tariff_id].push(item); return acc; }, {}); const result = []; for (const groupKey in tariffGroups) { if (tariffGroups.hasOwnProperty(groupKey)) result.push(await this.normalizeTariff(tariffGroups[groupKey])); } return result; }; this.getTariffById = async (req, res, next) => { try { const data = await this.ParkingsTariffsModel.GetOne(req.params.tariffId); if (!data || !data.length) { throw new golemio_errors_1.GeneralError(`TariffId ${req.params.tariffId} not found`, this.constructor.name, undefined, 404); } res.status(200).send(await this.normalizeTariff(data)); } catch (err) { next(err); } }; this.getMeasurements = async (req, res, next) => { const filterParams = (0, express_validator_1.matchedData)(req); if (filterParams.updatedSince && filterParams.minutesBefore) { throw new golemio_errors_1.GeneralError("Query should not contain both updatedSince and minutesBefore", this.constructor.name, undefined, 400); } try { const latest = filterParams.latest === "true"; const measureFrom = filterParams.from ? new Date(filterParams.from).toISOString() : undefined; const measureTo = filterParams.to ? new Date(filterParams.to).toISOString() : undefined; let limit = filterParams.limit ? Number(filterParams.limit) : 10000; let offset = filterParams.offset ? Number(filterParams.offset) : 0; let minutesBefore = filterParams.minutesBefore ? Number(filterParams.minutesBefore) : undefined; let updatedSince = filterParams.updatedSince ? new Date(filterParams.updatedSince) : undefined; const source = filterParams.source ? [filterParams.source] : await this.parkingSourcesRepository.getLegacySources({ isRestrictedToOpenData: false }); // Get data from DB const options = { source, sourceId: filterParams.sourceId, measureFrom, measureTo, updatedSince, minutesBefore, limit, offset, }; const data = latest ? await this.ParkingsMeasurementsActualModel.GetAll(options) : await this.ParkingsMeasurementsModel.GetAll(options); // Prepare paging Links for header let pagingLinksDefinition = PaginationHelper_1.default.generatePagingUrl(filterParams, data.length, offset, limit); if (pagingLinksDefinition) { res.setHeader("Link", `${pagingLinksDefinition}`); } res.status(200).send(data); } catch (err) { next(err); } }; this.initRoutes = () => { this.router.get("/tariffs", [ (0, express_validator_1.query)("source") .optional() .customSanitizer(ParamSanitizerHelper_1.ParamSanitizerHelper.sourceSanitizer()) .custom(this.primarySourceValidator.validateLegacy) .not() .isArray(), ], output_gateway_1.checkErrors, this.cacheHeaderMiddleware.getMiddleware(12 * 60 * 60, 60), this.getTariffs); this.router.get("/tariffs/:tariffId", (0, express_validator_1.param)("tariffId").exists(), output_gateway_1.checkErrors, this.cacheHeaderMiddleware.getMiddleware(12 * 60 * 60, 60), this.getTariffById); this.router.get("/measurements", [ (0, express_validator_1.query)("source") .optional() .customSanitizer(ParamSanitizerHelper_1.ParamSanitizerHelper.sourceSanitizer()) .custom(this.primarySourceValidator.validateLegacy) .not() .isArray(), (0, express_validator_1.query)("sourceId").optional().not().isEmpty({ ignore_whitespace: true }).not().isArray(), (0, express_validator_1.query)("from").optional().isISO8601().not().isArray(), (0, express_validator_1.query)("to").optional().isISO8601().not().isArray(), (0, express_validator_1.query)("latest").optional().isBoolean().not().isArray(), (0, express_validator_1.query)("minutesBefore").optional().isNumeric().not().isArray(), (0, express_validator_1.query)("updatedSince").optional().isISO8601().not().isArray(), ], (0, output_gateway_1.paginationLimitMiddleware)(this.constructor.name), output_gateway_1.checkErrors, this.cacheHeaderMiddleware.getMiddleware(5 * 60, 5), this.getMeasurements); this.router.get("/detail/:id", [(0, express_validator_1.param)("id").optional().isString()], output_gateway_1.checkErrors, this.cacheHeaderMiddleware.getMiddleware(5 * 60, 5), this.getDetailedLocationById); this.router.get("/detail", [ (0, express_validator_1.query)("latlng").optional().isLatLong().not().isArray(), (0, express_validator_1.query)("range").optional().isNumeric().not().isArray(), (0, express_validator_1.query)("source") .optional() .customSanitizer(ParamSanitizerHelper_1.ParamSanitizerHelper.sourceSanitizer()) .custom(this.primarySourceValidator.validateLegacy) .not() .isArray(), (0, express_validator_1.query)("sourceId").optional().not().isEmpty({ ignore_whitespace: true }).not().isArray(), (0, express_validator_1.query)("category") .optional() .not() .isEmpty({ ignore_whitespace: true }) .customSanitizer(ParamSanitizerHelper_1.ParamSanitizerHelper.toArraySanitizer()), (0, express_validator_1.query)("minutesBefore").optional().isNumeric().not().isArray(), (0, express_validator_1.query)("updatedSince").optional().not().isEmpty({ ignore_whitespace: true }).isISO8601().not().isArray(), (0, express_validator_1.query)("parkingType") .optional() .not() .isEmpty({ ignore_whitespace: true }) .customSanitizer(ParamSanitizerHelper_1.ParamSanitizerHelper.toArraySanitizer()), (0, express_validator_1.query)("zoneType") .optional() .not() .isEmpty({ ignore_whitespace: true }) .customSanitizer(ParamSanitizerHelper_1.ParamSanitizerHelper.toArraySanitizer()), ], (0, output_gateway_1.paginationLimitMiddleware)(this.constructor.name), output_gateway_1.checkErrors, this.cacheHeaderMiddleware.getMiddleware(5 * 60, 5), this.getDetailedLocations); this.router.get("/:id", [(0, express_validator_1.param)("id").optional().isString()], output_gateway_1.checkErrors, this.cacheHeaderMiddleware.getMiddleware(5 * 60, 5), this.getLocationById); this.router.get("/", [ (0, express_validator_1.query)("latlng").optional().isLatLong().not().isArray(), (0, express_validator_1.query)("range").optional().isNumeric().not().isArray(), (0, express_validator_1.query)("source") .optional() .customSanitizer(ParamSanitizerHelper_1.ParamSanitizerHelper.sourceSanitizer()) .custom(this.primarySourceValidator.validateLegacy) .not() .isArray(), (0, express_validator_1.query)("sourceId").optional().not().isEmpty({ ignore_whitespace: true }).not().isArray(), (0, express_validator_1.query)("category") .optional() .not() .isEmpty({ ignore_whitespace: true }) .customSanitizer(ParamSanitizerHelper_1.ParamSanitizerHelper.toArraySanitizer()), (0, express_validator_1.query)("minutesBefore").optional().isNumeric().not().isArray(), (0, express_validator_1.query)("updatedSince").optional().isISO8601().not().isArray(), ], (0, output_gateway_1.paginationLimitMiddleware)(this.constructor.name), output_gateway_1.checkErrors, this.cacheHeaderMiddleware.getMiddleware(5 * 60, 5), this.getLocations); }; this.ParkingsModel = models_1.models.ParkingsModel; this.ParkingsMeasurementsModel = models_1.models.ParkingsMeasurementsModel; this.ParkingsMeasurementsActualModel = models_1.models.ParkingsMeasurementsActualModel; this.ParkingsTariffsModel = models_1.models.ParkingsTariffsModel; this.logger = Di_1.ParkingsContainer.resolve(CoreToken_1.CoreToken.Logger); this.primarySourceValidator = Di_1.ParkingsContainer.resolve(ModuleContainerToken_1.ModuleContainerToken.PrimarySourceValidator); this.parkingSourcesRepository = Di_1.ParkingsContainer.resolve(ModuleContainerToken_1.ModuleContainerToken.CachedParkingSourcesRepository); this.cacheHeaderMiddleware = Di_1.ParkingsContainer.resolve(ioc_1.ContainerToken.CacheHeaderMiddleware); this.initRoutes(); } } const v2ParkingRouter = new V2ParkingRouter(); exports.v2ParkingRouter = v2ParkingRouter; //# sourceMappingURL=V2ParkingRouter.js.map