@golemio/parkings
Version:
Golemio Parkings Module
331 lines • 19.4 kB
JavaScript
"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