zeti-framework-backend 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/scripts/generate-registry.ts","../src/scripts/generate-swagger-types.ts","../src/scripts/run-prebuild.ts"],"sourcesContent":["import path from 'path';\n\nexport interface GenerateRegistryOptions {\n controllersPath: string;\n indexPath: string;\n startMarker?: string;\n endMarker?: string;\n /** Se true, escreve apenas os imports no arquivo (para .zeti/registry.ts) */\n outputMode?: 'inject' | 'standalone';\n}\n\nexport async function generateRegistry(options: GenerateRegistryOptions) {\n const {\n controllersPath,\n indexPath,\n startMarker = '// @CONTROLLERS_START',\n endMarker = '// @CONTROLLERS_END',\n outputMode = 'inject',\n } = options;\n\n // Usa Bun.Glob para listar arquivos (mais rápido)\n const glob = new Bun.Glob('**/*.ts');\n const imports: string[] = [];\n\n for await (const file of glob.scan({ cwd: controllersPath, absolute: true })) {\n const name = path.basename(file);\n if (name === 'index.ts' || name === 'registry.ts') continue;\n\n const relativePath = path.relative(path.dirname(indexPath), file);\n const importPath = relativePath.replace(/\\\\/g, '/').replace(/\\.ts$/, '');\n imports.push(`import \"${importPath.startsWith('.') ? importPath : './' + importPath}\";`);\n }\n\n if (outputMode === 'standalone') {\n const content = `// Generated by zeti-framework. Do not edit.\n\n${imports.join('\\n')}\n`;\n\n // Só escreve se o conteúdo mudou\n const file = Bun.file(indexPath);\n try {\n if (await file.exists()) {\n const existing = await file.text();\n if (existing === content) {\n console.log(`✅ Registry unchanged (${imports.length} controllers)`);\n return;\n }\n }\n } catch {\n // Arquivo não existe\n }\n\n await Bun.write(indexPath, content);\n console.log(`✅ Generated .zeti/registry.ts with ${imports.length} controller imports`);\n return;\n }\n\n // Modo inject\n const file = Bun.file(indexPath);\n const indexContent = await file.exists() ? await file.text() : '';\n\n const generatedBlock = `${startMarker}\\n${imports.join('\\n')}\\n${endMarker}`;\n\n let newContent: string;\n if (indexContent.includes(startMarker)) {\n const regex = new RegExp(`${startMarker}[\\\\s\\\\S]*?${endMarker}`, 'g');\n newContent = indexContent.replace(regex, generatedBlock);\n } else {\n newContent = indexContent + (indexContent ? '\\n\\n' : '') + generatedBlock;\n }\n\n // Só escreve se o conteúdo mudou\n if (newContent !== indexContent) {\n await Bun.write(indexPath, newContent);\n console.log(`✅ Injected ${imports.length} controller imports into ${indexPath}`);\n } else {\n console.log(`✅ Registry unchanged (${imports.length} controllers)`);\n }\n}\n","import path from 'path';\n\nexport interface GenerateSwaggerTypesOptions {\n controllersPath: string;\n outputPath: string;\n}\n\ninterface RouteInfo {\n path: string;\n method: string;\n returnType: string;\n schemaName?: string;\n hasFormData?: boolean;\n}\n\n// Divide um union type corretamente, respeitando aninhamento\nfunction splitUnionType(typeStr: string): string[] {\n const parts: string[] = [];\n let depth = 0;\n let current = '';\n \n for (let i = 0; i < typeStr.length; i++) {\n const char = typeStr[i];\n if (char === '<' || char === '{' || char === '[' || char === '(') depth++;\n else if (char === '>' || char === '}' || char === ']' || char === ')') depth--;\n else if (char === '|' && depth === 0) {\n if (current.trim()) parts.push(current.trim());\n current = '';\n continue;\n }\n current += char;\n }\n if (current.trim()) parts.push(current.trim());\n \n return parts;\n}\n\n// Converte tipo TypeScript para Zod schema, usando referências para tipos nomeados\nfunction typeToZodSchemaWithRefs(\n typeStr: string, \n typeDefinitions: Map<string, string>, \n namedSchemas: Map<string, string>,\n depth = 0\n): string {\n if (depth > 10) return 'z.any()';\n \n typeStr = typeStr.trim();\n \n // Remove Promise wrapper\n const promiseMatch = typeStr.match(/^Promise<(.+)>$/);\n if (promiseMatch) {\n typeStr = promiseMatch[1].trim();\n }\n \n // Tipos primitivos\n if (typeStr === 'string') return 'z.string()';\n if (typeStr === 'number') return 'z.number()';\n if (typeStr === 'boolean') return 'z.boolean()';\n if (typeStr === 'null') return 'z.null()';\n if (typeStr === 'undefined') return 'z.undefined()';\n if (typeStr === 'any') return 'z.any()';\n if (typeStr === 'unknown') return 'z.unknown()';\n if (typeStr === 'void') return 'z.void()';\n if (typeStr === 'Date') return 'z.date()';\n \n // String literal\n const stringLiteralMatch = typeStr.match(/^[\"'](.+)[\"']$/);\n if (stringLiteralMatch) {\n return `z.literal(\"${stringLiteralMatch[1]}\")`;\n }\n \n // Number literal\n if (/^\\d+$/.test(typeStr)) {\n return `z.literal(${typeStr})`;\n }\n \n // Array com tipo nomeado: TypeName[]\n const arrayNamedMatch = typeStr.match(/^(\\w+)\\[\\]$/);\n if (arrayNamedMatch) {\n const itemType = arrayNamedMatch[1];\n if (typeDefinitions.has(itemType)) {\n // Garante que o tipo referenciado seja processado\n if (!namedSchemas.has(itemType)) {\n const typeDef = typeDefinitions.get(itemType)!;\n namedSchemas.set(itemType, typeToZodSchemaWithRefs(typeDef, typeDefinitions, namedSchemas, depth + 1));\n }\n return `z.array(namedSchemas.${itemType})`;\n }\n return `z.array(${typeToZodSchemaWithRefs(itemType, typeDefinitions, namedSchemas, depth + 1)})`;\n }\n \n // Array genérico: Array<Type>\n const arrayGenericMatch = typeStr.match(/^Array<(.+)>$/);\n if (arrayGenericMatch) {\n const itemType = arrayGenericMatch[1].trim();\n if (typeDefinitions.has(itemType)) {\n if (!namedSchemas.has(itemType)) {\n const typeDef = typeDefinitions.get(itemType)!;\n namedSchemas.set(itemType, typeToZodSchemaWithRefs(typeDef, typeDefinitions, namedSchemas, depth + 1));\n }\n return `z.array(namedSchemas.${itemType})`;\n }\n return `z.array(${typeToZodSchemaWithRefs(itemType, typeDefinitions, namedSchemas, depth + 1)})`;\n }\n \n // Verifica se é uma referência a um tipo definido\n if (/^[A-Z]\\w*$/.test(typeStr) && typeDefinitions.has(typeStr)) {\n // Garante que o tipo referenciado seja processado\n if (!namedSchemas.has(typeStr)) {\n const typeDef = typeDefinitions.get(typeStr)!;\n namedSchemas.set(typeStr, typeToZodSchemaWithRefs(typeDef, typeDefinitions, namedSchemas, depth + 1));\n }\n return `namedSchemas.${typeStr}`;\n }\n \n // Object inline { key: type, ... }\n if (typeStr.startsWith('{') && typeStr.endsWith('}')) {\n const inner = typeStr.slice(1, -1).trim();\n if (!inner) return 'z.object({})';\n \n const props: string[] = [];\n let currentDepth = 0;\n let current = '';\n let inString = false;\n let stringChar = '';\n \n for (let i = 0; i < inner.length; i++) {\n const char = inner[i];\n \n if (!inString && (char === '\"' || char === \"'\" || char === '`')) {\n inString = true;\n stringChar = char;\n current += char;\n } else if (inString && char === stringChar && inner[i - 1] !== '\\\\') {\n inString = false;\n current += char;\n } else if (!inString) {\n if (char === '{' || char === '<' || char === '[' || char === '(') currentDepth++;\n else if (char === '}' || char === '>' || char === ']' || char === ')') currentDepth--;\n \n if ((char === ',' || char === ';') && currentDepth === 0) {\n if (current.trim()) props.push(current.trim());\n current = '';\n } else {\n current += char;\n }\n } else {\n current += char;\n }\n }\n if (current.trim()) props.push(current.trim());\n \n const zodProps = props.map(prop => {\n let colonIndex = -1;\n let propDepth = 0;\n for (let i = 0; i < prop.length; i++) {\n const char = prop[i];\n if (char === '<' || char === '{' || char === '[') propDepth++;\n else if (char === '>' || char === '}' || char === ']') propDepth--;\n else if (char === ':' && propDepth === 0) {\n colonIndex = i;\n break;\n }\n }\n \n if (colonIndex === -1) return null;\n \n let key = prop.slice(0, colonIndex).trim();\n const value = prop.slice(colonIndex + 1).trim();\n \n const isOptional = key.endsWith('?');\n if (isOptional) key = key.slice(0, -1);\n \n const zodType = typeToZodSchemaWithRefs(value, typeDefinitions, namedSchemas, depth + 1);\n return `${key}: ${isOptional ? `${zodType}.optional()` : zodType}`;\n }).filter(Boolean);\n \n return `z.object({ ${zodProps.join(', ')} })`;\n }\n \n // Union type\n if (typeStr.includes('|') && !typeStr.includes('{')) {\n const types = splitUnionType(typeStr).map(t => typeToZodSchemaWithRefs(t.trim(), typeDefinitions, namedSchemas, depth + 1));\n if (types.length === 2 && types.includes('z.undefined()')) {\n const other = types.find(t => t !== 'z.undefined()');\n return `${other}.optional()`;\n }\n if (types.length === 2 && types.includes('z.null()')) {\n const other = types.find(t => t !== 'z.null()');\n return `${other}.nullable()`;\n }\n return `z.union([${types.join(', ')}])`;\n }\n\n // Referência a tipo não encontrado\n if (/^[A-Z]\\w*$/.test(typeStr)) {\n return 'z.any()';\n }\n\n return 'z.any()';\n}\n\n// Converte tipo TypeScript inline para Zod schema (versão sem referências - para compatibilidade)\nfunction typeToZodSchema(typeStr: string, typeDefinitions: Map<string, string>, depth = 0): string {\n if (depth > 10) return 'z.any()'; // Previne recursão infinita\n \n typeStr = typeStr.trim();\n \n // Remove Promise wrapper\n const promiseMatch = typeStr.match(/^Promise<(.+)>$/);\n if (promiseMatch) {\n typeStr = promiseMatch[1].trim();\n }\n \n // Tipos primitivos\n if (typeStr === 'string') return 'z.string()';\n if (typeStr === 'number') return 'z.number()';\n if (typeStr === 'boolean') return 'z.boolean()';\n if (typeStr === 'null') return 'z.null()';\n if (typeStr === 'undefined') return 'z.undefined()';\n if (typeStr === 'any') return 'z.any()';\n if (typeStr === 'unknown') return 'z.unknown()';\n if (typeStr === 'void') return 'z.void()';\n if (typeStr === 'Date') return 'z.date()';\n \n // String literal\n const stringLiteralMatch = typeStr.match(/^[\"'](.+)[\"']$/);\n if (stringLiteralMatch) {\n return `z.literal(\"${stringLiteralMatch[1]}\")`;\n }\n \n // Number literal\n if (/^\\d+$/.test(typeStr)) {\n return `z.literal(${typeStr})`;\n }\n \n // Array\n const arrayMatch = typeStr.match(/^(.+)\\[\\]$/) || typeStr.match(/^Array<(.+)>$/);\n if (arrayMatch) {\n return `z.array(${typeToZodSchema(arrayMatch[1], typeDefinitions, depth + 1)})`;\n }\n \n // Verifica se é uma referência a um tipo definido (antes de processar como objeto)\n if (/^[A-Z]\\w*$/.test(typeStr) && typeDefinitions.has(typeStr)) {\n const typeDef = typeDefinitions.get(typeStr)!;\n return typeToZodSchema(typeDef, typeDefinitions, depth + 1);\n }\n \n // Object inline { key: type, ... }\n if (typeStr.startsWith('{') && typeStr.endsWith('}')) {\n const inner = typeStr.slice(1, -1).trim();\n if (!inner) return 'z.object({})';\n \n const props: string[] = [];\n let currentDepth = 0;\n let current = '';\n let inString = false;\n let stringChar = '';\n \n for (let i = 0; i < inner.length; i++) {\n const char = inner[i];\n \n if (!inString && (char === '\"' || char === \"'\" || char === '`')) {\n inString = true;\n stringChar = char;\n current += char;\n } else if (inString && char === stringChar && inner[i - 1] !== '\\\\') {\n inString = false;\n current += char;\n } else if (!inString) {\n if (char === '{' || char === '<' || char === '[' || char === '(') currentDepth++;\n else if (char === '}' || char === '>' || char === ']' || char === ')') currentDepth--;\n \n if ((char === ',' || char === ';') && currentDepth === 0) {\n if (current.trim()) props.push(current.trim());\n current = '';\n } else {\n current += char;\n }\n } else {\n current += char;\n }\n }\n if (current.trim()) props.push(current.trim());\n \n const zodProps = props.map(prop => {\n // Encontra o primeiro : que não está dentro de um tipo genérico\n let colonIndex = -1;\n let depth = 0;\n for (let i = 0; i < prop.length; i++) {\n const char = prop[i];\n if (char === '<' || char === '{' || char === '[') depth++;\n else if (char === '>' || char === '}' || char === ']') depth--;\n else if (char === ':' && depth === 0) {\n colonIndex = i;\n break;\n }\n }\n \n if (colonIndex === -1) return null;\n \n let key = prop.slice(0, colonIndex).trim();\n const value = prop.slice(colonIndex + 1).trim();\n \n const isOptional = key.endsWith('?');\n if (isOptional) key = key.slice(0, -1);\n \n const zodType = typeToZodSchema(value, typeDefinitions, depth + 1);\n return `${key}: ${isOptional ? `${zodType}.optional()` : zodType}`;\n }).filter(Boolean);\n \n return `z.object({ ${zodProps.join(', ')} })`;\n }\n \n // Union type\n if (typeStr.includes('|') && !typeStr.includes('{')) {\n const types = splitUnionType(typeStr).map(t => typeToZodSchema(t.trim(), typeDefinitions, depth + 1));\n if (types.length === 2 && types.includes('z.undefined()')) {\n const other = types.find(t => t !== 'z.undefined()');\n return `${other}.optional()`;\n }\n if (types.length === 2 && types.includes('z.null()')) {\n const other = types.find(t => t !== 'z.null()');\n return `${other}.nullable()`;\n }\n return `z.union([${types.join(', ')}])`;\n }\n \n // Intersection type\n if (typeStr.includes('&') && !typeStr.includes('{')) {\n const types = typeStr.split('&').map(t => typeToZodSchema(t.trim(), typeDefinitions, depth + 1));\n return `z.intersection(${types.join(', ')})`;\n }\n \n // Referência a tipo não encontrado - retorna z.any()\n if (/^[A-Z]\\w*$/.test(typeStr)) {\n return 'z.any()';\n }\n \n return 'z.any()';\n}\n\n// Extrai definições de tipos do arquivo (suporta tipos aninhados)\nfunction extractTypeDefinitions(content: string): Map<string, string> {\n const types = new Map<string, string>();\n \n // Remove comentários para evitar falsos positivos\n const cleanContent = content\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n .replace(/\\/\\/.*$/gm, '');\n \n // Captura: type Name = { ... } ou interface Name { ... }\n // Usa uma abordagem mais robusta para capturar objetos aninhados\n const typeRegex = /(?:export\\s+)?(?:type|interface)\\s+(\\w+)\\s*=?\\s*\\{/g;\n \n let match;\n while ((match = typeRegex.exec(cleanContent)) !== null) {\n const name = match[1];\n const startIndex = match.index + match[0].length - 1; // Posição do {\n \n // Encontra o } correspondente\n let depth = 1;\n let endIndex = startIndex + 1;\n \n while (depth > 0 && endIndex < cleanContent.length) {\n const char = cleanContent[endIndex];\n if (char === '{') depth++;\n else if (char === '}') depth--;\n endIndex++;\n }\n \n const body = cleanContent.slice(startIndex, endIndex);\n types.set(name, body);\n }\n \n return types;\n}\n\n// Extrai rotas usando regex (muito mais rápido que TypeScript parser)\nfunction extractRoutes(\n content: string, \n typeDefinitions: Map<string, string>,\n namedSchemas: Map<string, string>\n): RouteInfo[] {\n const routes: RouteInfo[] = [];\n \n // Regex para capturar app.get/post/etc ou get/post/etc\n const routeRegex = /(?:app\\.)?(get|post|put|del|patch)\\s*\\(\\s*[\"'`]([^\"'`]+)[\"'`]/g;\n \n let match;\n while ((match = routeRegex.exec(content)) !== null) {\n const [fullMatch, method, routePath] = match;\n \n // Procura o bloco da rota após o match\n const afterMatch = content.slice(match.index + fullMatch.length, match.index + fullMatch.length + 2000);\n \n let returnType = 'z.any()';\n let schemaName: string | undefined;\n \n // Tenta encontrar tipo explícito: Promise<TypeName> ou Promise<{...}>\n const explicitTypeMatch = afterMatch.match(/route\\s*:\\s*async\\s*\\([^)]*\\)\\s*:\\s*Promise\\s*<([^>]+)>/);\n if (explicitTypeMatch) {\n const typeRef = explicitTypeMatch[1].trim();\n \n // Verifica se é uma referência a um tipo definido\n if (typeDefinitions.has(typeRef)) {\n // Garante que o tipo seja processado com referências\n if (!namedSchemas.has(typeRef)) {\n const typeDef = typeDefinitions.get(typeRef)!;\n namedSchemas.set(typeRef, typeToZodSchemaWithRefs(typeDef, typeDefinitions, namedSchemas));\n }\n returnType = `namedSchemas.${typeRef}`;\n schemaName = typeRef;\n } else {\n // Tipo inline\n returnType = typeToZodSchemaWithRefs(typeRef, typeDefinitions, namedSchemas);\n }\n } else {\n // Tenta inferir do return statement\n const returnMatch = afterMatch.match(/return\\s+(\\{[^}]+\\})/);\n if (returnMatch) {\n returnType = inferTypeFromValue(returnMatch[1]);\n }\n }\n\n routes.push({\n path: routePath,\n method: method === 'del' ? 'delete' : method,\n returnType,\n schemaName,\n hasFormData: content.includes('formData'),\n });\n }\n \n return routes;\n}\n\n// Infere tipo Zod a partir de um valor literal\nfunction inferTypeFromValue(value: string): string {\n value = value.trim();\n \n // Objeto literal\n if (value.startsWith('{') && value.endsWith('}')) {\n const inner = value.slice(1, -1).trim();\n if (!inner) return 'z.object({})';\n \n const props: string[] = [];\n \n // Parse simples de propriedades\n const propRegex = /(\\w+)\\s*:\\s*(\"[^\"]*\"|'[^']*'|`[^`]*`|\\d+|true|false|null|\\{[^}]*\\}|\\[[^\\]]*\\])/g;\n let propMatch;\n \n while ((propMatch = propRegex.exec(inner)) !== null) {\n const [, key, val] = propMatch;\n const zodType = inferTypeFromValue(val);\n props.push(`${key}: ${zodType}`);\n }\n \n if (props.length > 0) {\n return `z.object({ ${props.join(', ')} })`;\n }\n }\n \n // String literal\n if ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\")) ||\n (value.startsWith('`') && value.endsWith('`'))) {\n return 'z.string()';\n }\n \n // Number\n if (/^\\d+(\\.\\d+)?$/.test(value)) {\n return 'z.number()';\n }\n \n // Boolean\n if (value === 'true' || value === 'false') {\n return 'z.boolean()';\n }\n \n // Null\n if (value === 'null') {\n return 'z.null()';\n }\n \n // Array\n if (value.startsWith('[') && value.endsWith(']')) {\n return 'z.array(z.any())';\n }\n \n return 'z.any()';\n}\n\nexport async function generateSwaggerTypes(options: GenerateSwaggerTypesOptions) {\n const { controllersPath, outputPath } = options;\n\n const routes: RouteInfo[] = [];\n const namedSchemas: Map<string, string> = new Map();\n\n // Usa Bun.Glob para listar arquivos\n const glob = new Bun.Glob('**/*.ts');\n const files: string[] = [];\n \n for await (const file of glob.scan({ cwd: controllersPath, absolute: true })) {\n const name = path.basename(file);\n if (name !== 'index.ts' && name !== 'registry.ts') {\n files.push(file);\n }\n }\n \n // Processa todos os arquivos em paralelo usando Bun.file\n await Promise.all(files.map(async (filePath) => {\n const file = Bun.file(filePath);\n const content = await file.text();\n \n // Extrai definições de tipos do arquivo\n const typeDefinitions = extractTypeDefinitions(content);\n \n // Adiciona TODOS os tipos definidos como schemas nomeados\n for (const [typeName, typeDef] of typeDefinitions) {\n if (!namedSchemas.has(typeName)) {\n const zodSchema = typeToZodSchemaWithRefs(typeDef, typeDefinitions, namedSchemas);\n namedSchemas.set(typeName, zodSchema);\n }\n }\n \n // Extrai rotas passando as definições de tipos\n const fileRoutes = extractRoutes(content, typeDefinitions, namedSchemas);\n \n routes.push(...fileRoutes);\n }));\n\n await writeOutput(outputPath, routes, namedSchemas);\n}\n\n// Ordena schemas por dependência (topological sort)\nfunction sortSchemasByDependency(schemas: Map<string, string>): string[] {\n const sorted: string[] = [];\n const visited = new Set<string>();\n const visiting = new Set<string>();\n \n function getDependencies(schema: string): string[] {\n const deps: string[] = [];\n // Procura por referências a outros schemas: namedSchemas.TypeName ou _TypeName\n const refMatches = schema.matchAll(/(?:namedSchemas\\.|_)([A-Z]\\w*)/g);\n for (const match of refMatches) {\n if (schemas.has(match[1])) {\n deps.push(match[1]);\n }\n }\n return deps;\n }\n \n function visit(name: string) {\n if (visited.has(name)) return;\n if (visiting.has(name)) return; // Ciclo detectado, ignora\n \n visiting.add(name);\n const schema = schemas.get(name);\n if (schema) {\n for (const dep of getDependencies(schema)) {\n visit(dep);\n }\n }\n visiting.delete(name);\n visited.add(name);\n sorted.push(name);\n }\n \n for (const name of schemas.keys()) {\n visit(name);\n }\n \n return sorted;\n}\n\nasync function writeOutput(outputPath: string, routes: RouteInfo[], namedSchemas: Map<string, string>) {\n const namedSchemasEntries = Array.from(namedSchemas.entries());\n \n // Ordena schemas por dependência\n const sortedNames = sortSchemasByDependency(namedSchemas);\n \n // Gera cada schema como uma variável separada (para evitar referência circular)\n const schemaDeclarations = sortedNames.map(name => {\n const schema = namedSchemas.get(name)!;\n // Substitui namedSchemas.X por _X (variável local)\n const fixedSchema = schema.replace(/namedSchemas\\.([A-Z]\\w*)/g, '_$1');\n return `const _${name} = ${fixedSchema};`;\n }).join('\\n');\n \n // Gera o objeto namedSchemas referenciando as variáveis\n const namedSchemasOutput = namedSchemasEntries.length > 0\n ? `export const namedSchemas = {\\n${sortedNames.map(name => ` ${name}: _${name},`).join('\\n')}\\n} as const;\\n\\n`\n : `export const namedSchemas = {} as const;\\n\\n`;\n\n const routeSchemasOutput = routes.map((r) => {\n const hasFormDataStr = r.hasFormData ? ', hasFormData: true' : '';\n if (r.schemaName) {\n return ` \"${r.path}\": { \"${r.method}\": { schema: _${r.schemaName}, ref: \"${r.schemaName}\"${hasFormDataStr} } },`;\n }\n // Substitui namedSchemas.X por _X no returnType também\n const fixedReturnType = r.returnType.replace(/namedSchemas\\.([A-Z]\\w*)/g, '_$1');\n return ` \"${r.path}\": { \"${r.method}\": { schema: ${fixedReturnType}, ref: null${hasFormDataStr} } },`;\n }).join('\\n');\n\n const output = `// Auto-generated by @zeti/framework/scripts\n// Do not edit manually\n\nimport { z } from \"zod\";\n\n${schemaDeclarations}\n\n${namedSchemasOutput}export const routeResponseSchemas: Record<string, Record<string, { schema: z.ZodTypeAny; ref: string | null; hasFormData?: boolean }>> = {\n${routeSchemasOutput}\n};\n`;\n\n const file = Bun.file(outputPath);\n \n try {\n if (await file.exists()) {\n const existing = await file.text();\n if (existing === output) {\n console.log(`✅ Response schemas unchanged (${routes.length} routes)`);\n return;\n }\n }\n } catch {\n // Arquivo não existe\n }\n\n await Bun.write(outputPath, output);\n console.log(`✅ Generated response schemas for ${routes.length} routes (${namedSchemasEntries.length} named schemas)`);\n}\n","import path from 'path';\nimport { generateRegistry } from './generate-registry.js';\nimport { generateSwaggerTypes } from './generate-swagger-types.js';\nimport type { ZetiConfigInternal } from '../types/config.js';\n\nexport interface RunPrebuildOptions {\n projectRoot?: string;\n zetiConfig?: ZetiConfigInternal;\n controllersPath?: string;\n registryPath?: string;\n swaggerOutputPath?: string;\n prismaImport?: string;\n /** Forçar regeneração mesmo se não houver mudanças */\n force?: boolean;\n}\n\nconst CACHE_FILE = '.zeti/.prebuild-cache.json';\n\nasync function getFileHash(filePath: string): Promise<string> {\n try {\n const file = Bun.file(filePath);\n const stat = await file.stat();\n return `${stat.mtime}-${stat.size}`;\n } catch {\n return '';\n }\n}\n\nasync function loadCache(projectRoot: string): Promise<Map<string, string>> {\n const cachePath = path.join(projectRoot, CACHE_FILE);\n try {\n const file = Bun.file(cachePath);\n if (await file.exists()) {\n const data = await file.json();\n return new Map(Object.entries(data));\n }\n } catch {\n // Cache corrupto, ignora\n }\n return new Map();\n}\n\nasync function saveCache(projectRoot: string, cache: Map<string, string>): Promise<void> {\n const cachePath = path.join(projectRoot, CACHE_FILE);\n try {\n await Bun.write(cachePath, JSON.stringify(Object.fromEntries(cache)));\n } catch {\n // Falha ao salvar cache não é crítico\n }\n}\n\nasync function hasChanges(controllersPath: string, cache: Map<string, string>): Promise<{ changed: boolean; newCache: Map<string, string> }> {\n const newCache = new Map<string, string>();\n let changed = false;\n\n // Verifica se a pasta existe\n const dirFile = Bun.file(controllersPath);\n try {\n await dirFile.stat();\n } catch {\n return { changed: cache.size > 0, newCache };\n }\n\n // Lista todos os arquivos .ts recursivamente usando Bun.Glob\n const glob = new Bun.Glob('**/*.ts');\n const files: string[] = [];\n \n for await (const file of glob.scan({ cwd: controllersPath, absolute: true })) {\n const name = path.basename(file);\n if (name !== 'index.ts' && name !== 'registry.ts') {\n files.push(file);\n }\n }\n\n // Processa em paralelo\n await Promise.all(files.map(async (file) => {\n const hash = await getFileHash(file);\n newCache.set(file, hash);\n\n if (cache.get(file) !== hash) {\n changed = true;\n }\n }));\n\n // Verifica se algum arquivo foi removido\n for (const file of cache.keys()) {\n if (!newCache.has(file)) {\n changed = true;\n break;\n }\n }\n\n return { changed, newCache };\n}\n\nconst APP_FILE_CONTENT = `import { createAppProxy, getRedisClient, hasRedis } from 'zeti-framework';\nimport type { PrismaClient } from '@prisma/client';\nimport type { Redis } from 'ioredis';\n\nexport const app = createAppProxy<PrismaClient, any>();\n\n/**\n * Cliente Redis singleton via Proxy.\n * Disponível após configuração em startZeti({ redis: {...} }).\n * \n * @example\n * import { app, redis } from '@zeti/app';\n * \n * await redis.set('key', 'value');\n * const value = await redis.get('key');\n */\nexport const redis: Redis = new Proxy({} as Redis, {\n get(_, prop) {\n if (!hasRedis()) {\n throw new Error('[Redis] Not configured. Add redis config to startZeti()');\n }\n const client = getRedisClient();\n const value = (client as any)[prop];\n return typeof value === 'function' ? value.bind(client) : value;\n }\n});\n\nexport const { get, post, put, del, patch, createMiddleware } = app;\n`;\n\nconst PRISMA_HELPERS_CONTENT = `/**\n * Helpers tipados para o PrismaClient do projeto\n * \n * Gerado automaticamente pelo zeti-framework.\n * Use estes helpers em middlewares e outros lugares onde\n * o tipo do PrismaClient não é inferido automaticamente.\n */\n\nimport type { Context, Next } from 'hono';\nimport type { PrismaClient } from '@prisma/client';\nimport { \n getPrismaClient as _getPrismaClient, \n getSpecialDatabase as _getSpecialDatabase,\n createMiddleware as _createMiddleware,\n} from 'zeti-framework';\nimport type { MiddlewareHandler as _MiddlewareHandler } from 'zeti-framework';\n\n// Re-exporta o tipo do PrismaClient\nexport type { PrismaClient };\nexport type AppPrismaClient = PrismaClient;\n\n/**\n * Handler de middleware tipado com o PrismaClient do projeto.\n */\nexport type MiddlewareHandler = _MiddlewareHandler<PrismaClient>;\n\n/**\n * Cria um middleware com o db tipado automaticamente.\n * \n * @example\n * import { createMiddleware } from '.zeti/prisma';\n * \n * export const authMiddleware = createMiddleware(async (c, next, db) => {\n * // db já vem tipado com os models do schema.prisma\n * const user = await db.user.findUnique({\n * where: { id: c.req.header('x-user-id') }\n * });\n * \n * if (!user) {\n * return c.json({ error: 'Unauthorized' }, 401);\n * }\n * \n * c.set('user', user);\n * await next();\n * });\n */\nexport function createMiddleware(\n handler: MiddlewareHandler\n): (c: Context, next: Next) => Promise<void | Response> {\n return _createMiddleware<PrismaClient>(handler);\n}\n\n/**\n * Cria uma factory de middleware com db tipado.\n * \n * @example\n * import { createMiddlewareFactory } from '.zeti/prisma';\n * \n * const requirePermission = createMiddlewareFactory(\n * (permissions: string[]) => async (c, next, db) => {\n * const user = c.get('user');\n * const userPerms = await db.permission.findMany({\n * where: { userId: user.id }\n * });\n * \n * if (!permissions.every(p => userPerms.some(up => up.name === p))) {\n * return c.json({ error: 'Forbidden' }, 403);\n * }\n * \n * await next();\n * }\n * );\n * \n * // Uso:\n * app.use('/admin/*', requirePermission(['admin:read']));\n */\nexport function createMiddlewareFactory<T extends any[]>(\n factory: (...args: T) => MiddlewareHandler\n): (...args: T) => (c: Context, next: Next) => Promise<void | Response> {\n return (...args: T) => _createMiddleware<PrismaClient>(factory(...args));\n}\n\n/**\n * Retorna o PrismaClient com tipagem correta do projeto\n * \n * @param tenantId - ID do tenant (opcional, usa o padrão se não fornecido)\n * @returns PrismaClient tipado com os models do schema.prisma\n * \n * @example\n * const db = getPrismaClient();\n * const users = await db.user.findMany(); // ✅ Tipado corretamente\n */\nexport function getPrismaClient(tenantId?: string): PrismaClient {\n return _getPrismaClient<PrismaClient>(tenantId);\n}\n\n/**\n * Retorna um database especial com tipagem correta\n * \n * @param key - Chave do database especial configurado em specialDatabases\n * @returns PrismaClient tipado\n * \n * @example\n * const adminDb = getSpecialDatabase('admin');\n * const logs = await adminDb.auditLog.findMany();\n */\nexport function getSpecialDatabase(key: string): PrismaClient {\n return _getSpecialDatabase<PrismaClient>(key);\n}\n`;\n\nasync function ensureAppFile(zetiDir: string, prismaImport: string): Promise<boolean> {\n const appPath = path.join(zetiDir, 'app.ts');\n const expectedContent = APP_FILE_CONTENT.replace('@prisma/client', prismaImport);\n \n try {\n const file = Bun.file(appPath);\n if (await file.exists()) {\n const currentContent = await file.text();\n if (currentContent === expectedContent) {\n return false; // Não mudou\n }\n }\n } catch {\n // Arquivo não existe ou erro ao ler\n }\n \n await Bun.write(appPath, expectedContent);\n return true;\n}\n\nasync function ensurePrismaHelpersFile(zetiDir: string, prismaImport: string): Promise<boolean> {\n const helpersPath = path.join(zetiDir, 'prisma.ts');\n const expectedContent = PRISMA_HELPERS_CONTENT.replace(/@prisma\\/client/g, prismaImport);\n \n try {\n const file = Bun.file(helpersPath);\n if (await file.exists()) {\n const currentContent = await file.text();\n if (currentContent === expectedContent) {\n return false; // Não mudou\n }\n }\n } catch {\n // Arquivo não existe ou erro ao ler\n }\n \n await Bun.write(helpersPath, expectedContent);\n return true;\n}\n\nexport async function runPrebuild(options: RunPrebuildOptions = {}): Promise<void> {\n const startTime = Bun.nanoseconds();\n const projectRoot = path.resolve(options.projectRoot || process.cwd());\n const zetiConfig = options.zetiConfig;\n\n const controllersPath = path.join(\n projectRoot,\n options.controllersPath || 'src/controllers'\n );\n const zetiDir = path.join(projectRoot, '.zeti');\n const registryPath = path.join(zetiDir, 'registry.ts');\n const swaggerOutputPath =\n options.swaggerOutputPath ||\n (zetiConfig?.swagger?.outputPath\n ? path.isAbsolute(zetiConfig.swagger.outputPath)\n ? zetiConfig.swagger.outputPath\n : path.join(projectRoot, zetiConfig.swagger.outputPath)\n : path.join(zetiDir, 'generated/swagger-schemas.ts'));\n\n // Garante que a pasta .zeti existe\n const fs = await import('fs');\n if (!fs.existsSync(zetiDir)) {\n fs.mkdirSync(zetiDir, { recursive: true });\n console.log('📁 [zeti] Created .zeti directory');\n }\n\n // Verifica se app.ts e prisma.ts precisam ser criados/atualizados\n const prismaImport = options.prismaImport || '@prisma/client';\n const [appChanged, prismaHelpersChanged] = await Promise.all([\n ensureAppFile(zetiDir, prismaImport),\n ensurePrismaHelpersFile(zetiDir, prismaImport),\n ]);\n\n // Carrega cache e verifica mudanças\n const cache = await loadCache(projectRoot);\n const { changed, newCache } = await hasChanges(controllersPath, cache);\n\n if (!options.force && !changed && !appChanged && !prismaHelpersChanged) {\n const elapsed = ((Bun.nanoseconds() - startTime) / 1_000_000).toFixed(0);\n console.log(`⚡ [zeti] No changes detected (${elapsed}ms)`);\n return;\n }\n\n console.log('🔄 [zeti] Generating files...');\n\n // Gera registry e swagger em paralelo\n await Promise.all([\n generateRegistry({\n controllersPath,\n indexPath: registryPath,\n outputMode: 'standalone',\n }),\n generateSwaggerTypes({\n controllersPath,\n outputPath: swaggerOutputPath,\n }),\n ]);\n\n // Salva cache\n await saveCache(projectRoot, newCache);\n\n const elapsed = ((Bun.nanoseconds() - startTime) / 1_000_000).toFixed(0);\n console.log(`✅ [zeti] Prebuild complete! (${elapsed}ms)`);\n}\n"],"mappings":"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","names":["file","path","path","path","path","elapsed"]}