UNPKG

@horizon-apps/domain-schema-core

Version:

Core domain schema utilities for Horizon Platform - Schema generators, data enrichers, converters and specifications

1,712 lines (1,675 loc) 48.6 kB
/** * 🎨 Horizon Domain Data Display Enricher * * Enriquecedor genérico de dados de domínios para display * Transforma dados brutos de entidades em objetos enriquecidos para UI * * @module horizon-domain-data-display-enricher * @version 1.0.0 */ interface FieldMetadata { key: string; label?: string; type?: string; format?: string; unit?: string; categories?: string[]; composedLabel?: string; icon?: string; iconName?: string; validation?: any; [key: string]: any; } interface EnrichmentOptions { data: Record<string, any>; metadata: FieldMetadata[]; locale?: string; currency?: string; getIcon?: (iconName: string) => any; } /** * Formata valor monetário */ declare function formatCurrency(value: number | string | null, currency?: string, locale?: string): string; /** * Formata data */ declare function formatDateTime(value: string | Date, locale?: string): string; /** * Formata área com unidade */ declare function formatArea(value: number | string, unit?: string): string; /** * Formata distância com unidade */ declare function formatDistance(value: number | string, unit?: string): string; /** * Formata porcentagem */ declare function formatPercent(value: number | string): string; /** * Formata contagem (números inteiros) */ declare function formatCount(value: number | string): string; /** * Formata ano */ declare function formatYear(value: number | string): string; /** * Processa template com pluralização e substituições */ declare function processTemplate(template: string | undefined, value: any, valueLabel: string): string | undefined; /** * Função principal de enriquecimento de dados * * @param options - Opções de enriquecimento * @returns Dados enriquecidos com metadados */ declare function domainDataDisplayEnricher(options: EnrichmentOptions): Record<string, any>; declare const formatters: { currency: typeof formatCurrency; date: typeof formatDateTime; area: typeof formatArea; distance: typeof formatDistance; percent: typeof formatPercent; count: typeof formatCount; year: typeof formatYear; }; declare const templateProcessor: typeof processTemplate; /** * Função de compatibilidade com a API antiga * @deprecated Use domainDataDisplayEnricher instead */ declare function EnrichFieldsWithMetadata({ data, metadata }: { data: any; metadata: any[]; }): any; /** * JsonToZodGenerator - Converte schemas Horizon Fields Metadata Pattern v2.2.0 para Zod * * Suporta o novo formato com: * - categories (ao invés de tags) * - validation.precision para decimais * - enum como object * - mask para validações automáticas * - conditions para campos condicionais * - parent para hierarquias * - db metadata (ignorado na geração Zod) * - Inferência inteligente */ interface HorizonFieldDefinition { key: string; type: "String" | "String[]" | "Number" | "Boolean" | "Json" | "Json[]" | "Array"; label: string; categories?: string[]; validation?: { required?: boolean; min?: number; max?: number; minLength?: number; maxLength?: number; precision?: number; }; format?: "currency" | "area" | "distance" | "count" | "percent" | "date" | "datetime" | "time"; unit?: string; mask?: "cpf" | "cnpj" | "cep" | "phone" | "email" | "url"; enum?: Record<string, string>; conditions?: string[]; parent?: string; searchable?: boolean; filterable?: boolean; sortable?: boolean; db?: { type?: string; unique?: boolean; index?: boolean | string; default?: any; }; origin?: string; modifiedBy?: string[]; } interface JsonToZodOptions { schemaName: string; addDescriptions?: boolean; addValidationMessages?: boolean; exportType?: boolean; sortFields?: boolean; enablePrecisionValidation?: boolean; logInference?: boolean; } declare class JsonToZodGenerator { private static inferenceLog; /** * Aplica inferência inteligente em um campo */ private static applyInference; private static log; /** * Converte um campo para Zod */ private static fieldToZod; /** * Gera o schema Zod completo */ static generate(fields: HorizonFieldDefinition[], options: JsonToZodOptions): string; /** * Gera schema a partir de arquivo JSON v2.2.0 */ static generateFromFile(jsonPath: string, options: JsonToZodOptions): Promise<string>; /** * Salva o schema gerado */ static saveToFile(fields: HorizonFieldDefinition[], options: JsonToZodOptions, outputPath: string): Promise<void>; /** * Analisa um schema e retorna estatísticas */ static analyzeSchema(fields: HorizonFieldDefinition[]): { totalFields: number; fieldTypes: Record<string, number>; fieldFormats: Record<string, number>; fieldCategories: Record<string, number>; requiredFields: number; fieldsWithValidation: number; fieldsWithMask: number; fieldsWithEnum: number; fieldsWithConditions: number; fieldsWithParent: number; }; } /** * 🔍 Horizon Domain Data Filters * * Funções utilitárias para filtrar e selecionar campos de dados de domínio * Compatível com formato array e objeto enriquecido * * @module horizon-domain-data-filters * @version 1.0.0 */ interface Field$1 { key: string; value?: any; label?: string; type?: string; category?: string | string[]; categories?: string | string[]; [key: string]: any; } type FieldsArray = Field$1[]; type FieldsObject = Record<string, Field$1>; type FieldsInput = FieldsArray | FieldsObject; /** * Filtra campos por categoria(s) * * @param fields - Array de campos ou objeto de campos enriquecidos * @param category - String de categoria única ou array de categorias * @param asObject - Se true, retorna como objeto; se false, retorna como array * @param preserveOrder - Se true, preserva a ordem das categorias solicitadas (padrão: false) * @returns Campos filtrados como array ou objeto * * @example * // Filtrar por categoria única * const mainFields = getFieldsByCategory(fields, 'main'); * * @example * // Filtrar por múltiplas categorias * const valueFields = getFieldsByCategory(fields, ['pricing', 'values']); * * @example * // Retornar como objeto * const fieldsObj = getFieldsByCategory(fields, 'main', true); * * @example * // Preservar ordem das categorias solicitadas * const orderedFields = getFieldsByCategory(fields, ['pricing', 'dimensions'], false, true); * // Retorna todos os campos 'pricing' primeiro, depois todos os 'dimensions' */ declare function getFieldsByCategory(fields: FieldsInput, category: string | string[], asObject?: boolean, preserveOrder?: boolean): FieldsArray | FieldsObject; /** * Filtra campos por lista de keys, mantendo a ordem especificada * Retorna apenas campos com valores válidos (não null, undefined, empty string ou NaN) * * @param fields - Array de campos ou objeto de campos enriquecidos * @param keys - Array de keys na ordem desejada * @param asObject - Se true, retorna como objeto; se false, retorna como array (padrão) * @returns Array ou objeto de campos na ordem das keys, apenas com valores válidos * * @example * // Buscar campos específicos na ordem desejada (array) * const orderedFields = getFieldsByKeys(fields, ['valor_venda', 'area_total', 'dormitorios']); * * @example * // Retornar como objeto para lookup rápido * const fieldsObj = getFieldsByKeys(fields, ['valor_venda', 'area_total'], true); * * @example * // Campos sem valores válidos são ignorados * const validFields = getFieldsByKeys(fields, ['field1', 'field2', 'field3']); * // Se field2.value for null, ele não aparece no resultado */ declare function getFieldsByKeys(fields: FieldsInput, keys: string[], asObject?: boolean): FieldsArray | FieldsObject; /** * 🔄 Horizon Domain Data Transformers * * Funções para transformar estruturas de dados de domínio * * @module horizon-domain-data-transformers * @version 1.0.0 */ interface Field { key: string; value?: any; label?: string; type?: string; [key: string]: any; } /** * Expande um campo array em múltiplos campos booleanos * Cada item do array se torna um campo independente com value: true * * @param field - Campo com value array ou diretamente um array de strings * @returns Array de campos booleanos * * @example * // Passando campo completo * const field = { key: 'amenities', value: ['pool', 'gym', 'parking'] }; * const booleans = expandArrayFieldToBoolean(field); * // Resultado: [ * // { key: 'pool', value: true, type: 'Boolean', label: 'pool' }, * // { key: 'gym', value: true, type: 'Boolean', label: 'gym' }, * // { key: 'parking', value: true, type: 'Boolean', label: 'parking' } * // ] * * @example * // Passando array direto * const booleans = expandArrayFieldToBoolean(['wifi', 'ac', 'tv']); * // Resultado: [ * // { key: 'wifi', value: true, type: 'Boolean', label: 'wifi' }, * // { key: 'ac', value: true, type: 'Boolean', label: 'ac' }, * // { key: 'tv', value: true, type: 'Boolean', label: 'tv' } * // ] * * @example * // Uso direto com propriedade * const property = { amenities: { key: 'amenities', value: ['pool', 'gym'] } }; * const booleans = expandArrayFieldToBoolean(property.amenities); */ declare function expandArrayFieldToBoolean(field: Field | string[]): Field[]; /** * Ordena um array de objetos baseado em múltiplos campos e direções * * @param fields - Array de objetos para ordenar * @param sortKeys - Array de strings no formato "campo:direção" (ex: ["name:asc", "price:desc"]) * @returns Array ordenado (nova instância, não modifica o original) * * @example * // Ordenar por nome crescente, depois preço decrescente * const products = [ * { name: "Casa A", price: 300000, area: 120 }, * { name: "Casa B", price: 250000, area: 100 }, * { name: "Casa A", price: 280000, area: 110 } * ]; * * const sorted = sortFields(products, ["name:asc", "price:desc"]); * // Resultado: Casa A (300k), Casa A (280k), Casa B (250k) * * @example * // Ordenar apenas por um campo * const sorted = sortFields(products, ["area:desc"]); */ declare function sortFields(fields: any[], sortKeys?: string[]): any[]; /** * Search to URL Query Serializer - Sistema de URLs com query params visíveis * * Sistema de serialização para URLs de busca com todos os parâmetros visíveis * na query string, sem compactação ou ocultação em base64. * * FORMATO DE ENTRADA: * { * "filters": { * "reference": "1829", * "tipo": "Casa" * }, * "search": "casa moderna", * "page": 1, * "limit": 20, * "sort": "valor_venda:asc" * } * * FORMATO URL: * ?q=casa+moderna&reference=1829&tipo=Casa&page=1&limit=20&sort=valor_venda:asc * * @module search-to-url-query-serializer */ /** * Parâmetros de busca genéricos */ interface SearchParams { filters?: Record<string, any>; search?: string; page?: number; limit?: number; sort?: string | Record<string, string>; } /** * Configuração de campos e operadores * v1.2.2: Removido defaults - agora usa padrões hardcoded */ interface FieldConfig { fieldMapping?: Record<string, string>; overrides?: Record<string, { operator?: string; caseSensitive?: boolean; }>; } /** * Defaults configuráveis para parâmetros de busca */ interface SearchDefaults { page: number; limit: number; sort: string | Record<string, string>; } /** * Configuração para o SearchUrlBuilder */ interface SearchUrlBuilderConfig { rootUrl: string; enableSlug?: boolean; slugConfig?: SeoSlugConfig; fieldConfig?: FieldConfig; defaults?: Partial<SearchDefaults>; } /** * Configuração para geração de slug SEO */ interface SeoSlugConfig { slugPrefix?: string; maxSlugLength?: number; requiredFields?: string[]; } /** * Resultado da construção de URL */ interface BuildUrlResult { url: string; slug: string | null; queryString: string; hasSlug: boolean; } declare class SearchUrlBuilder { private config; private fieldMapping; private defaults; constructor(config: SearchUrlBuilderConfig); /** * Constrói URL de busca com query params visíveis * * @example * ```typescript * const builder = new SearchUrlBuilder({ rootUrl: '/imoveis/' }); * const result = builder.buildUrl({ * filters: { * search_text: { search: "casa moderna" }, * tipo: "Casa", * cidade: "Ponta Grossa" * }, * page: 2 * }); * * // result.url: "/imoveis/?q=casa+moderna&tipo=Casa&cidade=Ponta+Grossa&page=2" * ``` */ buildUrl(params: SearchParams): BuildUrlResult; /** * Extrai parâmetros de busca da URL (todos visíveis) * * @example * ```typescript * const builder = new SearchUrlBuilder({ rootUrl: '/imoveis/' }); * const params = builder.parseUrl(context); * * // Retorna exatamente o que estava na URL: * // { * // filters: { search_text: { search: "casa" }, tipo: "Casa" }, * // page: 2, * // limit: 25, * // sort: 'valor_venda_desc' * // } * ``` */ parseUrl(context: any): SearchParams; /** * Enriquece estado Zustand para FrontendRequest (compatível com SearchRequestToPrismaMapper) * * @example * ```typescript * const builder = new SearchUrlBuilder({ rootUrl: '/imoveis/' }); * const enriched = builder.enrichForFrontendRequest(zustandState, { * fields: ["reference", "title"], * relations: { broker: ["name", "phone"] } * }); * * // enriched é compatível com SearchRequestToPrismaMapper * const prismaQuery = mapSearchRequestToPrisma(enriched); * ``` */ enrichForFrontendRequest(zustandState: SearchParams, options?: { fields?: string[]; relations?: Record<string, string[] | boolean>; }): any; /** * Parse valores da URL, tentando detectar o tipo correto */ private parseUrlValue; /** * Converte sort object para string para comparações */ private sortObjectToString; /** * Verifica se valor é um objeto complexo que precisa de base64 */ private isComplexObject; /** * Serializa valor complexo com base64 se necessário */ private serializeComplexValue; /** * Parse valor que pode ser base64 encoded */ private parseComplexValue; /** * Gera slug SEO baseado nos filtros (integração com seo-slug-generator) */ private generateSlugFromFilters; /** * Enriquece filtros do Zustand com operadores para API * v1.2.2: Usa lógica AND/OR ao invés de operadores Prisma específicos * Padrões hardcoded: strings = equals, arrays = or */ private enrichFiltersWithOperators; /** * Verifica se um objeto já contém operadores * v1.2.2: Inclui operadores lógicos AND/OR */ private hasOperators; /** * Processa ranges automáticos no nível principal dos filtros * Identifica campos com _min/_max e os converte para operadores gte/lte */ private processRangeFields; } /** * 🔧 Filter Interfaces - Interfaces Unificadas * * Todas as interfaces do Filter Engine em um local centralizado * RESPONSABILIDADES: * - Interfaces base do sistema * - Interfaces dos processors especializados * - Schema SSOT types * - Resultado de conversões */ /** * Schema SSOT para type awareness */ interface HorizonSchema { entity: string; table: string; pk: string; fields: HorizonField[]; } /** * Configuração do campo de banco de dados */ interface HorizonFieldDb { column: string; fulltext_type?: 'text' | 'vector'; } /** * Campo do schema SSOT */ interface HorizonField { name: string; type: string; db?: string | HorizonFieldDb; searchable?: boolean; facetable?: { enabled: boolean; kind: 'terms' | 'ranges' | 'histogram' | 'date_histogram'; [key: string]: any; }; join?: { through?: { table: string; fk_property: string; fk_term: string; }; target?: { table: string; id: string; label: string; }; }; } /** * Resultado da conversão de filtros */ interface FilterConversionResult { /** WHERE clause SQL gerada */ where: string; /** Parâmetros para binding */ params: Record<string, any>; /** Metadados sobre os filtros */ metadata: { hasFulltext: boolean; hasGeo: boolean; hasRanges: boolean; complexity: number; processorsUsed?: string[]; totalFilters?: number; hasAdvancedFeatures?: boolean; hasArrays?: boolean; hasExists?: boolean; }; } /** * Resultado de conversão com informações de debug */ interface FilterConversionResultWithDebug extends FilterConversionResult { debug: { processorsUsed: Array<{ key: string; processor: string; complexity: number; }>; totalProcessingTime?: number; fieldMappings?: Record<string, { dbColumn: string; fieldType: string; }>; }; } /** * Resultado de processamento de um filtro */ interface ProcessorResult { /** WHERE clause SQL gerada */ where: string; /** Parâmetros para binding */ params: Record<string, any>; /** Metadados sobre o processamento */ metadata: { processorType: 'geospatial' | 'basic' | 'array'; complexity: number; hasSpecialFeatures?: boolean; }; } /** * Interface base para todos os processors */ interface FilterProcessor { /** Nome do processor */ name: string; /** Verifica se pode processar este filtro */ canProcess(key: string, value: any, fieldInfo?: HorizonField): boolean; /** Processa o filtro e retorna SQL + params */ process(key: string, value: any, fieldInfo?: HorizonField): ProcessorResult; /** Retorna fragmentos SQL suportados */ getSupportedFragments(): string[]; } /** * Estatísticas dos processors */ interface ProcessorStats { totalProcessors: number; processorNames: string[]; hasSchema: boolean; fieldsInSchema: number; } /** * Informações de um processor registrado */ interface ProcessorInfo { name: string; supportedFragments: string[]; canProcessExamples?: string[]; } /** * Configuração de busca fulltext especial * IMPORTANTE: Usado FORA de filters, diretamente no request * SIMPLIFICADO: Apenas tsvector (sem fuzzy em textos longos) */ interface FulltextSearch { /** Texto/valor de busca */ value: string; /** Método de busca - agora apenas vector */ method?: 'vector'; } /** * 🚨 CONTRATO ALTAMENTE IMPORTANTE PARA FILTERS -> GEOM * * Nova estrutura que SEPARA operação espacial de tipo de geometria, * permitindo todas as combinações possíveis: * - within + bbox, within + polygon, within + circle * - intersects + bbox, intersects + polygon * - contains + point, near + point, etc. */ /** * Operações espaciais suportadas */ type GeospatialOperation = 'within' | 'intersects' | 'contains' | 'near'; /** * Tipos de geometria suportados */ type GeometryType = 'bbox' | 'polygon' | 'point' | 'circle'; /** * Geometria: Bounding Box */ interface BBoxGeometry { type: 'bbox'; bounds: { north: number; south: number; east: number; west: number; }; } /** * Geometria: Polígono customizado */ interface PolygonGeometry { type: 'polygon'; coordinates: number[][]; } /** * Geometria: Ponto */ interface PointGeometry { type: 'point'; coordinates: [number, number]; } /** * Geometria: Círculo (ponto + raio) */ interface CircleGeometry { type: 'circle'; center: { lat: number; lng: number; }; radius: number; } /** * União de todas as geometrias */ type Geometry = BBoxGeometry | PolygonGeometry | PointGeometry | CircleGeometry; /** * 🎯 FILTRO GEOESPACIAL - NOVA ESTRUTURA OFICIAL * * Esta é a interface CONTRATUAL que define como o frontend * deve enviar filtros geoespaciais para o backend. * * Exemplos de uso: * - { operation: 'within', geometry: { type: 'bbox', bounds: {...} } } * - { operation: 'within', geometry: { type: 'polygon', coordinates: [...] } } * - { operation: 'intersects', geometry: { type: 'bbox', bounds: {...} } } * - { operation: 'contains', geometry: { type: 'point', coordinates: [...] } } * - { operation: 'near', geometry: { type: 'point', coordinates: [...] }, distance: 1000 } */ interface GeospatialFilter { /** Operação espacial a ser executada */ operation: GeospatialOperation; /** Geometria sobre a qual executar a operação */ geometry: Geometry; /** Distância em metros (obrigatório para operation: 'near') */ distance?: number; } /** * Resultado do processor geoespacial */ interface GeospatialResult extends ProcessorResult { metadata: ProcessorResult['metadata'] & { processorType: 'geospatial'; operation: GeospatialOperation; geometryType: GeometryType; usesPostGIS: boolean; distance?: number; }; } /** * Operadores básicos suportados */ interface BasicFilter { /** Igual */ equals?: any; /** Maior que ou igual */ gte?: number; /** Maior que */ gt?: number; /** Menor que ou igual */ lte?: number; /** Menor que */ lt?: number; /** Existe/não existe */ exists?: boolean; /** Entre valores */ between?: [number, number]; /** LIKE pattern (case sensitive) */ like?: string; /** ILIKE pattern (case insensitive) */ ilike?: string; } /** * Resultado do processor básico */ interface BasicResult extends ProcessorResult { metadata: ProcessorResult['metadata'] & { processorType: 'basic'; operators: string[]; isRange: boolean; }; } /** * Operadores de array */ interface ArrayFilter { /** OR lógico (IN ou && overlap) */ or?: any[]; /** AND lógico (@> contains) */ and?: any[]; /** Contains exato */ contains?: any[]; /** Overlaps */ overlaps?: any[]; } /** * Resultado do processor de arrays */ interface ArrayResult extends ProcessorResult { metadata: ProcessorResult['metadata'] & { processorType: 'array'; arrayOperator: 'IN' | 'contains' | 'overlaps'; arrayType: 'simple' | 'postgresql'; }; } /** * Opções para conversão de filtros */ interface ConversionOptions { /** Nome da coluna de localização geográfica */ locationColumn?: string; /** Forçar uso de índices específicos */ forceIndexHints?: boolean; /** Modo de debug */ debug?: boolean; /** Limite de complexidade */ maxComplexity?: number; } /** * Configuração do FilterConverter */ interface FilterConverterConfig { /** Schema SSOT */ schema?: HorizonSchema; /** Logging habilitado */ logging?: boolean; /** Cache de resultados */ caching?: boolean; /** Validação estrita */ strictValidation?: boolean; } /** * 🔍 Filter Converter - Arquitetura Modular com Processors * * Converte filtros genéricos para WHERE clauses SQL otimizadas * RESPONSABILIDADES: * - Orquestrar processors especializados * - Combinar resultados de múltiplos processors * - Manter compatibilidade com builders existentes * - SSOT schema awareness * - Performance e debugging */ /** * Filter Converter com arquitetura modular baseada em processors especializados */ declare class FilterConverter { private schema?; private schemaFieldMap; private processors; private config; constructor(schema?: HorizonSchema | any, config?: FilterConverterConfig); /** * 🚨 ADAPTER TEMPORÁRIO: Detecta formato schema e converte se necessário */ private detectAndConvertSchema; /** * Atualiza schema SSOT para type awareness */ updateSchema(schema: HorizonSchema): void; /** * Registra um processor especializado */ registerProcessor(processor: FilterProcessor): void; /** * Converte filtros genéricos para WHERE clause SQL * Interface compatível com builders existentes */ convert(filters: Record<string, any>): FilterConversionResult; /** * Versão de debug que inclui informações detalhadas */ convertWithDebug(filters: Record<string, any>): FilterConversionResultWithDebug; /** * Encontra processor apropriado para um filtro */ private findProcessor; /** * Tenta fallback com basic processor se nenhum processor específico aceitar */ private tryBasicFallback; /** * Gera metadados combinados de todos os processors */ private generateCombinedMetadata; /** * Valida que fulltext não está em filters (deve estar em request.fulltext) */ private validateNoFulltextInFilters; /** * Detecta se é campo fulltext especial do SSOT */ private isFulltextField; /** * Detecta se é filtro fulltext legado */ private isLegacyFulltextFilter; /** * Retorna processors registrados */ getRegisteredProcessors(): ProcessorInfo[]; /** * Testa qual processor seria usado para um filtro */ testProcessorSelection(key: string, value: any): string | null; /** * Estatísticas dos processors */ getProcessorStats(): ProcessorStats; /** * Retorna schema atual */ getSchema(): HorizonSchema | undefined; /** * Retorna configuração atual */ getConfig(): FilterConverterConfig; /** * Sistema de logging configurável */ private log; } /** * Cria uma instância configurada do FilterConverter */ declare function createFilterConverter(schema?: HorizonSchema, config?: FilterConverterConfig): FilterConverter; /** * Converte filtros de forma simples (sem instância) */ declare function convertFilters(filters: Record<string, any>): FilterConversionResult; /** * Valida se filtros estão bem formados */ declare function validateFilters(filters: Record<string, any>): { valid: boolean; errors: string[]; }; /** * 🌍 Geospatial Processor - Filter Engine * * Especializado em filtros geoespaciais com PostGIS * RESPONSABILIDADES: * - BBOX (bounding box) queries * - Polygon (WKT) queries * - Radius (point + distance) queries * - PostGIS ST_* functions */ declare class GeospatialProcessor implements FilterProcessor { name: string; /** * Verifica se pode processar este filtro */ canProcess(_key: string, value: any, _fieldInfo?: HorizonField): boolean; /** * Detecta nova estrutura geoespacial (operation + geometry) */ private isNewGeospatialFilter; /** * Valida operação espacial */ private isValidOperation; /** * Valida geometria */ private isValidGeometry; /** * Processa filtro geoespacial e retorna SQL + params */ process(_key: string, value: any, _fieldInfo?: HorizonField, options?: { locationColumn?: string; }): GeospatialResult; /** * Retorna fragmentos SQL suportados */ getSupportedFragments(): string[]; /** * Gera SQL PostGIS baseado na operação e geometria */ private generateGeoSQL; /** * WITHIN: Encontrar geometrias DENTRO de uma área * Usa: ST_Within(location, area) */ private generateWithinSQL; /** * INTERSECTS: Encontrar geometrias que INTERSECTAM com área * Usa: ST_Intersects(location, area) */ private generateIntersectsSQL; /** * CONTAINS: Encontrar áreas que CONTÊM um ponto * Usa: ST_Contains(area, point) */ private generateContainsSQL; /** * NEAR: Encontrar geometrias PRÓXIMAS a um ponto * Usa: ST_DWithin(location, point, distance) */ private generateNearSQL; /** * WITHIN + BBOX: pontos dentro de bounding box */ private generateWithinBboxSQL; /** * WITHIN + POLYGON: pontos dentro de polígono */ private generateWithinPolygonSQL; /** * WITHIN + CIRCLE: pontos dentro de círculo */ private generateWithinCircleSQL; /** * INTERSECTS + BBOX: geometrias que intersectam bbox */ private generateIntersectsBboxSQL; /** * INTERSECTS + POLYGON: geometrias que intersectam polígono */ private generateIntersectsPolygonSQL; /** * INTERSECTS + CIRCLE: geometrias que intersectam círculo */ private generateIntersectsCircleSQL; /** * CONTAINS + POINT: áreas que contêm ponto */ private generateContainsPointSQL; /** * NEAR + POINT: pontos próximos a localização */ private generateNearPointSQL; /** * Valida bounds geográficos */ private validateBounds; /** * Coleta parâmetros para binding SQL */ private collectGeoParams; /** * Converte coordenadas GeoJSON para WKT */ private coordinatesToWKT; /** * Calcula complexidade baseada na operação e geometria */ private calculateGeoComplexity; /** * Testa se um filtro é geoespacial (método estático) */ static isGeospatialFilter(key: string, value: any): boolean; /** * Valida bounds (método estático) */ static validateBounds(bounds: any): boolean; /** * Cria instância configurada para testes */ static createForTesting(): GeospatialProcessor; } /** * 📋 Array Processor - Filter Engine * * Especializado em operadores de array (PostgreSQL e simples) * RESPONSABILIDADES: * - OR lógico (IN para campos simples, && para arrays PostgreSQL) * - AND lógico (@> contains para arrays PostgreSQL) * - Contains e Overlaps para arrays PostgreSQL * - SSOT awareness para detectar tipo de campo */ declare class ArrayProcessor implements FilterProcessor { name: string; /** * Verifica se pode processar este filtro */ canProcess(key: string, value: any, fieldInfo?: HorizonField): boolean; /** * Processa filtro de array e retorna SQL + params */ process(key: string, value: ArrayFilter, fieldInfo?: HorizonField): ArrayResult; /** * Retorna fragmentos SQL suportados */ getSupportedFragments(): string[]; /** * Gera SQL para operadores de array */ private generateArraySQL; /** * Processa operador OR (IN ou overlap) */ private processOrOperator; /** * Verifica se o campo é array baseado no schema SSOT */ private isArrayField; /** * Converte camelCase para snake_case */ private toSnakeCase; /** * Valida operador de array */ private validateArrayOperator; /** * Testa se um filtro é de array (método estático) */ static isArrayFilter(value: any): value is ArrayFilter; /** * Testa se campo é array (método estático) */ static isArrayField(fieldType: string): boolean; /** * Valida operadores de array (método estático) */ static validateArrayValues(values: any[]): boolean; /** * Cria instância configurada para testes */ static createForTesting(): ArrayProcessor; } /** * 🔢 Basic Processor - Filter Engine * * Especializado em filtros básicos (equals, ranges, EXISTS, etc) * RESPONSABILIDADES: * - Equals (=) * - Ranges (>, >=, <, <=, BETWEEN) * - EXISTS/NOT_EXISTS (IS NULL, IS NOT NULL) * - LIKE patterns * - Valores simples */ declare class BasicProcessor implements FilterProcessor { name: string; /** * Verifica se pode processar este filtro */ canProcess(key: string, value: any, fieldInfo?: HorizonField): boolean; /** * Processa filtro básico e retorna SQL + params */ process(key: string, value: any, fieldInfo?: HorizonField): BasicResult; /** * Retorna fragmentos SQL suportados */ getSupportedFragments(): string[]; /** * Gera SQL para filtros básicos (com detecção de array via SSOT) */ private generateBasicSQL; /** * Processa filtro tipo objeto */ private processObjectFilter; /** * Verifica se é um valor simples */ private isSimpleValue; /** * Converte camelCase para snake_case */ private toSnakeCase; /** * Testa se um filtro é básico (método estático) */ static isBasicFilter(value: any): boolean; /** * Testa se é valor simples (método estático) */ static isSimpleValue(value: any): boolean; /** * Cria instância configurada para testes */ static createForTesting(): BasicProcessor; } /** * 🔧 Filter Helpers - Utilitários Compartilhados * * Funções auxiliares para conversão e validação de filtros * RESPONSABILIDADES: * - Conversões de formato (camelCase ↔ snake_case) * - Validações de tipos e estruturas * - Coleta de parâmetros SQL * - Cálculos de complexidade * - Normalização de dados */ /** * Converte camelCase para snake_case */ declare function toSnakeCase(str: string): string; /** * Converte snake_case para camelCase */ declare function toCamelCase(str: string): string; /** * Normaliza nome de coluna do banco baseado no schema */ declare function getDbColumnName(fieldName: string, fieldInfo?: HorizonField): string; /** * Verifica se é um valor simples (string, number, boolean) */ declare function isSimpleValue(value: any): boolean; /** * Verifica se o campo é array baseado no schema */ declare function isArrayField(fieldType?: string): boolean; /** * Verifica se é um filtro de fulltext search */ declare function isFulltextFilter(value: any): boolean; /** * Verifica se é um filtro geoespacial */ declare function isGeospatialFilter(value: any): boolean; /** * Verifica se é um filtro de array (OR/AND operators) */ declare function isArrayFilter(value: any): boolean; /** * Verifica se há filtros de range */ declare function hasRangeOperators(value: any): boolean; /** * Verifica se há operadores EXISTS/NOT EXISTS */ declare function hasExistsOperators(value: any): boolean; /** * Analisa filtros e retorna estatísticas */ declare function analyzeFilters(filters: Record<string, any>): { hasFulltext: boolean; hasGeo: boolean; hasArrays: boolean; hasRanges: boolean; hasExists: boolean; filterCount: number; complexity: number; }; /** * Normaliza texto de busca para fulltext search */ declare function normalizeSearchText(searchText: string): string; /** * Valida bounds geográficos */ declare function validateGeoBounds(bounds: any): boolean; /** * Valida estrutura de filtro geoespacial */ declare function validateGeoFilter(geoFilter: any): boolean; /** * Cria instância de todos os processors padrão */ declare function createDefaultProcessors(): FilterProcessor[]; /** * Cria instância apenas dos processors básicos (sem geo) */ declare function createBasicProcessors(): FilterProcessor[]; /** * Cria instância de processors específicos por nome */ declare function createProcessorsByName(names: string[]): FilterProcessor[]; /** * Retorna informações sobre processors disponíveis */ declare function getProcessorInfo(): Record<string, { name: string; description: string; supportedFeatures: string[]; }>; /** * 🎯 Sort Parser - Bracket Modifier Syntax * * Converte entre string URLs e objetos estruturados * Suporte: campo:desc, campo[modifier]:desc */ /** * Objeto estruturado de ordenação */ interface SortObject { /** Campo real da tabela */ field: string; /** Tipo de cálculo especial (opcional) */ type?: 'fts_rank' | 'proximity' | 'center'; /** Direção da ordenação */ direction: 'asc' | 'desc'; } /** * Input aceito pelos builders */ type SortInput = SortObject | string | undefined; /** * 📋 Interfaces Específicas do List Builder * * Tipos e configurações exclusivas para listagem com paginação */ /** * Configuração para listagem com paginação */ interface ListConfig { fields?: string[]; page?: number; limit?: number; sort?: SortInput; } /** * 🗺️ Interfaces Específicas do Map Builder * * Tipos e configurações exclusivas para mapa geoespacial */ /** * Configuração para mapa geoespacial * REGRA: Dados geoespaciais ficam em filters.location, NÃO aqui! */ interface MapConfig { fields?: string[]; clustering?: ClusteringConfig; sort?: SortInput; } /** * Configuração de clustering */ interface ClusteringConfig { enabled?: boolean; auto_zoom?: boolean; gridSize?: number; } /** * 📊 Interfaces Específicas do Facets Builder * * Tipos e configurações exclusivas para facetas SSOT-driven */ /** * Configuração para facetas (baseado em facets-ssot.md) */ interface FacetsConfig { fields?: string[]; mode?: 'conjunctive' | 'disjunctive'; overrides?: Array<{ field: string; kind?: 'terms' | 'ranges' | 'histogram' | 'date_histogram'; [key: string]: any; }>; } /** * 📋 Interfaces Específicas do Item Builder * * Tipos e configurações exclusivas para busca de item único */ /** * Configuração para item específico */ interface ItemConfig { fields?: string[]; relations?: string[]; sort?: SortInput; } /** * 🔧 Interfaces Compartilhadas - Multi-Request SQL Builder * * Tipos comuns reutilizados por todos os builders * APENAS INTERFACES REALMENTE GENÉRICAS */ /** * Request genérico que pode conter múltiplos sub-requests */ interface GenericRequest { /** Filtros compartilhados entre todos os tipos */ filters?: Record<string, any>; /** 🆕 Busca search especial (FORA de filters) */ search?: { value: string; method?: 'vector'; }; /** Define quais tipos de resposta são solicitados */ include: string[]; /** Ordenação global (usada pelos builders) - suporte string e objeto */ sort?: SortInput; /** Configuração específica para listagem */ list?: ListConfig; /** Configuração específica para mapa */ map?: MapConfig; /** Configuração específica para facetas */ facets?: FacetsConfig; /** Configuração específica para item único */ item?: ItemConfig; } /** * Resultado de build completo com SQL + parâmetros */ interface SQLBuildResult { /** SQL gerado com placeholders */ sql: string; /** Parâmetros ordenados para binding */ params: any[]; /** Metadados opcionais */ metadata?: { complexity?: number; hasGeo?: boolean; hasFulltext?: boolean; }; } /** * Interface base que todos os builders devem implementar */ interface SQLBuilder { /** * Constrói SQL específico baseado no request */ build(request: GenericRequest): SQLBuildResult; /** * Verifica se este builder suporta o tipo solicitado */ supports(type: string): boolean; /** * Retorna filtros obrigatórios para este builder */ getRequiredFilters?(): string[]; } /** * Resultado da construção de SQLs */ interface BuildResult { /** Tipo de resultado: sempre paralelo */ type: 'parallel'; /** SQLs individuais para execução paralela */ sqls: Record<string, string>; /** Parâmetros ordenados para cada SQL */ params: Record<string, any[]>; /** Metadados sobre a construção */ metadata?: { buildersUsed: string[]; hasSharedFilters: boolean; estimatedComplexity: 'low' | 'medium' | 'high'; }; } /** * Tipos de builders disponíveis */ type BuilderType = 'list' | 'map' | 'facets' | 'item'; /** * Formatos de saída suportados */ type OutputFormat = 'parallel'; /** * 🎯 Interfaces Específicas do Core Orchestrator * * Tipos e configurações exclusivas do orquestrador principal */ /** * Configuração do orquestrador principal */ interface OrchestratorConfig { /** Schema SSOT para type awareness */ schema?: HorizonSchema; /** Configuração de logging */ logging?: { enabled: boolean; includeSQL: boolean; }; } /** * 🎯 Multi-Request SQL Builder - Orquestrador Principal * * Gestor que coordena todos os builders e decide formato de saída * RESPONSABILIDADES: * - Analisar request e decidir quais builders usar * - Coordenar geração de SQLs (paralelo ou unificado) * - Garantir reutilização de filtros compartilhados */ /** * Orquestrador principal do Multi-Request SQL Builder */ declare class MultiRequestSQLBuilder { private builders; private filterConverter; private fulltextConverter; private config; constructor(config?: OrchestratorConfig); /** * 🎯 MÉTODO PRINCIPAL - Constrói SQLs baseado no request * SEMPRE RETORNA FORMATO PARALLEL - Backend escolhe como executar */ build(request: GenericRequest): BuildResult; /** * 🔧 Registra um builder específico */ registerBuilder(type: BuilderType, builder: SQLBuilder): void; /** * 🔄 Atualiza schema SSOT */ updateSchema(schema: HorizonSchema | any): void; /** * 🚨 ADAPTER TEMPORÁRIO: Detecta formato schema e converte se necessário */ private detectAndConvertSchema; /** * Constrói SQLs para execução em paralelo */ private buildParallel; /** * Determina quais builders são necessários baseado no request */ private determineRequiredBuilders; /** * Valida se todos os builders necessários estão registrados */ private validateBuildersAvailable; /** * Valida request básico */ private validateRequest; /** * Estima complexidade da operação */ private estimateComplexity; /** * Sistema de logging configurável */ private log; /** * Retorna estatísticas do orquestrador */ getStats(): { registeredBuilders: string[]; hasSchema: boolean; }; } /** * 🔍 Fulltext Converter - Busca Fulltext Especializada * * Especializado em processar busca fulltext FORA dos filters normais * RESPONSABILIDADES: * - Processar request.fulltext (não filters.search_text) * - Suportar métodos: fuzzy, vector, hybrid * - Gerar WHERE clause para fulltext especial * - Trabalhar com campos fulltext e fulltext_vector */ declare class FulltextConverter { private schema?; constructor(schema?: HorizonSchema | any); /** * 🚨 ADAPTER TEMPORÁRIO: Detecta formato schema e converte se necessário */ private detectAndConvertSchema; /** * Processa busca fulltext e retorna SQL + params * SIMPLIFICADO: Apenas tsvector, sem fuzzy/hybrid */ convert(fulltext: FulltextSearch): ProcessorResult; /** * Atualiza schema SSOT */ updateSchema(schema: HorizonSchema): void; /** * Retorna schema atual */ getSchema(): HorizonSchema | undefined; /** * Valida entrada fulltext * SIMPLIFICADO: Apenas valida o valor de busca */ private validateFulltext; /** * Obtém campos fulltext do schema SSOT * Procura por campos com fulltext_type: 'text' | 'vector' */ private getFulltextFields; /** * 🔧 OBTER NOME DA COLUNA CORRETAMENTE * REGRA: field.db string → usar direto | field.db object → usar field.name | undefined → usar field.name */ private getColumnName; /** * Testa se entrada é fulltext válida */ static isValidFulltext(fulltext: any): fulltext is FulltextSearch; /** * Cria instância para testes */ static createForTesting(schema?: HorizonSchema): FulltextConverter; } /** * 📋 List Builder - Postgre-Search-SQL-Builder * * Gerador de SQL para listagem com paginação e total * RESPONSABILIDADES: * - Converter request genérico → SQL de listagem * - Incluir COUNT(*) OVER() para total * - Aplicar paginação (LIMIT/OFFSET) * - Aplicar ordenação */ interface ListBuilderConfig { /** Nome da tabela principal */ tableName?: string; /** Nome da coluna de localização (para geo) */ locationColumn?: string; /** Incluir total por padrão */ includeTotalByDefault?: boolean; /** Limite máximo de registros */ maxLimit?: number; } /** * Builder especializado em gerar SQLs de listagem */ declare class ListBuilder implements SQLBuilder { private filterConverter; private fulltextConverter; private config; constructor(filterConverter: FilterConverter, fulltextConverterOrConfig?: FulltextConverter | ListBuilderConfig, config?: ListBuilderConfig); /** * Verifica se este builder suporta o tipo solicitado */ supports(type: string): boolean; /** * Constrói SQL de listagem baseado no request */ build(request: GenericRequest): SQLBuildResult; /** * Retorna filtros obrigatórios para este builder */ getRequiredFilters(): string[]; /** * Constrói SELECT clause com campos, total, FTS_RANK e GEO_PROXIMITY se necessário */ private buildSelectClause; /** * Constrói SELECT básico de campos */ private buildBaseSelectClause; /** * Constrói FTS_RANK clause se sort tem type='fts_rank' e há search * SIMPLIFICADO: Apenas ts_rank do tsvector (sem fuzzy em textos longos) */ private buildFtsRankClause; /** * Constrói LOCATION clause para proximity ou center */ private buildGeoProximityClause; /** * Extrai coordenadas do centro geográfico dos filtros */ private extractGeoCenterFromFilters; /** * Extrai bounds geográficos (BBOX ou Polygon) dos filtros */ private extractGeoBoundsFromFilters; /** * Combina WHERE clauses de filtros + search */ private combineWhereClauses; /** * Constrói ORDER BY clause - Suporte SortObject e backward compatibility */ private buildOrderByClause; /** * Constrói LIMIT/OFFSET para paginação */ private buildPaginationClause; /** * Valida limites de paginação */ private validateLimits; /** * Limpa e formata SQL final */ private cleanSQL; /** * Retorna configuração atual (para testes) */ getConfig(): Required<ListBuilderConfig>; /** * Gera SQL de exemplo para debug */ generateExampleSQL(): SQLBuildResult; } /** * Cria uma instância configurada do PostgreSearchSQLBuilder */ declare function createSQLBuilder(config?: { schema?: HorizonSchema; logging?: boolean; }): MultiRequestSQLBuilder; /** * Versão do pacote */ declare const VERSION = "1.0.0"; export { type ArrayFilter, ArrayProcessor, type BasicFilter, BasicProcessor, type BuildResult, type BuildUrlResult, type BuilderType, type ConversionOptions, EnrichFieldsWithMetadata, type FieldConfig, type FilterConversionResult, type FilterConversionResultWithDebug, FilterConverter, type FilterConverterConfig, type FilterProcessor, FulltextConverter, type FulltextSearch, type GenericRequest, type GeospatialFilter, GeospatialProcessor, type HorizonField, type HorizonSchema, JsonToZodGenerator, ListBuilder, type OutputFormat, MultiRequestSQLBuilder as PostgreSearchSQLBuilder, type ProcessorInfo, type ProcessorResult, type ProcessorStats, type SQLBuilder, type SearchParams, SearchUrlBuilder, type SearchUrlBuilderConfig, VERSION, analyzeFilters, convertFilters, createBasicProcessors, createDefaultProcessors, createFilterConverter, createProcessorsByName, createSQLBuilder, domainDataDisplayEnricher as default, domainDataDisplayEnricher, expandArrayFieldToBoolean, formatters, getDbColumnName, getFieldsByCategory, getFieldsByKeys, getProcessorInfo, hasExistsOperators, hasRangeOperators, isArrayField, isArrayFilter, isFulltextFilter, isGeospatialFilter, isSimpleValue, normalizeSearchText, sortFields, templateProcessor, toCamelCase, toSnakeCase, validateFilters, validateGeoBounds, validateGeoFilter };