Refactor query handling in various routes to standardize sort property and order parameters
All checks were successful
farmcontrol/farmcontrol-api/pipeline/head This commit looks good

This commit updates multiple route handlers across the management and inventory modules to replace the `sort` and `order` parameters with `sortProperty` and `sortOrder`. This change enhances consistency in query handling and improves the clarity of the code. Additionally, the `getFilter` function is modified to accommodate these new parameters, ensuring that filtering logic remains intact. Corresponding tests have been updated to verify the correct functionality of the modified routes.
This commit is contained in:
Tom Butcher 2026-08-22 02:36:05 +01:00
parent 4ee5eb7d0a
commit 30d1469204
55 changed files with 703 additions and 253 deletions

View File

@ -2,6 +2,7 @@ import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions, hasPermission } from '../../database/permissions.js'; import { checkPermissions, hasPermission } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
import { invoiceModel } from '../../database/schemas/finance/invoice.schema.js';
const router = express.Router(); const router = express.Router();
@ -11,6 +12,10 @@ const listAllowedFilters = [
'state', 'state',
'vendor._id', 'vendor._id',
'client._id', 'client._id',
'from',
'from._id',
'to',
'to._id',
'order', 'order',
'order._id', 'order._id',
'orderType', 'orderType',
@ -22,8 +27,13 @@ const listAllowedSorters = ['createdAt', 'state', 'updatedAt', 'invoiceDate', 'd
const propertiesAllowedFilters = [ const propertiesAllowedFilters = [
'vendor', 'vendor',
'client', 'client',
'from',
'from._id',
'to',
'to._id',
'orderType', 'orderType',
'order', 'order',
'order._id',
'state.type', 'state.type',
'value', 'value',
'vendor._id', 'vendor._id',
@ -49,8 +59,8 @@ import {
// list of invoices // list of invoices
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters, true, invoiceModel);
listInvoicesRouteHandler( listInvoicesRouteHandler(
req, req,
res, res,
@ -59,8 +69,8 @@ router.get('/', isAuthenticated, async (req, res) => {
property, property,
filter, filter,
search, search,
getSort(sort, listAllowedSorters), getSort(sortProperty, listAllowedSorters),
order sortOrder
); );
}); });
@ -98,16 +108,16 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters, true, invoiceModel);
getInvoiceNeighborsRouteHandler( getInvoiceNeighborsRouteHandler(
req, req,
res, res,
property, property,
filter, filter,
search, search,
getSort(sort, listAllowedSorters), getSort(sortProperty, listAllowedSorters),
order, sortOrder,
id id
); );
}); });

View File

@ -50,9 +50,9 @@ import {
// list of payments // list of payments
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listPaymentsRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listPaymentsRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('payment', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('payment', 'list'), isAuthenticated, async (req, res) => {
@ -90,9 +90,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getPaymentNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getPaymentNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, checkPermissions('payment', 'info'), async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('payment', 'info'), async (req, res) => {

View File

@ -35,9 +35,9 @@ import {
// list of tax records // list of tax records
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listTaxRecordsRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listTaxRecordsRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('taxRecord', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('taxRecord', 'list'), isAuthenticated, async (req, res) => {
@ -75,9 +75,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getTaxRecordNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getTaxRecordNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, checkPermissions('taxRecord', 'info'), async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('taxRecord', 'info'), async (req, res) => {

View File

@ -45,9 +45,9 @@ import {
// list of filament stocks // list of filament stocks
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listFilamentStocksRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listFilamentStocksRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('filamentStock', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('filamentStock', 'list'), isAuthenticated, async (req, res) => {
@ -85,9 +85,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getFilamentStockNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getFilamentStockNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, checkPermissions('filamentStock', 'info'), async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('filamentStock', 'info'), async (req, res) => {

View File

@ -49,7 +49,7 @@ import {
// list of order items // list of order items
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listOrderItemsRouteHandler( listOrderItemsRouteHandler(
req, req,
@ -59,8 +59,8 @@ router.get('/', isAuthenticated, async (req, res) => {
property, property,
filter, filter,
search, search,
getSort(sort, listAllowedSorters), getSort(sortProperty, listAllowedSorters),
order sortOrder
); );
}); });
@ -98,7 +98,7 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getOrderItemNeighborsRouteHandler( getOrderItemNeighborsRouteHandler(
req, req,
@ -106,8 +106,8 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
property, property,
filter, filter,
search, search,
getSort(sort, listAllowedSorters), getSort(sortProperty, listAllowedSorters),
order, sortOrder,
id id
); );
}); });

View File

@ -37,9 +37,9 @@ import {
// list of part stocks // list of part stocks
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listPartStocksRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listPartStocksRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('partStock', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('partStock', 'list'), isAuthenticated, async (req, res) => {
@ -77,9 +77,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getPartStockNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getPartStockNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, checkPermissions('partStock', 'info'), async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('partStock', 'info'), async (req, res) => {

View File

@ -36,9 +36,9 @@ import {
} from '../../services/inventory/productstocks.js'; } from '../../services/inventory/productstocks.js';
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listProductStocksRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listProductStocksRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('productStock', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('productStock', 'list'), isAuthenticated, async (req, res) => {
@ -74,9 +74,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getProductStockNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getProductStockNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, checkPermissions('productStock', 'info'), async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('productStock', 'info'), async (req, res) => {

View File

@ -63,9 +63,9 @@ import {
// list of purchase orders // list of purchase orders
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listPurchaseOrdersRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listPurchaseOrdersRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('purchaseOrder', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('purchaseOrder', 'list'), isAuthenticated, async (req, res) => {
@ -102,9 +102,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getPurchaseOrderNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getPurchaseOrderNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, checkPermissions('purchaseOrder', 'info'), async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('purchaseOrder', 'info'), async (req, res) => {

View File

@ -54,7 +54,7 @@ import {
// list of shipments // list of shipments
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listShipmentsRouteHandler( listShipmentsRouteHandler(
req, req,
@ -64,8 +64,8 @@ router.get('/', isAuthenticated, async (req, res) => {
property, property,
filter, filter,
search, search,
getSort(sort, listAllowedSorters), getSort(sortProperty, listAllowedSorters),
order sortOrder
); );
}); });
@ -107,7 +107,7 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getShipmentNeighborsRouteHandler( getShipmentNeighborsRouteHandler(
req, req,
@ -115,8 +115,8 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
property, property,
filter, filter,
search, search,
getSort(sort, listAllowedSorters), getSort(sortProperty, listAllowedSorters),
order, sortOrder,
id id
); );
}); });

View File

@ -66,9 +66,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getStockAuditNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getStockAuditNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
// Get specific stock audit // Get specific stock audit

View File

@ -26,9 +26,9 @@ import {
// list of stock events // list of stock events
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, sort, order } = req.query; const { page, limit, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listStockEventsRouteHandler(req, res, page, limit, filter, getSort(sort, listAllowedSorters), order); listStockEventsRouteHandler(req, res, page, limit, filter, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('stockEvent', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('stockEvent', 'list'), isAuthenticated, async (req, res) => {
@ -66,9 +66,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getStockEventNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getStockEventNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, checkPermissions('stockEvent', 'info'), async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('stockEvent', 'info'), async (req, res) => {

View File

@ -25,9 +25,9 @@ import {
} from '../../services/inventory/stocklocations.js'; } from '../../services/inventory/stocklocations.js';
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listStockLocationsRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listStockLocationsRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('stockLocation', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('stockLocation', 'list'), isAuthenticated, async (req, res) => {
@ -63,9 +63,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getStockLocationNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getStockLocationNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, checkPermissions('stockLocation', 'info'), async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('stockLocation', 'info'), async (req, res) => {

View File

@ -34,9 +34,9 @@ import {
} from '../../services/inventory/stocktransfers.js'; } from '../../services/inventory/stocktransfers.js';
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listStockTransfersRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listStockTransfersRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('stockTransfer', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('stockTransfer', 'list'), isAuthenticated, async (req, res) => {
@ -72,9 +72,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getStockTransferNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getStockTransferNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, checkPermissions('stockTransfer', 'info'), async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('stockTransfer', 'info'), async (req, res) => {

View File

@ -34,9 +34,9 @@ import {
} from '../../services/management/apppasswords.js'; } from '../../services/management/apppasswords.js';
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listAppPasswordsRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listAppPasswordsRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('appPassword', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('appPassword', 'list'), isAuthenticated, async (req, res) => {
@ -73,9 +73,9 @@ router.post('/:id/regenerateSecret', isAuthenticated, checkPermissions('appPassw
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getAppPasswordNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getAppPasswordNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -23,7 +23,7 @@ const listAllowedFilters = [
const listAllowedSorters = ['createdAt', 'updatedAt']; const listAllowedSorters = ['createdAt', 'updatedAt'];
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, sort, order } = req.query; const { page, limit, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listAuditLogsRouteHandler( listAuditLogsRouteHandler(
req, req,
@ -31,8 +31,8 @@ router.get('/', isAuthenticated, async (req, res) => {
page, page,
limit, limit,
filter, filter,
getSort(sort, listAllowedSorters), getSort(sortProperty, listAllowedSorters),
order sortOrder
); );
}); });

View File

@ -35,9 +35,9 @@ import {
// list of couriers // list of couriers
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listCouriersRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listCouriersRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('courier', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('courier', 'list'), isAuthenticated, async (req, res) => {
@ -75,9 +75,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getCourierNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getCourierNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -59,9 +59,9 @@ import {
// list of courier services // list of courier services
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listCourierServicesRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listCourierServicesRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('courierService', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('courierService', 'list'), isAuthenticated, async (req, res) => {
@ -99,9 +99,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getCourierServiceNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getCourierServiceNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -33,9 +33,9 @@ import {
// list of document jobs // list of document jobs
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listDocumentJobsRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listDocumentJobsRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('documentJob', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('documentJob', 'list'), isAuthenticated, async (req, res) => {
@ -73,9 +73,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getDocumentJobNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getDocumentJobNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -34,9 +34,9 @@ import {
// list of document printers // list of document printers
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listDocumentPrintersRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listDocumentPrintersRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('documentPrinter', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('documentPrinter', 'list'), isAuthenticated, async (req, res) => {
@ -74,9 +74,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getDocumentPrinterNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getDocumentPrinterNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -49,9 +49,9 @@ import {
// list of document sizes // list of document sizes
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listDocumentSizesRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listDocumentSizesRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('documentSize', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('documentSize', 'list'), isAuthenticated, async (req, res) => {
@ -89,9 +89,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getDocumentSizeNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getDocumentSizeNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -49,9 +49,9 @@ import {
// list of document templates // list of document templates
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listDocumentTemplatesRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listDocumentTemplatesRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('documentTemplate', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('documentTemplate', 'list'), isAuthenticated, async (req, res) => {
@ -93,9 +93,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getDocumentTemplateNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getDocumentTemplateNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.post('/:id/preview', isAuthenticated, checkPermissions('documentTemplate', 'design'), async (req, res) => { router.post('/:id/preview', isAuthenticated, checkPermissions('documentTemplate', 'design'), async (req, res) => {

View File

@ -44,7 +44,7 @@ import {
// list of filaments // list of filaments
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
var filter = {}; var filter = {};
@ -57,7 +57,7 @@ router.get('/', isAuthenticated, async (req, res) => {
} }
} }
listFilamentsRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listFilamentsRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('filament', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('filament', 'list'), isAuthenticated, async (req, res) => {
@ -95,9 +95,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getFilamentNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getFilamentNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -44,9 +44,9 @@ import {
} from '../../services/management/filamentskus.js'; } from '../../services/management/filamentskus.js';
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listFilamentSkusRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listFilamentSkusRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('filamentSku', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('filamentSku', 'list'), isAuthenticated, async (req, res) => {
@ -81,9 +81,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getFilamentSkuNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getFilamentSkuNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -37,9 +37,9 @@ import {
// list of files // list of files
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listFilesRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listFilesRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('file', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('file', 'list'), isAuthenticated, async (req, res) => {
@ -81,9 +81,9 @@ router.delete('/:id/flush', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getFileNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getFileNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -33,9 +33,9 @@ import {
// list of hosts // list of hosts
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listHostsRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listHostsRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('host', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('host', 'list'), isAuthenticated, async (req, res) => {
@ -73,9 +73,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getHostNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getHostNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -24,7 +24,7 @@ import {
// list of materials // list of materials
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
var filter = {}; var filter = {};
@ -35,7 +35,7 @@ router.get('/', isAuthenticated, async (req, res) => {
} }
} }
listMaterialsRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listMaterialsRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('material', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('material', 'list'), isAuthenticated, async (req, res) => {
@ -73,9 +73,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getMaterialNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getMaterialNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -33,9 +33,9 @@ import {
// list of note types // list of note types
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listNoteTypesRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listNoteTypesRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('noteType', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('noteType', 'list'), isAuthenticated, async (req, res) => {
@ -73,9 +73,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getNoteTypeNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getNoteTypeNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -34,7 +34,7 @@ import {
// list of parts // list of parts
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listPartsRouteHandler( listPartsRouteHandler(
req, req,
@ -44,8 +44,8 @@ router.get('/', isAuthenticated, async (req, res) => {
property, property,
filter, filter,
search, search,
getSort(sort, listAllowedSorters), getSort(sortProperty, listAllowedSorters),
order sortOrder
); );
}); });
@ -84,7 +84,7 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getPartNeighborsRouteHandler( getPartNeighborsRouteHandler(
req, req,
@ -92,8 +92,8 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
property, property,
filter, filter,
search, search,
getSort(sort, listAllowedSorters), getSort(sortProperty, listAllowedSorters),
order, sortOrder,
id id
); );
}); });

View File

@ -45,9 +45,9 @@ import {
} from '../../services/management/partskus.js'; } from '../../services/management/partskus.js';
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listPartSkusRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listPartSkusRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('partSku', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('partSku', 'list'), isAuthenticated, async (req, res) => {
@ -83,9 +83,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getPartSkuNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getPartSkuNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -23,7 +23,7 @@ import {
} from '../../services/management/permissionsetting.js'; } from '../../services/management/permissionsetting.js';
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listPermissionSettingsRouteHandler( listPermissionSettingsRouteHandler(
req, req,
@ -33,8 +33,8 @@ router.get('/', isAuthenticated, async (req, res) => {
property, property,
filter, filter,
search, search,
getSort(sort, listAllowedSorters), getSort(sortProperty, listAllowedSorters),
order sortOrder
); );
}); });
@ -71,7 +71,7 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getPermissionSettingsNeighborsRouteHandler( getPermissionSettingsNeighborsRouteHandler(
req, req,
@ -79,8 +79,8 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
property, property,
filter, filter,
search, search,
getSort(sort, listAllowedSorters), getSort(sortProperty, listAllowedSorters),
order, sortOrder,
id id
); );
}); });

View File

@ -24,9 +24,9 @@ const listAllowedSorters = ['name', 'createdAt', 'updatedAt', '_id'];
const propertiesAllowedFilters = ['name']; const propertiesAllowedFilters = ['name'];
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listProductCategoriesRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listProductCategoriesRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('productCategory', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('productCategory', 'list'), isAuthenticated, async (req, res) => {
@ -62,9 +62,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getProductCategoryNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getProductCategoryNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -45,9 +45,9 @@ import {
// list of products // list of products
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listProductsRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listProductsRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('product', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('product', 'list'), isAuthenticated, async (req, res) => {
@ -85,9 +85,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getProductNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getProductNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -45,9 +45,9 @@ import {
} from '../../services/management/productskus.js'; } from '../../services/management/productskus.js';
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listProductSkusRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listProductSkusRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('productSku', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('productSku', 'list'), isAuthenticated, async (req, res) => {
@ -83,9 +83,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getProductSkuNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getProductSkuNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -43,9 +43,9 @@ import {
// list of tax rates // list of tax rates
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listTaxRatesRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listTaxRatesRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('taxRate', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('taxRate', 'list'), isAuthenticated, async (req, res) => {
@ -83,9 +83,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getTaxRateNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getTaxRateNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -23,7 +23,7 @@ import {
} from '../../services/management/usergroups.js'; } from '../../services/management/usergroups.js';
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listUserGroupsRouteHandler( listUserGroupsRouteHandler(
req, req,
@ -33,8 +33,8 @@ router.get('/', isAuthenticated, async (req, res) => {
property, property,
filter, filter,
search, search,
getSort(sort, listAllowedSorters), getSort(sortProperty, listAllowedSorters),
order sortOrder
); );
}); });
@ -71,7 +71,7 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getUserGroupNeighborsRouteHandler( getUserGroupNeighborsRouteHandler(
req, req,
@ -79,8 +79,8 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
property, property,
filter, filter,
search, search,
getSort(sort, listAllowedSorters), getSort(sortProperty, listAllowedSorters),
order, sortOrder,
id id
); );
}); });

View File

@ -35,9 +35,9 @@ import {
// list of document templates // list of document templates
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listUsersRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listUsersRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('user', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('user', 'list'), isAuthenticated, async (req, res) => {
@ -71,9 +71,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getUserNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getUserNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -33,9 +33,9 @@ import {
// list of vendors // list of vendors
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listVendorsRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listVendorsRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('vendor', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('vendor', 'list'), isAuthenticated, async (req, res) => {
@ -73,9 +73,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getVendorNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getVendorNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -35,9 +35,9 @@ const propertiesAllowedFilters = ['parent'];
// list of notes // list of notes
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listNotesRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listNotesRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', isAuthenticated, async (req, res) => { router.get('/properties', isAuthenticated, async (req, res) => {
@ -71,9 +71,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getNoteNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getNoteNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {

View File

@ -12,10 +12,10 @@ import { getFilter } from '../../utils.js';
const router = express.Router(); const router = express.Router();
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page = 1, limit = 50, sort = 'createdAt', order = 'descend' } = req.query; const { page = 1, limit = 50, sortProperty = 'createdAt', sortOrder = 'descend' } = req.query;
const allowedFilters = ['user']; const allowedFilters = ['user'];
const filter = await getFilter(req.query, allowedFilters); const filter = await getFilter(req.query, allowedFilters);
listNotificationsRouteHandler(req, res, page, limit, filter, sort, order); listNotificationsRouteHandler(req, res, page, limit, filter, sortProperty, sortOrder);
}); });
router.put('/read-all', isAuthenticated, async (req, res) => { router.put('/read-all', isAuthenticated, async (req, res) => {

View File

@ -12,10 +12,10 @@ import { getFilter } from '../../utils.js';
const router = express.Router(); const router = express.Router();
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const allowedFilters = ['user', 'object', 'objectType']; const allowedFilters = ['user', 'object', 'objectType'];
const filter = await getFilter(req.query, allowedFilters); const filter = await getFilter(req.query, allowedFilters);
listUserNotifiersRouteHandler(req, res, page, limit, property, filter, search, sort, order); listUserNotifiersRouteHandler(req, res, page, limit, property, filter, search, sortProperty, sortOrder);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, async (req, res) => {

View File

@ -21,7 +21,7 @@ const listAllowedSorters = ['name', 'createdAt', 'updatedAt'];
const propertiesAllowedFilters = ['name']; const propertiesAllowedFilters = ['name'];
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listFilamentProfilesRouteHandler( listFilamentProfilesRouteHandler(
req, req,
@ -31,8 +31,8 @@ router.get('/', isAuthenticated, async (req, res) => {
property, property,
filter, filter,
search, search,
getSort(sort, listAllowedSorters), getSort(sortProperty, listAllowedSorters),
order sortOrder
); );
}); });
@ -60,7 +60,7 @@ router.post('/', isAuthenticated, checkPermissions('filamentProfile', 'new'), as
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getFilamentProfileNeighborsRouteHandler( getFilamentProfileNeighborsRouteHandler(
req, req,
@ -68,8 +68,8 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
property, property,
filter, filter,
search, search,
getSort(sort, listAllowedSorters), getSort(sortProperty, listAllowedSorters),
order, sortOrder,
id id
); );
}); });

View File

@ -34,9 +34,9 @@ import { convertPropertiesString, getFilter, getSort } from '../../utils.js';
// list of gcodeFiles // list of gcodeFiles
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listGCodeFilesRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listGCodeFilesRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('gcodeFile', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('gcodeFile', 'list'), isAuthenticated, async (req, res) => {
@ -70,9 +70,9 @@ router.get('/stats', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getGCodeFileNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getGCodeFileNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, checkPermissions('gcodeFile', 'info'), async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('gcodeFile', 'info'), async (req, res) => {

View File

@ -43,9 +43,9 @@ import { convertPropertiesString, getFilter, getSort } from '../../utils.js';
// list of jobs // list of jobs
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listJobsRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listJobsRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('job', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('job', 'list'), isAuthenticated, async (req, res) => {
@ -82,9 +82,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getJobNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getJobNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, checkPermissions('job', 'info'), async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('job', 'info'), async (req, res) => {

View File

@ -30,9 +30,9 @@ const listAllowedSorters = [
const propertiesAllowedFilters = ['name']; const propertiesAllowedFilters = ['name'];
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listPrinterProfilesRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listPrinterProfilesRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('printerProfile', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('printerProfile', 'list'), isAuthenticated, async (req, res) => {
@ -59,9 +59,9 @@ router.post('/', isAuthenticated, checkPermissions('printer', 'newPrinterProfile
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getPrinterProfileNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getPrinterProfileNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, checkPermissions('printerProfile', 'info'), async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('printerProfile', 'info'), async (req, res) => {

View File

@ -34,9 +34,9 @@ const listAllowedSorters = ['name', 'state', 'connectedAt', 'createdAt', 'update
const propertiesAllowedFilters = ['tags']; const propertiesAllowedFilters = ['tags'];
// list of printers // list of printers
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listPrintersRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listPrintersRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('printer', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('printer', 'list'), isAuthenticated, async (req, res) => {
@ -69,9 +69,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getPrinterNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getPrinterNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
// get printer stats // get printer stats

View File

@ -41,9 +41,9 @@ import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
// list of sub jobs // list of sub jobs
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listSubJobsRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listSubJobsRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('subJob', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('subJob', 'list'), isAuthenticated, async (req, res) => {
@ -76,9 +76,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getSubJobNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getSubJobNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, checkPermissions('subJob', 'info'), async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('subJob', 'info'), async (req, res) => {

View File

@ -34,9 +34,9 @@ import {
// list of clients // list of clients
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listClientsRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listClientsRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('client', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('client', 'list'), isAuthenticated, async (req, res) => {
@ -74,9 +74,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getClientNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getClientNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, checkPermissions('client', 'info'), async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('client', 'info'), async (req, res) => {

View File

@ -60,9 +60,9 @@ import {
} from '../../services/sales/listings.js'; } from '../../services/sales/listings.js';
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listListingsRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listListingsRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('listing', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('listing', 'list'), isAuthenticated, async (req, res) => {
@ -105,9 +105,9 @@ router.post('/:id/unpublish', isAuthenticated, checkPermissions('listing', 'unpu
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getListingNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getListingNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, checkPermissions('listing', 'info'), async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('listing', 'info'), async (req, res) => {

View File

@ -47,9 +47,9 @@ import {
} from '../../services/sales/listingvarients.js'; } from '../../services/sales/listingvarients.js';
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listListingVarientsRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listListingVarientsRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('listingVarient', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('listingVarient', 'list'), isAuthenticated, async (req, res) => {
@ -93,9 +93,9 @@ router.post('/:id/unpublish', isAuthenticated, checkPermissions('listingVarient'
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getListingVarientNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getListingVarientNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, checkPermissions('listingVarient', 'info'), async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('listingVarient', 'info'), async (req, res) => {

View File

@ -49,9 +49,9 @@ import {
} from '../../services/sales/marketplaces.js'; } from '../../services/sales/marketplaces.js';
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listMarketplacesRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listMarketplacesRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('marketplace', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('marketplace', 'list'), isAuthenticated, async (req, res) => {
@ -124,9 +124,9 @@ router.post('/:id/hook', async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getMarketplaceNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getMarketplaceNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, checkPermissions('marketplace', 'info'), async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('marketplace', 'info'), async (req, res) => {

View File

@ -36,9 +36,9 @@ import {
// list of sales orders // list of sales orders
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sortProperty, sortOrder } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listSalesOrdersRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listSalesOrdersRouteHandler(req, res, page, limit, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder);
}); });
router.get('/properties', checkPermissions('salesOrder', 'list'), isAuthenticated, async (req, res) => { router.get('/properties', checkPermissions('salesOrder', 'list'), isAuthenticated, async (req, res) => {
@ -75,9 +75,9 @@ router.get('/history', isAuthenticated, async (req, res) => {
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sortProperty, sortOrder, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getSalesOrderNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getSalesOrderNeighborsRouteHandler(req, res, property, filter, search, getSort(sortProperty, listAllowedSorters), sortOrder, id);
}); });
router.get('/:id', isAuthenticated, checkPermissions('salesOrder', 'info'), async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('salesOrder', 'info'), async (req, res) => {

View File

@ -51,8 +51,7 @@ describe('formatTemplateContent', () => {
}); });
it('should not add spaces inside parentheses around EJS output', () => { it('should not add spaces inside parentheses around EJS output', () => {
const input = const input = '<Text><Bold><%= courierService.name %></Bold> ( <%= courier.name %> )</Text>';
'<Text><Bold><%= courierService.name %></Bold> ( <%= courier.name %> )</Text>';
const result = formatTemplateContent(input); const result = formatTemplateContent(input);
expect(result.content).toContain('</Bold> (<%= courier.name %>)'); expect(result.content).toContain('</Bold> (<%= courier.name %>)');

View File

@ -35,6 +35,10 @@ jest.unstable_mockModule('../../database/database.js', () => ({
listObjects: jest.fn(), listObjects: jest.fn(),
})); }));
jest.unstable_mockModule('../../utils.js', () => ({
getFilter: jest.fn(async (query) => query),
}));
jest.unstable_mockModule('../../database/schemas/management/documenttemplate.schema.js', () => ({ jest.unstable_mockModule('../../database/schemas/management/documenttemplate.schema.js', () => ({
documentTemplateModel: { modelName: 'DocumentTemplate' }, documentTemplateModel: { modelName: 'DocumentTemplate' },
})); }));
@ -91,11 +95,26 @@ jest.unstable_mockModule('../../config.js', () => ({
}, },
})); }));
const { TemplateManager, resolveDocumentPadding } = await import('../templatemanager.js'); const { TemplateManager, resolveDocumentPadding, stripDocumentTemplateReference } = await import('../templatemanager.js');
const { getObject } = await import('../../database/database.js'); const { getObject, listObjects } = await import('../../database/database.js');
const { getFilter } = await import('../../utils.js');
const ejs = (await import('ejs')).default; const ejs = (await import('ejs')).default;
const { generatePDF } = await import('../pdffactory.js'); const { generatePDF } = await import('../pdffactory.js');
describe('stripDocumentTemplateReference', () => {
it('strips a DTP: prefix', () => {
expect(stripDocumentTemplateReference('DTP:YPZY0P8XYKHZ')).toBe('YPZY0P8XYKHZ');
});
it('strips a dtp: prefix case-insensitively', () => {
expect(stripDocumentTemplateReference('dtp:YPZY0P8XYKHZ')).toBe('YPZY0P8XYKHZ');
});
it('returns a bare reference unchanged', () => {
expect(stripDocumentTemplateReference('YPZY0P8XYKHZ')).toBe('YPZY0P8XYKHZ');
});
});
describe('resolveDocumentPadding', () => { describe('resolveDocumentPadding', () => {
const paddedSize = { const paddedSize = {
printPadding: false, printPadding: false,
@ -172,6 +191,197 @@ describe('TemplateManager', () => {
expect(result).toEqual({ error: 'Document template not found.', code: 404 }); expect(result).toEqual({ error: 'Document template not found.', code: 404 });
}); });
it('exposes fc.renderDocumentTemplate when rendering', async () => {
getObject.mockResolvedValue({
documentSize: { width: 100, height: 100, infiniteHeight: false },
global: false,
objectType: 'printer',
_reference: 'PARENTREF',
});
await templateManager.renderTemplate('temp-id', 'some content', { name: 'Test' });
expect(ejs.render).toHaveBeenCalledWith(
'some content',
expect.objectContaining({
name: 'Test',
fc: expect.objectContaining({
renderDocumentTemplate: expect.any(Function),
}),
}),
expect.anything()
);
});
it('looks up a nested template by reference without the DTP: prefix', async () => {
getObject.mockResolvedValue({
documentSize: { width: 100, height: 100, infiniteHeight: false },
global: false,
objectType: 'printer',
_reference: 'PARENTREF',
});
listObjects.mockResolvedValue([
{
_reference: 'YPZY0P8XYKHZ',
content: '<Text><%= name %></Text>',
objectType: 'printer',
global: false,
},
]);
let capturedFc;
ejs.render.mockImplementation(async (content, data) => {
if (data?.fc?.renderDocumentTemplate) {
capturedFc = data.fc;
}
return `rendered: ${content}`;
});
await templateManager.renderTemplate('temp-id', 'some content', { name: 'Parent' });
const nestedHtml = await capturedFc.renderDocumentTemplate('DTP:YPZY0P8XYKHZ');
expect(listObjects).toHaveBeenCalledWith(
expect.objectContaining({
filter: { _reference: 'YPZY0P8XYKHZ' },
})
);
expect(ejs.render).toHaveBeenCalledWith(
'<Text><%= name %></Text>',
expect.objectContaining({ name: 'Parent' }),
expect.anything()
);
expect(nestedHtml).toBe('rendered: <Text><%= name %></Text>');
});
it('renders a nested template with a passed object instead of the parent object', async () => {
getObject.mockResolvedValue({
documentSize: { width: 100, height: 100, infiniteHeight: false },
global: false,
objectType: 'printer',
_reference: 'PARENTREF',
});
listObjects.mockResolvedValue([
{
_reference: 'YPZY0P8XYKHZ',
content: '<Text><%= name %></Text>',
objectType: 'printer',
global: false,
},
]);
let capturedFc;
ejs.render.mockImplementation(async (content, data) => {
if (data?.fc?.renderDocumentTemplate) {
capturedFc = data.fc;
}
return `rendered: ${content}`;
});
await templateManager.renderTemplate('temp-id', 'some content', { name: 'Parent' });
await capturedFc.renderDocumentTemplate('YPZY0P8XYKHZ', { name: 'Nested' });
expect(ejs.render).toHaveBeenCalledWith(
'<Text><%= name %></Text>',
expect.objectContaining({ name: 'Nested' }),
expect.anything()
);
});
it('uses the passed object as nested template data without fetching it', async () => {
getObject.mockResolvedValue({
documentSize: { width: 100, height: 100, infiniteHeight: false },
global: false,
objectType: 'printer',
_reference: 'PARENTREF',
});
listObjects.mockResolvedValue([
{
_reference: 'PKEFDZV5X1SU',
content: '<Text><%= totalAmount %></Text>',
objectType: 'invoice',
global: false,
},
]);
let capturedFc;
ejs.render.mockImplementation(async (content, data) => {
if (data?.fc?.renderDocumentTemplate) {
capturedFc = data.fc;
}
return `rendered: ${content}`;
});
await templateManager.renderTemplate('temp-id', 'some content', { name: 'Parent' });
getObject.mockClear();
const invoice = { _id: 'inv-1', totalAmount: 42, orderType: 'salesOrder' };
await capturedFc.renderDocumentTemplate('DTP:PKEFDZV5X1SU', invoice);
expect(getObject).not.toHaveBeenCalled();
expect(ejs.render).toHaveBeenCalledWith(
'<Text><%= totalAmount %></Text>',
expect.objectContaining({
_id: 'inv-1',
totalAmount: 42,
orderType: 'salesOrder',
}),
expect.objectContaining({ async: true })
);
});
it('wraps nested content in its parent template without page pagination chrome', async () => {
getObject.mockResolvedValue({
documentSize: { width: 100, height: 100, infiniteHeight: false },
global: false,
objectType: 'printer',
_reference: 'PARENTREF',
});
listObjects.mockResolvedValue([
{
_reference: 'PKEFDZV5X1SU',
content: '<Text>invoice</Text>',
objectType: 'invoice',
global: false,
parent: {
_reference: 'LETTERHEAD',
content: '<Container><%- content %></Container>',
},
},
]);
let capturedFc;
ejs.render.mockImplementation(async (content, data) => {
if (data?.fc?.renderDocumentTemplate) {
capturedFc = data.fc;
}
return `rendered: ${content}`;
});
await templateManager.renderTemplate('temp-id', 'some content', { name: 'Parent' });
ejs.render.mockClear();
const nestedHtml = await capturedFc.renderDocumentTemplate(
'DTP:PKEFDZV5X1SU',
{ totalAmount: 10 }
);
expect(ejs.render).toHaveBeenCalledWith(
'<Text>invoice</Text>',
expect.objectContaining({ totalAmount: 10 }),
expect.objectContaining({ async: true })
);
expect(ejs.render).toHaveBeenCalledWith(
'<Container><%- content %></Container>',
expect.objectContaining({ content: 'rendered: <Text>invoice</Text>' }),
expect.objectContaining({ async: true })
);
expect(nestedHtml).not.toContain('pagination');
expect(nestedHtml).not.toContain('previewDocument');
expect(nestedHtml).not.toContain('renderDocument');
});
}); });
describe('validateTemplate', () => { describe('validateTemplate', () => {
@ -187,6 +397,44 @@ describe('TemplateManager', () => {
}); });
}); });
describe('listObjects', () => {
it('parses a present filter with getFilter before listing', async () => {
const parsedFilter = { name: { $eq: 'Test' } };
getFilter.mockResolvedValue(parsedFilter);
listObjects.mockResolvedValue([{ name: 'Test' }]);
const result = await templateManager.listObjects('printer', { name: '=Test' });
expect(getFilter).toHaveBeenCalledWith(
{ name: '=Test' },
['name'],
true,
expect.anything()
);
expect(listObjects).toHaveBeenCalledWith(
expect.objectContaining({
filter: parsedFilter,
pagination: false,
})
);
expect(result).toEqual([{ name: 'Test' }]);
});
it('does not call getFilter when no filter is provided', async () => {
listObjects.mockResolvedValue([]);
await templateManager.listObjects('printer');
expect(getFilter).not.toHaveBeenCalled();
expect(listObjects).toHaveBeenCalledWith(
expect.objectContaining({
filter: {},
pagination: false,
})
);
});
});
describe('renderPDF', () => { describe('renderPDF', () => {
it('should render a PDF successfully', async () => { it('should render a PDF successfully', async () => {
const mockTemplate = { const mockTemplate = {

View File

@ -14,6 +14,7 @@ import '../database/schemas/management/documentsize.schema.js';
import config from '../config.js'; import config from '../config.js';
import { getObject, listObjects } from '../database/database.js'; import { getObject, listObjects } from '../database/database.js';
import { getModelByName } from '../services/misc/model.js'; import { getModelByName } from '../services/misc/model.js';
import { getFilter } from '../utils.js';
import { generatePDF } from './pdffactory.js'; import { generatePDF } from './pdffactory.js';
import { convertPDFToImage } from './pdfUtils.js'; import { convertPDFToImage } from './pdfUtils.js';
@ -40,10 +41,7 @@ async function loadTemplates() {
baseCSS = fs.readFileSync(join(__dirname, '/assets/styles.css'), 'utf8'); baseCSS = fs.readFileSync(join(__dirname, '/assets/styles.css'), 'utf8');
previewTemplate = fs.readFileSync(join(__dirname, '/assets/previewtemplate.ejs'), 'utf8'); previewTemplate = fs.readFileSync(join(__dirname, '/assets/previewtemplate.ejs'), 'utf8');
renderTemplateEjs = fs.readFileSync(join(__dirname, '/assets/rendertemplate.ejs'), 'utf8'); renderTemplateEjs = fs.readFileSync(join(__dirname, '/assets/rendertemplate.ejs'), 'utf8');
contentPlaceholder = fs.readFileSync( contentPlaceholder = fs.readFileSync(join(__dirname, '/assets/contentplaceholder.ejs'), 'utf8');
join(__dirname, '/assets/contentplaceholder.ejs'),
'utf8'
);
previewPaginationScript = fs.readFileSync( previewPaginationScript = fs.readFileSync(
join(__dirname, '/assets/previewpagination.js'), join(__dirname, '/assets/previewpagination.js'),
'utf8' 'utf8'
@ -247,7 +245,7 @@ async function transformCustomElements(content) {
}), }),
(tree) => (tree) =>
tree.match({ tag: 'DateTime' }, (node) => { tree.match({ tag: 'DateTime' }, (node) => {
const dateTime = dayjs.utc(node.content[0]); const dateTime = dayjs.utc(node?.content ? node.content[0] : '');
return { return {
content: [dateTime.format('YYYY-MM-DD hh:mm:ss')], content: [dateTime.format('YYYY-MM-DD hh:mm:ss')],
tag: 'span', tag: 'span',
@ -355,9 +353,7 @@ function normalizeDownloadType(type) {
function imageToSvg(pngBuffer, widthPx, heightPx, documentWidthMm, documentHeightMm) { function imageToSvg(pngBuffer, widthPx, heightPx, documentWidthMm, documentHeightMm) {
const b64 = pngBuffer.toString('base64'); const b64 = pngBuffer.toString('base64');
const heightAttr = const heightAttr =
documentHeightMm == 'auto' || documentHeightMm == null documentHeightMm == 'auto' || documentHeightMm == null ? '' : ` height="${documentHeightMm}mm"`;
? ''
: ` height="${documentHeightMm}mm"`;
return `<?xml version="1.0" encoding="UTF-8"?> return `<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="${documentWidthMm}mm"${heightAttr} viewBox="0 0 ${widthPx} ${heightPx}"> <svg xmlns="http://www.w3.org/2000/svg" width="${documentWidthMm}mm"${heightAttr} viewBox="0 0 ${widthPx} ${heightPx}">
<image href="data:image/png;base64,${b64}" width="${widthPx}" height="${heightPx}"/> <image href="data:image/png;base64,${b64}" width="${widthPx}" height="${heightPx}"/>
@ -390,6 +386,72 @@ export function resolveDocumentPadding(documentSize = {}, paddingRequested = fal
}; };
} }
export function stripDocumentTemplateReference(reference) {
const trimmed = String(reference ?? '').trim();
if (/^DTP:/i.test(trimmed)) {
return trimmed.slice(4).trim();
}
return trimmed;
}
function omitTemplateFc(data) {
if (data == null || typeof data !== 'object' || Array.isArray(data)) {
return data;
}
const rest = { ...data };
delete rest.fc;
return rest;
}
function resolveNestedTemplateObject(object) {
if (typeof object === 'string') {
const trimmed = object.trim();
if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
try {
const parsed = JSON.parse(trimmed);
if (parsed != null && typeof parsed === 'object') {
return omitTemplateFc(parsed);
}
} catch {
return object;
}
}
return object;
}
if (object != null && typeof object === 'object' && typeof object.toObject === 'function') {
return omitTemplateFc(object.toObject());
}
return omitTemplateFc(object);
}
function buildTemplateData(documentTemplate, data = {}, fc) {
const objectData = resolveNestedTemplateObject(data) ?? {};
if (documentTemplate?.global == true) {
if (objectData != null && typeof objectData === 'object' && !Array.isArray(objectData)) {
return { ...objectData, fc };
}
return { fc };
}
const objectType = documentTemplate?.objectType;
const modelEntry = getModelByName(objectType);
const model = modelEntry?.model || modelEntry;
const defaultValues = {};
if (model?.schema?.obj) {
for (const key of Object.keys(model.schema.obj)) {
defaultValues[key] = null;
}
}
if (objectData != null && typeof objectData === 'object' && !Array.isArray(objectData)) {
return { ...defaultValues, ...objectData, fc };
}
return { ...defaultValues, fc };
}
export class TemplateManager { export class TemplateManager {
constructor() { constructor() {
this.fc = { this.fc = {
@ -399,6 +461,108 @@ export class TemplateManager {
}; };
} }
createTemplateFc(getDefaultData, options, visited) {
const fc = {
listObjects: this.listObjects.bind(this),
getObject: this.getObject.bind(this),
formatDate: this.formatDate.bind(this),
};
fc.renderDocumentTemplate = async (reference, object) => {
const dataToUse = object !== undefined ? object : getDefaultData();
return this.renderNestedDocumentTemplate(reference, dataToUse, options, visited);
};
return fc;
}
async getDocumentTemplateByReference(reference) {
const strippedReference = stripDocumentTemplateReference(reference);
if (strippedReference == null || strippedReference === '') {
return { error: 'Document template reference is required.', code: 400 };
}
const results = await listObjects({
model: documentTemplateModel,
filter: { _reference: strippedReference },
populate: [{ path: 'parent', strictPopulate: false }, { path: 'documentSize' }],
pagination: false,
});
if (results == null || results.error) {
return {
error: results?.error || 'Document template not found.',
code: results?.code || 404,
};
}
if (!Array.isArray(results) || results.length === 0) {
return { error: 'Document template not found.', code: 404 };
}
return results[0];
}
async renderNestedDocumentTemplate(reference, object, options = {}, visited = new Set()) {
const strippedReference = stripDocumentTemplateReference(reference);
if (strippedReference == null || strippedReference === '') {
throw new Error('Document template reference is required.');
}
if (visited.has(strippedReference)) {
throw new Error(`Circular document template reference: ${strippedReference}`);
}
const nextVisited = new Set(visited);
nextVisited.add(strippedReference);
const nestedTemplate = await this.getDocumentTemplateByReference(strippedReference);
if (nestedTemplate == null || nestedTemplate.error) {
throw new Error(nestedTemplate?.error || `Document template not found: ${reference}`);
}
if (nestedTemplate.content == null || typeof nestedTemplate.content !== 'string') {
throw new Error(`Document template content is required: ${reference}`);
}
const renderOptions = {
async: true,
...options,
};
let nestedData;
const fc = this.createTemplateFc(() => nestedData, renderOptions, nextVisited);
nestedData = buildTemplateData(nestedTemplate, object, fc);
// Return a content fragment only. Page shells and previewPaginationScript
// already exist on the host document.
let nestedContent = await ejs.render(nestedTemplate.content, nestedData, renderOptions);
let parentTemplate = nestedTemplate.parent;
if (parentTemplate != undefined) {
if (
typeof parentTemplate === 'string' ||
parentTemplate.content == null ||
typeof parentTemplate.content !== 'string'
) {
parentTemplate = await getObject({
model: documentTemplateModel,
id: parentTemplate._id || parentTemplate.id || parentTemplate,
populate: [{ path: 'documentSize' }, { path: 'parent', strictPopulate: false }],
});
}
if (
parentTemplate?.error ||
parentTemplate.content == null ||
typeof parentTemplate.content !== 'string'
) {
throw new Error('Parent template content is required and must be a string.');
}
if (parentTemplate._reference) {
nextVisited.add(String(parentTemplate._reference));
}
const parentData = { content: nestedContent };
parentData.fc = this.createTemplateFc(() => parentData, renderOptions, nextVisited);
nestedContent = await ejs.render(parentTemplate.content, parentData, renderOptions);
}
return nestedContent;
}
async renderTemplate(id, content, data = {}, scale = 1, options = {}, preview = true) { async renderTemplate(id, content, data = {}, scale = 1, options = {}, preview = true) {
try { try {
const { padding: paddingRequested = false, ...ejsOptions } = options; const { padding: paddingRequested = false, ...ejsOptions } = options;
@ -411,10 +575,7 @@ export class TemplateManager {
const documentTemplate = await getObject({ const documentTemplate = await getObject({
model: documentTemplateModel, model: documentTemplateModel,
id, id,
populate: [ populate: [{ path: 'documentSize' }, { path: 'parent', strictPopulate: false }],
{ path: 'documentSize' },
{ path: 'parent', strictPopulate: false },
],
}); });
if (documentTemplate == null || documentTemplate.error) { if (documentTemplate == null || documentTemplate.error) {
@ -433,9 +594,14 @@ export class TemplateManager {
return { error: 'Template content is required and must be a string.', code: 400 }; return { error: 'Template content is required and must be a string.', code: 400 };
} }
const visited = new Set();
if (documentTemplate._reference) {
visited.add(String(documentTemplate._reference));
}
var templateData = {}; var templateData = {};
if (documentTemplate.global == true) { if (documentTemplate.global == true) {
templateData = { content: contentPlaceholder, fc: this.fc }; templateData = { content: contentPlaceholder };
} else { } else {
const objectType = documentTemplate?.objectType; const objectType = documentTemplate?.objectType;
const modelEntry = getModelByName(objectType); const modelEntry = getModelByName(objectType);
@ -448,8 +614,9 @@ export class TemplateManager {
for (const key of defaultKeys) { for (const key of defaultKeys) {
defaultValues[key] = null; defaultValues[key] = null;
} }
templateData = { ...defaultValues, ...data, fc: this.fc }; templateData = { ...defaultValues, ...data };
} }
templateData.fc = this.createTemplateFc(() => templateData, defaultOptions, visited);
const templateContent = await ejs.render(templateContentSource, templateData, defaultOptions); const templateContent = await ejs.render(templateContentSource, templateData, defaultOptions);
@ -461,13 +628,14 @@ export class TemplateManager {
parentTemplate = await getObject({ parentTemplate = await getObject({
model: documentTemplateModel, model: documentTemplateModel,
id: parentTemplate, id: parentTemplate,
populate: [ populate: [{ path: 'documentSize' }, { path: 'parent', strictPopulate: false }],
{ path: 'documentSize' },
{ path: 'parent', strictPopulate: false },
],
}); });
} }
if (parentTemplate?.error || parentTemplate.content == null || typeof parentTemplate.content !== 'string') { if (
parentTemplate?.error ||
parentTemplate.content == null ||
typeof parentTemplate.content !== 'string'
) {
logger.error( logger.error(
'Parent template content is required and must be a string.', 'Parent template content is required and must be a string.',
parentTemplate?.content parentTemplate?.content
@ -479,9 +647,14 @@ export class TemplateManager {
code: 400, code: 400,
}; };
} }
if (parentTemplate._reference) {
visited.add(String(parentTemplate._reference));
}
const parentData = { content: templateContent };
parentData.fc = this.createTemplateFc(() => parentData, defaultOptions, visited);
templateWithParentContent = await ejs.render( templateWithParentContent = await ejs.render(
parentTemplate.content, parentTemplate.content,
{ content: templateContent, fc: this.fc }, parentData,
defaultOptions defaultOptions
); );
} else { } else {
@ -638,15 +811,7 @@ export class TemplateManager {
for (const image of images) { for (const image of images) {
const png = await sharp(image).png().toBuffer(); const png = await sharp(image).png().toBuffer();
const meta = await sharp(png).metadata(); const meta = await sharp(png).metadata();
svgs.push( svgs.push(imageToSvg(png, meta.width, meta.height, pdfResult.width, pdfResult.height));
imageToSvg(
png,
meta.width,
meta.height,
pdfResult.width,
pdfResult.height
)
);
} }
return { svgs }; return { svgs };
} catch (error) { } catch (error) {
@ -708,9 +873,14 @@ export class TemplateManager {
if (model == undefined) { if (model == undefined) {
throw new Error('Farm Control: Object type not found.'); throw new Error('Farm Control: Object type not found.');
} }
const resolvedFilter =
filter != null && Object.keys(filter).length > 0
? await getFilter(filter, Object.keys(filter), true, model)
: filter;
const objects = await listObjects({ const objects = await listObjects({
model, model,
filter, filter: resolvedFilter,
populate, populate,
pagination: false, pagination: false,
}); });

View File

@ -162,7 +162,7 @@ function buildRegexOp(pattern, useOptions = true) {
function getSchemaRefName(property, model = null) { function getSchemaRefName(property, model = null) {
const baseProperty = getBaseProperty(property); const baseProperty = getBaseProperty(property);
const path = model?.schema?.path(baseProperty) ?? getSchemaPathFromModels(baseProperty); const path = model?.schema?.path(baseProperty) ?? getSchemaPathFromModels(baseProperty);
return path?.options?.ref ?? path?.caster?.options?.ref ?? path?.path ?? null; return path?.options?.ref ?? path?.caster?.options?.ref ?? null;
} }
function getRefModelEntryFromSchemaRef(refName) { function getRefModelEntryFromSchemaRef(refName) {
@ -666,10 +666,14 @@ async function resolveRefLeaf(rawToken, fallbackRefName) {
if (token === '') return NO_MATCH_CONDITION; if (token === '') return NO_MATCH_CONDITION;
const refModelEntry = getRefModelEntryForToken(token, fallbackRefName); const refModelEntry = getRefModelEntryForToken(token, fallbackRefName);
if (!refModelEntry?.model) return NO_MATCH_CONDITION;
const lookupToken = stripPrefixFromOperand(token); const lookupToken = stripPrefixFromOperand(token);
if (!refModelEntry?.model) {
const objectId = extractObjectIdFromOperand(lookupToken);
if (objectId) return { value: objectId };
return NO_MATCH_CONDITION;
}
const rangeIdx = lookupToken.indexOf('..'); const rangeIdx = lookupToken.indexOf('..');
if (rangeIdx !== -1) { if (rangeIdx !== -1) {
const ids = await listRefModelIds(refModelEntry, lookupToken); const ids = await listRefModelIds(refModelEntry, lookupToken);
@ -739,7 +743,7 @@ async function parseFilter(property, value, model = null) {
const trimmed = value.trim(); const trimmed = value.trim();
if (fieldKind.kind === 'objectId' && property != '_id') { if ((fieldKind.kind === 'objectId' || fieldKind.kind === 'objectRef') && property != '_id') {
const refName = fieldKind.ref ?? getSchemaRefName(property, model); const refName = fieldKind.ref ?? getSchemaRefName(property, model);
return resolveObjectRefFilter(filterProperty, trimmed, refName); return resolveObjectRefFilter(filterProperty, trimmed, refName);
} }
@ -1580,14 +1584,33 @@ function getSort(sort, allowedSorters, defaultSort = 'createdAt') {
return defaultSort; return defaultSort;
} }
function normalizeFilterQuery(query = {}) {
const queryClean = { ...query };
// qs turns `order._id=` into `{ order: { _id } }`. Lift it so it can be parsed
// as the order object filter instead of a nested query object.
if (queryClean.order && typeof queryClean.order === 'object' && !Array.isArray(queryClean.order)) {
if (queryClean.order._id !== undefined) {
queryClean['order._id'] = queryClean.order._id;
}
delete queryClean.order;
}
return queryClean;
}
// Returns a filter object based on allowed filters and req.query // Returns a filter object based on allowed filters and req.query
async function getFilter(query, allowedFilters, parse = true, model = null) { async function getFilter(query, allowedFilters, parse = true, model = null) {
const clauses = []; const clauses = [];
const queryClean = { ...query }; const queryClean = normalizeFilterQuery(query);
for (const key of ['sort', 'order', 'page', 'limit']) { for (const key of ['sortProperty', 'sortOrder', 'page', 'limit']) {
if (key in queryClean) delete queryClean[key]; if (key in queryClean) delete queryClean[key];
} }
logger.info('queryExcludingSortAndOrder', queryClean); logger.info('queryExcludingSortAndOrder', queryClean);
if (!parse && queryClean['order._id'] !== undefined && allowedFilters.includes('order')) {
queryClean.order = queryClean['order._id'];
delete queryClean['order._id'];
}
for (const [key, value] of Object.entries(queryClean)) { for (const [key, value] of Object.entries(queryClean)) {
if (allowedFilters.includes(key)) { if (allowedFilters.includes(key)) {
clauses.push(parse ? await parseFilter(key, value, model) : { [key]: value }); clauses.push(parse ? await parseFilter(key, value, model) : { [key]: value });