mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-04 04:26:11 +00:00
feat: build strict find filter
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
import { Knex } from "knex";
|
import { Knex } from "knex";
|
||||||
import { Tables } from "knex/types/tables";
|
import { Tables } from "knex/types/tables";
|
||||||
|
|
||||||
|
import { TableName } from "@app/db/schemas";
|
||||||
|
|
||||||
import { DatabaseError } from "../errors";
|
import { DatabaseError } from "../errors";
|
||||||
import { buildDynamicKnexQuery, TKnexDynamicOperator } from "./dynamic";
|
import { buildDynamicKnexQuery, TKnexDynamicOperator } from "./dynamic";
|
||||||
|
|
||||||
@@ -25,6 +27,51 @@ export type TFindFilter<R extends object = object> = Partial<R> & {
|
|||||||
$search?: Partial<{ [k in keyof R]: R[k] }>;
|
$search?: Partial<{ [k in keyof R]: R[k] }>;
|
||||||
$complex?: TKnexDynamicOperator<R>;
|
$complex?: TKnexDynamicOperator<R>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const buildStrictFindFilter =
|
||||||
|
<R extends object = object>(
|
||||||
|
{ $in, $notNull, $search, $complex, ...filter }: TFindFilter<R>,
|
||||||
|
tableName: TableName,
|
||||||
|
excludeKeys?: Array<keyof R>
|
||||||
|
) =>
|
||||||
|
(bd: Knex.QueryBuilder<R, R>) => {
|
||||||
|
const strictFilter = Object.fromEntries(
|
||||||
|
Object.entries(filter)
|
||||||
|
.filter(([key]) => !excludeKeys || !excludeKeys.includes(key as keyof R))
|
||||||
|
.map(([key, value]) => [`${tableName}.${key}`, value])
|
||||||
|
);
|
||||||
|
|
||||||
|
void bd.where(strictFilter);
|
||||||
|
if ($in) {
|
||||||
|
Object.entries($in).forEach(([key, val]) => {
|
||||||
|
if (val) {
|
||||||
|
void bd.whereIn([`${tableName}.${key}`] as never, val as never);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($notNull?.length) {
|
||||||
|
$notNull.forEach((key) => {
|
||||||
|
void bd.whereNotNull([`${tableName}.${key as string}`] as never);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($search) {
|
||||||
|
Object.entries($search).forEach(([key, val]) => {
|
||||||
|
if (val) {
|
||||||
|
void bd.whereILike([`${tableName}.${key}`] as never, val as never);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if ($complex) {
|
||||||
|
return buildDynamicKnexQuery(bd, $complex);
|
||||||
|
}
|
||||||
|
return bd;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use `buildStrictFindFilter` instead
|
||||||
|
*/
|
||||||
export const buildFindFilter =
|
export const buildFindFilter =
|
||||||
<R extends object = object>({ $in, $notNull, $search, $complex, ...filter }: TFindFilter<R>) =>
|
<R extends object = object>({ $in, $notNull, $search, $complex, ...filter }: TFindFilter<R>) =>
|
||||||
(bd: Knex.QueryBuilder<R, R>) => {
|
(bd: Knex.QueryBuilder<R, R>) => {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { generateCacheKeyFromData } from "@app/lib/crypto/cache";
|
|||||||
import { BadRequestError, DatabaseError, NotFoundError } from "@app/lib/errors";
|
import { BadRequestError, DatabaseError, NotFoundError } from "@app/lib/errors";
|
||||||
import {
|
import {
|
||||||
buildFindFilter,
|
buildFindFilter,
|
||||||
|
buildStrictFindFilter,
|
||||||
ormify,
|
ormify,
|
||||||
selectAllTableCols,
|
selectAllTableCols,
|
||||||
sqlNestRelationships,
|
sqlNestRelationships,
|
||||||
@@ -63,7 +64,8 @@ export const secretV2BridgeDALFactory = ({ db, keyStore }: TSecretV2DalArg) => {
|
|||||||
const findOne = async (filter: Partial<TSecretsV2>, tx?: Knex) => {
|
const findOne = async (filter: Partial<TSecretsV2>, tx?: Knex) => {
|
||||||
try {
|
try {
|
||||||
const docs = await (tx || db)(TableName.SecretV2)
|
const docs = await (tx || db)(TableName.SecretV2)
|
||||||
.where(filter)
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||||
|
.where(buildStrictFindFilter(filter, TableName.SecretV2))
|
||||||
.leftJoin(
|
.leftJoin(
|
||||||
TableName.SecretV2JnTag,
|
TableName.SecretV2JnTag,
|
||||||
`${TableName.SecretV2}.id`,
|
`${TableName.SecretV2}.id`,
|
||||||
@@ -142,9 +144,14 @@ export const secretV2BridgeDALFactory = ({ db, keyStore }: TSecretV2DalArg) => {
|
|||||||
const find = async (filter: TFindFilter<TSecretsV2>, opts: TFindOpt<TSecretsV2> = {}) => {
|
const find = async (filter: TFindFilter<TSecretsV2>, opts: TFindOpt<TSecretsV2> = {}) => {
|
||||||
const { offset, limit, sort, tx } = opts;
|
const { offset, limit, sort, tx } = opts;
|
||||||
try {
|
try {
|
||||||
|
const qualifiedFilter = { ...filter };
|
||||||
|
if ("userId" in qualifiedFilter) {
|
||||||
|
delete qualifiedFilter.userId;
|
||||||
|
}
|
||||||
|
|
||||||
const query = (tx || db)(TableName.SecretV2)
|
const query = (tx || db)(TableName.SecretV2)
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||||
.where(buildFindFilter(filter))
|
.where(buildFindFilter(qualifiedFilter))
|
||||||
.leftJoin(
|
.leftJoin(
|
||||||
TableName.SecretV2JnTag,
|
TableName.SecretV2JnTag,
|
||||||
`${TableName.SecretV2}.id`,
|
`${TableName.SecretV2}.id`,
|
||||||
|
|||||||
Reference in New Issue
Block a user