UNPKG

mantiqh-query-converter

Version:

query string maker with object and array

700 lines (636 loc) 14.4 kB
import qs from 'qs' export function toQS( obj: Record<string, any>, prefix = '', options = { arrayFormat: 'brackets' }, ): string { if (!obj || typeof obj !== 'object') return '' return Object.keys(obj) .filter((key) => !['__proto__', 'constructor', 'prototype'].includes(key)) .map((key) => { const value = obj[key] const fullKey = prefix ? `${prefix}[${key}]` : key if ( typeof value === 'object' && value !== null && !Array.isArray(value) ) { return toQS(value, fullKey, options) } else if (Array.isArray(value)) { if (options.arrayFormat === 'brackets') { return value .map( (val) => `${encodeURIComponent(fullKey)}[]=${encodeURIComponent(val)}`, ) .join('&') } else if (options.arrayFormat === 'comma') { return `${encodeURIComponent(fullKey)}=${value.map(encodeURIComponent).join(',')}` } else if (options.arrayFormat === 'indices') { return value .map( (val, index) => `${encodeURIComponent(fullKey)}[${index}]=${encodeURIComponent(val)}`, ) .join('&') } else { return value .map( (val) => `${encodeURIComponent(fullKey)}=${encodeURIComponent(val)}`, ) .join('&') } } else { return `${encodeURIComponent(fullKey)}=${encodeURIComponent(value)}` } }) .filter(Boolean) .join('&') } function getDealerStatusFilter(status: string) { const now = new Date() const nowISO = now.toISOString().split('T')[0] // YYYY-MM-DD const plus5 = new Date(now.getTime() + 5 * 24 * 60 * 60 * 1000) const plus5ISO = plus5.toISOString().split('T')[0] switch (status) { case 'new': return { dealer_subscriptions: { id: { $null: true } } } case 'active': case 'trialing': return { dealer_subscriptions: { sub_status: { $eq: status } } } case 'expiring_soon': return { dealer_subscriptions: { next_billing_date: { $gte: nowISO, $lte: plus5ISO }, }, } case 'expired': return { dealer_subscriptions: { next_billing_date: { $lt: nowISO } } } default: return {} } } // Modified async query functions (no need to await `toQS`) export function getLeadsQuery({ page, pageSize, sort = [], dealerId, search, isOpen, }: { page: number pageSize: number sort?: string[] dealerId?: number search?: string isOpen?: boolean }) { const filters: Record<string, any> = {} if (dealerId) { filters.dealer_admin = { id: { $eq: dealerId, }, } } if (search && search.trim()) { filters.rb_user = { name: { $containsi: search.trim() } } } filters.is_open = { $eq: true } if (typeof isOpen === 'boolean') { filters.is_open = { $eq: isOpen } } const data = { fields: ['lead_status', 'createdAt', 'is_open'], populate: { rb_user: { fields: ['name', 'phone', 'email'], }, product: { fields: ['name', 'is_featured', 'is_exclusive', 'admin_managed'], }, dealer_admin: { fields: ['name'], }, market_places: { fields: ['name'], }, }, filters, sort, pagination: { page, pageSize, }, } return toQS(data) } export function getDealersQuery( page: number, pageSize: number, sort: string[] = [], status?: string[] | [], userId?: number | null | undefined, search?: string | null | undefined, ) { const filters: Record<string, any> = {} if (status && status.length) { filters.$or = [] for (let i = 0; i < status.length; i++) { const data = getDealerStatusFilter(status[i]) console.log(data) if (data && Object.keys(data).length > 0) { filters.$or.push(data) } } if (filters.$or.length === 0) { delete filters.$or } } if (userId) { filters.user = { id: { $eq: userId, }, } } if (search && search.trim()) { filters.name = { $containsi: search.trim() } // Case-insensitive contains } console.log(JSON.stringify(filters)) const data = { fields: [ 'company_name', 'name', 'dealers_logo', 'street_address', 'mobile', 'email', 'stripe_customer_id', 'onboarded', ], populate: { dealer_subscriptions: { fields: ['sub_status', 'trial_end_date', 'next_billing_date'], }, }, sort, pagination: { page, pageSize, }, filters: filters, } return qs.stringify(data, { encodeValuesOnly: true }) } export function getNavbarQuery({ metalType, productType, }: { metalType: string productType?: string }) { const filters: Record<string, any> = {} if (typeof metalType === 'string') { filters.metal = { $eq: metalType } } if (typeof productType === 'string') { filters.product_type = { $eq: productType } } const data = { fields: ['id', 'document_id', 'name', 'metal'], populate: { dealer_admin: { fields: ['company_name', 'name'], }, product_images: { fields: ['url'], }, pricing: { fields: ['*'], }, comparisons: { fields: ['*'], populate: { product_images: { fields: ['*'], }, }, }, }, filters, sort: ['id:desc'], isNavbarOnly: true, pagination: { page: 1, pageSize: 6, }, } return toQS(data) } // ["is_active:desc"] export function getProductsQuery( page: number, pageSize: number, sort: string[] = [], isFeatured?: boolean | null, isExclusive?: boolean | null, adminManaged?: boolean | null, search?: string | null, dealerAdminId?: number | null, isActive?: boolean | null, productType?: string | null, ) { const filters: Record<string, any> = {} if (typeof isActive === 'boolean') { filters.is_active = { $eq: isActive } } if (typeof dealerAdminId === 'number') { filters.dealer_admin = { id: { $eq: dealerAdminId } } } if (typeof isFeatured === 'boolean') { filters.is_featured = { $eq: isFeatured } } if (typeof isExclusive === 'boolean') { filters.is_exclusive = { $eq: isExclusive } } if (typeof adminManaged === 'boolean') { filters.admin_managed = { $eq: adminManaged } } if (typeof productType === 'string') { filters.product_type = { $eq: productType } } if (search && search.trim()) { filters.name = { $containsi: search.trim() } } const data = { fields: [ 'id', 'document_id', 'name', 'views', 'is_active', 'metal', 'product_type', 'weight', 'is_active', 'unit', 'is_melt_price', 'is_featured', 'is_exclusive', 'admin_managed', 'mint_year', 'description', 'is_ira_approved', 'coin_tag', ], populate: { dealer_admin: { fields: ['company_name', 'name'], populate: { plans: { fields: ['plan_name', 'featured_fee'], }, }, }, product_images: { fields: ['url'], }, pricing: { fields: ['*'], }, comparisons: { fields: ['*'], populate: { product_images: { // Explicitly include product_images relation fields: ['*'], // Get all fields of product_images }, }, }, }, filters, sort, pagination: { page, pageSize, }, } return toQS(data) } // 'dealer_admin.company_name:desc', // 'is_active:desc', // 'is_featured:desc', // 'is_exclusive:desc', // 'admin_managed:desc', export function getFrontendProductsQuery( page: number, pageSize: number, sort: string[] = ['name:desc'], isFeatured?: boolean | null | undefined, ) { // Base filters - always include is_active const filters: Record<string, any> = { is_active: { $eq: true }, } // Only add is_featured filter if it's explicitly true or false if (typeof isFeatured === 'boolean') { filters.is_featured = { $eq: isFeatured } } const data = { fields: [ 'name', 'views', 'is_active', 'metal', 'product_type', 'weight', 'is_active', 'unit', 'is_melt_price', 'is_featured', 'is_exclusive', 'coin_tag', ], filters, populate: { dealer_admin: { fields: ['company_name', 'name', 'document_id', 'id'], }, pricing: { fields: ['*'], }, }, sort, pagination: { page, pageSize, }, } return toQS(data) } /** * get single products * populate with dealer admin * and pricing data */ export function getSingleProduct() { const data = { fields: [ 'name', 'views', 'is_active', 'metal', 'product_type', 'weight', 'is_active', 'unit', 'is_melt_price', 'is_featured', 'is_exclusive', 'coin_tag', ], populate: { dealer_admin: { fields: ['company_name', 'name', 'document_id', 'id'], }, pricing: { fields: ['*'], }, comparisons: { fields: ['*'], populate: { product_images: { // Explicitly include product_images relation fields: ['*'], // Get all fields of product_images }, }, }, product_images: { fields: ['*'], }, }, } return toQS(data) } export function getPaymentsQuery( page: number, pageSize: number, sort: string[] = [], search?: string | null, Status?: string | null, ) { const filters: Record<string, any> = {} if (typeof Status === 'string') { filters.invoice_status = { $eq: Status } } if (search && search.trim()) { filters.dealer_admin = { company_name: { $containsi: search.trim() } } } const data = { fields: ['invoice_id', 'createdAt', 'invoice_status'], populate: { dealer_admin: { fields: ['company_name'], populate: { dealer_subscriptions: { fields: ['price', 'next_billing_date'], }, }, }, }, filters, sort, pagination: { page, pageSize, }, } return toQS(data) } export function getCartDetails({ page, pageSize, userId, }: { page: number pageSize: number userId: number }) { const filters: Record<string, any> = {} if (typeof userId === 'number') { filters.rb_user = { id: { $eq: userId } } } const data = { fields: ['quantity'], populate: { product: { fields: ['name', 'description', 'mint_year', 'unit', 'weight', 'metal'], populate: { product_images: { fields: ['url', 'name'], }, dealer_admin: { fields: ['name', 'mobile', 'email'], }, pricing: { fields: ['price_type', 'price', 'adder', 'multiplier', 'max'], }, }, }, }, filters, pagination: { page, pageSize, }, } return toQS(data) } export function getDealerAdminWithPlan() { const data = { fields: ['*'], populate: { plans: { fields: ['*'], }, }, } return toQS(data) } export function getPaymentDetails({ page, pageSize, sort = [], search, dealerId, status, searchByDealer, }: { page: number pageSize: number sort?: string[] search?: string dealerId?: number status?: string searchByDealer?: boolean }) { const filters: Record<string, any> = {} if (search && search.trim()) { if (searchByDealer) { filters.dealer_admin = filters.dealer_admin || {} filters.dealer_admin.name = { $containsi: search.trim() } } else { filters.invoice_id = { $containsi: search.trim() } } } if (status && typeof status === 'string') { filters.invoice_status = { $eq: status } } if (dealerId) { filters.dealer_admin = filters.dealer_admin || {} filters.dealer_admin.id = { $eq: dealerId } } const data = { fields: ['*'], populate: { dealer_admin: { fields: ['*'], populate: { dealer_subscriptions: { fields: ['*'], }, }, }, }, sort, filters, pagination: { page, pageSize, }, } return toQS(data) } export function getDealeradminCoin(page: number, pageSize: number) { const data = { fields: ['id', 'documentId', 'name', 'company_name'], pagination: { page, pageSize, }, } return toQS(data) } const queries = [ // { // name: 'LEADS', // query: getLeadsQuery({ // page: 1, // pageSize: 10, // sort: [], // dealerId: 13, // }), // }, // { // name: 'DEALERS', // query: getDealersQuery(1, 10, [], ['new', 'trialing'], null), // }, // { // name: 'GET-CART', // query: getCartDetails({ page: 1, pageSize: 10, userId: 4 }), // }, // { // name: 'navebar-query', // query: getNavbarQuery({ metalType: 'gold', productType: 'coin' }), // }, // { // name: 'GET-DEALER-WITH-PLAN', // query: getDealerAdminWithPlan(), // }, // { // name: 'GET-PAYMENT-LIST', // query: getPaymentDetails({ // dealerId: 14, // page: 1, // pageSize: 10, // search: 'omkar', // sort: [], // status: undefined, // searchByDealer: true, // }), // }, // { // name: 'PRODUCTS', // query: getProductsQuery( // 1, // 10, // [], // true, // null, // null, // null, // null, // null, // null, // ), // }, { name: 'DealerAdminCoin', query: getDealeradminCoin(1, 10), }, // { // name: 'PAYMENTS', // query: getPaymentsQuery(1, 10, [], 'Alta Coins Hub', 'paid'), // } // { name: 'SINGOLE-PRODUCTS', query: getSingleProduct() }, // { // name: 'FRONTEND-PRODUCTS', // query: getFrontendProductsQuery(1, 10), // }, ] queries.forEach(({ name, query }) => { console.log(`---${name}_QUERY---`, decodeURIComponent(query)) })