updated filtering code
This commit is contained in:
10
src/index.ts
10
src/index.ts
@@ -1,12 +1,12 @@
|
|||||||
import mongoose from "mongoose";
|
import mongoose from 'mongoose';
|
||||||
import app from "./server";
|
import app from './server';
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
const PORT = parseInt(process.env.PORT ?? "8000");
|
const PORT = parseInt(process.env.PORT ?? '8000');
|
||||||
const DB_URI = process.env.DB_URI ?? "";
|
const DB_URI = process.env.DB_URI ?? '';
|
||||||
|
|
||||||
await mongoose.connect(DB_URI);
|
await mongoose.connect(DB_URI);
|
||||||
await app.listen({ port: PORT, host: "0.0.0.0" });
|
await app.listen({ port: PORT, host: '0.0.0.0' });
|
||||||
})().catch((err) => {
|
})().catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
|
|||||||
@@ -43,11 +43,11 @@ export async function listNotifications(
|
|||||||
const page = params.page || 1;
|
const page = params.page || 1;
|
||||||
const pageSize = params.pageSize || 10;
|
const pageSize = params.pageSize || 10;
|
||||||
const sortObj = getSortObject(params, notificationFields);
|
const sortObj = getSortObject(params, notificationFields);
|
||||||
const filterObj = getFilterObject(params, notificationFields);
|
const filterObj = getFilterObject(params);
|
||||||
|
|
||||||
const pipeline: any = [
|
const pipeline: any = [
|
||||||
{
|
{
|
||||||
$match: { $and: [{ tenantId: tenantId }, ...filterObj] },
|
$match: { $and: [{ tenantId: tenantId }, { ...filterObj }] },
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { getFilterObject, getSortObject, PageQueryParams } from "../pagination";
|
import { getFilterObject, getSortObject, PageQueryParams } from '../pagination';
|
||||||
import { ChangeEvent, dbEvents } from "../realtime";
|
import { ChangeEvent, dbEvents } from '../realtime';
|
||||||
import { generateId } from "../utils/id";
|
import { generateId } from '../utils/id';
|
||||||
import {
|
import {
|
||||||
CreateOrgInput,
|
CreateOrgInput,
|
||||||
orgFields,
|
orgFields,
|
||||||
orgModel,
|
orgModel,
|
||||||
UpdateOrgInput,
|
UpdateOrgInput,
|
||||||
} from "./organization.schema";
|
} from './organization.schema';
|
||||||
|
|
||||||
export async function createOrg(input: CreateOrgInput, tenantId: string) {
|
export async function createOrg(input: CreateOrgInput, tenantId: string) {
|
||||||
const org = await orgModel.create({
|
const org = await orgModel.create({
|
||||||
@@ -17,13 +17,13 @@ export async function createOrg(input: CreateOrgInput, tenantId: string) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
dbEvents.emit(
|
dbEvents.emit(
|
||||||
"change",
|
'change',
|
||||||
{
|
{
|
||||||
type: "insert",
|
type: 'insert',
|
||||||
collection: "orgs",
|
collection: 'orgs',
|
||||||
document: org,
|
document: org,
|
||||||
} as ChangeEvent,
|
} as ChangeEvent,
|
||||||
["org:read"]
|
['org:read']
|
||||||
);
|
);
|
||||||
|
|
||||||
return org;
|
return org;
|
||||||
@@ -39,13 +39,13 @@ export async function listOrgs(params: PageQueryParams, tenantId: string) {
|
|||||||
const page = params.page || 1;
|
const page = params.page || 1;
|
||||||
const pageSize = params.pageSize || 10;
|
const pageSize = params.pageSize || 10;
|
||||||
const sortObj = getSortObject(params, orgFields);
|
const sortObj = getSortObject(params, orgFields);
|
||||||
const filterObj = getFilterObject(params, orgFields);
|
const filterObj = getFilterObject(params);
|
||||||
|
|
||||||
const orgs = await orgModel.aggregate([
|
const orgs = await orgModel.aggregate([
|
||||||
{ $match: { $and: [{ tenantId: tenantId }, ...filterObj] } },
|
{ $match: { $and: [{ tenantId: tenantId }, { ...filterObj }] } },
|
||||||
{
|
{
|
||||||
$facet: {
|
$facet: {
|
||||||
metadata: [{ $count: "count" }],
|
metadata: [{ $count: 'count' }],
|
||||||
data: [
|
data: [
|
||||||
{ $sort: sortObj },
|
{ $sort: sortObj },
|
||||||
{ $skip: (page - 1) * pageSize },
|
{ $skip: (page - 1) * pageSize },
|
||||||
@@ -83,13 +83,13 @@ export async function updateOrg(
|
|||||||
|
|
||||||
if (updateOrgResult) {
|
if (updateOrgResult) {
|
||||||
dbEvents.emit(
|
dbEvents.emit(
|
||||||
"change",
|
'change',
|
||||||
{
|
{
|
||||||
type: "update",
|
type: 'update',
|
||||||
collection: "orgs",
|
collection: 'orgs',
|
||||||
document: updateOrgResult,
|
document: updateOrgResult,
|
||||||
} as ChangeEvent,
|
} as ChangeEvent,
|
||||||
["org:read"]
|
['org:read']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,15 +103,15 @@ export async function deleteOrg(orgId: string, tenantId: string) {
|
|||||||
|
|
||||||
if (res.deletedCount > 0) {
|
if (res.deletedCount > 0) {
|
||||||
dbEvents.emit(
|
dbEvents.emit(
|
||||||
"change",
|
'change',
|
||||||
{
|
{
|
||||||
type: "delete",
|
type: 'delete',
|
||||||
collection: "orgs",
|
collection: 'orgs',
|
||||||
document: {
|
document: {
|
||||||
pid: orgId,
|
pid: orgId,
|
||||||
},
|
},
|
||||||
} as ChangeEvent,
|
} as ChangeEvent,
|
||||||
["org:read"]
|
['org:read']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,15 +122,15 @@ export async function searchOrgs(params: PageQueryParams, tenantId: string) {
|
|||||||
const page = params.page || 1;
|
const page = params.page || 1;
|
||||||
const pageSize = params.pageSize || 10;
|
const pageSize = params.pageSize || 10;
|
||||||
const sortObj = getSortObject(params, orgFields);
|
const sortObj = getSortObject(params, orgFields);
|
||||||
const filterObj = getFilterObject(params, orgFields);
|
const filterObj = getFilterObject(params);
|
||||||
|
|
||||||
if (!params.searchToken)
|
if (!params.searchToken)
|
||||||
return { orgs: [], metadata: { count: 0, page, pageSize } };
|
return { orgs: [], metadata: { count: 0, page, pageSize } };
|
||||||
|
|
||||||
const regex = new RegExp(params.searchToken, "i");
|
const regex = new RegExp(params.searchToken, 'i');
|
||||||
|
|
||||||
const orgs = await orgModel.aggregate([
|
const orgs = await orgModel.aggregate([
|
||||||
{ $match: { $and: [{ tenantId: tenantId }, ...filterObj] } },
|
{ $match: { $and: [{ tenantId: tenantId }, { ...filterObj }] } },
|
||||||
{
|
{
|
||||||
$match: {
|
$match: {
|
||||||
$or: [{ name: { $regex: regex } }, { domain: { $regex: regex } }],
|
$or: [{ name: { $regex: regex } }, { domain: { $regex: regex } }],
|
||||||
@@ -138,7 +138,7 @@ export async function searchOrgs(params: PageQueryParams, tenantId: string) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
$facet: {
|
$facet: {
|
||||||
metadata: [{ $count: "count" }],
|
metadata: [{ $count: 'count' }],
|
||||||
data: [
|
data: [
|
||||||
{ $sort: sortObj },
|
{ $sort: sortObj },
|
||||||
{ $skip: (page - 1) * pageSize },
|
{ $skip: (page - 1) * pageSize },
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { z } from "zod";
|
import { z } from 'zod';
|
||||||
import { parse } from "./utils/queryParser";
|
import { parse } from './utils/queryParser';
|
||||||
|
|
||||||
export const pageMetadata = z.object({
|
export const pageMetadata = z.object({
|
||||||
count: z.number(),
|
count: z.number(),
|
||||||
@@ -23,30 +23,23 @@ export function getSortObject(
|
|||||||
) {
|
) {
|
||||||
const sortObj: Record<string, 1 | -1> = {};
|
const sortObj: Record<string, 1 | -1> = {};
|
||||||
|
|
||||||
if (params.sort && params.sort != "") {
|
if (params.sort && params.sort != '') {
|
||||||
const sortOptions = params.sort.split(",");
|
const sortOptions = params.sort.split(',');
|
||||||
sortOptions.forEach((item) => {
|
sortOptions.forEach((item) => {
|
||||||
const order = item.startsWith("-") ? -1 : 1;
|
const order = item.startsWith('-') ? -1 : 1;
|
||||||
const field = item.replace("-", "").trim();
|
const field = item.replace('-', '').trim();
|
||||||
|
|
||||||
if (validFields.includes(field)) sortObj[field] = order;
|
if (validFields.includes(field)) sortObj[field] = order;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Object.keys(sortObj).length == 0) sortObj["createdAt"] = -1;
|
if (Object.keys(sortObj).length == 0) sortObj['createdAt'] = -1;
|
||||||
|
|
||||||
return sortObj;
|
return sortObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFilterObject(
|
export function getFilterObject(params: PageQueryParams) {
|
||||||
params: PageQueryParams,
|
if (params.filter && params.filter != '') {
|
||||||
validFields: Array<string>
|
return parse(params.filter.split(','));
|
||||||
) {
|
|
||||||
const filterObj: Array<{}> = [];
|
|
||||||
|
|
||||||
if (params.filter && params.filter != "") {
|
|
||||||
filterObj.push(...parse(params.filter, validFields));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return filterObj;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,11 +59,11 @@ export async function listPermits(params: PageQueryParams, tenantId: string) {
|
|||||||
const page = params.page || 1;
|
const page = params.page || 1;
|
||||||
const pageSize = params.pageSize || 10;
|
const pageSize = params.pageSize || 10;
|
||||||
const sortObj = getSortObject(params, permitFields);
|
const sortObj = getSortObject(params, permitFields);
|
||||||
const filterObj = getFilterObject(params, permitFields);
|
const filterObj = getFilterObject(params);
|
||||||
|
|
||||||
const permitsList = await permitModel.aggregate([
|
const permitsList = await permitModel.aggregate([
|
||||||
{
|
{
|
||||||
$match: { $and: [{ tenantId: tenantId }, ...filterObj] },
|
$match: { $and: [{ tenantId: tenantId }, { ...filterObj }] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
@@ -205,7 +205,7 @@ export async function searchPermit(params: PageQueryParams, tenantId: string) {
|
|||||||
const page = params.page || 1;
|
const page = params.page || 1;
|
||||||
const pageSize = params.pageSize || 10;
|
const pageSize = params.pageSize || 10;
|
||||||
const sortObj = getSortObject(params, permitFields);
|
const sortObj = getSortObject(params, permitFields);
|
||||||
const filterObj = getFilterObject(params, permitFields);
|
const filterObj = getFilterObject(params);
|
||||||
|
|
||||||
if (!params.searchToken)
|
if (!params.searchToken)
|
||||||
return { permits: [], metadata: { count: 0, page, pageSize } };
|
return { permits: [], metadata: { count: 0, page, pageSize } };
|
||||||
@@ -214,7 +214,7 @@ export async function searchPermit(params: PageQueryParams, tenantId: string) {
|
|||||||
|
|
||||||
const permitsList = await permitModel.aggregate([
|
const permitsList = await permitModel.aggregate([
|
||||||
{
|
{
|
||||||
$match: { $and: [{ tenantId: tenantId }, ...filterObj] },
|
$match: { $and: [{ tenantId: tenantId }, { ...filterObj }] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$match: {
|
$match: {
|
||||||
|
|||||||
@@ -40,11 +40,11 @@ export async function listProcessedPermits(
|
|||||||
const page = params.page || 1;
|
const page = params.page || 1;
|
||||||
const pageSize = params.pageSize || 10;
|
const pageSize = params.pageSize || 10;
|
||||||
const sortObj = getSortObject(params, processedFields);
|
const sortObj = getSortObject(params, processedFields);
|
||||||
const filterObj = getFilterObject(params, processedFields);
|
const filterObj = getFilterObject(params);
|
||||||
|
|
||||||
const pipeline: any = [
|
const pipeline: any = [
|
||||||
{
|
{
|
||||||
$match: { $and: [{ tenantId: tenantId }, ...filterObj] },
|
$match: { $and: [{ tenantId: tenantId }, { ...filterObj }] },
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ import {
|
|||||||
rtsModel,
|
rtsModel,
|
||||||
UpdateRtsInput,
|
UpdateRtsInput,
|
||||||
UploadRtsInput,
|
UploadRtsInput,
|
||||||
} from "./rts.schema";
|
} from './rts.schema';
|
||||||
import { AuthenticatedUser } from "../auth";
|
import { AuthenticatedUser } from '../auth';
|
||||||
import { generateId } from "../utils/id";
|
import { generateId } from '../utils/id';
|
||||||
import { getFilterObject, getSortObject, PageQueryParams } from "../pagination";
|
import { getFilterObject, getSortObject, PageQueryParams } from '../pagination';
|
||||||
import { getUser } from "../user/user.service";
|
import { getUser } from '../user/user.service';
|
||||||
import { orgModel } from "../organization/organization.schema";
|
import { orgModel } from '../organization/organization.schema';
|
||||||
import { userModel } from "../user/user.schema";
|
import { userModel } from '../user/user.schema';
|
||||||
|
|
||||||
export async function createRts(
|
export async function createRts(
|
||||||
input: CreateRtsInput,
|
input: CreateRtsInput,
|
||||||
@@ -53,43 +53,43 @@ export async function createRts(
|
|||||||
export async function getRts(id: string, tenantId: string) {
|
export async function getRts(id: string, tenantId: string) {
|
||||||
return await rtsModel
|
return await rtsModel
|
||||||
.findOne({ pid: id, tenantId: tenantId })
|
.findOne({ pid: id, tenantId: tenantId })
|
||||||
.populate({ path: "county", select: "pid name avatar" })
|
.populate({ path: 'county', select: 'pid name avatar' })
|
||||||
.populate({ path: "client", select: "pid name avatar" })
|
.populate({ path: 'client', select: 'pid name avatar' })
|
||||||
.populate({ path: "createdBy", select: "pid name avatar" });
|
.populate({ path: 'createdBy', select: 'pid name avatar' });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function listRts(params: PageQueryParams, tenantId: string) {
|
export async function listRts(params: PageQueryParams, tenantId: string) {
|
||||||
const page = params.page || 1;
|
const page = params.page || 1;
|
||||||
const pageSize = params.pageSize || 10;
|
const pageSize = params.pageSize || 10;
|
||||||
const sortObj = getSortObject(params, rtsFields);
|
const sortObj = getSortObject(params, rtsFields);
|
||||||
const filterObj = getFilterObject(params, rtsFields);
|
const filterObj = getFilterObject(params);
|
||||||
|
|
||||||
const rtsList = await rtsModel.aggregate([
|
const rtsList = await rtsModel.aggregate([
|
||||||
{
|
{
|
||||||
$match: { $and: [{ tenantId: tenantId }, ...filterObj] },
|
$match: { $and: [{ tenantId: tenantId }, { ...filterObj }] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "organizations",
|
from: 'organizations',
|
||||||
localField: "county",
|
localField: 'county',
|
||||||
foreignField: "_id",
|
foreignField: '_id',
|
||||||
as: "countyRec",
|
as: 'countyRec',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "organizations",
|
from: 'organizations',
|
||||||
localField: "client",
|
localField: 'client',
|
||||||
foreignField: "_id",
|
foreignField: '_id',
|
||||||
as: "clientRec",
|
as: 'clientRec',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "users",
|
from: 'users',
|
||||||
localField: "createdBy",
|
localField: 'createdBy',
|
||||||
foreignField: "_id",
|
foreignField: '_id',
|
||||||
as: "createdRec",
|
as: 'createdRec',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -101,36 +101,36 @@ export async function listRts(params: PageQueryParams, tenantId: string) {
|
|||||||
createdAt: 1,
|
createdAt: 1,
|
||||||
county: {
|
county: {
|
||||||
$let: {
|
$let: {
|
||||||
vars: { county: { $arrayElemAt: ["$countyRec", 0] } },
|
vars: { county: { $arrayElemAt: ['$countyRec', 0] } },
|
||||||
in: {
|
in: {
|
||||||
_id: "$$county._id",
|
_id: '$$county._id',
|
||||||
pid: "$$county.pid",
|
pid: '$$county.pid',
|
||||||
name: "$$county.name",
|
name: '$$county.name',
|
||||||
type: "$$county.type",
|
type: '$$county.type',
|
||||||
avatar: "$$county.avatar",
|
avatar: '$$county.avatar',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
client: {
|
client: {
|
||||||
$let: {
|
$let: {
|
||||||
vars: { client: { $arrayElemAt: ["$clientRec", 0] } },
|
vars: { client: { $arrayElemAt: ['$clientRec', 0] } },
|
||||||
in: {
|
in: {
|
||||||
_id: "$$client._id",
|
_id: '$$client._id',
|
||||||
pid: "$$client.pid",
|
pid: '$$client.pid',
|
||||||
name: "$$client.name",
|
name: '$$client.name',
|
||||||
type: "$$client.type",
|
type: '$$client.type',
|
||||||
avatar: "$$client.avatar",
|
avatar: '$$client.avatar',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
createdBy: {
|
createdBy: {
|
||||||
$let: {
|
$let: {
|
||||||
vars: { created: { $arrayElemAt: ["$createdRec", 0] } },
|
vars: { created: { $arrayElemAt: ['$createdRec', 0] } },
|
||||||
in: {
|
in: {
|
||||||
_id: "$$created._id",
|
_id: '$$created._id',
|
||||||
pid: "$$created.pid",
|
pid: '$$created.pid',
|
||||||
name: "$$created.name",
|
name: '$$created.name',
|
||||||
avatar: "$$created.avatar",
|
avatar: '$$created.avatar',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -138,7 +138,7 @@ export async function listRts(params: PageQueryParams, tenantId: string) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
$facet: {
|
$facet: {
|
||||||
metadata: [{ $count: "count" }],
|
metadata: [{ $count: 'count' }],
|
||||||
data: [
|
data: [
|
||||||
{ $sort: sortObj },
|
{ $sort: sortObj },
|
||||||
{ $skip: (page - 1) * pageSize },
|
{ $skip: (page - 1) * pageSize },
|
||||||
@@ -168,9 +168,9 @@ export async function updateRts(
|
|||||||
) {
|
) {
|
||||||
const updatedRts = await rtsModel
|
const updatedRts = await rtsModel
|
||||||
.findOneAndUpdate({ pid: id, tenantId: tenantId }, input, { new: true })
|
.findOneAndUpdate({ pid: id, tenantId: tenantId }, input, { new: true })
|
||||||
.populate({ path: "createdBy", select: "pid name avatar" })
|
.populate({ path: 'createdBy', select: 'pid name avatar' })
|
||||||
.populate({ path: "county", select: "pid name avatar" })
|
.populate({ path: 'county', select: 'pid name avatar' })
|
||||||
.populate({ path: "client", select: "pid name avatar" });
|
.populate({ path: 'client', select: 'pid name avatar' });
|
||||||
|
|
||||||
return updatedRts;
|
return updatedRts;
|
||||||
}
|
}
|
||||||
@@ -202,12 +202,12 @@ export async function getUniqueValuesRTS(field: string, tenenatId: string) {
|
|||||||
let values = await rtsModel.distinct(field, { tenantId: tenenatId });
|
let values = await rtsModel.distinct(field, { tenantId: tenenatId });
|
||||||
|
|
||||||
let matchedValues = [];
|
let matchedValues = [];
|
||||||
if (field === "county") {
|
if (field === 'county') {
|
||||||
matchedValues = await orgModel.find().where("_id").in(values).exec();
|
matchedValues = await orgModel.find().where('_id').in(values).exec();
|
||||||
} else if (field === "client") {
|
} else if (field === 'client') {
|
||||||
matchedValues = await orgModel.find().where("_id").in(values).exec();
|
matchedValues = await orgModel.find().where('_id').in(values).exec();
|
||||||
} else if (field === "createdBy") {
|
} else if (field === 'createdBy') {
|
||||||
matchedValues = await userModel.find().where("_id").in(values).exec();
|
matchedValues = await userModel.find().where('_id').in(values).exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matchedValues.length > 0) {
|
if (matchedValues.length > 0) {
|
||||||
|
|||||||
@@ -59,11 +59,11 @@ export async function listTasks(params: PageQueryParams, tenantId: string) {
|
|||||||
const page = params.page || 1;
|
const page = params.page || 1;
|
||||||
const pageSize = params.pageSize || 10;
|
const pageSize = params.pageSize || 10;
|
||||||
const sortObj = getSortObject(params, taskFields);
|
const sortObj = getSortObject(params, taskFields);
|
||||||
const filterObj = getFilterObject(params, taskFields);
|
const filterObj = getFilterObject(params);
|
||||||
|
|
||||||
const taskList = await taskModel.aggregate([
|
const taskList = await taskModel.aggregate([
|
||||||
{
|
{
|
||||||
$match: { $and: [{ tenantId: tenantId }, ...filterObj] },
|
$match: { $and: [{ tenantId: tenantId }, { ...filterObj }] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
@@ -145,13 +145,13 @@ export async function searchTasks(params: PageQueryParams, tenantId: string) {
|
|||||||
const page = params.page || 1;
|
const page = params.page || 1;
|
||||||
const pageSize = params.pageSize || 10;
|
const pageSize = params.pageSize || 10;
|
||||||
const sortObj = getSortObject(params, taskFields);
|
const sortObj = getSortObject(params, taskFields);
|
||||||
const filterObj = getFilterObject(params, taskFields);
|
const filterObj = getFilterObject(params);
|
||||||
|
|
||||||
const regex = new RegExp(params.searchToken, 'i');
|
const regex = new RegExp(params.searchToken, 'i');
|
||||||
|
|
||||||
const taskList = await taskModel.aggregate([
|
const taskList = await taskModel.aggregate([
|
||||||
{
|
{
|
||||||
$match: { $and: [{ tenantId: tenantId }, ...filterObj] },
|
$match: { $and: [{ tenantId: tenantId }, { ...filterObj }] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$match: {
|
$match: {
|
||||||
|
|||||||
@@ -1,111 +1,67 @@
|
|||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
|
|
||||||
type ParsedQuery = Array<
|
type MongoFilter = Record<string, any>;
|
||||||
Record<string, Record<'$eq' | '$ne' | '$in' | '$nin', string | Date | Object>>
|
|
||||||
>;
|
|
||||||
|
|
||||||
function convertValue(value: any) {
|
function formulaToMongoFilter(formula: string): MongoFilter {
|
||||||
if (mongoose.Types.ObjectId.isValid(value)) {
|
// Split the formula into parts
|
||||||
return mongoose.Types.ObjectId.createFromHexString(value);
|
const operatorMatch = formula.match(/([^!<>=]+)([!<>=]+)(.+)/);
|
||||||
|
|
||||||
|
if (!operatorMatch) {
|
||||||
|
throw new Error(`Invalid formula format: ${formula}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const [, field, operator, value] = operatorMatch;
|
||||||
|
const trimmedField = field.trim();
|
||||||
|
const trimmedValue = value.trim();
|
||||||
|
|
||||||
|
if (trimmedField === 'tenantId') return {};
|
||||||
|
|
||||||
|
// Convert value to appropriate type (date or number if possible)
|
||||||
|
let parsedValue: any = trimmedValue;
|
||||||
|
|
||||||
|
if (/^\d{4}-\d{2}-\d{2}$/.test(trimmedValue)) {
|
||||||
|
// Check if it's a date (ISO format)
|
||||||
|
parsedValue = new Date(trimmedValue);
|
||||||
|
} else if (!isNaN(Number(trimmedValue))) {
|
||||||
|
// Check if it's a number
|
||||||
|
parsedValue = Number(trimmedValue);
|
||||||
} else if (
|
} else if (
|
||||||
!isNaN(parseInt(value)) &&
|
typeof parsedValue === 'string' &&
|
||||||
parseInt(value).toString().length == value.toString().length
|
mongoose.Types.ObjectId.isValid(parsedValue)
|
||||||
) {
|
) {
|
||||||
return parseInt(value);
|
parsedValue = new mongoose.Types.ObjectId(parsedValue);
|
||||||
} else if (!isNaN(Date.parse(value))) {
|
} else if (parsedValue === 'true') {
|
||||||
return new Date(value);
|
parsedValue = true;
|
||||||
} else if (value === 'true') {
|
} else if (parsedValue === 'false') {
|
||||||
return true;
|
parsedValue = false;
|
||||||
} else if (value === 'false') {
|
} else if (parsedValue === 'null') {
|
||||||
return false;
|
parsedValue = null;
|
||||||
} else {
|
}
|
||||||
return value;
|
|
||||||
|
// Convert operator to MongoDB operator
|
||||||
|
switch (operator) {
|
||||||
|
case '=':
|
||||||
|
return { [trimmedField]: { $eq: parsedValue } };
|
||||||
|
case '!=':
|
||||||
|
return { [trimmedField]: { $ne: parsedValue } };
|
||||||
|
case '>':
|
||||||
|
return { [trimmedField]: { $gt: parsedValue } };
|
||||||
|
case '<':
|
||||||
|
return { [trimmedField]: { $lt: parsedValue } };
|
||||||
|
case '>=':
|
||||||
|
return { [trimmedField]: { $gte: parsedValue } };
|
||||||
|
case '<=':
|
||||||
|
return { [trimmedField]: { $lte: parsedValue } };
|
||||||
|
default:
|
||||||
|
throw new Error(`Unsupported operator: ${operator}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parse(query: string, validFields: Array<string>): ParsedQuery {
|
export function parse(formulas: string[]): MongoFilter {
|
||||||
const result = [];
|
const parsedQuery: MongoFilter = formulas.reduce((filter, formula) => {
|
||||||
|
const newFilter = formulaToMongoFilter(formula);
|
||||||
|
return { ...filter, ...newFilter };
|
||||||
|
}, {});
|
||||||
|
|
||||||
let currentStage = 'field';
|
return parsedQuery;
|
||||||
let token = '';
|
|
||||||
let field = '';
|
|
||||||
let op = '';
|
|
||||||
let value = '';
|
|
||||||
let valueArr = [];
|
|
||||||
for (let i = 0; i < query.length; i++) {
|
|
||||||
let char = query[i];
|
|
||||||
|
|
||||||
if (currentStage === 'field') {
|
|
||||||
if (char === '=' || char === '!') {
|
|
||||||
field = token;
|
|
||||||
token = '';
|
|
||||||
currentStage = 'value';
|
|
||||||
|
|
||||||
if (char === '=') {
|
|
||||||
op = '$eq';
|
|
||||||
} else {
|
|
||||||
op = '$ne';
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
token += char;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentStage === 'value') {
|
|
||||||
if (char === '[') {
|
|
||||||
currentStage = 'valueArr';
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (char === ',' || i == query.length - 1) {
|
|
||||||
if (i == query.length - 1) token += char;
|
|
||||||
|
|
||||||
value = token;
|
|
||||||
result.push({ [field]: { [op]: convertValue(value) } });
|
|
||||||
|
|
||||||
token = '';
|
|
||||||
field = '';
|
|
||||||
op = '';
|
|
||||||
|
|
||||||
currentStage = 'field';
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
token += char;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentStage === 'valueArr') {
|
|
||||||
if (char === ',') {
|
|
||||||
valueArr.push(convertValue(token));
|
|
||||||
token = '';
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (char === ']') {
|
|
||||||
valueArr.push(convertValue(token));
|
|
||||||
result.push({
|
|
||||||
[field]: { [op === '$eq' ? '$in' : '$nin']: valueArr },
|
|
||||||
});
|
|
||||||
|
|
||||||
token = '';
|
|
||||||
field = '';
|
|
||||||
op = '';
|
|
||||||
valueArr = [];
|
|
||||||
|
|
||||||
currentStage = 'field';
|
|
||||||
i++;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
token += char;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(result);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,13 +33,13 @@ export async function listViews(
|
|||||||
const page = params.page || 1;
|
const page = params.page || 1;
|
||||||
const pageSize = params.pageSize || 10;
|
const pageSize = params.pageSize || 10;
|
||||||
const sortObj = getSortObject(params, viewFields);
|
const sortObj = getSortObject(params, viewFields);
|
||||||
const filterObj = getFilterObject(params, viewFields);
|
const filterObj = getFilterObject(params);
|
||||||
|
|
||||||
return await viewModel.find({
|
return await viewModel.find({
|
||||||
$and: [
|
$and: [
|
||||||
{ tenantId: user.tenantId },
|
{ tenantId: user.tenantId },
|
||||||
{ createdBy: user.userId },
|
{ createdBy: user.userId },
|
||||||
...filterObj,
|
{ ...filterObj },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user