mirror of https://github.com/buster-so/buster.git
array parter
This commit is contained in:
parent
5dc31814d8
commit
0d01dfcb4c
|
@ -14,6 +14,8 @@ const app = new Hono().get(
|
|||
const { id: userId } = c.get('busterUser');
|
||||
const options = c.req.valid('query');
|
||||
|
||||
console.log(options);
|
||||
|
||||
try {
|
||||
const result: GetUserToOrganizationResponse = await getUserToOrganization({
|
||||
userId,
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
import { type InferSelectModel, and, asc, count, eq, isNull, like } from 'drizzle-orm';
|
||||
import { type InferSelectModel, and, asc, count, eq, inArray, isNull, like } from 'drizzle-orm';
|
||||
import { createSelectSchema } from 'drizzle-zod';
|
||||
import { z } from 'zod';
|
||||
import { db } from '../../connection';
|
||||
import { users, usersToOrganizations } from '../../schema';
|
||||
import {
|
||||
userOrganizationRoleEnum,
|
||||
userOrganizationStatusEnum,
|
||||
users,
|
||||
usersToOrganizations,
|
||||
} from '../../schema';
|
||||
import { getUserOrganizationId } from '../organizations/organizations';
|
||||
import { type PaginatedResponse, createPaginatedResponse } from '../shared-types';
|
||||
import { withPagination } from '../shared-types/with-pagination';
|
||||
|
@ -17,6 +23,8 @@ const GetUserToOrganizationInputSchema = z.object({
|
|||
page_size: z.number().optional().default(250),
|
||||
user_name: z.string().optional(),
|
||||
email: z.string().optional(),
|
||||
role: z.array(z.enum(userOrganizationRoleEnum.enumValues)).optional(),
|
||||
status: z.array(z.enum(userOrganizationStatusEnum.enumValues)).optional(),
|
||||
});
|
||||
|
||||
type GetUserToOrganizationInput = z.infer<typeof GetUserToOrganizationInputSchema>;
|
||||
|
@ -33,7 +41,7 @@ export const getUserToOrganization = async (
|
|||
params: GetUserToOrganizationInput
|
||||
): Promise<PaginatedResponse<OrganizationUser>> => {
|
||||
// Validate and destructure input
|
||||
const { userId, page, page_size, user_name, email } =
|
||||
const { userId, page, page_size, user_name, email, role, status } =
|
||||
GetUserToOrganizationInputSchema.parse(params);
|
||||
|
||||
// Get the user's organization ID
|
||||
|
@ -49,7 +57,9 @@ export const getUserToOrganization = async (
|
|||
eq(usersToOrganizations.organizationId, organizationId),
|
||||
isNull(usersToOrganizations.deletedAt),
|
||||
user_name ? like(users.name, `%${user_name}%`) : undefined,
|
||||
email ? like(users.email, `%${email}%`) : undefined
|
||||
email ? like(users.email, `%${email}%`) : undefined,
|
||||
role ? inArray(usersToOrganizations.role, role) : undefined,
|
||||
status ? inArray(usersToOrganizations.status, status) : undefined
|
||||
);
|
||||
|
||||
const getData = withPagination(
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
export * from './isEqual';
|
||||
export * from './pagination';
|
||||
export * from './query-array-preprocessor';
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
import { z } from 'zod';
|
||||
|
||||
/**
|
||||
* Creates a preprocessor that converts query parameter strings into arrays.
|
||||
* Handles various input formats:
|
||||
* - Single value: "admin" → ["admin"]
|
||||
* - Comma-separated: "admin,member" → ["admin", "member"]
|
||||
* - Already an array: ["admin", "member"] → ["admin", "member"]
|
||||
* - No value: undefined → undefined
|
||||
*/
|
||||
export const createQueryArrayPreprocessor = <T>(schema: z.ZodArray<z.ZodType<T>>) => {
|
||||
return z.preprocess((val) => {
|
||||
// Handle no value
|
||||
if (!val) return undefined;
|
||||
|
||||
// Already an array, pass through
|
||||
if (Array.isArray(val)) return val;
|
||||
|
||||
// Handle string input (single or comma-separated)
|
||||
if (typeof val === 'string') {
|
||||
return val
|
||||
.split(',')
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
// Single value case (wrap in array)
|
||||
return [val];
|
||||
}, schema);
|
||||
};
|
||||
|
||||
/**
|
||||
* Type-safe helper for creating optional query array preprocessors
|
||||
*/
|
||||
export const createOptionalQueryArrayPreprocessor = <T>(itemSchema: z.ZodType<T>) => {
|
||||
return z.preprocess((val) => {
|
||||
// Handle no value
|
||||
if (!val) return undefined;
|
||||
|
||||
// Already an array, pass through
|
||||
if (Array.isArray(val)) return val;
|
||||
|
||||
// Handle string input (single or comma-separated)
|
||||
if (typeof val === 'string') {
|
||||
return val
|
||||
.split(',')
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
// Single value case (wrap in array)
|
||||
return [val];
|
||||
}, z.array(itemSchema).optional());
|
||||
};
|
|
@ -1,6 +1,8 @@
|
|||
import { z } from 'zod';
|
||||
import { OrganizationStatusSchema } from '../organization';
|
||||
import { OrganizationRoleSchema } from '../organization/roles.types';
|
||||
import { ShareAssetTypeSchema } from '../share';
|
||||
import { createOptionalQueryArrayPreprocessor } from '../type-utilities';
|
||||
|
||||
export const UserRequestSchema = z.object({
|
||||
user_id: z.string(),
|
||||
|
@ -50,9 +52,13 @@ export type GetUserListRequest = z.infer<typeof GetUserListRequestSchema>;
|
|||
|
||||
export const GetUserToOrganizationRequestSchema = z.object({
|
||||
page: z.coerce.number().min(1).optional().default(1),
|
||||
page_size: z.coerce.number().min(1).max(5000).optional().default(250),
|
||||
page_size: z.coerce.number().min(1).max(5000).optional().default(25),
|
||||
user_name: z.string().optional(),
|
||||
email: z.string().optional(),
|
||||
//We need this because the frontend sends the roles as a comma-separated string in the query params
|
||||
role: createOptionalQueryArrayPreprocessor(OrganizationRoleSchema),
|
||||
//We need this because the frontend sends the status as a comma-separated string in the query params
|
||||
status: createOptionalQueryArrayPreprocessor(OrganizationStatusSchema),
|
||||
});
|
||||
|
||||
export type GetUserToOrganizationRequest = z.infer<typeof GetUserToOrganizationRequestSchema>;
|
||||
|
|
Loading…
Reference in New Issue