/** * Index File Generator * * Generates a consolidated index.ts that re-exports everything * from the generated files for clean imports. */ function pascalCase(str) { return str.charAt(0).toUpperCase() + str.slice(1) } function toPascalCase(str) { return str .split(/[.\-_]/) .map(part => part.charAt(0).toUpperCase() + part.slice(1)) .join('') } /** * Generate the consolidated index.ts file. */ export function generateIndex({ channelsSchema, mizanSchema }) { const lines = [ '/**', ' * mizan API - Consolidated Exports', ' *', ' * Import everything from here:', ' *', ' * @example', ' * ```tsx', ' * import {', ' * MizanContext,', ' * useCurrentUser,', ' * useEcho,', ' * useChatChannel,', ' * } from \'@/api\'', ' * ```', ' */', '', '// AUTO-GENERATED by mizan - do not edit manually', '// Regenerate with: npm run schemas', '', ] const functions = mizanSchema?.['x-mizan-functions'] || [] const contextGroups = mizanSchema?.['x-mizan-contexts'] || {} const hasMizan = functions.length > 0 if (hasMizan) { const globalContexts = functions.filter(fn => fn.isContext === 'global') const regularFunctions = functions.filter(fn => !fn.isContext && !fn.isForm) const namedContextEntries = Object.entries(contextGroups).filter(([name]) => name !== 'global') lines.push('// =============================================================================') lines.push('// mizan Provider & Hooks') lines.push('// =============================================================================') lines.push('') // Server exports if (globalContexts.length > 0) { lines.push('export {') lines.push(' getMizanHydration,') lines.push(' getDjangoHydration,') lines.push(' type MizanHydrationData,') lines.push(' type DjangoHydration,') lines.push("} from './generated.server'") lines.push('') } // Client exports lines.push('export {') lines.push(' // Provider') lines.push(' MizanContext,') lines.push(' type MizanContextProps,') lines.push(' DjangoContext,') lines.push(' type DjangoContextProps,') // Global context hooks if (globalContexts.length > 0) { lines.push('') lines.push(' // Global context hooks') for (const ctx of globalContexts) { const hookPascal = pascalCase(ctx.camelName) lines.push(` use${hookPascal},`) } lines.push('') lines.push(' // Refresh hooks') lines.push(' useMizanRefresh,') lines.push(' useDjangoRefresh,') } // Named context providers and hooks if (namedContextEntries.length > 0) { lines.push('') lines.push(' // Named context providers') for (const [ctxName, ctxMeta] of namedContextEntries) { const ctxPascal = toPascalCase(ctxName) lines.push(` ${ctxPascal}Context,`) // Hooks for this context's functions const ctxFunctions = functions.filter(fn => fn.isContext === ctxName) for (const fn of ctxFunctions) { const hookPascal = pascalCase(fn.camelName) lines.push(` use${hookPascal},`) } } } // Function hooks (mutations + plain) if (regularFunctions.length > 0) { lines.push('') lines.push(' // Function hooks') for (const fn of regularFunctions) { const pascal = pascalCase(fn.camelName) lines.push(` use${pascal},`) } } lines.push('') lines.push(' // Re-exports from mizan library') lines.push(' useMizan,') lines.push(' useMizanStatus,') lines.push(' usePush,') lines.push(' DjangoError,') lines.push(' type ConnectionStatus,') lines.push(' type PushMessage,') lines.push(' type PushListener,') lines.push("} from './generated.provider'") lines.push('') } // ========================================================================== // Channel Hooks // ========================================================================== const channels = channelsSchema?.['x-mizan-channels'] || [] if (channels.length > 0) { lines.push('// =============================================================================') lines.push('// Channel Hooks') lines.push('// =============================================================================') lines.push('') lines.push('export {') for (const ch of channels) { lines.push(` use${ch.pascalName}Channel,`) } lines.push("} from './generated.channels.hooks'") lines.push('') lines.push('// =============================================================================') lines.push('// Channel Types') lines.push('// =============================================================================') lines.push('') lines.push('export type {') for (const ch of channels) { if (ch.hasParams) lines.push(` ${ch.paramsType},`) if (ch.hasReactMessage) lines.push(` ${ch.reactMessageType},`) if (ch.hasDjangoMessage) lines.push(` ${ch.djangoMessageType},`) } lines.push("} from './generated.channels'") lines.push('') } return lines.join('\n') }