{"version":3,"sources":["../src/domain-data-display-enricher/field-enricher.ts","../src/domain-data-display-enricher/domain-enricher-engine.ts","../src/domain-data-display-enricher/hooks.ts","../src/json-schema-to-zod-generator/index.ts","../src/domain-data-filters/index.ts","../src/domain-data-transformers/index.ts","../src/search-state-to-url-parser/src/resolvers/base/BaseResolver.ts","../src/search-state-to-url-parser/src/identifiers/RangeIdentifier.ts","../src/search-state-to-url-parser/src/identifiers/BetweenIdentifier.ts","../src/search-state-to-url-parser/src/identifiers/MinMaxIdentifier.ts","../src/search-state-to-url-parser/src/identifiers/index.ts","../src/search-state-to-url-parser/src/resolvers/Base64Resolver.ts","../src/search-state-to-url-parser/src/resolvers/FieldsResolver.ts","../src/search-state-to-url-parser/src/resolvers/SimpleValueResolver.ts","../src/search-state-to-url-parser/src/resolvers/PaginationSortResolver.ts","../src/search-state-to-url-parser/src/resolvers/LatLngResolver.ts","../src/search-state-to-url-parser/src/resolvers/PassthroughResolver.ts","../src/search-state-to-url-parser/src/resolvers/index.ts","../src/search-state-to-url-parser/src/core/UrlStateSerializer.ts","../src/search-state-to-url-parser/src/index.ts","../src/seo-slug-generator/src/extractors/FieldExtractor.ts","../src/seo-slug-generator/src/utils/slugify.ts","../src/seo-slug-generator/src/core/SlugGenerator.ts","../src/seo-slug-generator/src/index.ts","../src/search-state-to-request/src/core/SearchStateEnricher.ts"],"names":["format","sortFields","regex","defaultConfig"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * 🎨 Field Enricher - Enriquecimento de Campo Individual\n * \n * Função isolada para enriquecer um único campo com seus metadados\n * Preserva toda a lógica de formatação e processamento de templates\n * \n * @module field-enricher\n * @version 2.0.0\n */\n\nimport { format } from \"date-fns\";\nimport ptBR from \"date-fns/locale/pt-BR/index.js\";\nimport type { FieldMetadata, EnrichedField, EnrichmentOptions } from \"./types\";\n\n// ============================================\n// FORMATADORES\n// ============================================\n\n/**\n * Formata valor monetário\n */\nfunction formatCurrency(\n\tvalue: number | string | null,\n\tcurrency = \"BRL\",\n\tlocale = \"pt-BR\"\n): string {\n\tif (value === null || value === undefined) {\n\t\treturn \"Valor sob consulta\";\n\t}\n\n\tconst numValue = Number(value);\n\tif (isNaN(numValue)) return String(value);\n\n\tconst formatted = numValue.toLocaleString(locale, {\n\t\tstyle: \"currency\",\n\t\tcurrency: currency,\n\t\tminimumFractionDigits: 2,\n\t});\n\n\t// Substituir non-breaking space por espaço normal para consistência\n\treturn formatted.replace(/\\u00A0/g, ' ');\n}\n\n/**\n * Formata data\n */\nfunction formatDateTime(value: string | Date, locale = \"pt-BR\"): string {\n\ttry {\n\t\tconst date = value instanceof Date ? value : new Date(value);\n\t\tif (isNaN(date.getTime())) return String(value);\n\n\t\t// Para pt-BR usa date-fns\n\t\tif (locale === \"pt-BR\") {\n\t\t\treturn format(date, \"d 'de' MMMM 'de' yyyy\", { locale: ptBR });\n\t\t}\n\n\t\t// Para outros locales usa toLocaleDateString\n\t\treturn date.toLocaleDateString(locale);\n\t} catch {\n\t\treturn String(value);\n\t}\n}\n\n/**\n * Formata área com unidade\n */\nfunction formatArea(value: number | string, unit = \"m²\"): string {\n\tif (value === null || value === undefined) return \"\";\n\t\n\tconst unitMap: Record<string, string> = {\n\t\t\"m2\": \"m²\",\n\t\t\"m²\": \"m²\",\n\t\t\"ft2\": \"ft²\",\n\t\t\"hectare\": \"hectares\",\n\t\t\"hectares\": \"hectares\",\n\t\t\"km2\": \"km²\"\n\t};\n\n\tconst displayUnit = unitMap[unit] || unit;\n\treturn `${value} ${displayUnit}`;\n}\n\n/**\n * Formata distância com unidade\n */\nfunction formatDistance(value: number | string, unit = \"m\"): string {\n\tif (value === null || value === undefined) return \"\";\n\t\n\tconst unitMap: Record<string, string> = {\n\t\t\"m\": \"m\",\n\t\t\"meters\": \"m\",\n\t\t\"km\": \"km\",\n\t\t\"mi\": \"mi\",\n\t\t\"miles\": \"mi\"\n\t};\n\n\tconst displayUnit = unitMap[unit] || unit;\n\treturn `${value}${displayUnit}`;\n}\n\n/**\n * Formata porcentagem\n */\nfunction formatPercent(value: number | string): string {\n\tif (value === null || value === undefined) return \"\";\n\t\n\tconst numValue = Number(value);\n\tif (isNaN(numValue)) return String(value);\n\n\t// Se o valor já estiver em porcentagem (ex: 15 para 15%)\n\tif (numValue > 1) {\n\t\treturn `${numValue}%`;\n\t}\n\t\n\t// Se o valor estiver em decimal (ex: 0.15 para 15%)\n\treturn `${(numValue * 100).toFixed(2)}%`;\n}\n\n/**\n * Formata contagem (números inteiros)\n */\nfunction formatCount(value: number | string): string {\n\tif (value === null || value === undefined) return \"0\";\n\treturn String(Math.floor(Number(value)));\n}\n\n/**\n * Formata ano\n */\nfunction formatYear(value: number | string): string {\n\tif (value === null || value === undefined) return \"\";\n\treturn String(value);\n}\n\n\n// ============================================\n// PROCESSAMENTO DE TEMPLATE\n// ============================================\n\n/**\n * Processa template com pluralização e substituições\n */\nfunction processTemplate(\n\ttemplate: string | undefined,\n\tvalue: any,\n\tvalueLabel: string | string[] | undefined\n): string | undefined {\n\tif (!template) return undefined;\n\n\tlet result = template;\n\n\t// Processar valueLabel baseado no tipo\n\tlet processedValueLabel: string;\n\tif (Array.isArray(valueLabel)) {\n\t\t// Se valueLabel é array, NÃO processar template (frontend decide formatação)\n\t\treturn undefined;\n\t} else {\n\t\t// Se é string ou undefined, usar como string\n\t\tprocessedValueLabel = valueLabel || String(value);\n\t}\n\n\t// Substitui valor bruto\n\tresult = result.replace(/{{value}}/g, String(value));\n\n\t// Substitui valor formatado (sempre string)\n\tresult = result.replace(/{{valueLabel}}/g, processedValueLabel);\n\n\t// Processa pluralização {{p:texto}}\n\tresult = result.replace(/{{p:(.*?)}}/g, (_, plural) => {\n\t\tconst numValue = Number(value);\n\t\treturn numValue !== 1 ? plural : \"\";\n\t});\n\n\t// Processa singular {{s:texto}}\n\tresult = result.replace(/{{s:(.*?)}}/g, (_, singular) => {\n\t\tconst numValue = Number(value);\n\t\treturn numValue === 1 ? singular : \"\";\n\t});\n\n\treturn result;\n}\n\n// ============================================\n// GERAÇÃO DE VALUE LABEL\n// ============================================\n\n/**\n * Gera label formatado para o valor baseado no tipo e formato\n */\nfunction generateValueLabel(\n\tvalue: any,\n\tmetadata: FieldMetadata,\n\toptions: Partial<EnrichmentOptions> = {}\n): string | string[] | undefined {\n\tconst { format, unit, type, enum: enumValues } = metadata;\n\tconst { locale = \"pt-BR\", currency = \"BRL\" } = options;\n\n\t// Se não houver valor\n\tif (value === null || value === undefined) {\n\t\tif (format === \"currency\") return \"Valor sob consulta\";\n\t\treturn undefined;\n\t}\n\n\t// Formatação baseada no format\n\tswitch (format) {\n\t\tcase \"currency\":\n\t\t\treturn formatCurrency(value, unit || currency, locale);\n\n\t\tcase \"date\":\n\t\tcase \"datetime\":\n\t\t\treturn formatDateTime(value, locale);\n\n\t\tcase \"area\":\n\t\t\treturn formatArea(value, unit);\n\n\t\tcase \"distance\":\n\t\t\treturn formatDistance(value, unit);\n\n\t\tcase \"percent\":\n\t\t\treturn formatPercent(value);\n\n\t\tcase \"count\":\n\t\t\treturn formatCount(value);\n\n\t\tcase \"year\":\n\t\t\treturn formatYear(value);\n\t}\n\n\t// Para tipos específicos que precisam de transformação\n\tif (type === \"Boolean\") {\n\t\treturn value ? \"Sim\" : \"Não\";\n\t}\n\n\t// Arrays: retornar array de labels para valueLabel\n\tif (type === \"String[]\" && Array.isArray(value)) {\n\t\t// Se tem enum, mapear valores para labels\n\t\tif (enumValues && typeof enumValues === 'object') {\n\t\t\treturn value.map(v => enumValues[v] || v); // Array de labels\n\t\t}\n\t\t// Se não tem enum, retornar o próprio array (já vem formatado)\n\t\treturn value; // Array de labels já prontos\n\t}\n\n\t// String simples com enum: mapear valor para label\n\tif (type === \"String\" && enumValues && typeof enumValues === 'object') {\n\t\treturn enumValues[value] || value;\n\t}\n\n\t// Para JSON, Json[]: deixar o frontend decidir\n\tif (type === \"Json\" || type === \"Json[]\") {\n\t\treturn undefined;\n\t}\n\n\t// Para strings simples e números simples: NÃO gera valueLabel\n\treturn undefined;\n}\n\n// ============================================\n// FUNÇÃO PRINCIPAL DE ENRIQUECIMENTO\n// ============================================\n\n/**\n * Enriquece um único campo com seus metadados\n * Adaptado para o formato SSOT com contextos\n * \n * @param value - Valor do campo\n * @param metadata - Metadados SSOT do campo\n * @param options - Opções de enriquecimento\n * @returns Campo enriquecido\n */\nexport function enrichField(\n\trawValue: any,\n\tmetadata: FieldMetadata,\n\toptions: Partial<EnrichmentOptions> = {}\n): EnrichedField {\n\t// 1. DETERMINAR VALUE BASEADO NO TIPO\n\t// SEMPRE MANTER VALUE COMO RAW - resolução acontece só no valueLabel\n\tlet processedValue = rawValue;\n\t\n\t// 2. CRIAR RESULTADO ENXUTO\n\tconst result: EnrichedField = {\n\t\t// SEMPRE PRIMEIRO (conforme solicitado)\n\t\tkey: metadata.key,\n\t\t\n\t\t// VALORES CORE\n\t\tvalue: processedValue,\n\t\tlabel: metadata.ui?.label || metadata.key || \"Campo\"\n\t};\n\n\t// 3. GERAR VALUELABEL\n\tconst valueLabel = generateValueLabel(rawValue, metadata, options);\n\tif (valueLabel !== undefined) {\n\t\tresult.valueLabel = valueLabel;\n\t}\n\n\t// 4. PROCESSAR DISPLAYTEMPLATE (só para campos simples, não arrays)\n\tif (metadata.ui?.displayTemplate && !Array.isArray(valueLabel)) {\n\t\tconst displayLabel = processTemplate(\n\t\t\tmetadata.ui.displayTemplate,\n\t\t\tprocessedValue,\n\t\t\tvalueLabel\n\t\t);\n\t\tif (displayLabel) {\n\t\t\tresult.displayLabel = displayLabel;\n\t\t}\n\t}\n\n\t// 5. ADICIONAR ICONNAME E ICON RESOLVIDO\n\tif (metadata.ui?.iconName) {\n\t\tresult.iconName = metadata.ui.iconName;\n\t\t\n\t\t// Se getIcon foi configurado, resolver o ícone\n\t\tif (options.getIcon) {\n\t\t\tresult.icon = options.getIcon(metadata.ui.iconName);\n\t\t}\n\t}\n\n\t// 6. METADADOS BÁSICOS\n\tif (metadata.categories?.length) {\n\t\tresult.categories = metadata.categories;\n\t}\n\t\n\t// Sempre incluir type, format e unit quando existirem (para uso direto no frontend)\n\tif (metadata.type) {\n\t\tresult.type = metadata.type;\n\t}\n\tif (metadata.format) {\n\t\tresult.format = metadata.format;\n\t}\n\tif (metadata.unit) {\n\t\tresult.unit = metadata.unit;\n\t}\n\n\t// 7. METADADOS COMPLETOS (só quando includeMetadata: true)\n\tif (options.includeMetadata) {\n\t\t// Copiar TODOS os metadados do campo (cópia completa do objeto)\n\t\tresult.metadata = { ...metadata };\n\t}\n\n\treturn result;\n}\n\n// ============================================\n// EXPORTS ÚTEIS\n// ============================================\n\nexport const formatters = {\n\tcurrency: formatCurrency,\n\tdate: formatDateTime,\n\tarea: formatArea,\n\tdistance: formatDistance,\n\tpercent: formatPercent,\n\tcount: formatCount,\n\tyear: formatYear,\n};\n\nexport const templateProcessor = processTemplate;","/**\n * 🚀 Domain Enricher Engine - Motor Principal de Enriquecimento v2.0\n * \n * Classe principal que gerencia o enriquecimento de dados de domínios\n * com suporte a relacionamentos nested e campos computados\n * \n * @module domain-enricher-engine\n * @version 2.0.0\n */\n\nimport { enrichField } from \"./field-enricher\";\nimport type {\n\tDomainRegistry,\n\tFieldMetadata,\n\tIndexedDomainSchema,\n\tEnrichedData,\n\tEnrichedField,\n\tEnrichmentOptions\n} from \"./types\";\n\n// Removed: isRelationship, isRelationshipArray - using schema type as source of truth\n\n/**\n * Motor principal de enriquecimento de dados\n * \n * @example\n * ```typescript\n * const enricher = new DomainDataDisplayEnricher(registry, options);\n * const enrichedData = enricher.enrich(rawData, \"property\");\n * ```\n */\nexport class DomainDataDisplayEnricher {\n\tprivate registry: DomainRegistry;\n\tprivate options: EnrichmentOptions;\n\n\t/**\n\t * Construtor do motor de enriquecimento\n\t * \n\t * @param registry - Registry com configurações de todos os domínios\n\t * @param options - Opções globais de enriquecimento\n\t */\n\tconstructor(registry: DomainRegistry, options: EnrichmentOptions = {}) {\n\t\tthis.registry = registry;\n\t\tthis.options = {\n\t\t\tlocale: options.locale || \"pt-BR\",\n\t\t\tcurrency: options.currency || \"BRL\",\n\t\t\tincludeMetadata: options.includeMetadata,\n\t\t\tgetIcon: options.getIcon\n\t\t};\n\t}\n\n\t/**\n\t * Enriquece dados de um domínio específico\n\t * \n\t * @param rawData - Dados brutos do banco/API\n\t * @param domainKey - Chave do domínio (ex: \"property\", \"broker\")\n\t * @returns Dados enriquecidos com estrutura flat\n\t */\n\tpublic enrich(rawData: Record<string, any>, domainKey: string): EnrichedData {\n\t\t// Buscar configuração do domínio\n\t\tconst domainConfig = this.registry[domainKey];\n\t\tif (!domainConfig) {\n\t\t\tthrow new Error(`Domain \"${domainKey}\" not found in registry`);\n\t\t}\n\n\t\t// Executar enrichMapper do domínio para obter as 4 informações\n\t\tconst { data, schema, computedSchema, computedData } = domainConfig.enrichMapper(rawData);\n\n\t\t// Converter arrays para formato indexado interno\n\t\tconst indexedSchema = this.arrayToIndexedSchema(schema);\n\t\tconst indexedComputedSchema = this.arrayToIndexedSchema(computedSchema);\n\n\t\t// Criar objeto resultado (flat)\n\t\tconst enrichedResult: EnrichedData = {};\n\n\t\t// 1. Processar campos principais\n\t\tthis.processMainFields(data, indexedSchema, enrichedResult);\n\n\t\t// 2. Processar campos computados\n\t\tif (computedData && Object.keys(computedData).length > 0) {\n\t\t\tenrichedResult.computed = this.processComputedFields(computedData, indexedComputedSchema);\n\t\t}\n\n\t\treturn enrichedResult;\n\t}\n\n\t/**\n\t * Enriquece uma lista inteira de dados\n\t * \n\t * @param rawDataArray - Array de dados brutos\n\t * @param domainKey - Chave do domínio (\"property\", \"broker\", etc.)\n\t * @returns Array de dados enriquecidos\n\t */\n\tenrichList(rawDataArray: any[], domainKey: string): EnrichedData[] {\n\t\tif (!Array.isArray(rawDataArray)) {\n\t\t\tthrow new Error(\"enrichList expects an array as first parameter\");\n\t\t}\n\n\t\treturn rawDataArray.map(item => this.enrich(item, domainKey));\n\t}\n\n\t/**\n\t * Converte array de fields para formato indexado interno\n\t */\n\tprivate arrayToIndexedSchema(fields: FieldMetadata[]): IndexedDomainSchema {\n\t\tconst indexed: IndexedDomainSchema = {};\n\t\tfields.forEach(field => {\n\t\t\tindexed[field.key] = field;\n\t\t});\n\t\treturn indexed;\n\t}\n\n\t/**\n\t * Processa campos principais (incluindo relacionamentos)\n\t */\n\tprivate processMainFields(\n\t\tdata: Record<string, any>,\n\t\tindexedSchema: IndexedDomainSchema,\n\t\tresult: EnrichedData\n\t): void {\n\t\tfor (const [fieldKey, fieldValue] of Object.entries(data)) {\n\t\t\t// Se for undefined ou null, pular\n\t\t\tif (fieldValue === undefined || fieldValue === null) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Verificar metadados do campo no schema (SOURCE OF TRUTH)\n\t\t\tconst fieldMetadata = indexedSchema[fieldKey];\n\t\t\t\n\t\t\t// Se é relacionamento DECLARADO no schema\n\t\t\tif (fieldMetadata?.type === \"Relation\") {\n\t\t\t\t// Verificar se existe domínio no registry\n\t\t\t\tif (this.registry[fieldKey]) {\n\t\t\t\t\t// Array de relacionamentos\n\t\t\t\t\tif (Array.isArray(fieldValue)) {\n\t\t\t\t\t\tresult[fieldKey] = fieldValue.map((item: any) => \n\t\t\t\t\t\t\tthis.enrich(item, fieldKey)\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Relacionamento único\n\t\t\t\t\t\tresult[fieldKey] = this.enrich(fieldValue, fieldKey);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Relacionamento declarado mas sem domínio no registry - manter como está\n\t\t\t\t\tresult[fieldKey] = fieldValue;\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Campo normal - enriquecer com metadados ou manter como está\n\t\t\tif (fieldMetadata) {\n\t\t\t\tresult[fieldKey] = enrichField(fieldValue, fieldMetadata, this.options);\n\t\t\t} else {\n\t\t\t\t// Campo sem metadados - preservar valor original\n\t\t\t\tresult[fieldKey] = { value: fieldValue };\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Processa campos computados\n\t */\n\tprivate processComputedFields(\n\t\tcomputedData: Record<string, any>,\n\t\tindexedComputedSchema: IndexedDomainSchema\n\t): Record<string, EnrichedField> {\n\t\tconst enrichedComputed: Record<string, EnrichedField> = {};\n\n\t\tfor (const [fieldKey, fieldValue] of Object.entries(computedData)) {\n\t\t\t// Se for undefined ou null, pular\n\t\t\tif (fieldValue === undefined || fieldValue === null) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Buscar metadados do campo computado\n\t\t\tconst fieldMetadata = indexedComputedSchema[fieldKey];\n\t\t\tif (fieldMetadata) {\n\t\t\t\tenrichedComputed[fieldKey] = enrichField(fieldValue, fieldMetadata, this.options);\n\t\t\t} else {\n\t\t\t\t// Campo computado sem metadados - preservar valor\n\t\t\t\tenrichedComputed[fieldKey] = { \n\t\t\t\t\tkey: fieldKey,\n\t\t\t\t\tvalue: fieldValue, \n\t\t\t\t\tlabel: fieldKey \n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn enrichedComputed;\n\t}\n\n\n\t/**\n\t * Atualiza o registry em runtime\n\t * \n\t * @param domainKey - Chave do domínio\n\t * @param config - Nova configuração do domínio\n\t */\n\tpublic registerDomain(domainKey: string, config: any): void {\n\t\tthis.registry[domainKey] = config;\n\t}\n\n\t/**\n\t * Remove um domínio do registry\n\t * \n\t * @param domainKey - Chave do domínio a remover\n\t */\n\tpublic unregisterDomain(domainKey: string): void {\n\t\tdelete this.registry[domainKey];\n\t}\n\n\t/**\n\t * Atualiza opções globais\n\t * \n\t * @param options - Novas opções\n\t */\n\tpublic updateOptions(options: Partial<EnrichmentOptions>): void {\n\t\tthis.options = {\n\t\t\t...this.options,\n\t\t\t...options\n\t\t};\n\t}\n\n\t/**\n\t * Obtém o registry atual\n\t */\n\tpublic getRegistry(): DomainRegistry {\n\t\treturn this.registry;\n\t}\n\n\t/**\n\t * Obtém as opções atuais\n\t */\n\tpublic getOptions(): EnrichmentOptions {\n\t\treturn this.options;\n\t}\n}\n\n// Export default\nexport default DomainDataDisplayEnricher;","/**\n * 🎣 React Hooks para Domain Data Display Enricher\n * \n * Hooks customizados para facilitar uso do enricher em React\n * \n * @module hooks\n * @version 2.0.0\n */\n\nimport { useState, useEffect, useMemo } from 'react';\nimport { DomainDataDisplayEnricher } from './domain-enricher-engine';\nimport type { DomainRegistry, EnrichedData, EnrichmentOptions } from './types';\n\n/**\n * Hook para enriquecer uma lista de dados automaticamente\n * \n * @param rawData - Array de dados brutos\n * @param domainKey - Chave do domínio (\"property\", \"broker\", etc.)\n * @param registry - Registry de domínios\n * @param options - Opções de enriquecimento (opcional)\n * @returns { enrichedData, loading, error }\n */\nexport function useEnrichList(\n\trawData: any[], \n\tdomainKey: string,\n\tregistry: DomainRegistry,\n\toptions?: Partial<EnrichmentOptions>\n) {\n\tconst [enrichedData, setEnrichedData] = useState<EnrichedData[]>([]);\n\tconst [loading, setLoading] = useState(false);\n\tconst [error, setError] = useState<Error | null>(null);\n\n\t// Criar instância do enricher apenas quando necessário\n\tconst enricher = useMemo(() => {\n\t\treturn new DomainDataDisplayEnricher(registry, options);\n\t}, [registry, options]);\n\n\tuseEffect(() => {\n\t\t// Se não há dados, limpar estado\n\t\tif (!rawData?.length) {\n\t\t\tsetEnrichedData([]);\n\t\t\tsetLoading(false);\n\t\t\tsetError(null);\n\t\t\treturn;\n\t\t}\n\n\t\t// Validar domainKey\n\t\tif (!registry[domainKey]) {\n\t\t\tconst err = new Error(`Domain '${domainKey}' not found in registry`);\n\t\t\tsetError(err);\n\t\t\tsetLoading(false);\n\t\t\treturn;\n\t\t}\n\n\t\tsetLoading(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst enriched = enricher.enrichList(rawData, domainKey);\n\t\t\tsetEnrichedData(enriched);\n\t\t} catch (err) {\n\t\t\tsetError(err instanceof Error ? err : new Error(String(err)));\n\t\t} finally {\n\t\t\tsetLoading(false);\n\t\t}\n\t}, [rawData, domainKey, enricher]);\n\n\treturn { enrichedData, loading, error };\n}\n\n/**\n * Hook para enriquecer um único item\n * \n * @param rawData - Dados brutos\n * @param domainKey - Chave do domínio\n * @param registry - Registry de domínios\n * @param options - Opções de enriquecimento (opcional)\n * @returns { enrichedData, loading, error }\n */\nexport function useEnrich(\n\trawData: any,\n\tdomainKey: string,\n\tregistry: DomainRegistry,\n\toptions?: Partial<EnrichmentOptions>\n) {\n\tconst [enrichedData, setEnrichedData] = useState<EnrichedData | null>(null);\n\tconst [loading, setLoading] = useState(false);\n\tconst [error, setError] = useState<Error | null>(null);\n\n\t// Criar instância do enricher apenas quando necessário\n\tconst enricher = useMemo(() => {\n\t\treturn new DomainDataDisplayEnricher(registry, options);\n\t}, [registry, options]);\n\n\tuseEffect(() => {\n\t\t// Se não há dados, limpar estado\n\t\tif (!rawData) {\n\t\t\tsetEnrichedData(null);\n\t\t\tsetLoading(false);\n\t\t\tsetError(null);\n\t\t\treturn;\n\t\t}\n\n\t\t// Validar domainKey\n\t\tif (!registry[domainKey]) {\n\t\t\tconst err = new Error(`Domain '${domainKey}' not found in registry`);\n\t\t\tsetError(err);\n\t\t\tsetLoading(false);\n\t\t\treturn;\n\t\t}\n\n\t\tsetLoading(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst enriched = enricher.enrich(rawData, domainKey);\n\t\t\tsetEnrichedData(enriched);\n\t\t} catch (err) {\n\t\t\tsetError(err instanceof Error ? err : new Error(String(err)));\n\t\t} finally {\n\t\t\tsetLoading(false);\n\t\t}\n\t}, [rawData, domainKey, enricher]);\n\n\treturn { enrichedData, loading, error };\n}\n\n/**\n * Hook para criar uma instância persistente do enricher\n * \n * @param registry - Registry de domínios\n * @param options - Opções de enriquecimento (opcional)\n * @returns instância do DomainDataDisplayEnricher\n */\nexport function useEnricher(\n\tregistry: DomainRegistry,\n\toptions?: Partial<EnrichmentOptions>\n): DomainDataDisplayEnricher {\n\treturn useMemo(() => {\n\t\treturn new DomainDataDisplayEnricher(registry, options);\n\t}, [registry, options]);\n}","/**\n * JsonToZodGenerator - Converte schemas Horizon Fields Metadata Pattern v2.2.0 para Zod\n * \n * Suporta o novo formato com:\n * - categories (ao invés de tags)\n * - validation.precision para decimais\n * - enum como object\n * - mask para validações automáticas\n * - conditions para campos condicionais\n * - parent para hierarquias\n * - db metadata (ignorado na geração Zod)\n * - Inferência inteligente\n */\n\nexport interface HorizonFieldDefinition {\n  key: string\n  type: \"String\" | \"String[]\" | \"Number\" | \"Boolean\" | \"Json\" | \"Json[]\" | \"Array\"\n  label: string\n  categories?: string[]\n  \n  // Validação\n  validation?: {\n    required?: boolean\n    min?: number\n    max?: number\n    minLength?: number\n    maxLength?: number\n    precision?: number  // Novo campo para decimais\n  }\n  \n  // Formato e apresentação\n  format?: \"currency\" | \"area\" | \"distance\" | \"count\" | \"percent\" | \"date\" | \"datetime\" | \"time\"\n  unit?: string\n  mask?: \"cpf\" | \"cnpj\" | \"cep\" | \"phone\" | \"email\" | \"url\"  // Frontend only! Backend recebe dados limpos\n  \n  // Enum novo formato (object)\n  enum?: Record<string, string>\n  \n  // Relações e dependências\n  conditions?: string[]  // [\"operacao:venda\", \"tipo.equals:apartamento\"]\n  parent?: string\n  \n  // UI/UX\n  searchable?: boolean\n  filterable?: boolean\n  sortable?: boolean\n  \n  // DB (ignorado na geração Zod)\n  db?: {\n    type?: string\n    unique?: boolean\n    index?: boolean | string\n    default?: any\n  }\n  \n  // Auditoria\n  origin?: string\n  modifiedBy?: string[]\n}\n\nexport interface JsonToZodOptions {\n  schemaName: string\n  addDescriptions?: boolean\n  addValidationMessages?: boolean\n  exportType?: boolean\n  sortFields?: boolean\n  \n  // Novos options v2\n  enablePrecisionValidation?: boolean  // Gerar .multipleOf() para precision\n  // MASK É SÓ FRONTEND! Backend recebe dados limpos\n  // CONDITIONS É SÓ FRONTEND! (controle de exibição de campos)\n  logInference?: boolean               // Log das inferências realizadas\n}\n\nexport class JsonToZodGenerator {\n  private static inferenceLog: string[] = []\n  \n  /**\n   * Aplica inferência inteligente em um campo\n   */\n  private static applyInference(field: HorizonFieldDefinition, options: JsonToZodOptions): HorizonFieldDefinition {\n    const inferredField = { ...field }\n    \n    if (options.logInference) {\n      this.inferenceLog = []\n    }\n    \n    // Inferência de precision para multipleOf\n    if (field.validation?.precision && options.enablePrecisionValidation) {\n      const multipleOf = Math.pow(10, -field.validation.precision)\n      this.log(`🔢 ${field.key}: precision ${field.validation.precision} → multipleOf ${multipleOf}`)\n    }\n    \n    // MASK É SÓ PARA FRONTEND! Backend recebe dados limpos\n    if (field.mask) {\n      this.log(`🎭 ${field.key}: mask \"${field.mask}\" → FRONTEND ONLY (backend receives clean data)`)\n    }\n    \n    // Inferência de tipos especiais\n    if (field.type === 'Json') {\n      this.log(`📦 ${field.key}: Json type → z.any() or z.record()`)\n    }\n    \n    // Inferência para arrays\n    if (field.type === 'String[]' && field.searchable) {\n      this.log(`🔍 ${field.key}: String[] + searchable → GIN index (DB only)`)\n    }\n    \n    // Inferência para campos de texto longo\n    if (field.type === 'String' && field.searchable && !field.validation?.maxLength) {\n      this.log(`📝 ${field.key}: String + searchable + no maxLength → fulltext index (DB only)`)\n    }\n    \n    return inferredField\n  }\n  \n  private static log(message: string) {\n    this.inferenceLog.push(message)\n  }\n  \n  \n  /**\n   * Converte um campo para Zod\n   */\n  private static fieldToZod(field: HorizonFieldDefinition, options: JsonToZodOptions): string {\n    // Aplicar inferência\n    const processedField = this.applyInference(field, options)\n    \n    const { key, type, label, validation, enum: enumValues } = processedField\n    \n    let zodType = ''\n    let validations: string[] = []\n    \n    // Mapear tipos base\n    switch (type) {\n      case 'String':\n        if (enumValues && Object.keys(enumValues).length > 0) {\n          // Enum com novo formato object\n          const enumArray = Object.keys(enumValues).map(k => `\"${k}\"`).join(', ')\n          zodType = `z.enum([${enumArray}])`\n        } else {\n          zodType = 'z.string()'\n        }\n        \n        // Validações de string\n        if (validation?.minLength) validations.push(`.min(${validation.minLength})`)\n        if (validation?.maxLength) validations.push(`.max(${validation.maxLength})`)\n        \n        // MASK É SÓ PARA FRONTEND! Backend recebe dados limpos\n        break\n        \n      case 'Number':\n        zodType = 'z.number()'\n        \n        // Validações numéricas\n        if (validation?.min !== undefined) validations.push(`.min(${validation.min})`)\n        if (validation?.max !== undefined) validations.push(`.max(${validation.max})`)\n        \n        // Precision para multipleOf\n        if (validation?.precision && options.enablePrecisionValidation) {\n          const multipleOf = Math.pow(10, -validation.precision)\n          validations.push(`.multipleOf(${multipleOf})`)\n        }\n        break\n        \n      case 'Boolean':\n        zodType = 'z.boolean()'\n        break\n        \n      case 'String[]':\n        if (enumValues && Object.keys(enumValues).length > 0) {\n          // Array de enum\n          const enumArray = Object.keys(enumValues).map(k => `\"${k}\"`).join(', ')\n          zodType = `z.array(z.enum([${enumArray}]))`\n        } else {\n          zodType = 'z.array(z.string())'\n        }\n        break\n        \n      case 'Array':\n        zodType = 'z.array(z.any())'\n        break\n        \n      case 'Json':\n        // Objeto JSON único\n        zodType = 'z.any()' // ou z.record(z.any()) dependendo do uso\n        break\n        \n      case 'Json[]':\n        // Array de objetos JSON\n        zodType = 'z.array(z.any())'\n        break\n        \n      default:\n        zodType = 'z.any()'\n    }\n    \n    // Adicionar validações\n    zodType += validations.join('')\n    \n    // Adicionar descrição se habilitado\n    if (options.addDescriptions && label) {\n      zodType += `.describe(\"${label}\")`\n    }\n    \n    // Required/Optional\n    if (!validation?.required) {\n      zodType += '.optional()'\n    }\n    \n    return `  ${key}: ${zodType},`\n  }\n  \n  \n  /**\n   * Gera o schema Zod completo\n   */\n  static generate(fields: HorizonFieldDefinition[], options: JsonToZodOptions): string {\n    const { \n      schemaName, \n      sortFields = false, \n      exportType = true,\n      logInference = false\n    } = options\n    \n    if (logInference) {\n      console.log(`\\n🧠 INICIANDO GERAÇÃO COM INFERÊNCIA - ${schemaName}`)\n      console.log(`📊 Total de campos: ${fields.length}`)\n    }\n    \n    // Ordenar campos se solicitado\n    const processedFields = sortFields \n      ? [...fields].sort((a, b) => a.key.localeCompare(b.key))\n      : fields\n    \n    // Gerar imports\n    const imports = `import { z } from \"zod\"\\n`\n    \n    // Gerar campos do schema\n    const schemaFields = processedFields\n      .map(field => this.fieldToZod(field, options))\n      .join('\\n')\n    \n    // Gerar schema base\n    const schema = `\n// Schema Horizon v2.2.0 para ${schemaName}\n// Gerado automaticamente com inferência inteligente\nexport const ${schemaName}Zod = z.object({\n${schemaFields}\n})\n`\n    \n    // CONDITIONS É SÓ PARA FRONTEND! (controle de exibição de campos)\n    \n    // Gerar tipo TypeScript se solicitado\n    const typeExport = exportType \n      ? `\n// Tipo inferido a partir do schema\nexport type ${schemaName}Type = z.infer<typeof ${schemaName}Zod>\n\n// Função helper para validação\nexport const validate${schemaName} = (data: unknown): ${schemaName}Type => {\n  return ${schemaName}Zod.parse(data)\n}\n\n// Função helper para validação safe\nexport const safeValidate${schemaName} = (data: unknown) => {\n  return ${schemaName}Zod.safeParse(data)\n}\n\n// Função helper para validação parcial\nexport const validatePartial${schemaName} = (data: unknown) => {\n  return ${schemaName}Zod.partial().parse(data)\n}\n`\n      : ''\n    \n    // Log das inferências\n    if (logInference && this.inferenceLog.length > 0) {\n      console.log(`\\n🧠 INFERÊNCIAS APLICADAS:`)\n      this.inferenceLog.forEach(log => console.log(log))\n      console.log(`\\n✅ Geração concluída com ${this.inferenceLog.length} inferências`)\n    }\n    \n    return imports + schema + typeExport\n  }\n  \n  /**\n   * Gera schema a partir de arquivo JSON v2.2.0\n   */\n  static async generateFromFile(jsonPath: string, options: JsonToZodOptions): Promise<string> {\n    const fs = await import('fs/promises')\n    const jsonContent = await fs.readFile(jsonPath, 'utf-8')\n    const data = JSON.parse(jsonContent)\n    \n    // Suporta formato { fields: [...] }\n    const fields = data.fields || data\n    \n    if (!Array.isArray(fields)) {\n      throw new Error('JSON deve conter um array de campos ou objeto com propriedade \"fields\"')\n    }\n    \n    return this.generate(fields, options)\n  }\n  \n  /**\n   * Salva o schema gerado\n   */\n  static async saveToFile(\n    fields: HorizonFieldDefinition[], \n    options: JsonToZodOptions, \n    outputPath: string\n  ): Promise<void> {\n    const fs = await import('fs/promises')\n    const path = await import('path')\n    \n    const generated = this.generate(fields, options)\n    \n    // Criar diretório se não existir\n    const dir = path.dirname(outputPath)\n    await fs.mkdir(dir, { recursive: true })\n    \n    // Salvar arquivo\n    await fs.writeFile(outputPath, generated, 'utf-8')\n    \n    if (options.logInference) {\n      console.log(`\\n💾 Schema salvo: ${outputPath}`)\n    }\n  }\n  \n  /**\n   * Analisa um schema e retorna estatísticas\n   */\n  static analyzeSchema(fields: HorizonFieldDefinition[]): {\n    totalFields: number\n    fieldTypes: Record<string, number>\n    fieldFormats: Record<string, number>\n    fieldCategories: Record<string, number>\n    requiredFields: number\n    fieldsWithValidation: number\n    fieldsWithMask: number\n    fieldsWithEnum: number\n    fieldsWithConditions: number\n    fieldsWithParent: number\n  } {\n    const analysis = {\n      totalFields: fields.length,\n      fieldTypes: {} as Record<string, number>,\n      fieldFormats: {} as Record<string, number>,\n      fieldCategories: {} as Record<string, number>,\n      requiredFields: 0,\n      fieldsWithValidation: 0,\n      fieldsWithMask: 0,\n      fieldsWithEnum: 0,\n      fieldsWithConditions: 0,\n      fieldsWithParent: 0\n    }\n    \n    fields.forEach(field => {\n      // Tipos\n      analysis.fieldTypes[field.type] = (analysis.fieldTypes[field.type] || 0) + 1\n      \n      // Formatos\n      if (field.format) {\n        analysis.fieldFormats[field.format] = (analysis.fieldFormats[field.format] || 0) + 1\n      }\n      \n      // Categorias\n      if (field.categories) {\n        field.categories.forEach(cat => {\n          analysis.fieldCategories[cat] = (analysis.fieldCategories[cat] || 0) + 1\n        })\n      }\n      \n      // Contadores\n      if (field.validation?.required) analysis.requiredFields++\n      if (field.validation) analysis.fieldsWithValidation++\n      if (field.mask) analysis.fieldsWithMask++\n      if (field.enum) analysis.fieldsWithEnum++\n      if (field.conditions) analysis.fieldsWithConditions++\n      if (field.parent) analysis.fieldsWithParent++\n    })\n    \n    return analysis\n  }\n}\n\n// Re-exportar tipos para conveniência\nexport type { JsonToZodOptions as GeneratorOptions }","/**\n * 🔍 Horizon Domain Data Filters\n * \n * Funções utilitárias para filtrar e selecionar campos de dados de domínio\n * Compatível com formato array e objeto enriquecido\n * \n * @module horizon-domain-data-filters\n * @version 1.0.0\n */\n\n// ============================================\n// TYPES & INTERFACES\n// ============================================\n\nexport interface Field {\n\tkey: string;\n\tvalue?: any;\n\tlabel?: string;\n\ttype?: string;\n\tcategory?: string | string[];\n\tcategories?: string | string[];\n\t[key: string]: any;\n}\n\nexport type FieldsArray = Field[];\nexport type FieldsObject = Record<string, Field>;\nexport type FieldsInput = FieldsArray | FieldsObject;\n\n// ============================================\n// FILTER FUNCTIONS\n// ============================================\n\n/**\n * Filtra campos por categoria(s)\n * \n * @param fields - Array de campos ou objeto de campos enriquecidos\n * @param category - String de categoria única ou array de categorias\n * @param asObject - Se true, retorna como objeto; se false, retorna como array\n * @param preserveOrder - Se true, preserva a ordem das categorias solicitadas (padrão: false)\n * @returns Campos filtrados como array ou objeto\n * \n * @example\n * // Filtrar por categoria única\n * const mainFields = getFieldsByCategory(fields, 'main');\n * \n * @example\n * // Filtrar por múltiplas categorias\n * const valueFields = getFieldsByCategory(fields, ['pricing', 'values']);\n * \n * @example\n * // Retornar como objeto\n * const fieldsObj = getFieldsByCategory(fields, 'main', true);\n * \n * @example\n * // Preservar ordem das categorias solicitadas\n * const orderedFields = getFieldsByCategory(fields, ['pricing', 'dimensions'], false, true);\n * // Retorna todos os campos 'pricing' primeiro, depois todos os 'dimensions'\n */\nexport function getFieldsByCategory(\n\tfields: FieldsInput,\n\tcategory: string | string[],\n\tasObject: boolean = false,\n\tpreserveOrder: boolean = false\n): FieldsArray | FieldsObject {\n\t\n\t// Função helper para verificar match de categoria\n\tconst matchesCategory = (fieldCategory: string | string[] | undefined): boolean => {\n\t\tif (!fieldCategory) return false;\n\t\t\n\t\t// Normalizar para sempre trabalhar com arrays\n\t\tconst fieldCats = Array.isArray(fieldCategory) ? fieldCategory : [fieldCategory];\n\t\tconst searchCats = Array.isArray(category) ? category : [category];\n\t\t\n\t\t// Verificar se alguma categoria do campo está nas categorias buscadas\n\t\treturn fieldCats.some(cat => searchCats.includes(cat));\n\t};\n\t\n\t// Função helper para extrair categoria do campo\n\tconst getFieldCategory = (field: Field): string | string[] | undefined => {\n\t\t// Suporta tanto 'category' quanto 'categories' como nome do campo\n\t\treturn field?.categories || field?.category;\n\t};\n\t\n\t// Processar baseado no tipo de input\n\tlet matchingFields: FieldsArray;\n\t\n\tif (preserveOrder && Array.isArray(category)) {\n\t\t// Se preserveOrder é true e temos múltiplas categorias, ordenar pela ordem das categorias\n\t\tconst allFields = Array.isArray(fields) ? fields : Object.values(fields);\n\t\tmatchingFields = [];\n\t\t\n\t\t// Para cada categoria na ordem solicitada\n\t\tfor (const cat of category) {\n\t\t\t// Adicionar todos os campos dessa categoria\n\t\t\tconst categoryFields = allFields.filter(field => {\n\t\t\t\tconst fieldCat = getFieldCategory(field);\n\t\t\t\tif (!fieldCat) return false;\n\t\t\t\t\n\t\t\t\t// Check se o campo tem exatamente essa categoria\n\t\t\t\tif (Array.isArray(fieldCat)) {\n\t\t\t\t\treturn fieldCat.includes(cat);\n\t\t\t\t}\n\t\t\t\treturn fieldCat === cat;\n\t\t\t});\n\t\t\t\n\t\t\t// Adicionar apenas campos que ainda não foram adicionados (evitar duplicatas)\n\t\t\tcategoryFields.forEach(field => {\n\t\t\t\tif (!matchingFields.some(f => f.key === field.key)) {\n\t\t\t\t\tmatchingFields.push(field);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t} else {\n\t\t// Comportamento padrão: filtrar mantendo ordem original\n\t\tif (Array.isArray(fields)) {\n\t\t\t// Formato array: filtrar diretamente\n\t\t\tmatchingFields = fields.filter(field => \n\t\t\t\tmatchesCategory(getFieldCategory(field))\n\t\t\t);\n\t\t} else {\n\t\t\t// Formato objeto: converter valores para array e filtrar\n\t\t\tmatchingFields = Object.values(fields).filter(field =>\n\t\t\t\tmatchesCategory(getFieldCategory(field))\n\t\t\t);\n\t\t}\n\t}\n\t\n\t// Retornar no formato solicitado\n\tif (asObject) {\n\t\tconst result: FieldsObject = {};\n\t\tmatchingFields.forEach(field => {\n\t\t\tresult[field.key] = field;\n\t\t});\n\t\treturn result;\n\t}\n\t\n\treturn matchingFields;\n}\n\n/**\n * Filtra campos por lista de keys, mantendo a ordem especificada\n * Retorna apenas campos com valores válidos (não null, undefined, empty string ou NaN)\n * \n * @param fields - Array de campos ou objeto de campos enriquecidos\n * @param keys - Array de keys na ordem desejada\n * @param asObject - Se true, retorna como objeto; se false, retorna como array (padrão)\n * @returns Array ou objeto de campos na ordem das keys, apenas com valores válidos\n * \n * @example\n * // Buscar campos específicos na ordem desejada (array)\n * const orderedFields = getFieldsByKeys(fields, ['valor_venda', 'area_total', 'dormitorios']);\n * \n * @example\n * // Retornar como objeto para lookup rápido\n * const fieldsObj = getFieldsByKeys(fields, ['valor_venda', 'area_total'], true);\n * \n * @example\n * // Campos sem valores válidos são ignorados\n * const validFields = getFieldsByKeys(fields, ['field1', 'field2', 'field3']);\n * // Se field2.value for null, ele não aparece no resultado\n */\nexport function getFieldsByKeys(\n\tfields: FieldsInput,\n\tkeys: string[],\n\tasObject: boolean = false\n): FieldsArray | FieldsObject {\n\t\n\tif (!Array.isArray(keys) || keys.length === 0) {\n\t\treturn asObject ? {} : [];\n\t}\n\t\n\t// Função helper para verificar se tem valor válido\n\tconst hasValidValue = (field: Field | undefined): boolean => {\n\t\tif (!field) return false;\n\t\t\n\t\tconst value = field.value;\n\t\t\n\t\t// Considera inválido se for:\n\t\t// - null\n\t\t// - undefined\n\t\t// - string vazia\n\t\t// - NaN\n\t\tif (value === null || value === undefined || value === '' || Number.isNaN(value)) {\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\t// Arrays vazios também são considerados inválidos\n\t\tif (Array.isArray(value) && value.length === 0) {\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\treturn true;\n\t};\n\t\n\t// Criar mapa para acesso rápido\n\tlet fieldsMap: Map<string, Field>;\n\t\n\tif (Array.isArray(fields)) {\n\t\t// Formato array: criar mapa a partir do array\n\t\tfieldsMap = new Map(fields.map(field => [field.key, field]));\n\t} else {\n\t\t// Formato objeto: criar mapa a partir do objeto\n\t\tfieldsMap = new Map(Object.entries(fields));\n\t}\n\t\n\t// Mapear keys para campos, mantendo ordem e filtrando inválidos\n\tconst matchingFields = keys\n\t\t.map(key => fieldsMap.get(key))\n\t\t.filter((field): field is Field => hasValidValue(field));\n\t\n\t// Retornar no formato solicitado\n\tif (asObject) {\n\t\tconst result: FieldsObject = {};\n\t\tmatchingFields.forEach(field => {\n\t\t\tresult[field.key] = field;\n\t\t});\n\t\treturn result;\n\t}\n\t\n\treturn matchingFields;\n}\n\n// ============================================\n// EXPORTS\n// ============================================\n\nexport default {\n\tgetFieldsByCategory,\n\tgetFieldsByKeys\n};","/**\n * 🔄 Horizon Domain Data Transformers\n * \n * Funções para transformar estruturas de dados de domínio\n * \n * @module horizon-domain-data-transformers\n * @version 1.0.0\n */\n\n// ============================================\n// TYPES & INTERFACES\n// ============================================\n\nexport interface Field {\n\tkey: string;\n\tvalue?: any;\n\tlabel?: string;\n\ttype?: string;\n\t[key: string]: any;\n}\n\n// ============================================\n// TRANSFORM FUNCTIONS\n// ============================================\n\n/**\n * Expande um campo array em múltiplos campos booleanos\n * Cada item do array se torna um campo independente com value: true\n * \n * @param field - Campo com value array ou diretamente um array de strings\n * @returns Array de campos booleanos\n * \n * @example\n * // Passando campo completo\n * const field = { key: 'amenities', value: ['pool', 'gym', 'parking'] };\n * const booleans = expandArrayFieldToBoolean(field);\n * // Resultado: [\n * //   { key: 'pool', value: true, type: 'Boolean', label: 'pool' },\n * //   { key: 'gym', value: true, type: 'Boolean', label: 'gym' },\n * //   { key: 'parking', value: true, type: 'Boolean', label: 'parking' }\n * // ]\n * \n * @example\n * // Passando array direto\n * const booleans = expandArrayFieldToBoolean(['wifi', 'ac', 'tv']);\n * // Resultado: [\n * //   { key: 'wifi', value: true, type: 'Boolean', label: 'wifi' },\n * //   { key: 'ac', value: true, type: 'Boolean', label: 'ac' },\n * //   { key: 'tv', value: true, type: 'Boolean', label: 'tv' }\n * // ]\n * \n * @example\n * // Uso direto com propriedade\n * const property = { amenities: { key: 'amenities', value: ['pool', 'gym'] } };\n * const booleans = expandArrayFieldToBoolean(property.amenities);\n */\nexport function expandArrayFieldToBoolean(field: Field | string[]): Field[] {\n\t// Se receber array direto de strings\n\tif (Array.isArray(field)) {\n\t\treturn field.map(item => ({\n\t\t\tkey: String(item),\n\t\t\tvalue: true,\n\t\t\ttype: 'Boolean',\n\t\t\tlabel: String(item)\n\t\t}));\n\t}\n\t\n\t// Se receber campo com value array\n\tif (field && field.value && Array.isArray(field.value)) {\n\t\treturn field.value.map(item => ({\n\t\t\tkey: String(item),\n\t\t\tvalue: true,\n\t\t\ttype: 'Boolean',\n\t\t\tlabel: String(item)\n\t\t}));\n\t}\n\t\n\t// Se não for array válido, retorna array vazio\n\treturn [];\n}\n\n/**\n * Ordena um array de objetos baseado em múltiplos campos e direções\n * \n * @param fields - Array de objetos para ordenar\n * @param sortKeys - Array de strings no formato \"campo:direção\" (ex: [\"name:asc\", \"price:desc\"])\n * @returns Array ordenado (nova instância, não modifica o original)\n * \n * @example\n * // Ordenar por nome crescente, depois preço decrescente\n * const products = [\n *   { name: \"Casa A\", price: 300000, area: 120 },\n *   { name: \"Casa B\", price: 250000, area: 100 },\n *   { name: \"Casa A\", price: 280000, area: 110 }\n * ];\n * \n * const sorted = sortFields(products, [\"name:asc\", \"price:desc\"]);\n * // Resultado: Casa A (300k), Casa A (280k), Casa B (250k)\n * \n * @example\n * // Ordenar apenas por um campo\n * const sorted = sortFields(products, [\"area:desc\"]);\n */\nexport function sortFields(fields: any[], sortKeys: string[] = []): any[] {\n    return [...fields].sort((a, b) => {\n        for (const rule of sortKeys) {\n            const [field, direction] = rule.split(\":\");\n            const valA = a[field];\n            const valB = b[field];\n\n            if (valA === undefined || valB === undefined) continue;\n\n            const isAsc = direction === \"asc\";\n            const isDesc = direction === \"desc\";\n\n            if (!isAsc && !isDesc) {\n                console.warn(`Direção inválida: \"${direction}\". Use \"asc\" ou \"desc\".`);\n                continue;\n            }\n\n            if (valA < valB) return isAsc ? -1 : 1;\n            if (valA > valB) return isAsc ? 1 : -1;\n        }\n        return 0;\n    });\n}\n\n// ============================================\n// EXPORTS\n// ============================================\n\nexport default {\n\texpandArrayFieldToBoolean,\n\tsortFields\n};","/**\n * 🎯 Base Resolver - Classe abstrata para todos os resolvers\n */\n\nimport { IResolver, FieldConfig } from '../../core/interfaces'\n\nexport abstract class BaseResolver implements IResolver {\n  protected config: FieldConfig\n  \n  constructor(config?: FieldConfig) {\n    this.config = config || { resolver: 'base' }\n  }\n  \n  /**\n   * Obtém o nome do campo para usar na URL (considera alias)\n   */\n  protected getUrlKey(key: string): string {\n    return this.config.alias || key\n  }\n  \n  /**\n   * Serializa um valor para query string params\n   */\n  abstract serialize(key: string, value: any): string[]\n  \n  /**\n   * Deserializa de volta para o valor original\n   */\n  abstract deserialize(params: Record<string, string | string[]>, key: string): any\n  \n  /**\n   * Helper para encodar valores na URL\n   */\n  protected encodeValue(value: any): string {\n    if (value === null || value === undefined) {\n      return ''\n    }\n    // Para valores simples, converte para string\n    // Nota: : e , não precisam encoding\n    return String(value)\n  }\n  \n  /**\n   * Helper para criar param no formato key=value\n   */\n  protected createParam(key: string, value: any): string {\n    return `${key}=${this.encodeValue(value)}`\n  }\n}","/**\n * 🎯 Range Identifier\n * \n * Identifica e processa objetos com gte/lte\n * Ex: { gte: 100, lte: 500 } → campo[min]=100&campo[max]=500\n */\n\nimport { IJsonIdentifier } from '../core/interfaces'\n\nexport class RangeIdentifier implements IJsonIdentifier {\n  name = 'range'\n  \n  /**\n   * Detecta se é um objeto range (tem gte ou lte)\n   */\n  detect(value: any): boolean {\n    if (!value || typeof value !== 'object' || Array.isArray(value)) {\n      return false\n    }\n    \n    // Verifica se tem gte, lte, gt ou lt\n    return 'gte' in value || 'lte' in value || 'gt' in value || 'lt' in value\n  }\n  \n  /**\n   * Serializa para formato [min]/[max]\n   */\n  serialize(key: string, value: any): string[] {\n    const params: string[] = []\n    \n    // Processa min (gte ou gt)\n    if ('gte' in value && value.gte !== undefined && value.gte !== null) {\n      params.push(`${key}[min]=${value.gte}`)\n    } else if ('gt' in value && value.gt !== undefined && value.gt !== null) {\n      params.push(`${key}[min]=${value.gt}`)\n    }\n    \n    // Processa max (lte ou lt)\n    if ('lte' in value && value.lte !== undefined && value.lte !== null) {\n      params.push(`${key}[max]=${value.lte}`)\n    } else if ('lt' in value && value.lt !== undefined && value.lt !== null) {\n      params.push(`${key}[max]=${value.lt}`)\n    }\n    \n    return params\n  }\n  \n  /**\n   * Deserializa de volta para objeto com gte/lte\n   */\n  deserialize(params: Record<string, string | string[]>, key: string): any {\n    const minKey = `${key}[min]`\n    const maxKey = `${key}[max]`\n    \n    const minValue = params[minKey]\n    const maxValue = params[maxKey]\n    \n    // Se não tem nenhum, retorna undefined\n    if (!minValue && !maxValue) {\n      return undefined\n    }\n    \n    const result: any = {}\n    \n    // Processa min\n    if (minValue) {\n      const min = Array.isArray(minValue) ? minValue[0] : minValue\n      const numMin = Number(min)\n      result.gte = isNaN(numMin) ? min : numMin\n    }\n    \n    // Processa max\n    if (maxValue) {\n      const max = Array.isArray(maxValue) ? maxValue[0] : maxValue\n      const numMax = Number(max)\n      result.lte = isNaN(numMax) ? max : numMax\n    }\n    \n    return result\n  }\n}","/**\n * 🎯 Between Identifier\n * \n * Identifica objetos range e serializa como único param\n * Ex: { gte: 100, lte: 500 } → campo[entre]=100,500\n */\n\nimport { IJsonIdentifier } from '../core/interfaces'\n\nexport class BetweenIdentifier implements IJsonIdentifier {\n  name = 'between'\n  \n  /**\n   * Detecta se é um objeto com AMBOS gte E lte\n   */\n  detect(value: any): boolean {\n    if (!value || typeof value !== 'object' || Array.isArray(value)) {\n      return false\n    }\n    \n    // Só detecta se tem AMBOS os valores\n    return ('gte' in value && 'lte' in value) || \n           ('gt' in value && 'lt' in value) ||\n           ('min' in value && 'max' in value)\n  }\n  \n  /**\n   * Serializa para formato [entre]=min,max\n   */\n  serialize(key: string, value: any): string[] {\n    let min: any = null\n    let max: any = null\n    \n    // Detecta min\n    if ('gte' in value) min = value.gte\n    else if ('gt' in value) min = value.gt\n    else if ('min' in value) min = value.min\n    \n    // Detecta max\n    if ('lte' in value) max = value.lte\n    else if ('lt' in value) max = value.lt  \n    else if ('max' in value) max = value.max\n    \n    // Se não tem ambos, retorna vazio\n    if (min === null || max === null) {\n      return []\n    }\n    \n    // Retorna como único param com valores separados por vírgula\n    return [`${key}[entre]=${min},${max}`]\n  }\n  \n  /**\n   * Deserializa de volta para objeto com gte/lte\n   */\n  deserialize(params: Record<string, string | string[]>, key: string): any {\n    const entreKey = `${key}[entre]`\n    const entreValue = params[entreKey]\n    \n    // Se não existe, retorna undefined\n    if (!entreValue) {\n      return undefined\n    }\n    \n    // Pega string e separa por vírgula\n    const valueString = Array.isArray(entreValue) ? entreValue[0] : entreValue\n    const [minStr, maxStr] = valueString.split(',')\n    \n    // Se não tem ambos, retorna undefined\n    if (!minStr || !maxStr) {\n      return undefined\n    }\n    \n    // Converte para números se possível\n    const min = Number(minStr)\n    const max = Number(maxStr)\n    \n    return {\n      gte: isNaN(min) ? minStr : min,\n      lte: isNaN(max) ? maxStr : max\n    }\n  }\n}","/**\n * 🎯 Min/Max Identifier\n * \n * Identifica objetos com min/max explícitos\n * Ex: { min: 100, max: 500 } → campo[min]=100&campo[max]=500\n */\n\nimport { IJsonIdentifier } from '../core/interfaces'\n\nexport class MinMaxIdentifier implements IJsonIdentifier {\n  name = 'min-max'\n  \n  /**\n   * Detecta se é um objeto com min ou max\n   */\n  detect(value: any): boolean {\n    if (!value || typeof value !== 'object' || Array.isArray(value)) {\n      return false\n    }\n    \n    // Verifica se tem min ou max\n    return 'min' in value || 'max' in value\n  }\n  \n  /**\n   * Serializa para formato [min]/[max]\n   */\n  serialize(key: string, value: any): string[] {\n    const params: string[] = []\n    \n    // Processa min\n    if ('min' in value && value.min !== undefined && value.min !== null) {\n      params.push(`${key}[min]=${value.min}`)\n    }\n    \n    // Processa max\n    if ('max' in value && value.max !== undefined && value.max !== null) {\n      params.push(`${key}[max]=${value.max}`)\n    }\n    \n    return params\n  }\n  \n  /**\n   * Deserializa de volta para objeto com min/max\n   */\n  deserialize(params: Record<string, string | string[]>, key: string): any {\n    const minKey = `${key}[min]`\n    const maxKey = `${key}[max]`\n    \n    const minValue = params[minKey]\n    const maxValue = params[maxKey]\n    \n    // Se não tem nenhum, retorna undefined\n    if (!minValue && !maxValue) {\n      return undefined\n    }\n    \n    const result: any = {}\n    \n    // Processa min\n    if (minValue) {\n      const min = Array.isArray(minValue) ? minValue[0] : minValue\n      const numMin = Number(min)\n      result.min = isNaN(numMin) ? min : numMin\n    }\n    \n    // Processa max\n    if (maxValue) {\n      const max = Array.isArray(maxValue) ? maxValue[0] : maxValue\n      const numMax = Number(max)\n      result.max = isNaN(numMax) ? max : numMax\n    }\n    \n    return result\n  }\n}","/**\n * 🎯 JSON Identifiers - Export central\n */\n\nexport { RangeIdentifier } from './RangeIdentifier'\nexport { BetweenIdentifier } from './BetweenIdentifier'\nexport { MinMaxIdentifier } from './MinMaxIdentifier'\n\nimport { IJsonIdentifier, IdentifierRegistry } from '../core/interfaces'\nimport { RangeIdentifier } from './RangeIdentifier'\nimport { BetweenIdentifier } from './BetweenIdentifier'\nimport { MinMaxIdentifier } from './MinMaxIdentifier'\n\n/**\n * Registry padrão de identificadores\n */\nexport const defaultIdentifiers: IdentifierRegistry = {\n  'range': new RangeIdentifier(),\n  'between': new BetweenIdentifier(),\n  'min-max': new MinMaxIdentifier()\n}\n\n/**\n * Obtém identificador por nome\n */\nexport function getIdentifier(name: string): IJsonIdentifier | undefined {\n  return defaultIdentifiers[name]\n}","/**\n * 🎯 Base64 Resolver\n * \n * Fallback para JSONs complexos não identificados\n * Serializa qualquer objeto/array como base64\n */\n\nimport { BaseResolver } from './base/BaseResolver'\n\nexport class Base64Resolver extends BaseResolver {\n  /**\n   * Serializa valor complexo para base64\n   */\n  serialize(key: string, value: any): string[] {\n    // Se não tem valor, retorna vazio\n    if (value === null || value === undefined) {\n      return []\n    }\n    \n    const urlKey = this.getUrlKey(key)\n    \n    try {\n      // Converte para JSON string\n      const jsonString = JSON.stringify(value)\n      \n      // Codifica em base64 (browser e Node.js compatível)\n      const base64 = this.toBase64(jsonString)\n      \n      // Retorna com prefixo base64: para identificação\n      return [`${urlKey}=base64:${base64}`]\n    } catch (error) {\n      // Se falhar serialização, retorna vazio\n      console.error(`Failed to serialize ${key} to base64:`, error)\n      return []\n    }\n  }\n  \n  /**\n   * Deserializa base64 de volta para valor original\n   */\n  deserialize(params: Record<string, string | string[]>, key: string): any {\n    const urlKey = this.getUrlKey(key)\n    const value = params[urlKey]\n    \n    // Se não existe, retorna undefined\n    if (!value) {\n      return undefined\n    }\n    \n    // Pega string (se for array, pega primeiro)\n    const base64String = Array.isArray(value) ? value[0] : value\n    \n    // Verifica se tem prefixo base64:\n    if (!base64String.startsWith('base64:')) {\n      return undefined\n    }\n    \n    try {\n      // Remove prefixo e decodifica\n      const base64 = base64String.substring(7) // Remove \"base64:\"\n      const jsonString = this.fromBase64(base64)\n      \n      // Parse do JSON\n      return JSON.parse(jsonString)\n    } catch (error) {\n      console.error(`Failed to deserialize base64 for ${key}:`, error)\n      return undefined\n    }\n  }\n  \n  /**\n   * Converte string para base64 (compatível com browser e Node.js)\n   */\n  private toBase64(str: string): string {\n    if (typeof Buffer !== 'undefined') {\n      // Node.js\n      return Buffer.from(str).toString('base64')\n    } else {\n      // Browser\n      return btoa(unescape(encodeURIComponent(str)))\n    }\n  }\n  \n  /**\n   * Converte base64 para string (compatível com browser e Node.js)\n   */\n  private fromBase64(base64: string): string {\n    if (typeof Buffer !== 'undefined') {\n      // Node.js\n      return Buffer.from(base64, 'base64').toString()\n    } else {\n      // Browser\n      return decodeURIComponent(escape(atob(base64)))\n    }\n  }\n}","/**\n * 🎯 Fields Resolver\n * \n * Processa o campo \"fields\" fazendo flatten para a raiz da URL\n * Aplica identificadores JSON configurados para valores complexos\n */\n\nimport { BaseResolver } from './base/BaseResolver'\nimport { FieldConfig } from '../core/interfaces'\nimport { getIdentifier } from '../identifiers'\nimport { Base64Resolver } from './Base64Resolver'\n\nexport class FieldsResolver extends BaseResolver {\n  private base64Resolver: Base64Resolver\n  \n  constructor(config?: FieldConfig) {\n    super(config)\n    this.base64Resolver = new Base64Resolver()\n  }\n  \n  /**\n   * Serializa campos internos de \"fields\" para a raiz da URL\n   */\n  serialize(_key: string, value: any): string[] {\n    // Se não é objeto, retorna vazio\n    if (!value || typeof value !== 'object' || Array.isArray(value)) {\n      return []\n    }\n    \n    const params: string[] = []\n    \n    // Processa cada campo interno\n    for (const [fieldKey, fieldValue] of Object.entries(value)) {\n      // Valor simples: adiciona direto\n      if (this.isSimpleValue(fieldValue)) {\n        if (fieldValue !== null && fieldValue !== undefined && fieldValue !== '') {\n          // Para strings, usa encodeURIComponent\n          if (typeof fieldValue === 'string') {\n            params.push(`${fieldKey}=${encodeURIComponent(fieldValue)}`)\n          } else {\n            params.push(`${fieldKey}=${fieldValue}`)\n          }\n        }\n      }\n      // ⭐ ARRAYS: converte para string com vírgula\n      else if (Array.isArray(fieldValue)) {\n        if (fieldValue.length > 0) {\n          const arrayString = fieldValue\n            .filter(v => v !== null && v !== undefined && v !== '')\n            .map(v => encodeURIComponent(String(v)))\n            .join(',')\n          \n          if (arrayString) {\n            params.push(`${fieldKey}=${arrayString}`)\n          }\n        }\n      }\n      // Valor complexo: tenta identificar formato\n      else if (typeof fieldValue === 'object') {\n        const identified = this.identifyAndSerialize(fieldKey, fieldValue)\n        params.push(...identified)\n      }\n    }\n    \n    return params\n  }\n  \n  /**\n   * Deserializa params da URL de volta para o objeto fields\n   */\n  deserialize(params: Record<string, string | string[]>, _key: string): any {\n    const fields: Record<string, any> = {}\n    \n    // Lista de chaves já processadas\n    const processedKeys = new Set<string>()\n    \n    // Primeiro, tenta identificar campos com patterns conhecidos\n    for (const paramKey of Object.keys(params)) {\n      // Pula se já foi processado\n      if (processedKeys.has(paramKey)) continue\n      \n      // Verifica se é um campo com identificador (ex: campo[min], campo[max])\n      const bracketMatch = paramKey.match(/^(.+?)\\[(.+?)\\]$/)\n      \n      if (bracketMatch) {\n        const [, fieldName] = bracketMatch\n        \n        // Tenta deserializar com identificadores configurados\n        const identifierNames = this.config.jsonIdentifiers || []\n        \n        for (const identifierName of identifierNames) {\n          const identifier = getIdentifier(identifierName)\n          if (identifier) {\n            const result = identifier.deserialize(params, fieldName)\n            if (result !== undefined) {\n              fields[fieldName] = result\n              \n              // Marca todas as chaves relacionadas como processadas\n              for (const pk of Object.keys(params)) {\n                if (pk.startsWith(`${fieldName}[`)) {\n                  processedKeys.add(pk)\n                }\n              }\n              break\n            }\n          }\n        }\n      }\n      // Campo com prefixo base64:\n      else if (typeof params[paramKey] === 'string' && params[paramKey].startsWith('base64:')) {\n        const result = this.base64Resolver.deserialize(params, paramKey)\n        if (result !== undefined) {\n          fields[paramKey] = result\n          processedKeys.add(paramKey)\n        }\n      }\n      // Campo simples (não é sort, page, limit, etc - campos especiais)\n      else if (!this.isSpecialField(paramKey)) {\n        const value = params[paramKey]\n        const stringValue = Array.isArray(value) ? value[0] : value\n        \n        // Decodifica e converte tipo\n        fields[paramKey] = this.parseSimpleValue(stringValue)\n        processedKeys.add(paramKey)\n      }\n    }\n    \n    return Object.keys(fields).length > 0 ? fields : undefined\n  }\n  \n  /**\n   * Verifica se é valor simples\n   */\n  private isSimpleValue(value: any): boolean {\n    return value === null || \n           typeof value === 'string' || \n           typeof value === 'number' || \n           typeof value === 'boolean'\n  }\n  \n  /**\n   * Identifica formato JSON e serializa apropriadamente\n   */\n  private identifyAndSerialize(key: string, value: any): string[] {\n    // Tenta cada identificador configurado\n    const identifierNames = this.config.jsonIdentifiers || []\n    \n    for (const identifierName of identifierNames) {\n      const identifier = getIdentifier(identifierName)\n      if (identifier && identifier.detect(value)) {\n        return identifier.serialize(key, value)\n      }\n    }\n    \n    // Fallback: usa resolver configurado ou base64\n    const fallbackResolver = this.config.unknownJson || 'base64'\n    \n    if (fallbackResolver === 'base64') {\n      return this.base64Resolver.serialize(key, value)\n    }\n    \n    // Se não tem fallback, retorna vazio\n    return []\n  }\n  \n  /**\n   * Verifica se é campo especial (não pertence ao fields)\n   */\n  private isSpecialField(key: string): boolean {\n    const specialFields = [\n      'q', 'fts', 'geom', 'page', 'limit', 'sort', \n      'zoom', 'center_lat', 'center_lng', 'bbox',\n      'layout', 'card'\n    ]\n    \n    return specialFields.includes(key) || \n           key.startsWith('center_') || \n           key.startsWith('bbox_')\n  }\n  \n  /**\n   * Parse de valor simples com detecção de tipo\n   */\n  private parseSimpleValue(value: string): any {\n    // Decodifica primeiro\n    const decoded = decodeURIComponent(value)\n    \n    // ⭐ DETECÇÃO DE ARRAYS COM VÍRGULA (APENAS SE CONFIGURADO)\n    const commaArrayEnabled = this.config.jsonIdentifiers?.includes('comma-array') || false\n    \n    if (commaArrayEnabled && decoded.includes(',')) {\n      const parts = decoded.split(',')\n        .map(part => part.trim())\n        .filter(part => part !== '')\n      \n      // Se só tem uma parte após o split, retorna como string\n      if (parts.length <= 1) {\n        return decoded\n      }\n      \n      // ⚠️ HEURÍSTICA: Se contém números ou padrões de endereço, não converte para array\n      if (this.isLikelyAddress(decoded) || this.hasNumericParts(parts)) {\n        return decoded\n      }\n      \n      // Converte cada parte para o tipo apropriado\n      return parts.map(part => this.convertValue(part))\n    }\n    \n    // Valor simples (ou vírgula não configurada para detecção)\n    return this.convertValue(decoded)\n  }\n  \n  /**\n   * Detecta se parece ser um endereço\n   */\n  private isLikelyAddress(value: string): boolean {\n    // Padrões comuns de endereço\n    const addressPatterns = [\n      /\\b\\d+\\b/, // Contém números (provável número da casa)\n      /\\b(rua|av|avenida|pça|praça|alameda|estrada|rodovia)\\b/i, // Tipos de logradouro\n      /\\bcep\\b/i, // CEP\n      /-\\s*\\d{5}/  // Padrão CEP\n    ]\n    \n    return addressPatterns.some(pattern => pattern.test(value))\n  }\n  \n  /**\n   * Verifica se as partes contêm números (indicativo de endereço/medida)\n   */\n  private hasNumericParts(parts: string[]): boolean {\n    return parts.some(part => /^\\d+$/.test(part.trim()))\n  }\n  \n  /**\n   * Converte string para tipo apropriado\n   */\n  private convertValue(value: string): any {\n    // Boolean\n    if (value === 'true') return true\n    if (value === 'false') return false\n    \n    // Número\n    if (/^-?\\d+(\\.\\d+)?$/.test(value)) {\n      const num = Number(value)\n      if (!isNaN(num)) {\n        return num\n      }\n    }\n    \n    // String\n    return value\n  }\n}","/**\n * 🎯 Simple Value Resolver\n * \n * Processa valores simples (string, number, boolean)\n * Suporta alias configurável\n */\n\nimport { BaseResolver } from './base/BaseResolver'\n\nexport class SimpleValueResolver extends BaseResolver {\n  /**\n   * Serializa valor simples para URL\n   * Ex: fts=\"casa moderna\" → [\"q=casa+moderna\"]\n   */\n  serialize(key: string, value: any): string[] {\n    // Se valor é nulo ou undefined, não inclui na URL\n    if (value === null || value === undefined || value === '') {\n      return []\n    }\n    \n    const urlKey = this.getUrlKey(key)\n    \n    // Para boolean, converte para string\n    if (typeof value === 'boolean') {\n      return [this.createParam(urlKey, value ? 'true' : 'false')]\n    }\n    \n    // Para string, usa encodeURIComponent para espaços e caracteres especiais\n    if (typeof value === 'string') {\n      return [`${urlKey}=${encodeURIComponent(value)}`]\n    }\n    \n    // Para números e outros, converte direto\n    return [this.createParam(urlKey, value)]\n  }\n  \n  /**\n   * Deserializa de volta para valor simples\n   */\n  deserialize(params: Record<string, string | string[]>, key: string): any {\n    const urlKey = this.getUrlKey(key)\n    const value = params[urlKey]\n    \n    // Se não existe o param, retorna undefined\n    if (value === undefined) {\n      return undefined\n    }\n    \n    // Se for array, pega o primeiro valor (não deveria acontecer)\n    const stringValue = Array.isArray(value) ? value[0] : value\n    \n    // Tenta detectar o tipo original\n    \n    // Boolean\n    if (stringValue === 'true') return true\n    if (stringValue === 'false') return false\n    \n    // Número\n    if (/^-?\\d+(\\.\\d+)?$/.test(stringValue)) {\n      const num = Number(stringValue)\n      if (!isNaN(num)) {\n        return num\n      }\n    }\n    \n    // String decodificada\n    return decodeURIComponent(stringValue)\n  }\n}","/**\n * 🎯 Pagination Sort Resolver\n * \n * Converte objetos de ordenação para formato URL amigável\n * Suporta múltiplos campos de ordenação\n */\n\nimport { BaseResolver } from './base/BaseResolver'\n\nexport class PaginationSortResolver extends BaseResolver {\n  /**\n   * Serializa objeto de sort para URL\n   * Ex: { price: \"desc\", date: \"asc\" } → [\"sort=price:desc,date:asc\"]\n   */\n  serialize(key: string, value: any): string[] {\n    // Se não tem valor, retorna vazio\n    if (!value || typeof value !== 'object') {\n      return []\n    }\n    \n    const urlKey = this.getUrlKey(key)\n    const sortParts: string[] = []\n    \n    // Processa cada campo de ordenação\n    for (const [field, direction] of Object.entries(value)) {\n      if (direction === 'asc' || direction === 'desc') {\n        sortParts.push(`${field}:${direction}`)\n      }\n    }\n    \n    // Se não tem ordenação válida, retorna vazio\n    if (sortParts.length === 0) {\n      return []\n    }\n    \n    // Retorna como único parâmetro com campos separados por vírgula\n    return [`${urlKey}=${sortParts.join(',')}`]\n  }\n  \n  /**\n   * Deserializa string de sort para objeto\n   * Ex: \"price:desc,date:asc\" → { price: \"desc\", date: \"asc\" }\n   */\n  deserialize(params: Record<string, string | string[]>, key: string): any {\n    const urlKey = this.getUrlKey(key)\n    const value = params[urlKey]\n    \n    // Se não existe o param, retorna undefined\n    if (!value) {\n      return undefined\n    }\n    \n    // Pega string (se for array, pega primeiro) e decodifica URL\n    const rawValue = Array.isArray(value) ? value[0] : value\n    const sortString = decodeURIComponent(rawValue)\n    \n    // Parse da string de ordenação\n    const sortObject: Record<string, 'asc' | 'desc'> = {}\n    \n    // Separa por vírgula para múltiplos campos\n    const sortParts = sortString.split(',')\n    \n    for (const part of sortParts) {\n      // Separa campo:direção\n      const [field, direction] = part.split(':')\n      \n      if (field && (direction === 'asc' || direction === 'desc')) {\n        sortObject[field] = direction\n      }\n    }\n    \n    // Retorna objeto se tem campos, senão undefined\n    return Object.keys(sortObject).length > 0 ? sortObject : undefined\n  }\n}","/**\n * 🎯 Lat/Lng Resolver\n * \n * Converte objetos com latitude/longitude para params separados\n * Ex: center: {lat: -25, lng: -50} → center_lat=-25&center_lng=-50\n */\n\nimport { BaseResolver } from './base/BaseResolver'\n\nexport class LatLngResolver extends BaseResolver {\n  /**\n   * Serializa objeto lat/lng para params separados\n   */\n  serialize(key: string, value: any): string[] {\n    // Valida se é objeto com lat/lng\n    if (!value || typeof value !== 'object') {\n      return []\n    }\n    \n    const { lat, lng } = value\n    \n    // Ambos devem existir e ser números\n    if (typeof lat !== 'number' || typeof lng !== 'number') {\n      return []\n    }\n    \n    const urlKey = this.getUrlKey(key)\n    \n    // Retorna dois params separados\n    return [\n      `${urlKey}_lat=${lat}`,\n      `${urlKey}_lng=${lng}`\n    ]\n  }\n  \n  /**\n   * Deserializa params separados para objeto lat/lng\n   */\n  deserialize(params: Record<string, string | string[]>, key: string): any {\n    const urlKey = this.getUrlKey(key)\n    const latKey = `${urlKey}_lat`\n    const lngKey = `${urlKey}_lng`\n    \n    const latValue = params[latKey]\n    const lngValue = params[lngKey]\n    \n    // Se não tem ambos, retorna undefined\n    if (!latValue || !lngValue) {\n      return undefined\n    }\n    \n    // Converte para números\n    const lat = Number(Array.isArray(latValue) ? latValue[0] : latValue)\n    const lng = Number(Array.isArray(lngValue) ? lngValue[0] : lngValue)\n    \n    // Valida se são números válidos\n    if (isNaN(lat) || isNaN(lng)) {\n      return undefined\n    }\n    \n    return { lat, lng }\n  }\n}","/**\n * 🎯 Passthrough Resolver\n * \n * Resolver simples que passa valores direto sem transformação\n * Usado para page, limit, zoom, layout, card, etc\n */\n\nimport { BaseResolver } from './base/BaseResolver'\n\nexport class PassthroughResolver extends BaseResolver {\n  /**\n   * Serializa valor direto para URL\n   */\n  serialize(key: string, value: any): string[] {\n    // Se não tem valor, retorna vazio\n    if (value === null || value === undefined || value === '') {\n      return []\n    }\n    \n    const urlKey = this.getUrlKey(key)\n    \n    // Para strings, usa encodeURIComponent\n    if (typeof value === 'string') {\n      return [`${urlKey}=${encodeURIComponent(value)}`]\n    }\n    \n    // Para outros tipos, converte direto\n    return [`${urlKey}=${value}`]\n  }\n  \n  /**\n   * Deserializa valor direto da URL\n   */\n  deserialize(params: Record<string, string | string[]>, key: string): any {\n    const urlKey = this.getUrlKey(key)\n    const value = params[urlKey]\n    \n    // Se não existe, retorna undefined\n    if (value === undefined) {\n      return undefined\n    }\n    \n    // Pega string (se for array, pega primeiro)\n    const stringValue = Array.isArray(value) ? value[0] : value\n    \n    // Para números, tenta converter\n    if (/^-?\\d+(\\.\\d+)?$/.test(stringValue)) {\n      const num = Number(stringValue)\n      if (!isNaN(num)) {\n        return num\n      }\n    }\n    \n    // Decodifica string\n    return decodeURIComponent(stringValue)\n  }\n}","/**\n * 🎯 Resolvers - Export central\n */\n\nexport { BaseResolver } from './base/BaseResolver'\nexport { FieldsResolver } from './FieldsResolver'\nexport { SimpleValueResolver } from './SimpleValueResolver'\nexport { PaginationSortResolver } from './PaginationSortResolver'\nexport { LatLngResolver } from './LatLngResolver'\nexport { Base64Resolver } from './Base64Resolver'\nexport { PassthroughResolver } from './PassthroughResolver'\n\nimport { IResolver, ResolverRegistry, FieldConfig } from '../core/interfaces'\nimport { FieldsResolver } from './FieldsResolver'\nimport { SimpleValueResolver } from './SimpleValueResolver'\nimport { PaginationSortResolver } from './PaginationSortResolver'\nimport { LatLngResolver } from './LatLngResolver'\nimport { Base64Resolver } from './Base64Resolver'\nimport { PassthroughResolver } from './PassthroughResolver'\n\n/**\n * Registry padrão de resolvers\n */\nexport const defaultResolvers: ResolverRegistry = {\n  'fields': FieldsResolver,\n  'simple-value': SimpleValueResolver,\n  'pagination-sort': PaginationSortResolver,\n  'lat-lng': LatLngResolver,\n  'base64': Base64Resolver,\n  'passthrough': PassthroughResolver\n}\n\n/**\n * Cria resolver por nome\n */\nexport function createResolver(name: string, config?: FieldConfig): IResolver | undefined {\n  const ResolverClass = defaultResolvers[name]\n  if (!ResolverClass) {\n    return undefined\n  }\n  \n  return new ResolverClass(config)\n}","/**\n * 🎯 URL State Serializer V2\n * \n * Sistema baseado em resolvers configuráveis\n * Responsável por Estado ↔ Query String\n */\n\nimport { \n  SerializerConfig, \n  SearchState, \n  IResolver\n} from './interfaces'\nimport { createResolver } from '../resolvers'\n\nexport class UrlStateSerializer {\n  private config: SerializerConfig\n  private resolvers: Map<string, IResolver>\n  \n  constructor(config: SerializerConfig) {\n    this.config = config\n    this.resolvers = new Map()\n    \n    // Inicializa resolvers para cada campo configurado\n    this.initializeResolvers()\n  }\n  \n  /**\n   * Inicializa resolvers baseado na configuração\n   */\n  private initializeResolvers(): void {\n    for (const [fieldName, fieldConfig] of Object.entries(this.config)) {\n      const resolver = createResolver(fieldConfig.resolver, fieldConfig)\n      \n      if (!resolver) {\n        console.warn(`Resolver \"${fieldConfig.resolver}\" not found for field \"${fieldName}\"`)\n        continue\n      }\n      \n      this.resolvers.set(fieldName, resolver)\n    }\n  }\n  \n  /**\n   * Serializa estado para query string\n   */\n  serialize(state: SearchState): string {\n    const params: string[] = []\n    \n    // Processa cada campo do estado\n    for (const [fieldName, fieldValue] of Object.entries(state)) {\n      // Pula valores undefined/null\n      if (fieldValue === undefined || fieldValue === null) {\n        continue\n      }\n      \n      // Busca resolver configurado para este campo\n      const resolver = this.resolvers.get(fieldName)\n      \n      if (!resolver) {\n        // Campo não configurado - ignora\n        console.warn(`No resolver configured for field \"${fieldName}\"`)\n        continue\n      }\n      \n      // Serializa usando o resolver\n      try {\n        const fieldParams = resolver.serialize(fieldName, fieldValue)\n        params.push(...fieldParams)\n      } catch (error) {\n        console.error(`Error serializing field \"${fieldName}\":`, error)\n      }\n    }\n    \n    // Junta todos os params\n    return params.join('&')\n  }\n  \n  /**\n   * Deserializa query string para estado\n   */\n  deserialize(queryString: string): SearchState {\n    // Parse da query string\n    const params = this.parseQueryString(queryString)\n    const state: SearchState = {}\n    \n    // Processa cada campo configurado\n    for (const [fieldName] of Object.entries(this.config)) {\n      const resolver = this.resolvers.get(fieldName)\n      \n      if (!resolver) {\n        continue\n      }\n      \n      try {\n        // Deserializa usando o resolver\n        const value = resolver.deserialize(params, fieldName)\n        \n        // Só adiciona se tem valor\n        if (value !== undefined) {\n          state[fieldName] = value\n        }\n      } catch (error) {\n        console.error(`Error deserializing field \"${fieldName}\":`, error)\n      }\n    }\n    \n    return state\n  }\n  \n  /**\n   * Parse de query string para objeto de params\n   */\n  private parseQueryString(queryString: string): Record<string, string | string[]> {\n    const params: Record<string, string | string[]> = {}\n    \n    // Remove ? inicial se existir\n    const cleanQuery = queryString.startsWith('?') \n      ? queryString.substring(1) \n      : queryString\n    \n    // Se vazio, retorna objeto vazio\n    if (!cleanQuery) {\n      return params\n    }\n    \n    // Separa por &\n    const pairs = cleanQuery.split('&')\n    \n    for (const pair of pairs) {\n      const [key, value] = pair.split('=')\n      \n      if (!key) continue\n      \n      // Decodifica key (mas não o value - deixa para o resolver)\n      const decodedKey = decodeURIComponent(key)\n      const rawValue = value || ''\n      \n      // Se já existe a chave, transforma em array\n      if (params[decodedKey]) {\n        const existing = params[decodedKey]\n        if (Array.isArray(existing)) {\n          existing.push(rawValue)\n        } else {\n          params[decodedKey] = [existing, rawValue]\n        }\n      } else {\n        params[decodedKey] = rawValue\n      }\n    }\n    \n    return params\n  }\n  \n  /**\n   * Configuração padrão recomendada\n   */\n  static getDefaultConfig(): SerializerConfig {\n    return {\n      filters: {\n        resolver: 'fields',\n        jsonIdentifiers: ['range', 'between', 'min-max'],\n        unknownJson: 'base64'\n      },\n      fts: {\n        resolver: 'simple-value',\n        alias: 'q'\n      },\n      page: {\n        resolver: 'passthrough'\n      },\n      limit: {\n        resolver: 'passthrough'\n      },\n      sort: {\n        resolver: 'pagination-sort'\n      },\n      zoom: {\n        resolver: 'passthrough'\n      },\n      center: {\n        resolver: 'lat-lng'\n      },\n      layout: {\n        resolver: 'passthrough'\n      },\n      card: {\n        resolver: 'passthrough'\n      }\n    }\n  }\n}","/**\n * 🎯 URL State Serializer V2\n * \n * Sistema de serialização Estado ↔ Query String\n * baseado em resolvers configuráveis\n */\n\n// Core\nexport { UrlStateSerializer } from './core/UrlStateSerializer'\nexport * from './core/interfaces'\n\n// Resolvers\nexport * from './resolvers'\n\n// Identifiers\nexport * from './identifiers'\n\n// Configuração padrão recomendada\nimport { UrlStateSerializer } from './core/UrlStateSerializer'\nexport const defaultConfig = UrlStateSerializer.getDefaultConfig()","/**\n * 🎯 Field Extractor - Extração de valores dos campos\n * \n * Extrai valores dos campos de busca baseado na configuração\n */\n\nimport { SearchFields, FieldsConfig } from '../core/interfaces'\n\n/**\n * Extrator de campos - responsável por encontrar valores nos dados de entrada\n */\nexport class FieldExtractor {\n  private fieldsConfig: FieldsConfig\n  \n  constructor(fieldsConfig: FieldsConfig) {\n    this.fieldsConfig = fieldsConfig\n  }\n  \n  /**\n   * Extrai valor de um campo lógico dos dados de entrada\n   * Procura por diferentes nomes de campo conforme configuração\n   */\n  extractField(logicalField: string, searchFields: SearchFields): string | null {\n    const possibleFieldNames = this.fieldsConfig[logicalField]\n    \n    if (!possibleFieldNames || !Array.isArray(possibleFieldNames)) {\n      return null\n    }\n    \n    // Tenta cada possível nome de campo\n    for (const fieldName of possibleFieldNames) {\n      const value = this.extractFieldValue(searchFields, fieldName)\n      if (value !== null) {\n        return value\n      }\n    }\n    \n    return null\n  }\n  \n  /**\n   * Extrai valor de um campo específico, lidando com diferentes tipos\n   */\n  private extractFieldValue(searchFields: SearchFields, fieldName: string): string | null {\n    const value = searchFields[fieldName]\n    \n    if (value === null || value === undefined) {\n      return null\n    }\n    \n    // String simples\n    if (typeof value === 'string') {\n      return value.trim() || null\n    }\n    \n    // Número\n    if (typeof value === 'number') {\n      return String(value)\n    }\n    \n    // Boolean\n    if (typeof value === 'boolean') {\n      return value ? 'sim' : 'nao'\n    }\n    \n    // Array - pega o primeiro valor válido\n    if (Array.isArray(value) && value.length > 0) {\n      const firstValue = value[0]\n      if (typeof firstValue === 'string' && firstValue.trim()) {\n        return firstValue.trim()\n      }\n      if (typeof firstValue === 'number') {\n        return String(firstValue)\n      }\n    }\n    \n    // Para outros tipos (objetos), não extrai\n    // O gerador de slug trabalha apenas com valores simples\n    return null\n  }\n  \n  /**\n   * Extrai todos os campos configurados de uma vez\n   * Retorna mapa com campos encontrados e valores\n   */\n  extractAllFields(searchFields: SearchFields): Record<string, string> {\n    const extracted: Record<string, string> = {}\n    \n    for (const logicalField of Object.keys(this.fieldsConfig)) {\n      const value = this.extractField(logicalField, searchFields)\n      if (value !== null) {\n        extracted[logicalField] = value\n      }\n    }\n    \n    return extracted\n  }\n  \n  /**\n   * Lista os campos configurados que não foram encontrados nos dados\n   */\n  getMissingFields(searchFields: SearchFields): string[] {\n    const missing: string[] = []\n    \n    for (const logicalField of Object.keys(this.fieldsConfig)) {\n      const value = this.extractField(logicalField, searchFields)\n      if (value === null) {\n        missing.push(logicalField)\n      }\n    }\n    \n    return missing\n  }\n}","/**\n * 🎯 Slugify Simples - Sem dependências pesadas\n * \n * Normaliza texto para formato URL-friendly usando apenas JavaScript nativo\n */\n\n/**\n * Normaliza texto para slug URL-safe usando apenas JS nativo\n * Remove acentos, caracteres especiais e formata para slug\n */\nexport function slugify(text: string | number, preserveSlash: boolean = false): string {\n  if (text === null || text === undefined) {\n    return ''\n  }\n  \n  return String(text)\n    .toLowerCase()\n    .trim()\n    // Remove acentos portugueses/espanhóis usando replace simples\n    .replace(/[àáâãäå]/g, 'a')\n    .replace(/[èéêë]/g, 'e') \n    .replace(/[ìíîï]/g, 'i')\n    .replace(/[òóôõö]/g, 'o')\n    .replace(/[ùúûü]/g, 'u')\n    .replace(/[ç]/g, 'c')\n    .replace(/[ñ]/g, 'n')\n    .replace(/[ÿ]/g, 'y')\n    // Caracteres especiais comuns\n    .replace(/[&]/g, 'e') // & → e\n    .replace(/[+]/g, 'mais') // + → mais\n    .replace(/[%]/g, 'pct') // % → pct\n    // Remove todos os caracteres que não são letras, números, espaços, hífens (e barras se preserveSlash)\n    .replace(preserveSlash ? /[^\\w\\s-/]/g : /[^\\w\\s-]/g, '')\n    // Substitui espaços e underscores por hífens\n    .replace(/[\\s_]+/g, '-')\n    // Remove hífens duplicados\n    .replace(/-+/g, '-')\n    // Remove hífens no início e fim\n    .replace(/^-+|-+$/g, '')\n}\n\n/**\n * Trunca slug mantendo palavras completas\n * Evita cortar no meio de uma palavra\n */\nexport function truncateSlug(slug: string, maxLength: number, separator: string = '-'): string {\n  if (slug.length <= maxLength) {\n    return slug\n  }\n  \n  // Encontra o último separador antes do limite\n  const truncated = slug.substring(0, maxLength)\n  const lastSeparator = truncated.lastIndexOf(separator)\n  \n  // Se encontrou separador válido, corta ali\n  // Senão, corta no limite mesmo\n  return lastSeparator > 0 ? truncated.substring(0, lastSeparator) : truncated\n}\n\n/**\n * Valida se um slug está no formato correto\n */\nexport function isValidSlug(slug: string): boolean {\n  // Deve conter apenas letras minúsculas, números e hífens\n  // Não pode começar ou terminar com hífen\n  // Não pode ter hífens consecutivos\n  return /^[a-z0-9]+(-[a-z0-9]+)*$/.test(slug)\n}","/**\n * 🎯 SEO Slug Generator - Classe principal\n * \n * Gera slugs SEO a partir de campos de busca de forma configurável\n */\n\nimport { \n  SlugGeneratorConfig, \n  SearchFields, \n  SlugResult, \n  SlugAnalysisResult,\n  SlugOptions \n} from './interfaces'\nimport { FieldExtractor } from '../extractors/FieldExtractor'\nimport { slugify, truncateSlug } from '../utils/slugify'\n\nexport class SlugGenerator {\n  private config: SlugGeneratorConfig\n  private extractor: FieldExtractor\n  private options: Required<SlugOptions>\n  \n  constructor(config: SlugGeneratorConfig) {\n    this.config = config\n    this.extractor = new FieldExtractor(config.fields)\n    \n    // Define opções padrão\n    this.options = {\n      prefix: config.options?.prefix || '',\n      maxLength: config.options?.maxLength || 80,\n      minParts: config.options?.minParts || 2,\n      separator: this.resolveSeparator(config.options?.separator || 'dash')\n    }\n  }\n  \n  /**\n   * Resolve o separador baseado na configuração\n   */\n  private resolveSeparator(separator: 'dash' | 'slash' | string): string {\n    if (separator === 'dash') return '-'\n    if (separator === 'slash') return '/'\n    return separator\n  }\n  \n  /**\n   * Formata valor do campo para melhor legibilidade na URL\n   */\n  private formatFieldValue(logicalField: string, value: string): string {\n    // Formatação específica para campos de quartos\n    if (logicalField === 'quartos' || logicalField === 'bedrooms') {\n      if (/^\\d+$/.test(value)) {\n        return `${value}-quarto`\n      }\n    }\n    \n    // Outros campos ficam como estão\n    return value\n  }\n  \n  /**\n   * Gera slug simples a partir dos campos de busca\n   */\n  generate(searchFields: SearchFields): string | null {\n    const result = this.generateWithDetails(searchFields)\n    return result.slug\n  }\n  \n  /**\n   * Gera slug com detalhes completos do processo\n   */\n  generateWithDetails(searchFields: SearchFields): SlugResult {\n    // Extrai todos os campos configurados\n    const extractedFields = this.extractor.extractAllFields(searchFields)\n    const missingFields = this.extractor.getMissingFields(searchFields)\n    \n    // Monta partes do slug na ordem configurada\n    const parts: string[] = []\n    const usedFields: Record<string, string> = {}\n    \n    const isSlashMode = this.options.separator === '/'\n    \n    for (const logicalField of this.config.order) {\n      const value = extractedFields[logicalField]\n      if (value) {\n        const formattedValue = this.formatFieldValue(logicalField, value)\n        const slugPart = slugify(formattedValue, isSlashMode)\n        if (slugPart) {\n          parts.push(slugPart)\n          usedFields[logicalField] = value\n        }\n      }\n    }\n    \n    // Verifica se tem partes suficientes\n    if (parts.length < this.options.minParts) {\n      return {\n        slug: null,\n        parts,\n        usedFields,\n        missingFields\n      }\n    }\n    \n    // Monta o slug\n    let slug = parts.join(this.options.separator)\n    \n    // Adiciona prefixo se configurado\n    if (this.options.prefix) {\n      const prefixSlug = slugify(this.options.prefix, isSlashMode)\n      if (prefixSlug) {\n        slug = `${prefixSlug}${this.options.separator}${slug}`\n      }\n    }\n    \n    // Trunca se necessário\n    if (slug.length > this.options.maxLength) {\n      slug = truncateSlug(slug, this.options.maxLength, this.options.separator)\n    }\n    \n    // Valida resultado final (adaptado para separador customizado)\n    const finalSlug = this.isValidSlugForSeparator(slug) ? slug : null\n    \n    return {\n      slug: finalSlug,\n      parts,\n      usedFields,\n      missingFields\n    }\n  }\n  \n  /**\n   * Gera slug com análise de qualidade (opcional)\n   */\n  generateWithAnalysis(searchFields: SearchFields): SlugAnalysisResult {\n    const result = this.generateWithDetails(searchFields)\n    \n    // Analisa qualidade baseada nos campos disponíveis\n    const quality = this.analyzeQuality(result)\n    const suggestions = this.generateSuggestions(result)\n    \n    return {\n      ...result,\n      quality,\n      suggestions\n    }\n  }\n  \n  /**\n   * Analisa a qualidade do slug baseado nos campos disponíveis\n   */\n  private analyzeQuality(result: SlugResult): 'high' | 'medium' | 'low' | 'none' {\n    if (!result.slug) {\n      return 'none'\n    }\n    \n    const partsCount = result.parts.length\n    const configuredFieldsCount = Object.keys(this.config.fields).length\n    const coverage = partsCount / configuredFieldsCount\n    \n    if (coverage >= 0.7 && partsCount >= 4) {\n      return 'high'\n    } else if (coverage >= 0.5 && partsCount >= 3) {\n      return 'medium'\n    } else if (partsCount >= 2) {\n      return 'low'\n    } else {\n      return 'none'\n    }\n  }\n  \n  /**\n   * Gera sugestões para melhorar o slug\n   */\n  private generateSuggestions(result: SlugResult): string[] {\n    const suggestions: string[] = []\n    \n    if (!result.slug) {\n      suggestions.push('Adicione mais campos relevantes para gerar um slug')\n      return suggestions\n    }\n    \n    // Sugestões baseadas em campos faltando\n    if (result.missingFields.includes('tipo')) {\n      suggestions.push('Adicione o tipo para melhor identificação')\n    }\n    if (result.missingFields.includes('cidade')) {\n      suggestions.push('Adicione a cidade para melhor SEO local')\n    }\n    if (result.missingFields.includes('operacao')) {\n      suggestions.push('Especifique a operação (venda/aluguel)')\n    }\n    \n    // Sugestões baseadas na qualidade\n    if (result.parts.length < 3) {\n      suggestions.push('Inclua mais campos para um slug mais descritivo')\n    }\n    \n    if (result.slug.length < 20) {\n      suggestions.push('Slug pode ser mais descritivo')\n    }\n    \n    return suggestions\n  }\n  \n  /**\n   * Valida slug considerando separador customizado\n   */\n  private isValidSlugForSeparator(slug: string): boolean {\n    const separator = this.options.separator.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') // escape regex\n    \n    // Para slash, permitir caracteres de URL válidos\n    if (this.options.separator === '/') {\n      const regex = new RegExp(`^[a-z0-9-]+(${separator}[a-z0-9-]+)*$`)\n      return regex.test(slug)\n    }\n    \n    // Para dash e outros separadores\n    const regex = new RegExp(`^[a-z0-9]+(${separator}[a-z0-9]+)*$`)\n    return regex.test(slug)\n  }\n  \n  /**\n   * Testa a configuração com dados de exemplo\n   */\n  testConfiguration(testData: SearchFields): {\n    config: SlugGeneratorConfig\n    result: SlugAnalysisResult\n    extractedFields: Record<string, string>\n  } {\n    const result = this.generateWithAnalysis(testData)\n    const extractedFields = this.extractor.extractAllFields(testData)\n    \n    return {\n      config: this.config,\n      result,\n      extractedFields\n    }\n  }\n}","/**\n * 🎯 SEO Slug Generator\n * \n * Sistema leve para geração de slugs SEO a partir de campos de busca\n */\n\n// Core\nexport { SlugGenerator } from './core/SlugGenerator'\nexport * from './core/interfaces'\n\n// Utilities\nexport { slugify, truncateSlug, isValidSlug } from './utils/slugify'\n\n// Extractors\nexport { FieldExtractor } from './extractors/FieldExtractor'\n\n// Configuração padrão para imóveis\nimport { SlugGeneratorConfig } from './core/interfaces'\n\nexport const defaultImoveisConfig: SlugGeneratorConfig = {\n  fields: {\n    tipo: ['tipo', 'type'],\n    subtipo: ['subtipo', 'subtype'], \n    operacao: ['operacao', 'operation', 'finalidade'],\n    bairro: ['bairro', 'neighborhood'],\n    cidade: ['cidade', 'city', 'endereco_cidade'],\n    estado: ['estado', 'state'],\n    quartos: ['quartos', 'bedrooms']\n  },\n  order: ['tipo', 'subtipo', 'bairro', 'cidade', 'quartos'],\n  options: {\n    prefix: 'imoveis',\n    maxLength: 80,\n    minParts: 2,\n    separator: 'dash'\n  }\n}\n\nexport const defaultConfig: SlugGeneratorConfig = {\n  fields: {\n    tipo: ['tipo', 'type'],\n    operacao: ['operacao', 'operation'],\n    cidade: ['cidade', 'city']\n  },\n  order: ['tipo', 'operacao', 'cidade'],\n  options: {\n    maxLength: 80,\n    minParts: 2,\n    separator: 'dash'\n  }\n}","/**\n * 🎯 Search State Enricher - Classe Principal\n * \n * Enriquece estado da URL com operadores baseado em schema\n */\n\nimport type { \n  SearchSchema, \n  ParsedState, \n  EnrichedRequest, \n  EnricherConfig,\n  EnricherOptions,\n  FieldMetadata\n} from './interfaces'\n\nexport class SearchStateEnricher {\n  private schema: SearchSchema\n  private options: EnricherOptions\n  \n  \n  /**\n   * Campos que devem ser tratados como string, não array\n   * Importante para validar se AND em campos string faz sentido\n   */\n  private static readonly STRING_FIELDS = new Set([\n    'endereco_bairro',\n    'endereco_cidade',\n    'endereco_estado'\n    // adicionar outros conforme necessário\n  ])\n\n  constructor(config: EnricherConfig) {\n    this.schema = config.schema\n    this.options = config.options || {}\n    \n    // Migração automática se o schema está no formato legado\n    if (Array.isArray((this.schema as any).fields)) {\n      this.migrateFromLegacySchema()\n    }\n  }\n  \n  /**\n   * Migra schema legado para novo formato\n   * @deprecated Apenas para backward compatibility\n   */\n  private migrateFromLegacySchema(): void {\n    const legacySchema = this.schema as any\n    const newFields: Record<string, FieldMetadata> = {}\n    \n    // Converte array de fields para objeto\n    if (Array.isArray(legacySchema.fields)) {\n      for (const field of legacySchema.fields) {\n        newFields[field.key] = {\n          key: field.key,\n          type: field.type,\n          operator: field.operator,\n          multiple: field.multiple,\n          default: field.default\n        }\n      }\n    }\n    \n    // Move defaults do schema para options\n    if (legacySchema.defaults && !this.options.defaults) {\n      this.options.defaults = legacySchema.defaults\n    }\n    \n    // Atualiza schema (v1.4.0 - padronizado para filters)\n    this.schema = {\n      filters: newFields,\n      ...legacySchema.fts && { fts: legacySchema.fts },\n      ...legacySchema.geom && { geom: legacySchema.geom }\n    }\n  }\n\n  /**\n   * Enriquece estado simples para request do backend\n   */\n  enrich(state: ParsedState): EnrichedRequest {\n    const enriched: EnrichedRequest = {}\n\n    // 1. Enriquecer FTS se existir\n    if (state.fts) {\n      enriched.fts = this.enrichFts(state.fts)\n    }\n\n    // 2. Enriquecer GEOM se existir\n    if (state.geom) {\n      enriched.geom = this.enrichGeom(state.geom)\n    }\n\n    // 3. Enriquecer FILTERS se existir\n    if (state.filters) {\n      enriched.filters = this.enrichFilters(state.filters)\n    }\n\n    // 4. Preservar outros campos do estado (page, limit, etc.)\n    for (const [key, value] of Object.entries(state)) {\n      if (!['fts', 'geom', 'filters'].includes(key)) {\n        enriched[key] = value\n      }\n    }\n\n    return enriched\n  }\n\n  /**\n   * Enriquece FTS com operador padrão\n   */\n  private enrichFts(fts: string | { value: string; operator?: string }): any {\n    // Busca defaults na ordem: schema.fts -> options.defaults -> fallback\n    const defaultOperator = \n      this.schema.fts?.operator || \n      this.options.defaults?.fts?.operator || \n      'websearch'\n\n    // Se já é objeto, preservar estrutura\n    if (typeof fts === 'object' && fts.value) {\n      return {\n        value: fts.value,\n        operator: fts.operator || defaultOperator\n      }\n    }\n\n    // Se é string, criar objeto\n    return {\n      value: fts,\n      operator: defaultOperator\n    }\n  }\n\n  /**\n   * Enriquece GEOM com operator padrão (CORRIGIDO para API format)\n   */\n  private enrichGeom(geom: any): any {\n    // Busca defaults na ordem: schema.geom -> options.defaults -> fallback\n    const defaultOperator = \n      this.schema.geom?.operation || \n      this.options.defaults?.geom?.operation || \n      'within'\n\n    return {\n      operator: geom.operator || geom.operation || defaultOperator,  // operation → operator (API format)\n      value: geom.value || geom.geometry || geom   // geometry → value (API format)\n    }\n  }\n\n  /**\n   * Enriquece FILTERS baseado no schema\n   */\n  private enrichFilters(filters: Record<string, any>): Record<string, any> {\n    const enriched: Record<string, any> = {}\n\n    for (const [fieldName, value] of Object.entries(filters)) {\n      const fieldMetadata = this.getFieldSchema(fieldName)\n\n      if (fieldMetadata) {\n        enriched[fieldName] = this.enrichField(value, fieldMetadata)\n      } else if (!this.options.strict) {\n        // Se não está no schema mas não é strict, preserva como está\n        enriched[fieldName] = value\n      }\n    }\n\n    return enriched\n  }\n\n  /**\n   * Enriquece campo individual baseado no schema\n   */\n  private enrichField(value: any, fieldMetadata: FieldMetadata): any {\n    // Se valor é null/undefined, retorna como está\n    if (value === null || value === undefined) {\n      return value\n    }\n\n    // Se é array, aplica lógica de operadores\n    if (Array.isArray(value)) {\n      return this.enrichArrayField(value, fieldMetadata)\n    }\n\n    // Se é range (objeto com min/max), aplica lógica de range\n    if (this.isRangeValue(value)) {\n      return this.enrichRangeField(value, fieldMetadata)\n    }\n\n    // Para valores simples, aplicar operador se necessário\n    return this.enrichSimpleField(value, fieldMetadata)\n  }\n\n  /**\n   * Enriquece array com operador AND/OR (CORRIGIDO com validação de tipos)\n   */\n  private enrichArrayField(value: any[], fieldMetadata: FieldMetadata): any {\n    const fieldName = fieldMetadata.key\n    const operator = fieldMetadata.operator || this.options.defaults?.arrays?.operator || 'and'\n\n    // Se campo deve ser string, usar apenas primeiro valor\n    if (SearchStateEnricher.STRING_FIELDS.has(fieldName)) {\n      return value.length > 0 ? value[0] : null\n    }\n\n    // Se array tem só 1 elemento, retorna direto (não precisa operador)\n    if (value.length === 1) {\n      return value[0]\n    }\n\n    // Se array tem múltiplos elementos, aplica operador\n    return {\n      [operator]: value\n    }\n  }\n\n  /**\n   * Enriquece range com operador between/gte/lte\n   */\n  private enrichRangeField(value: any, fieldMetadata: FieldMetadata): any {\n    const operator = fieldMetadata.operator || this.options.defaults?.ranges?.operator || 'between'\n\n    // Se é range simples (min/max), formata baseado no operador\n    if (value.min !== undefined || value.max !== undefined) {\n      if (operator === 'between' && value.min && value.max) {\n        return { between: [value.min, value.max] }\n      }\n      if (operator === 'gte' && value.min) {\n        return { gte: value.min }\n      }\n      if (operator === 'lte' && value.max) {\n        return { lte: value.max }\n      }\n    }\n\n    return value\n  }\n\n  /**\n   * Enriquece campo simples\n   */\n  private enrichSimpleField(value: any, _fieldMetadata: FieldMetadata): any {\n    // Para a maioria dos campos simples, retorna como está (equals implícito)\n    return value\n  }\n\n  /**\n   * Busca metadata de um campo específico\n   */\n  private getFieldSchema(fieldName: string): FieldMetadata | undefined {\n    return this.schema.filters[fieldName]\n  }\n\n\n  /**\n   * Verifica se valor é um range (objeto com min/max)\n   */\n  private isRangeValue(value: any): boolean {\n    return typeof value === 'object' && \n           !Array.isArray(value) && \n           (value.min !== undefined || value.max !== undefined)\n  }\n}"]}